Skip to content

Commit 82397bf

Browse files
committed
compose: Support save snippets
We sort the saved snippets by title to be consistent with the web implementation. A subtle nuance of having a compose box in a modal bottom sheet is that the message list page behind will shift when the keyboard is expanded, even though its compose box is not visible anyway. An UX improvement would be preserving the inputs on the saved snippet compose box after the user has navigated away. Fixes: #863
1 parent 5242d83 commit 82397bf

14 files changed

+1001
-40
lines changed

assets/l10n/app_en.arb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,42 @@
385385
"@composeBoxAttachFromCameraTooltip": {
386386
"description": "Tooltip for compose box icon to attach an image from the camera to the message."
387387
},
388+
"composeBoxShowSavedSnippetsTooltip": "Show saved snippets",
389+
"@composeBoxShowSavedSnippetsTooltip": {
390+
"description": "Tooltip for compose box icon to show a list of saved snippets."
391+
},
392+
"noSavedSnippets": "No saved snippets",
393+
"@noSavedSnippets": {
394+
"description": "Text to show on the saved snippets bottom sheet when there are no saved snippets."
395+
},
396+
"newSavedSnippetButton": "New",
397+
"@newSavedSnippetButton": {
398+
"description": "Label for adding a new saved snippet."
399+
},
400+
"newSavedSnippetTitle": "New snippet",
401+
"@newSavedSnippetTitle": {
402+
"description": "Title for the bottom sheet to add a new saved snippet."
403+
},
404+
"newSavedSnippetTitleHint": "Title",
405+
"@newSavedSnippetTitleHint": {
406+
"description": "Hint text for the title input when adding a new saved snippet."
407+
},
408+
"newSavedSnippetContentHint": "Content",
409+
"@newSavedSnippetContentHint": {
410+
"description": "Hint text for the content input when adding a new saved snippet."
411+
},
412+
"errorFailedToCreateSavedSnippetTitle": "Failed to create saved snippet",
413+
"@errorFailedToCreateSavedSnippetTitle": {
414+
"description": "Error title when the saved snippet failed to be created."
415+
},
416+
"savedSnippetTitleValidationErrorEmpty": "Title cannot be empty.",
417+
"@savedSnippetTitleValidationErrorEmpty": {
418+
"description": "Validation error message when the title of the saved snippet is empty."
419+
},
420+
"savedSnippetTitleValidationErrorTooLong": "Title length shouldn't be greater than 60 characters.",
421+
"@savedSnippetTitleValidationErrorTooLong": {
422+
"description": "Validation error message when the title of the saved snippet is too long."
423+
},
388424
"composeBoxGenericContentHint": "Type a message",
389425
"@composeBoxGenericContentHint": {
390426
"description": "Hint text for content input when sending a message."

lib/generated/l10n/zulip_localizations.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,60 @@ abstract class ZulipLocalizations {
640640
/// **'Take a photo'**
641641
String get composeBoxAttachFromCameraTooltip;
642642

643+
/// Tooltip for compose box icon to show a list of saved snippets.
644+
///
645+
/// In en, this message translates to:
646+
/// **'Show saved snippets'**
647+
String get composeBoxShowSavedSnippetsTooltip;
648+
649+
/// Text to show on the saved snippets bottom sheet when there are no saved snippets.
650+
///
651+
/// In en, this message translates to:
652+
/// **'No saved snippets'**
653+
String get noSavedSnippets;
654+
655+
/// Label for adding a new saved snippet.
656+
///
657+
/// In en, this message translates to:
658+
/// **'New'**
659+
String get newSavedSnippetButton;
660+
661+
/// Title for the bottom sheet to add a new saved snippet.
662+
///
663+
/// In en, this message translates to:
664+
/// **'New snippet'**
665+
String get newSavedSnippetTitle;
666+
667+
/// Hint text for the title input when adding a new saved snippet.
668+
///
669+
/// In en, this message translates to:
670+
/// **'Title'**
671+
String get newSavedSnippetTitleHint;
672+
673+
/// Hint text for the content input when adding a new saved snippet.
674+
///
675+
/// In en, this message translates to:
676+
/// **'Content'**
677+
String get newSavedSnippetContentHint;
678+
679+
/// Error title when the saved snippet failed to be created.
680+
///
681+
/// In en, this message translates to:
682+
/// **'Failed to create saved snippet'**
683+
String get errorFailedToCreateSavedSnippetTitle;
684+
685+
/// Validation error message when the title of the saved snippet is empty.
686+
///
687+
/// In en, this message translates to:
688+
/// **'Title cannot be empty.'**
689+
String get savedSnippetTitleValidationErrorEmpty;
690+
691+
/// Validation error message when the title of the saved snippet is too long.
692+
///
693+
/// In en, this message translates to:
694+
/// **'Title length shouldn\'t be greater than 60 characters.'**
695+
String get savedSnippetTitleValidationErrorTooLong;
696+
643697
/// Hint text for content input when sending a message.
644698
///
645699
/// In en, this message translates to:

lib/generated/l10n/zulip_localizations_ar.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,35 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
323323
@override
324324
String get composeBoxAttachFromCameraTooltip => 'Take a photo';
325325

326+
@override
327+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
328+
329+
@override
330+
String get noSavedSnippets => 'No saved snippets';
331+
332+
@override
333+
String get newSavedSnippetButton => 'New';
334+
335+
@override
336+
String get newSavedSnippetTitle => 'New snippet';
337+
338+
@override
339+
String get newSavedSnippetTitleHint => 'Title';
340+
341+
@override
342+
String get newSavedSnippetContentHint => 'Content';
343+
344+
@override
345+
String get errorFailedToCreateSavedSnippetTitle =>
346+
'Failed to create saved snippet';
347+
348+
@override
349+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
350+
351+
@override
352+
String get savedSnippetTitleValidationErrorTooLong =>
353+
'Title length shouldn\'t be greater than 60 characters.';
354+
326355
@override
327356
String get composeBoxGenericContentHint => 'Type a message';
328357

lib/generated/l10n/zulip_localizations_en.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,35 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
323323
@override
324324
String get composeBoxAttachFromCameraTooltip => 'Take a photo';
325325

326+
@override
327+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
328+
329+
@override
330+
String get noSavedSnippets => 'No saved snippets';
331+
332+
@override
333+
String get newSavedSnippetButton => 'New';
334+
335+
@override
336+
String get newSavedSnippetTitle => 'New snippet';
337+
338+
@override
339+
String get newSavedSnippetTitleHint => 'Title';
340+
341+
@override
342+
String get newSavedSnippetContentHint => 'Content';
343+
344+
@override
345+
String get errorFailedToCreateSavedSnippetTitle =>
346+
'Failed to create saved snippet';
347+
348+
@override
349+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
350+
351+
@override
352+
String get savedSnippetTitleValidationErrorTooLong =>
353+
'Title length shouldn\'t be greater than 60 characters.';
354+
326355
@override
327356
String get composeBoxGenericContentHint => 'Type a message';
328357

lib/generated/l10n/zulip_localizations_ja.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,35 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
323323
@override
324324
String get composeBoxAttachFromCameraTooltip => 'Take a photo';
325325

326+
@override
327+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
328+
329+
@override
330+
String get noSavedSnippets => 'No saved snippets';
331+
332+
@override
333+
String get newSavedSnippetButton => 'New';
334+
335+
@override
336+
String get newSavedSnippetTitle => 'New snippet';
337+
338+
@override
339+
String get newSavedSnippetTitleHint => 'Title';
340+
341+
@override
342+
String get newSavedSnippetContentHint => 'Content';
343+
344+
@override
345+
String get errorFailedToCreateSavedSnippetTitle =>
346+
'Failed to create saved snippet';
347+
348+
@override
349+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
350+
351+
@override
352+
String get savedSnippetTitleValidationErrorTooLong =>
353+
'Title length shouldn\'t be greater than 60 characters.';
354+
326355
@override
327356
String get composeBoxGenericContentHint => 'Type a message';
328357

lib/generated/l10n/zulip_localizations_nb.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,35 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
323323
@override
324324
String get composeBoxAttachFromCameraTooltip => 'Take a photo';
325325

326+
@override
327+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
328+
329+
@override
330+
String get noSavedSnippets => 'No saved snippets';
331+
332+
@override
333+
String get newSavedSnippetButton => 'New';
334+
335+
@override
336+
String get newSavedSnippetTitle => 'New snippet';
337+
338+
@override
339+
String get newSavedSnippetTitleHint => 'Title';
340+
341+
@override
342+
String get newSavedSnippetContentHint => 'Content';
343+
344+
@override
345+
String get errorFailedToCreateSavedSnippetTitle =>
346+
'Failed to create saved snippet';
347+
348+
@override
349+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
350+
351+
@override
352+
String get savedSnippetTitleValidationErrorTooLong =>
353+
'Title length shouldn\'t be greater than 60 characters.';
354+
326355
@override
327356
String get composeBoxGenericContentHint => 'Type a message';
328357

lib/generated/l10n/zulip_localizations_pl.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,35 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
330330
@override
331331
String get composeBoxAttachFromCameraTooltip => 'Zrób zdjęcie';
332332

333+
@override
334+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
335+
336+
@override
337+
String get noSavedSnippets => 'No saved snippets';
338+
339+
@override
340+
String get newSavedSnippetButton => 'New';
341+
342+
@override
343+
String get newSavedSnippetTitle => 'New snippet';
344+
345+
@override
346+
String get newSavedSnippetTitleHint => 'Title';
347+
348+
@override
349+
String get newSavedSnippetContentHint => 'Content';
350+
351+
@override
352+
String get errorFailedToCreateSavedSnippetTitle =>
353+
'Failed to create saved snippet';
354+
355+
@override
356+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
357+
358+
@override
359+
String get savedSnippetTitleValidationErrorTooLong =>
360+
'Title length shouldn\'t be greater than 60 characters.';
361+
333362
@override
334363
String get composeBoxGenericContentHint => 'Wpisz wiadomość';
335364

lib/generated/l10n/zulip_localizations_ru.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,35 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
331331
@override
332332
String get composeBoxAttachFromCameraTooltip => 'Сделать снимок';
333333

334+
@override
335+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
336+
337+
@override
338+
String get noSavedSnippets => 'No saved snippets';
339+
340+
@override
341+
String get newSavedSnippetButton => 'New';
342+
343+
@override
344+
String get newSavedSnippetTitle => 'New snippet';
345+
346+
@override
347+
String get newSavedSnippetTitleHint => 'Title';
348+
349+
@override
350+
String get newSavedSnippetContentHint => 'Content';
351+
352+
@override
353+
String get errorFailedToCreateSavedSnippetTitle =>
354+
'Failed to create saved snippet';
355+
356+
@override
357+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
358+
359+
@override
360+
String get savedSnippetTitleValidationErrorTooLong =>
361+
'Title length shouldn\'t be greater than 60 characters.';
362+
334363
@override
335364
String get composeBoxGenericContentHint => 'Ввести сообщение';
336365

lib/generated/l10n/zulip_localizations_sk.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,35 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
323323
@override
324324
String get composeBoxAttachFromCameraTooltip => 'Take a photo';
325325

326+
@override
327+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
328+
329+
@override
330+
String get noSavedSnippets => 'No saved snippets';
331+
332+
@override
333+
String get newSavedSnippetButton => 'New';
334+
335+
@override
336+
String get newSavedSnippetTitle => 'New snippet';
337+
338+
@override
339+
String get newSavedSnippetTitleHint => 'Title';
340+
341+
@override
342+
String get newSavedSnippetContentHint => 'Content';
343+
344+
@override
345+
String get errorFailedToCreateSavedSnippetTitle =>
346+
'Failed to create saved snippet';
347+
348+
@override
349+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
350+
351+
@override
352+
String get savedSnippetTitleValidationErrorTooLong =>
353+
'Title length shouldn\'t be greater than 60 characters.';
354+
326355
@override
327356
String get composeBoxGenericContentHint => 'Type a message';
328357

lib/generated/l10n/zulip_localizations_uk.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,35 @@ class ZulipLocalizationsUk extends ZulipLocalizations {
332332
@override
333333
String get composeBoxAttachFromCameraTooltip => 'Зробити фото';
334334

335+
@override
336+
String get composeBoxShowSavedSnippetsTooltip => 'Show saved snippets';
337+
338+
@override
339+
String get noSavedSnippets => 'No saved snippets';
340+
341+
@override
342+
String get newSavedSnippetButton => 'New';
343+
344+
@override
345+
String get newSavedSnippetTitle => 'New snippet';
346+
347+
@override
348+
String get newSavedSnippetTitleHint => 'Title';
349+
350+
@override
351+
String get newSavedSnippetContentHint => 'Content';
352+
353+
@override
354+
String get errorFailedToCreateSavedSnippetTitle =>
355+
'Failed to create saved snippet';
356+
357+
@override
358+
String get savedSnippetTitleValidationErrorEmpty => 'Title cannot be empty.';
359+
360+
@override
361+
String get savedSnippetTitleValidationErrorTooLong =>
362+
'Title length shouldn\'t be greater than 60 characters.';
363+
335364
@override
336365
String get composeBoxGenericContentHint => 'Ввести повідомлення';
337366

0 commit comments

Comments
 (0)