Skip to content

Commit

Permalink
action_sheet: Pass/use whole-page context in show{Message,Topic}Actio…
Browse files Browse the repository at this point in the history
…nSheet
  • Loading branch information
chrisbobbe committed Jan 24, 2025
1 parent f200ff9 commit 3e67860
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
16 changes: 12 additions & 4 deletions lib/widgets/action_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,16 @@ class ActionSheetCancelButton extends StatelessWidget {
}

/// Show a sheet of actions you can take on a topic.
void showTopicActionSheet(BuildContext context, {
///
/// [pageContext] should be the context of the whole page in the nav,
/// not of the specific element that was long-pressed.
/// The long-pressed element live-updates on server events,
/// so it might unmount before the action-sheet buttons have finished using it.
void showTopicActionSheet(BuildContext pageContext, {
required int channelId,
required TopicName topic,
}) {
final store = PerAccountStoreWidget.of(context);
final store = PerAccountStoreWidget.of(pageContext);
final subscription = store.subscriptions[channelId];

final optionButtons = <ActionSheetMenuItemButton>[];
Expand Down Expand Up @@ -237,7 +242,7 @@ void showTopicActionSheet(BuildContext context, {
currentVisibilityPolicy: visibilityPolicy,
newVisibilityPolicy: to,
narrow: TopicNarrow(channelId, topic),
pageContext: context);
pageContext: pageContext);
}));

if (optionButtons.isEmpty) {
Expand All @@ -250,7 +255,7 @@ void showTopicActionSheet(BuildContext context, {
return;
}

_showActionSheet(context, optionButtons: optionButtons);
_showActionSheet(pageContext, optionButtons: optionButtons);
}

class UserTopicUpdateButton extends ActionSheetMenuItemButton {
Expand Down Expand Up @@ -390,6 +395,9 @@ void showMessageActionSheet({required BuildContext context, required Message mes
final markAsUnreadSupported = store.connection.zulipFeatureLevel! >= 155; // TODO(server-6)
final showMarkAsUnreadButton = markAsUnreadSupported && isMessageRead;

// TODO like in showTopicActionSheet, don't pass buttons a BuildContext
// for live-updating UI that could unmount before it's finished being used.

final optionButtons = [
ReactionButtons(message: message, pageContext: context),
StarButton(message: message, pageContext: context),
Expand Down
25 changes: 23 additions & 2 deletions lib/widgets/inbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,34 @@ import 'text.dart';
import 'theme.dart';
import 'unread_count_badge.dart';


/// The interface for the state of an [InboxPageBody].
///
/// To obtain one of these, see [InboxPageBody.ancestorOf].
abstract class InboxPageState {
BuildContext get context;
}

class InboxPageBody extends StatefulWidget {
const InboxPageBody({super.key});

/// The [InboxPageState] above this context in the tree.
///
/// Uses the inefficient [BuildContext.findAncestorStateOfType];
/// don't call this in a build method.
// If we do find ourselves wanting this in a build method, it won't be hard
// to enable that: we'd just need to add an [InheritedWidget] here.
static InboxPageState ancestorOf(BuildContext context) {
final state = context.findAncestorStateOfType<_InboxPageState>();
assert(state != null, 'No InboxPageBody ancestor');
return state!;
}

@override
State<InboxPageBody> createState() => _InboxPageState();
}

class _InboxPageState extends State<InboxPageBody> with PerAccountStoreAwareStateMixin<InboxPageBody> {
class _InboxPageState extends State<InboxPageBody> with PerAccountStoreAwareStateMixin<InboxPageBody> implements InboxPageState {
Unreads? unreadsModel;
RecentDmConversationsView? recentDmConversationsModel;

Expand Down Expand Up @@ -516,7 +536,8 @@ class _TopicItem extends StatelessWidget {
Navigator.push(context,
MessageListPage.buildRoute(context: context, narrow: narrow));
},
onLongPress: () => showTopicActionSheet(context,
onLongPress: () => showTopicActionSheet(
InboxPageBody.ancestorOf(context).context,
channelId: streamId, topic: topic),
child: ConstrainedBox(constraints: const BoxConstraints(minHeight: 34),
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
Expand Down
8 changes: 6 additions & 2 deletions lib/widgets/message_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ abstract class MessageListPageState {
///
/// This is null if [MessageList] has not mounted yet.
MessageListView? get model;

BuildContext get context;
}

class MessageListPage extends StatefulWidget {
Expand Down Expand Up @@ -400,7 +402,8 @@ class MessageListAppBarTitle extends StatelessWidget {
width: double.infinity,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onLongPress: () => showTopicActionSheet(context,
onLongPress: () => showTopicActionSheet(
MessageListPage.ancestorOf(context).context,
channelId: streamId, topic: topic),
child: Column(
crossAxisAlignment: willCenterTitle ? CrossAxisAlignment.center
Expand Down Expand Up @@ -1112,7 +1115,8 @@ class StreamMessageRecipientHeader extends StatelessWidget {
onTap: () => Navigator.push(context,
MessageListPage.buildRoute(context: context,
narrow: TopicNarrow.ofMessage(message))),
onLongPress: () => showTopicActionSheet(context,
onLongPress: () => showTopicActionSheet(
MessageListPage.ancestorOf(context).context,
channelId: message.streamId, topic: topic),
child: ColoredBox(
color: backgroundColor,
Expand Down

0 comments on commit 3e67860

Please sign in to comment.