Skip to content

Commit f28a083

Browse files
committed
action_sheet: Redesign bottom sheet
Fixes: #90
1 parent 1964388 commit f28a083

File tree

11 files changed

+220
-46
lines changed

11 files changed

+220
-46
lines changed

assets/icons/ZulipIcons.ttf

1.53 KB
Binary file not shown.

assets/icons/copy.svg

Lines changed: 4 additions & 0 deletions
Loading

assets/icons/format_quote.svg

Lines changed: 3 additions & 0 deletions
Loading

assets/icons/share.svg

Lines changed: 3 additions & 0 deletions
Loading

assets/icons/share_ios.svg

Lines changed: 3 additions & 0 deletions
Loading

assets/icons/smile.svg

Lines changed: 6 additions & 0 deletions
Loading

assets/icons/star.svg

Lines changed: 3 additions & 0 deletions
Loading

lib/widgets/action_sheet.dart

Lines changed: 86 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:io';
2+
13
import 'package:flutter/material.dart';
24
import 'package:flutter/services.dart';
35
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
@@ -11,10 +13,11 @@ import '../model/narrow.dart';
1113
import 'clipboard.dart';
1214
import 'compose_box.dart';
1315
import 'dialog.dart';
14-
import 'draggable_scrollable_modal_bottom_sheet.dart';
1516
import 'icons.dart';
1617
import 'message_list.dart';
1718
import 'store.dart';
19+
import 'text.dart';
20+
import 'theme.dart';
1821

1922
/// Show a sheet of actions you can take on a message in the message list.
2023
///
@@ -36,20 +39,47 @@ void showMessageActionSheet({required BuildContext context, required Message mes
3639
&& reactionWithVotes.userIds.contains(store.selfUserId))
3740
?? false;
3841

39-
showDraggableScrollableModalBottomSheet<void>(
42+
final designVariables = DesignVariables.of(context);
43+
showModalBottomSheet<void>(
4044
context: context,
45+
clipBehavior: Clip.antiAlias,
46+
backgroundColor: designVariables.actionSheetBackground,
47+
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(20.0))),
48+
useSafeArea: true,
49+
isScrollControlled: true,
4150
builder: (BuildContext _) {
42-
return Column(children: [
43-
if (!hasThumbsUpReactionVote) AddThumbsUpButton(message: message, messageListContext: context),
44-
StarButton(message: message, messageListContext: context),
45-
if (isComposeBoxOffered) QuoteAndReplyButton(
46-
message: message,
47-
messageListContext: context,
51+
return Padding(
52+
padding: const EdgeInsets.all(16.0),
53+
child: Column(
54+
crossAxisAlignment: CrossAxisAlignment.stretch,
55+
mainAxisSize: MainAxisSize.min,
56+
children: [
57+
// TODO(#217): show message text
58+
Flexible(
59+
child: SingleChildScrollView(
60+
child: ClipRRect(
61+
borderRadius: BorderRadius.circular(7),
62+
child: Column(children: [
63+
if (!hasThumbsUpReactionVote) AddThumbsUpButton(message: message, messageListContext: context),
64+
StarButton(message: message, messageListContext: context),
65+
if (isComposeBoxOffered) QuoteAndReplyButton(
66+
message: message,
67+
messageListContext: context,
68+
),
69+
CopyMessageTextButton(message: message, messageListContext: context),
70+
CopyMessageLinkButton(message: message, messageListContext: context),
71+
ShareButton(message: message, messageListContext: context),
72+
// TODO: The following line could be replaced by the [spacing]
73+
// property when https://github.com/flutter/flutter/issues/55378 is fixed.
74+
].expand((item) => [const SizedBox(height: 1), item]).skip(1).toList()),
75+
),
76+
),
77+
),
78+
const SizedBox(height: 8),
79+
const MessageActionSheetCancelButton(),
80+
],
4881
),
49-
CopyMessageTextButton(message: message, messageListContext: context),
50-
CopyMessageLinkButton(message: message, messageListContext: context),
51-
ShareButton(message: message, messageListContext: context),
52-
]);
82+
);
5383
});
5484
}
5585

@@ -69,11 +99,22 @@ abstract class MessageActionSheetMenuItemButton extends StatelessWidget {
6999

70100
@override
71101
Widget build(BuildContext context) {
102+
final designVariables = DesignVariables.of(context);
72103
final zulipLocalizations = ZulipLocalizations.of(context);
73104
return MenuItemButton(
74-
leadingIcon: Icon(icon),
105+
trailingIcon: Icon(icon, color: designVariables.actionSheetMenuButtonForeground),
106+
style: MenuItemButton.styleFrom(
107+
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
108+
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
109+
minimumSize: Size.zero,
110+
backgroundColor: designVariables.actionSheetMenuButtonBackground,
111+
foregroundColor: designVariables.actionSheetMenuButtonForeground,
112+
),
75113
onPressed: () => onPressed(context),
76-
child: Text(label(zulipLocalizations)));
114+
child: Text(label(zulipLocalizations),
115+
style: const TextStyle(fontSize: 20)
116+
.merge(weightVariableTextStyle(context, wght: 600)),
117+
));
77118
}
78119
}
79120

@@ -86,7 +127,7 @@ class AddThumbsUpButton extends MessageActionSheetMenuItemButton {
86127
required super.messageListContext,
87128
});
88129

89-
@override IconData get icon => Icons.add_reaction_outlined;
130+
@override IconData get icon => ZulipIcons.smile;
90131

91132
@override
92133
String label(ZulipLocalizations zulipLocalizations) {
@@ -127,11 +168,13 @@ class StarButton extends MessageActionSheetMenuItemButton {
127168
required super.messageListContext,
128169
});
129170

130-
@override IconData get icon => ZulipIcons.star_filled;
171+
@override IconData get icon => _isStarred ? ZulipIcons.star_filled : ZulipIcons.star;
172+
173+
bool get _isStarred => message.flags.contains(MessageFlag.starred);
131174

132175
@override
133176
String label(ZulipLocalizations zulipLocalizations) {
134-
return message.flags.contains(MessageFlag.starred)
177+
return _isStarred
135178
? zulipLocalizations.actionSheetOptionUnstarMessage
136179
: zulipLocalizations.actionSheetOptionStarMessage;
137180
}
@@ -223,7 +266,7 @@ class QuoteAndReplyButton extends MessageActionSheetMenuItemButton {
223266
required super.messageListContext,
224267
});
225268

226-
@override IconData get icon => Icons.format_quote_outlined;
269+
@override IconData get icon => ZulipIcons.format_quote;
227270

228271
@override
229272
String label(ZulipLocalizations zulipLocalizations) {
@@ -285,7 +328,7 @@ class CopyMessageTextButton extends MessageActionSheetMenuItemButton {
285328
required super.messageListContext,
286329
});
287330

288-
@override IconData get icon => Icons.copy;
331+
@override IconData get icon => ZulipIcons.copy;
289332

290333
@override
291334
String label(ZulipLocalizations zulipLocalizations) {
@@ -353,7 +396,7 @@ class ShareButton extends MessageActionSheetMenuItemButton {
353396
required super.messageListContext,
354397
});
355398

356-
@override IconData get icon => Icons.adaptive.share;
399+
@override IconData get icon => Platform.isIOS ? ZulipIcons.share_ios : ZulipIcons.share;
357400

358401
@override
359402
String label(ZulipLocalizations zulipLocalizations) {
@@ -402,3 +445,26 @@ class ShareButton extends MessageActionSheetMenuItemButton {
402445
}
403446
}
404447
}
448+
449+
class MessageActionSheetCancelButton extends StatelessWidget {
450+
const MessageActionSheetCancelButton({super.key});
451+
452+
@override
453+
Widget build(BuildContext context) {
454+
final designVariables = DesignVariables.of(context);
455+
return TextButton(
456+
style: TextButton.styleFrom(
457+
padding: const EdgeInsets.all(10),
458+
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
459+
minimumSize: Size.zero,
460+
backgroundColor: designVariables.actionSheetCancelButtonBackground,
461+
foregroundColor: designVariables.actionSheetCancelButtonForeground,
462+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(7)),
463+
),
464+
onPressed: () => Navigator.pop(context),
465+
child: Text(ZulipLocalizations.of(context).dialogCancel,
466+
style: const TextStyle(fontSize: 20)
467+
.merge(weightVariableTextStyle(context, wght: 600))),
468+
);
469+
}
470+
}

lib/widgets/icons.dart

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,62 @@ abstract final class ZulipIcons {
4242
/// The Zulip custom icon "clock".
4343
static const IconData clock = IconData(0xf106, fontFamily: "Zulip Icons");
4444

45+
/// The Zulip custom icon "copy".
46+
static const IconData copy = IconData(0xf107, fontFamily: "Zulip Icons");
47+
4548
/// The Zulip custom icon "edited".
46-
static const IconData edited = IconData(0xf107, fontFamily: "Zulip Icons");
49+
static const IconData edited = IconData(0xf108, fontFamily: "Zulip Icons");
50+
51+
/// The Zulip custom icon "format_quote".
52+
static const IconData format_quote = IconData(0xf109, fontFamily: "Zulip Icons");
4753

4854
/// The Zulip custom icon "globe".
49-
static const IconData globe = IconData(0xf108, fontFamily: "Zulip Icons");
55+
static const IconData globe = IconData(0xf10a, fontFamily: "Zulip Icons");
5056

5157
/// The Zulip custom icon "group_dm".
52-
static const IconData group_dm = IconData(0xf109, fontFamily: "Zulip Icons");
58+
static const IconData group_dm = IconData(0xf10b, fontFamily: "Zulip Icons");
5359

5460
/// The Zulip custom icon "hash_sign".
55-
static const IconData hash_sign = IconData(0xf10a, fontFamily: "Zulip Icons");
61+
static const IconData hash_sign = IconData(0xf10c, fontFamily: "Zulip Icons");
5662

5763
/// The Zulip custom icon "language".
58-
static const IconData language = IconData(0xf10b, fontFamily: "Zulip Icons");
64+
static const IconData language = IconData(0xf10d, fontFamily: "Zulip Icons");
5965

6066
/// The Zulip custom icon "lock".
61-
static const IconData lock = IconData(0xf10c, fontFamily: "Zulip Icons");
67+
static const IconData lock = IconData(0xf10e, fontFamily: "Zulip Icons");
6268

6369
/// The Zulip custom icon "message_moved".
64-
static const IconData message_moved = IconData(0xf10d, fontFamily: "Zulip Icons");
70+
static const IconData message_moved = IconData(0xf10f, fontFamily: "Zulip Icons");
6571

6672
/// The Zulip custom icon "mute".
67-
static const IconData mute = IconData(0xf10e, fontFamily: "Zulip Icons");
73+
static const IconData mute = IconData(0xf110, fontFamily: "Zulip Icons");
6874

6975
/// The Zulip custom icon "read_receipts".
70-
static const IconData read_receipts = IconData(0xf10f, fontFamily: "Zulip Icons");
76+
static const IconData read_receipts = IconData(0xf111, fontFamily: "Zulip Icons");
77+
78+
/// The Zulip custom icon "share".
79+
static const IconData share = IconData(0xf112, fontFamily: "Zulip Icons");
80+
81+
/// The Zulip custom icon "share_ios".
82+
static const IconData share_ios = IconData(0xf113, fontFamily: "Zulip Icons");
83+
84+
/// The Zulip custom icon "smile".
85+
static const IconData smile = IconData(0xf114, fontFamily: "Zulip Icons");
86+
87+
/// The Zulip custom icon "star".
88+
static const IconData star = IconData(0xf115, fontFamily: "Zulip Icons");
7189

7290
/// The Zulip custom icon "star_filled".
73-
static const IconData star_filled = IconData(0xf110, fontFamily: "Zulip Icons");
91+
static const IconData star_filled = IconData(0xf116, fontFamily: "Zulip Icons");
7492

7593
/// The Zulip custom icon "topic".
76-
static const IconData topic = IconData(0xf111, fontFamily: "Zulip Icons");
94+
static const IconData topic = IconData(0xf117, fontFamily: "Zulip Icons");
7795

7896
/// The Zulip custom icon "unmute".
79-
static const IconData unmute = IconData(0xf112, fontFamily: "Zulip Icons");
97+
static const IconData unmute = IconData(0xf118, fontFamily: "Zulip Icons");
8098

8199
/// The Zulip custom icon "user".
82-
static const IconData user = IconData(0xf113, fontFamily: "Zulip Icons");
100+
static const IconData user = IconData(0xf119, fontFamily: "Zulip Icons");
83101

84102
// END GENERATED ICON DATA
85103
}

0 commit comments

Comments
 (0)