1
+ import 'package:collection/collection.dart' ;
1
2
import 'package:flutter/material.dart' ;
2
3
import 'package:flutter/services.dart' ;
3
4
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart' ;
@@ -33,18 +34,40 @@ void showMessageActionSheet({required BuildContext context, required Message mes
33
34
&& reactionWithVotes.userIds.contains (store.selfUserId))
34
35
?? false ;
35
36
37
+ List <Widget > actionSheetButtons = [
38
+ if (! hasThumbsUpReactionVote) AddThumbsUpButton (message: message, messageListContext: context),
39
+ StarButton (message: message, messageListContext: context),
40
+ ShareButton (message: message, messageListContext: context),
41
+ if (isComposeBoxOffered) QuoteAndReplyButton (message: message,messageListContext: context),
42
+ CopyButton (message: message, messageListContext: context),
43
+ const MessageActionSheetCancelButton (),
44
+ ];
45
+
36
46
showDraggableScrollableModalBottomSheet (
37
47
context: context,
38
48
builder: (BuildContext _) {
39
49
return Column (children: [
40
- if (! hasThumbsUpReactionVote) AddThumbsUpButton (message: message, messageListContext: context),
41
- StarButton (message: message, messageListContext: context),
42
- ShareButton (message: message, messageListContext: context),
43
- if (isComposeBoxOffered) QuoteAndReplyButton (
44
- message: message,
45
- messageListContext: context,
46
- ),
47
- CopyButton (message: message, messageListContext: context),
50
+ ...actionSheetButtons.mapIndexed (
51
+ (index, element) {
52
+ if (index == 0 ){
53
+ // If element is the first element
54
+ // set the _isFirst value and unset the _isLast value
55
+ return (element as MessageActionSheetMenuItemButton )..setIsFirst ()..unsetIsLast ();
56
+ }
57
+ else if (index == actionSheetButtons.length - 2 ){
58
+ // If element is the last element of the action Sheet
59
+ // set the _isLast value and unset the _isFirst value
60
+ return (element as MessageActionSheetMenuItemButton )..setIsLast ()..unsetIsFirst ();
61
+ }
62
+ else if (index == actionSheetButtons.length - 1 ){
63
+ // If the element is the Cancel Button then return as it is.
64
+ return element;
65
+ }
66
+ // If the element is any other element
67
+ // unset the _isFirst value and unset the _isLast value.
68
+ return (element as MessageActionSheetMenuItemButton )..unsetIsFirst ()..unsetIsLast ();
69
+ },
70
+ ),
48
71
]);
49
72
});
50
73
}
@@ -60,16 +83,65 @@ abstract class MessageActionSheetMenuItemButton extends StatelessWidget {
60
83
String label (ZulipLocalizations zulipLocalizations);
61
84
void Function (BuildContext ) get onPressed;
62
85
86
+ late final bool _isFirst;
87
+ late final bool _isLast;
88
+
89
+ void setIsFirst (){
90
+ _isFirst = true ;
91
+ }
92
+ void setIsLast (){
93
+ _isLast = true ;
94
+ }
95
+
96
+ void unsetIsFirst (){
97
+ _isFirst = false ;
98
+ }
99
+ void unsetIsLast (){
100
+ _isLast = false ;
101
+ }
102
+
63
103
final Message message;
64
104
final BuildContext messageListContext;
65
105
106
+ final Color _kActionSheetIconColor = const Color (0xff666699 );
107
+ final Color _kActionSheetMenuItemButtonsColor = const Color (0xff4040BF ).withOpacity (0.08 );
108
+ final Color _kActionSheetMenuItemLabelColor = const Color (0xff262659 );
109
+
110
+
66
111
@override
67
112
Widget build (BuildContext context) {
68
113
final zulipLocalizations = ZulipLocalizations .of (context);
69
- return MenuItemButton (
70
- leadingIcon: Icon (icon),
71
- onPressed: () => onPressed (context),
72
- child: Text (label (zulipLocalizations)));
114
+ return Padding (
115
+ padding: const EdgeInsets .only (left: 16 ,right: 16 ,bottom: 1.5 ),
116
+ child: MenuItemButton (
117
+ trailingIcon: Icon (icon),
118
+ onPressed: () => onPressed (context),
119
+ style: ButtonStyle (
120
+ padding: const MaterialStatePropertyAll (EdgeInsets .symmetric (vertical: 10 ,horizontal: 15 )),
121
+ backgroundColor: MaterialStatePropertyAll (_kActionSheetMenuItemButtonsColor),
122
+ iconColor: MaterialStatePropertyAll (_kActionSheetIconColor),
123
+ shape: MaterialStatePropertyAll (
124
+ RoundedRectangleBorder (
125
+ // If the element is the first element we have the border of first element
126
+ // If the element is the last element we have the border of last element
127
+ // else the element is rendered with the default borders.
128
+ borderRadius:
129
+ (_isFirst)? const BorderRadius .only (
130
+ topLeft: Radius .circular (7 ),topRight: Radius .circular (7 ),)
131
+ : (_isLast)? const BorderRadius .only (
132
+ bottomRight: Radius .circular (7 ),bottomLeft: Radius .circular (7 ),)
133
+ : BorderRadius .zero,
134
+ ),
135
+ ),
136
+ ),
137
+ child: Text (label (zulipLocalizations),style: TextStyle (
138
+ color: _kActionSheetMenuItemLabelColor,
139
+ fontSize: 20 ,
140
+ fontWeight: FontWeight .w600,
141
+ fontFamily: "Source Sans 3" ,
142
+ ),),
143
+ ),
144
+ );
73
145
}
74
146
}
75
147
@@ -366,3 +438,34 @@ class CopyButton extends MessageActionSheetMenuItemButton {
366
438
data: ClipboardData (text: rawContent));
367
439
};
368
440
}
441
+
442
+ class MessageActionSheetCancelButton extends StatelessWidget {
443
+ const MessageActionSheetCancelButton ({super .key});
444
+
445
+ @override
446
+ Widget build (BuildContext context) {
447
+ return Padding (
448
+ padding: const EdgeInsets .symmetric (horizontal: 15.0 ,vertical: 5 ),
449
+ child: MaterialButton (
450
+ onPressed: (){
451
+ Navigator .of (context).pop ();
452
+ },
453
+ color: const Color (0xffe3e3e5 ),
454
+ elevation: 0 ,
455
+ padding: const EdgeInsets .symmetric (vertical: 7 ),
456
+ shape: RoundedRectangleBorder (
457
+ borderRadius: BorderRadius .circular (10 ),
458
+ ),
459
+ child: LayoutBuilder (builder: (context, constraints) {
460
+ return SizedBox (
461
+ width: constraints.maxWidth,
462
+ child: const Text ("Cancel" ,style: TextStyle (
463
+ fontSize: 20 ,
464
+ color: Color (0xff222222 ),
465
+ fontWeight: FontWeight .w500
466
+ ),textAlign: TextAlign .center,));
467
+ },),
468
+ ),
469
+ );
470
+ }
471
+ }
0 commit comments