@@ -100,13 +100,13 @@ abstract class MessageActionSheetMenuItemButton extends StatelessWidget {
100
100
IconData get icon;
101
101
String label (ZulipLocalizations zulipLocalizations);
102
102
103
- /// Called when the button is pressed.
103
+ /// Called when the button is pressed, after dismissing the action sheet .
104
104
///
105
- /// Generally this method's implementation should begin by dismissing the
106
- /// action sheet with [NavigatorState.pop] .
107
- /// After that step, the given `context` may no longer be mounted;
108
- /// operations that need a [BuildContext] should typically use [pageContext] .
109
- void onPressed (BuildContext context );
105
+ /// If the action may take a long time, this method is responsible for
106
+ /// arranging any form of progress feedback that may be desired .
107
+ ///
108
+ /// For operations that need a [BuildContext] , see [pageContext] .
109
+ void onPressed ();
110
110
111
111
final Message message;
112
112
@@ -124,6 +124,15 @@ abstract class MessageActionSheetMenuItemButton extends StatelessWidget {
124
124
return MessageListPage .ancestorOf (pageContext);
125
125
}
126
126
127
+ void _handlePressed (BuildContext context) {
128
+ // Dismiss the enclosing action sheet immediately,
129
+ // for swift UI feedback that the user's selection was received.
130
+ Navigator .of (context).pop ();
131
+
132
+ assert (pageContext.mounted);
133
+ onPressed ();
134
+ }
135
+
127
136
@override
128
137
Widget build (BuildContext context) {
129
138
final designVariables = DesignVariables .of (context);
@@ -137,7 +146,7 @@ abstract class MessageActionSheetMenuItemButton extends StatelessWidget {
137
146
).copyWith (backgroundColor: WidgetStateColor .resolveWith ((states) =>
138
147
designVariables.contextMenuItemBg.withValues (
139
148
alpha: states.contains (WidgetState .pressed) ? 0.20 : 0.12 ))),
140
- onPressed: () => onPressed (context),
149
+ onPressed: () => _handlePressed (context),
141
150
child: Text (label (zulipLocalizations),
142
151
style: const TextStyle (fontSize: 20 , height: 24 / 20 )
143
152
.merge (weightVariableTextStyle (context, wght: 600 )),
@@ -186,8 +195,7 @@ class AddThumbsUpButton extends MessageActionSheetMenuItemButton {
186
195
return 'React with 👍' ; // TODO(i18n) skip translation for now
187
196
}
188
197
189
- @override void onPressed (BuildContext context) async {
190
- Navigator .of (context).pop ();
198
+ @override void onPressed () async {
191
199
String ? errorMessage;
192
200
try {
193
201
await addReaction (PerAccountStoreWidget .of (pageContext).connection,
@@ -231,8 +239,7 @@ class StarButton extends MessageActionSheetMenuItemButton {
231
239
: zulipLocalizations.actionSheetOptionStarMessage;
232
240
}
233
241
234
- @override void onPressed (BuildContext context) async {
235
- Navigator .of (context).pop ();
242
+ @override void onPressed () async {
236
243
final zulipLocalizations = ZulipLocalizations .of (pageContext);
237
244
final op = message.flags.contains (MessageFlag .starred)
238
245
? UpdateMessageFlagsOp .remove
@@ -325,10 +332,7 @@ class QuoteAndReplyButton extends MessageActionSheetMenuItemButton {
325
332
return zulipLocalizations.actionSheetOptionQuoteAndReply;
326
333
}
327
334
328
- @override void onPressed (BuildContext context) async {
329
- // Close the message action sheet. We'll show the request progress
330
- // in the compose-box content input with a "[Quoting…]" placeholder.
331
- Navigator .of (context).pop ();
335
+ @override void onPressed () async {
332
336
final zulipLocalizations = ZulipLocalizations .of (pageContext);
333
337
334
338
// This will be null only if the compose box disappeared after the
@@ -343,6 +347,9 @@ class QuoteAndReplyButton extends MessageActionSheetMenuItemButton {
343
347
) {
344
348
topicController.value = TextEditingValue (text: message.topic);
345
349
}
350
+
351
+ // This inserts a "[Quoting…]" placeholder into the content input,
352
+ // giving the user a form of progress feedback.
346
353
final tag = composeBoxController.contentController
347
354
.registerQuoteAndReplyStart (PerAccountStoreWidget .of (pageContext),
348
355
message: message,
@@ -388,8 +395,7 @@ class MarkAsUnreadButton extends MessageActionSheetMenuItemButton {
388
395
return zulipLocalizations.actionSheetOptionMarkAsUnread;
389
396
}
390
397
391
- @override void onPressed (BuildContext context) async {
392
- Navigator .of (context).pop ();
398
+ @override void onPressed () async {
393
399
unawaited (markNarrowAsUnreadFromMessage (pageContext, message, narrow));
394
400
}
395
401
}
@@ -408,11 +414,11 @@ class CopyMessageTextButton extends MessageActionSheetMenuItemButton {
408
414
return zulipLocalizations.actionSheetOptionCopyMessageText;
409
415
}
410
416
411
- @override void onPressed (BuildContext context ) async {
412
- // Close the message action sheet. We won 't be showing request progress,
413
- // but hopefully it won't take long at all, and
417
+ @override void onPressed () async {
418
+ // This action doesn 't show request progress.
419
+ // But hopefully it won't take long at all; and
414
420
// fetchRawContentWithFeedback has a TODO for giving feedback if it does.
415
- Navigator . of (context). pop ();
421
+
416
422
final zulipLocalizations = ZulipLocalizations .of (pageContext);
417
423
418
424
final rawContent = await fetchRawContentWithFeedback (
@@ -445,8 +451,7 @@ class CopyMessageLinkButton extends MessageActionSheetMenuItemButton {
445
451
return zulipLocalizations.actionSheetOptionCopyMessageLink;
446
452
}
447
453
448
- @override void onPressed (BuildContext context) {
449
- Navigator .of (context).pop ();
454
+ @override void onPressed () {
450
455
final zulipLocalizations = ZulipLocalizations .of (pageContext);
451
456
452
457
final store = PerAccountStoreWidget .of (pageContext);
@@ -479,15 +484,16 @@ class ShareButton extends MessageActionSheetMenuItemButton {
479
484
return zulipLocalizations.actionSheetOptionShare;
480
485
}
481
486
482
- @override void onPressed (BuildContext context) async {
483
- // Close the message action sheet; we're about to show the share
484
- // sheet. (We could do this after the sharing Future settles
485
- // with [ShareResultStatus.success], but on iOS I get impatient with
486
- // how slowly our action sheet dismisses in that case.)
487
+ @override void onPressed () async {
487
488
// TODO(#591): Fix iOS bug where if the keyboard was open before the call
488
489
// to `showMessageActionSheet`, it reappears briefly between
489
490
// the `pop` of the action sheet and the appearance of the share sheet.
490
- Navigator .of (context).pop ();
491
+ //
492
+ // (Alternatively we could delay the [NavigatorState.pop] that
493
+ // dismisses the action sheet until after the sharing Future settles
494
+ // with [ShareResultStatus.success]. But on iOS one gets impatient with
495
+ // how slowly our action sheet dismisses in that case.)
496
+
491
497
final zulipLocalizations = ZulipLocalizations .of (pageContext);
492
498
493
499
final rawContent = await fetchRawContentWithFeedback (
0 commit comments