Skip to content

Commit 84f8eb6

Browse files
committed
action_sheet: Redesign bottom sheet
Also, remove the custom modal bottom sheet we no longer use. Fixes: zulip#90
1 parent c048ed1 commit 84f8eb6

File tree

4 files changed

+178
-153
lines changed

4 files changed

+178
-153
lines changed

lib/widgets/action_sheet.dart

+93-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:async';
22

3+
import 'package:flutter/foundation.dart';
34
import 'package:flutter/material.dart';
45
import 'package:flutter/services.dart';
56
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
@@ -14,10 +15,12 @@ import 'actions.dart';
1415
import 'clipboard.dart';
1516
import 'compose_box.dart';
1617
import 'dialog.dart';
17-
import 'draggable_scrollable_modal_bottom_sheet.dart';
1818
import 'icons.dart';
19+
import 'inset_shadow.dart';
1920
import 'message_list.dart';
2021
import 'store.dart';
22+
import 'text.dart';
23+
import 'theme.dart';
2124

2225
/// Show a sheet of actions you can take on a message in the message list.
2326
///
@@ -43,21 +46,48 @@ void showMessageActionSheet({required BuildContext context, required Message mes
4346
&& reactionWithVotes.userIds.contains(store.selfUserId))
4447
?? false;
4548

46-
showDraggableScrollableModalBottomSheet<void>(
49+
final optionButtons = [
50+
if (!hasThumbsUpReactionVote)
51+
AddThumbsUpButton(message: message, messageListContext: context),
52+
StarButton(message: message, messageListContext: context),
53+
if (isComposeBoxOffered)
54+
QuoteAndReplyButton(message: message, messageListContext: context),
55+
if (showMarkAsUnreadButton)
56+
MarkAsUnreadButton(message: message, messageListContext: context, narrow: narrow),
57+
CopyMessageTextButton(message: message, messageListContext: context),
58+
CopyMessageLinkButton(message: message, messageListContext: context),
59+
ShareButton(message: message, messageListContext: context),
60+
];
61+
62+
showModalBottomSheet<void>(
4763
context: context,
64+
// Clip.hardEdge looks bad; Clip.antiAliasWithSaveLayer looks pixel-perfect
65+
// on my iPhone 13 Pro but is marked as "much slower":
66+
// https://api.flutter.dev/flutter/dart-ui/Clip.html
67+
clipBehavior: Clip.antiAlias,
68+
useSafeArea: true,
69+
isScrollControlled: true,
4870
builder: (BuildContext _) {
49-
return Column(children: [
50-
if (!hasThumbsUpReactionVote)
51-
AddThumbsUpButton(message: message, messageListContext: context),
52-
StarButton(message: message, messageListContext: context),
53-
if (isComposeBoxOffered)
54-
QuoteAndReplyButton(message: message, messageListContext: context),
55-
if (showMarkAsUnreadButton)
56-
MarkAsUnreadButton(message: message, messageListContext: context, narrow: narrow),
57-
CopyMessageTextButton(message: message, messageListContext: context),
58-
CopyMessageLinkButton(message: message, messageListContext: context),
59-
ShareButton(message: message, messageListContext: context),
60-
]);
71+
return SafeArea(
72+
minimum: const EdgeInsets.only(bottom: 16),
73+
child: Padding(
74+
padding: const EdgeInsets.fromLTRB(16, 0, 16, 0),
75+
child: Column(
76+
crossAxisAlignment: CrossAxisAlignment.stretch,
77+
mainAxisSize: MainAxisSize.min,
78+
children: [
79+
// TODO(#217): show message text
80+
Flexible(child: InsetShadowBox(
81+
top: 8, bottom: 8,
82+
color: DesignVariables.of(context).bgContextMenu,
83+
child: SingleChildScrollView(
84+
padding: const EdgeInsets.only(top: 16, bottom: 8),
85+
child: ClipRRect(
86+
borderRadius: BorderRadius.circular(7),
87+
child: Column(spacing: 1,
88+
children: optionButtons))))),
89+
const MessageActionSheetCancelButton(),
90+
])));
6191
});
6292
}
6393

@@ -77,11 +107,47 @@ abstract class MessageActionSheetMenuItemButton extends StatelessWidget {
77107

78108
@override
79109
Widget build(BuildContext context) {
110+
final designVariables = DesignVariables.of(context);
80111
final zulipLocalizations = ZulipLocalizations.of(context);
81112
return MenuItemButton(
82-
leadingIcon: Icon(icon),
113+
trailingIcon: Icon(icon, color: designVariables.contextMenuItemText),
114+
style: MenuItemButton.styleFrom(
115+
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
116+
foregroundColor: designVariables.contextMenuItemText,
117+
splashFactory: NoSplash.splashFactory,
118+
).copyWith(backgroundColor: WidgetStateColor.resolveWith((states) =>
119+
designVariables.contextMenuItemBg.withValues(
120+
alpha: states.contains(WidgetState.pressed) ? 0.20 : 0.12))),
83121
onPressed: () => onPressed(context),
84-
child: Text(label(zulipLocalizations)));
122+
child: Text(label(zulipLocalizations),
123+
style: const TextStyle(fontSize: 20, height: 24 / 20)
124+
.merge(weightVariableTextStyle(context, wght: 600)),
125+
));
126+
}
127+
}
128+
129+
class MessageActionSheetCancelButton extends StatelessWidget {
130+
const MessageActionSheetCancelButton({super.key});
131+
132+
@override
133+
Widget build(BuildContext context) {
134+
final designVariables = DesignVariables.of(context);
135+
return TextButton(
136+
style: TextButton.styleFrom(
137+
padding: const EdgeInsets.all(10),
138+
foregroundColor: designVariables.contextMenuCancelText,
139+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(7)),
140+
splashFactory: NoSplash.splashFactory,
141+
).copyWith(backgroundColor: WidgetStateColor.resolveWith((states) =>
142+
designVariables.contextMenuCancelBg.withValues(
143+
alpha: states.contains(WidgetState.pressed) ? 0.20 : 0.15))),
144+
onPressed: () {
145+
Navigator.pop(context);
146+
},
147+
child: Text(ZulipLocalizations.of(context).dialogCancel,
148+
style: const TextStyle(fontSize: 20, height: 24 / 20)
149+
.merge(weightVariableTextStyle(context, wght: 600))),
150+
);
85151
}
86152
}
87153

@@ -94,7 +160,7 @@ class AddThumbsUpButton extends MessageActionSheetMenuItemButton {
94160
required super.messageListContext,
95161
});
96162

97-
@override IconData get icon => Icons.add_reaction_outlined;
163+
@override IconData get icon => ZulipIcons.smile;
98164

99165
@override
100166
String label(ZulipLocalizations zulipLocalizations) {
@@ -135,11 +201,13 @@ class StarButton extends MessageActionSheetMenuItemButton {
135201
required super.messageListContext,
136202
});
137203

138-
@override IconData get icon => ZulipIcons.star_filled;
204+
@override IconData get icon => _isStarred ? ZulipIcons.star_filled : ZulipIcons.star;
205+
206+
bool get _isStarred => message.flags.contains(MessageFlag.starred);
139207

140208
@override
141209
String label(ZulipLocalizations zulipLocalizations) {
142-
return message.flags.contains(MessageFlag.starred)
210+
return _isStarred
143211
? zulipLocalizations.actionSheetOptionUnstarMessage
144212
: zulipLocalizations.actionSheetOptionStarMessage;
145213
}
@@ -231,7 +299,7 @@ class QuoteAndReplyButton extends MessageActionSheetMenuItemButton {
231299
required super.messageListContext,
232300
});
233301

234-
@override IconData get icon => Icons.format_quote_outlined;
302+
@override IconData get icon => ZulipIcons.format_quote;
235303

236304
@override
237305
String label(ZulipLocalizations zulipLocalizations) {
@@ -316,7 +384,7 @@ class CopyMessageTextButton extends MessageActionSheetMenuItemButton {
316384
required super.messageListContext,
317385
});
318386

319-
@override IconData get icon => Icons.copy;
387+
@override IconData get icon => ZulipIcons.copy;
320388

321389
@override
322390
String label(ZulipLocalizations zulipLocalizations) {
@@ -384,7 +452,10 @@ class ShareButton extends MessageActionSheetMenuItemButton {
384452
required super.messageListContext,
385453
});
386454

387-
@override IconData get icon => Icons.adaptive.share;
455+
@override
456+
IconData get icon => defaultTargetPlatform == TargetPlatform.iOS
457+
? ZulipIcons.share_ios
458+
: ZulipIcons.share;
388459

389460
@override
390461
String label(ZulipLocalizations zulipLocalizations) {

lib/widgets/draggable_scrollable_modal_bottom_sheet.dart

-118
This file was deleted.

0 commit comments

Comments
 (0)