Skip to content

Commit e798189

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

File tree

11 files changed

+204
-33
lines changed

11 files changed

+204
-33
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: 83 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,10 @@ 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 'theme.dart';
1820

1921
/// Show a sheet of actions you can take on a message in the message list.
2022
///
@@ -36,20 +38,47 @@ void showMessageActionSheet({required BuildContext context, required Message mes
3638
&& reactionWithVotes.userIds.contains(store.selfUserId))
3739
?? false;
3840

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

@@ -69,11 +98,21 @@ abstract class MessageActionSheetMenuItemButton extends StatelessWidget {
6998

7099
@override
71100
Widget build(BuildContext context) {
101+
final designVariables = DesignVariables.of(context);
72102
final zulipLocalizations = ZulipLocalizations.of(context);
73103
return MenuItemButton(
74-
leadingIcon: Icon(icon),
104+
trailingIcon: Icon(icon, color: designVariables.actionSheetMenuButtonForeground),
105+
style: MenuItemButton.styleFrom(
106+
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
107+
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
108+
minimumSize: Size.zero,
109+
backgroundColor: designVariables.actionSheetMenuButtonBackground,
110+
foregroundColor: designVariables.actionSheetMenuButtonForeground,
111+
),
75112
onPressed: () => onPressed(context),
76-
child: Text(label(zulipLocalizations)));
113+
child: Text(label(zulipLocalizations),
114+
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
115+
));
77116
}
78117
}
79118

@@ -86,7 +125,7 @@ class AddThumbsUpButton extends MessageActionSheetMenuItemButton {
86125
required super.messageListContext,
87126
});
88127

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

91130
@override
92131
String label(ZulipLocalizations zulipLocalizations) {
@@ -127,11 +166,13 @@ class StarButton extends MessageActionSheetMenuItemButton {
127166
required super.messageListContext,
128167
});
129168

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

132173
@override
133174
String label(ZulipLocalizations zulipLocalizations) {
134-
return message.flags.contains(MessageFlag.starred)
175+
return _isStarred
135176
? zulipLocalizations.actionSheetOptionUnstarMessage
136177
: zulipLocalizations.actionSheetOptionStarMessage;
137178
}
@@ -223,7 +264,7 @@ class QuoteAndReplyButton extends MessageActionSheetMenuItemButton {
223264
required super.messageListContext,
224265
});
225266

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

228269
@override
229270
String label(ZulipLocalizations zulipLocalizations) {
@@ -285,7 +326,7 @@ class CopyMessageTextButton extends MessageActionSheetMenuItemButton {
285326
required super.messageListContext,
286327
});
287328

288-
@override IconData get icon => Icons.copy;
329+
@override IconData get icon => ZulipIcons.copy;
289330

290331
@override
291332
String label(ZulipLocalizations zulipLocalizations) {
@@ -353,7 +394,7 @@ class ShareButton extends MessageActionSheetMenuItemButton {
353394
required super.messageListContext,
354395
});
355396

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

358399
@override
359400
String label(ZulipLocalizations zulipLocalizations) {
@@ -402,3 +443,25 @@ class ShareButton extends MessageActionSheetMenuItemButton {
402443
}
403444
}
404445
}
446+
447+
class MessageActionSheetCancelButton extends StatelessWidget {
448+
const MessageActionSheetCancelButton({super.key});
449+
450+
@override
451+
Widget build(BuildContext context) {
452+
final designVariables = DesignVariables.of(context);
453+
return TextButton(
454+
style: TextButton.styleFrom(
455+
padding: const EdgeInsets.all(10),
456+
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
457+
minimumSize: Size.zero,
458+
backgroundColor: designVariables.actionSheetCancelButtonBackground,
459+
foregroundColor: designVariables.actionSheetCancelButtonForeground,
460+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(7)),
461+
),
462+
onPressed: () => Navigator.pop(context),
463+
child: Text(ZulipLocalizations.of(context).dialogCancel,
464+
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
465+
);
466+
}
467+
}

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)