Skip to content

Commit e8fe3c5

Browse files
reactions: Support adding arbitrary reactions
1 parent 4615ee1 commit e8fe3c5

10 files changed

+525
-7
lines changed

assets/l10n/app_en.arb

+12
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@
330330
"@dialogContinue": {
331331
"description": "Button label in dialogs to proceed."
332332
},
333+
"dialogClose": "Close",
334+
"@dialogClose": {
335+
"description": "Button label in dialogs to close."
336+
},
333337
"errorDialogContinue": "OK",
334338
"@errorDialogContinue": {
335339
"description": "Button label in error dialogs to acknowledge the error and close the dialog."
@@ -611,5 +615,13 @@
611615
"errorReactionRemovingFailedTitle": "Removing reaction failed",
612616
"@errorReactionRemovingFailedTitle": {
613617
"description": "Error title when removing a message reaction fails"
618+
},
619+
"emojiReactionsMore": "more",
620+
"@emojiReactionsMore": {
621+
"description": "Label for a button opening the emoji picker."
622+
},
623+
"emojiPickerSearchEmoji": "Search emoji",
624+
"@emojiPickerSearchEmoji": {
625+
"description": "Hint text for the emoji picker search text field."
614626
}
615627
}

lib/generated/l10n/zulip_localizations.dart

+18
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,12 @@ abstract class ZulipLocalizations {
529529
/// **'Continue'**
530530
String get dialogContinue;
531531

532+
/// Button label in dialogs to close.
533+
///
534+
/// In en, this message translates to:
535+
/// **'Close'**
536+
String get dialogClose;
537+
532538
/// Button label in error dialogs to acknowledge the error and close the dialog.
533539
///
534540
/// In en, this message translates to:
@@ -906,6 +912,18 @@ abstract class ZulipLocalizations {
906912
/// In en, this message translates to:
907913
/// **'Removing reaction failed'**
908914
String get errorReactionRemovingFailedTitle;
915+
916+
/// Label for a button opening the emoji picker.
917+
///
918+
/// In en, this message translates to:
919+
/// **'more'**
920+
String get emojiReactionsMore;
921+
922+
/// Hint text for the emoji picker search text field.
923+
///
924+
/// In en, this message translates to:
925+
/// **'Search emoji'**
926+
String get emojiPickerSearchEmoji;
909927
}
910928

911929
class _ZulipLocalizationsDelegate extends LocalizationsDelegate<ZulipLocalizations> {

lib/generated/l10n/zulip_localizations_ar.dart

+9
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
260260
@override
261261
String get dialogContinue => 'Continue';
262262

263+
@override
264+
String get dialogClose => 'Close';
265+
263266
@override
264267
String get errorDialogContinue => 'OK';
265268

@@ -484,4 +487,10 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
484487

485488
@override
486489
String get errorReactionRemovingFailedTitle => 'Removing reaction failed';
490+
491+
@override
492+
String get emojiReactionsMore => 'more';
493+
494+
@override
495+
String get emojiPickerSearchEmoji => 'Search emoji';
487496
}

lib/generated/l10n/zulip_localizations_en.dart

+9
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
260260
@override
261261
String get dialogContinue => 'Continue';
262262

263+
@override
264+
String get dialogClose => 'Close';
265+
263266
@override
264267
String get errorDialogContinue => 'OK';
265268

@@ -484,4 +487,10 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
484487

485488
@override
486489
String get errorReactionRemovingFailedTitle => 'Removing reaction failed';
490+
491+
@override
492+
String get emojiReactionsMore => 'more';
493+
494+
@override
495+
String get emojiPickerSearchEmoji => 'Search emoji';
487496
}

lib/generated/l10n/zulip_localizations_ja.dart

+9
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
260260
@override
261261
String get dialogContinue => 'Continue';
262262

263+
@override
264+
String get dialogClose => 'Close';
265+
263266
@override
264267
String get errorDialogContinue => 'OK';
265268

@@ -484,4 +487,10 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
484487

485488
@override
486489
String get errorReactionRemovingFailedTitle => 'Removing reaction failed';
490+
491+
@override
492+
String get emojiReactionsMore => 'more';
493+
494+
@override
495+
String get emojiPickerSearchEmoji => 'Search emoji';
487496
}

lib/widgets/action_sheet.dart

+43-7
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,16 @@ class ReactionButtons extends StatelessWidget {
222222
: zulipLocalizations.errorReactionAddingFailedTitle);
223223
}
224224

225+
void _handleTapMore() {
226+
// TODO(design): have emoji picker slide in from right and push
227+
// action sheet off to the left
228+
229+
// Dismiss current action sheet before opening emoji picker sheet.
230+
Navigator.of(pageContext).pop();
231+
232+
showEmojiPickerSheet(pageContext: pageContext, message: message);
233+
}
234+
225235
Widget _buildButton({
226236
required BuildContext context,
227237
required EmojiCandidate emoji,
@@ -257,6 +267,7 @@ class ReactionButtons extends StatelessWidget {
257267
assert(EmojiStore.popularEmojiCandidates.every(
258268
(emoji) => emoji.emojiType == ReactionType.unicodeEmoji));
259269

270+
final zulipLocalizations = ZulipLocalizations.of(context);
260271
final store = PerAccountStoreWidget.of(pageContext);
261272
final designVariables = DesignVariables.of(context);
262273

@@ -271,13 +282,38 @@ class ReactionButtons extends StatelessWidget {
271282
return Container(
272283
decoration: BoxDecoration(
273284
color: designVariables.contextMenuItemBg.withFadedAlpha(0.12)),
274-
child: Row(spacing: 1, children: List.unmodifiable(
275-
EmojiStore.popularEmojiCandidates.mapIndexed((index, emoji) =>
276-
_buildButton(
277-
context: context,
278-
emoji: emoji,
279-
isSelfVoted: hasSelfVote(emoji),
280-
isFirst: index == 0)))));
285+
child: Row(children: [
286+
Flexible(child: Row(spacing: 1, children: List.unmodifiable(
287+
EmojiStore.popularEmojiCandidates.mapIndexed((index, emoji) =>
288+
_buildButton(
289+
context: context,
290+
emoji: emoji,
291+
isSelfVoted: hasSelfVote(emoji),
292+
isFirst: index == 0))))),
293+
InkWell(
294+
onTap: _handleTapMore,
295+
splashFactory: NoSplash.splashFactory,
296+
borderRadius: const BorderRadius.only(topRight: Radius.circular(7)),
297+
overlayColor: WidgetStateColor.resolveWith((states) =>
298+
states.any((e) => e == WidgetState.pressed)
299+
? designVariables.contextMenuItemBg.withFadedAlpha(0.20)
300+
: Colors.transparent),
301+
child: Padding(
302+
padding: const EdgeInsetsDirectional.fromSTEB(12, 12, 4, 12),
303+
child: Row(children: [
304+
Text(zulipLocalizations.emojiReactionsMore,
305+
textAlign: TextAlign.end,
306+
style: TextStyle(
307+
color: designVariables.contextMenuItemText,
308+
fontSize: 14,
309+
).merge(weightVariableTextStyle(context, wght: 600))),
310+
Icon(ZulipIcons.chevron_right,
311+
color: designVariables.contextMenuItemText,
312+
size: 24),
313+
]),
314+
)),
315+
]),
316+
);
281317
}
282318
}
283319

lib/widgets/autocomplete.dart

+1
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ class _EmojiAutocompleteItem extends StatelessWidget {
260260
final store = PerAccountStoreWidget.of(context);
261261
final candidate = option.candidate;
262262

263+
// TODO deduplicate this logic with [EmojiPickerListEntry]
263264
final emojiDisplay = candidate.emojiDisplay.resolve(store.userSettings);
264265
final Widget? glyph = switch (emojiDisplay) {
265266
ImageEmojiDisplay() =>

0 commit comments

Comments
 (0)