@@ -23,76 +23,6 @@ import 'store.dart';
23
23
import 'text.dart' ;
24
24
import 'theme.dart' ;
25
25
26
- /// Show a sheet of actions you can take on a message in the message list.
27
- ///
28
- /// Must have a [MessageListPage] ancestor.
29
- void showMessageActionSheet ({required BuildContext context, required Message message}) {
30
- final store = PerAccountStoreWidget .of (context);
31
-
32
- // The UI that's conditioned on this won't live-update during this appearance
33
- // of the action sheet (we avoid calling composeBoxControllerOf in a build
34
- // method; see its doc).
35
- // So we rely on the fact that isComposeBoxOffered for any given message list
36
- // will be constant through the page's life.
37
- final messageListPage = MessageListPage .ancestorOf (context);
38
- final isComposeBoxOffered = messageListPage.composeBoxController != null ;
39
-
40
- final isMessageRead = message.flags.contains (MessageFlag .read);
41
- final markAsUnreadSupported = store.connection.zulipFeatureLevel! >= 155 ; // TODO(server-6)
42
- final showMarkAsUnreadButton = markAsUnreadSupported && isMessageRead;
43
-
44
- final hasThumbsUpReactionVote = message.reactions
45
- ? .aggregated.any ((reactionWithVotes) =>
46
- reactionWithVotes.reactionType == ReactionType .unicodeEmoji
47
- && reactionWithVotes.emojiCode == '1f44d'
48
- && reactionWithVotes.userIds.contains (store.selfUserId))
49
- ?? false ;
50
-
51
- final optionButtons = [
52
- if (! hasThumbsUpReactionVote)
53
- AddThumbsUpButton (message: message, pageContext: context),
54
- StarButton (message: message, pageContext: context),
55
- if (isComposeBoxOffered)
56
- QuoteAndReplyButton (message: message, pageContext: context),
57
- if (showMarkAsUnreadButton)
58
- MarkAsUnreadButton (message: message, pageContext: context),
59
- CopyMessageTextButton (message: message, pageContext: context),
60
- CopyMessageLinkButton (message: message, pageContext: context),
61
- ShareButton (message: message, pageContext: context),
62
- ];
63
-
64
- showModalBottomSheet <void >(
65
- context: context,
66
- // Clip.hardEdge looks bad; Clip.antiAliasWithSaveLayer looks pixel-perfect
67
- // on my iPhone 13 Pro but is marked as "much slower":
68
- // https://api.flutter.dev/flutter/dart-ui/Clip.html
69
- clipBehavior: Clip .antiAlias,
70
- useSafeArea: true ,
71
- isScrollControlled: true ,
72
- builder: (BuildContext _) {
73
- return SafeArea (
74
- minimum: const EdgeInsets .only (bottom: 16 ),
75
- child: Padding (
76
- padding: const EdgeInsets .fromLTRB (16 , 0 , 16 , 0 ),
77
- child: Column (
78
- crossAxisAlignment: CrossAxisAlignment .stretch,
79
- mainAxisSize: MainAxisSize .min,
80
- children: [
81
- // TODO(#217): show message text
82
- Flexible (child: InsetShadowBox (
83
- top: 8 , bottom: 8 ,
84
- color: DesignVariables .of (context).bgContextMenu,
85
- child: SingleChildScrollView (
86
- padding: const EdgeInsets .only (top: 16 , bottom: 8 ),
87
- child: ClipRRect (
88
- borderRadius: BorderRadius .circular (7 ),
89
- child: Column (spacing: 1 ,
90
- children: optionButtons))))),
91
- const ActionSheetCancelButton (),
92
- ])));
93
- });
94
- }
95
-
96
26
abstract class ActionSheetMenuItemButton extends StatelessWidget {
97
27
const ActionSheetMenuItemButton ({super .key, required this .pageContext});
98
28
@@ -151,16 +81,6 @@ abstract class ActionSheetMenuItemButton extends StatelessWidget {
151
81
}
152
82
}
153
83
154
- abstract class MessageActionSheetMenuItemButton extends ActionSheetMenuItemButton {
155
- MessageActionSheetMenuItemButton ({
156
- super .key,
157
- required this .message,
158
- required super .pageContext,
159
- }) : assert (pageContext.findAncestorWidgetOfExactType <MessageListPage >() != null );
160
-
161
- final Message message;
162
- }
163
-
164
84
class ActionSheetCancelButton extends StatelessWidget {
165
85
const ActionSheetCancelButton ({super .key});
166
86
@@ -187,6 +107,86 @@ class ActionSheetCancelButton extends StatelessWidget {
187
107
}
188
108
}
189
109
110
+ /// Show a sheet of actions you can take on a message in the message list.
111
+ ///
112
+ /// Must have a [MessageListPage] ancestor.
113
+ void showMessageActionSheet ({required BuildContext context, required Message message}) {
114
+ final store = PerAccountStoreWidget .of (context);
115
+
116
+ // The UI that's conditioned on this won't live-update during this appearance
117
+ // of the action sheet (we avoid calling composeBoxControllerOf in a build
118
+ // method; see its doc).
119
+ // So we rely on the fact that isComposeBoxOffered for any given message list
120
+ // will be constant through the page's life.
121
+ final messageListPage = MessageListPage .ancestorOf (context);
122
+ final isComposeBoxOffered = messageListPage.composeBoxController != null ;
123
+
124
+ final isMessageRead = message.flags.contains (MessageFlag .read);
125
+ final markAsUnreadSupported = store.connection.zulipFeatureLevel! >= 155 ; // TODO(server-6)
126
+ final showMarkAsUnreadButton = markAsUnreadSupported && isMessageRead;
127
+
128
+ final hasThumbsUpReactionVote = message.reactions
129
+ ? .aggregated.any ((reactionWithVotes) =>
130
+ reactionWithVotes.reactionType == ReactionType .unicodeEmoji
131
+ && reactionWithVotes.emojiCode == '1f44d'
132
+ && reactionWithVotes.userIds.contains (store.selfUserId))
133
+ ?? false ;
134
+
135
+ final optionButtons = [
136
+ if (! hasThumbsUpReactionVote)
137
+ AddThumbsUpButton (message: message, pageContext: context),
138
+ StarButton (message: message, pageContext: context),
139
+ if (isComposeBoxOffered)
140
+ QuoteAndReplyButton (message: message, pageContext: context),
141
+ if (showMarkAsUnreadButton)
142
+ MarkAsUnreadButton (message: message, pageContext: context),
143
+ CopyMessageTextButton (message: message, pageContext: context),
144
+ CopyMessageLinkButton (message: message, pageContext: context),
145
+ ShareButton (message: message, pageContext: context),
146
+ ];
147
+
148
+ showModalBottomSheet <void >(
149
+ context: context,
150
+ // Clip.hardEdge looks bad; Clip.antiAliasWithSaveLayer looks pixel-perfect
151
+ // on my iPhone 13 Pro but is marked as "much slower":
152
+ // https://api.flutter.dev/flutter/dart-ui/Clip.html
153
+ clipBehavior: Clip .antiAlias,
154
+ useSafeArea: true ,
155
+ isScrollControlled: true ,
156
+ builder: (BuildContext _) {
157
+ return SafeArea (
158
+ minimum: const EdgeInsets .only (bottom: 16 ),
159
+ child: Padding (
160
+ padding: const EdgeInsets .fromLTRB (16 , 0 , 16 , 0 ),
161
+ child: Column (
162
+ crossAxisAlignment: CrossAxisAlignment .stretch,
163
+ mainAxisSize: MainAxisSize .min,
164
+ children: [
165
+ // TODO(#217): show message text
166
+ Flexible (child: InsetShadowBox (
167
+ top: 8 , bottom: 8 ,
168
+ color: DesignVariables .of (context).bgContextMenu,
169
+ child: SingleChildScrollView (
170
+ padding: const EdgeInsets .only (top: 16 , bottom: 8 ),
171
+ child: ClipRRect (
172
+ borderRadius: BorderRadius .circular (7 ),
173
+ child: Column (spacing: 1 ,
174
+ children: optionButtons))))),
175
+ const ActionSheetCancelButton (),
176
+ ])));
177
+ });
178
+ }
179
+
180
+ abstract class MessageActionSheetMenuItemButton extends ActionSheetMenuItemButton {
181
+ MessageActionSheetMenuItemButton ({
182
+ super .key,
183
+ required this .message,
184
+ required super .pageContext,
185
+ }) : assert (pageContext.findAncestorWidgetOfExactType <MessageListPage >() != null );
186
+
187
+ final Message message;
188
+ }
189
+
190
190
// This button is very temporary, to complete #125 before we have a way to
191
191
// choose an arbitrary reaction (#388). So, skipping i18n.
192
192
class AddThumbsUpButton extends MessageActionSheetMenuItemButton {
0 commit comments