From 55d0dacdbe60a258bba3613b44ead2de854236e6 Mon Sep 17 00:00:00 2001 From: "Dat H. Pham" Date: Wed, 18 Sep 2024 12:04:44 +0000 Subject: [PATCH 01/15] Translated using Weblate (Vietnamese) Currently translated at 100.0% (639 of 639 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/vi/ --- lib/l10n/intl_vi.arb | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/l10n/intl_vi.arb b/lib/l10n/intl_vi.arb index 505fbefc29..6407c1c895 100644 --- a/lib/l10n/intl_vi.arb +++ b/lib/l10n/intl_vi.arb @@ -4209,5 +4209,41 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "spamFolderNotFound": "Không thấy thư mục Spam", + "@spamFolderNotFound": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotAddedActionToRule": "Bạn chưa thêm các hành động.", + "@youHaveNotAddedActionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotAddedConditionToRule": "Bạn chưa thêm điều kiện.", + "@youHaveNotAddedConditionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotSelectedAnyActionForRule": "Bạn chưa lựa chọn bất kì một hành động nào.", + "@youHaveNotSelectedAnyActionForRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youAreOffline": "Bạn đang ngoại tuyến.", + "@youAreOffline": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "tryAgain": "Thử lại", + "@tryAgain": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From 2df9417412fd4271beb8096098191f987d90eea2 Mon Sep 17 00:00:00 2001 From: Taisiya Prudentova Date: Thu, 19 Sep 2024 08:21:53 +0000 Subject: [PATCH 02/15] Translated using Weblate (Russian) Currently translated at 100.0% (639 of 639 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/ru/ --- lib/l10n/intl_ru.arb | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb index 092891683a..d6579185dc 100644 --- a/lib/l10n/intl_ru.arb +++ b/lib/l10n/intl_ru.arb @@ -4221,5 +4221,41 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "spamFolderNotFound": "Папка \"Спам\" не найдена", + "@spamFolderNotFound": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotSelectedAnyActionForRule": "Вы не выбрали действие для правила.", + "@youHaveNotSelectedAnyActionForRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "tryAgain": "Попробуйте еще раз", + "@tryAgain": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotAddedActionToRule": "Вы не добавили действие для правила.", + "@youHaveNotAddedActionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youAreOffline": "Вы не в сети. Кажется, вы не подключены к интернету.", + "@youAreOffline": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotAddedConditionToRule": "Вы не добавили условие для правила.", + "@youHaveNotAddedConditionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From 4c5c567b239cd23528002db55ac55825d863e33a Mon Sep 17 00:00:00 2001 From: Florian DANIEL aka Facyla Date: Fri, 20 Sep 2024 15:59:52 +0000 Subject: [PATCH 03/15] Translated using Weblate (French) Currently translated at 99.8% (638 of 639 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/fr/ --- lib/l10n/intl_fr.arb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 340680fde9..0a387cdf43 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -4209,5 +4209,35 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "youHaveNotAddedConditionToRule": "Vous n'avez pas ajouté de condition à la règle.", + "@youHaveNotAddedConditionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotAddedActionToRule": "Vous n'avez pas ajouté d'action à la règle.", + "@youHaveNotAddedActionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youAreOffline": "Vous êtes hors ligne. Il semble que vous n'êtes pas connecté.", + "@youAreOffline": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotSelectedAnyActionForRule": "Vous n’avez sélectionné aucune action pour la règle.", + "@youHaveNotSelectedAnyActionForRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "tryAgain": "Veuillez réessayer", + "@tryAgain": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From d098bcded46e4ce7e1f75ed4063f67bd81c54824 Mon Sep 17 00:00:00 2001 From: chrismaster Date: Wed, 16 Oct 2024 11:01:32 +0700 Subject: [PATCH 04/15] Translated using Weblate (German) Currently translated at 86.5% (553 of 639 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/de/ Signed-off-by: dab246 --- lib/l10n/intl_de.arb | 210 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 1 deletion(-) diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index 8240a11f3b..61a3207624 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -2085,7 +2085,7 @@ "placeholders_order": [], "placeholders": {} }, - "titleReadReceiptRequestNotificationMessage": "", + "titleReadReceiptRequestNotificationMessage": "Lesebestätigung anfordern", "@titleReadReceiptRequestNotificationMessage": { "type": "text", "placeholders_order": [], @@ -3358,5 +3358,213 @@ "placeholders": { "maxSize": {} } + }, + "toastMessageMarkAsMailboxReadSuccess": "Sie haben alle Nachrichten in \"{mailboxName}\" als gelesen markiert", + "@toastMessageMarkAsMailboxReadSuccess": { + "type": "text", + "placeholders_order": [ + "mailboxName" + ], + "placeholders": { + "mailboxName": {} + } + }, + "Bad credentials": "Ungültige Anmeldedaten", + "@Bad credentials": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "flag": "Kennzeichnen", + "@flag": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "un_spam": "Kein Spam", + "@un_spam": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "not_starred": "Nicht markiert", + "@not_starred": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "star": "Stern", + "@star": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageCannotFoundEmailIdWhenSendReceipt": "Die E-Mail-ID konnte nicht gefunden werden", + "@toastMessageCannotFoundEmailIdWhenSendReceipt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogSendEmailUploadingAttachment": "Ihre Nachricht konnte nicht gesendet werden, da ein Anhang hochgeladen wird", + "@messageDialogSendEmailUploadingAttachment": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageLocalCopyDisable": "Lokale Kopie beibehalten deaktivieren.", + "@toastMessageLocalCopyDisable": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "bcc_to": "Bcc to", + "@bcc_to": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "deleteFoldersSuccessfully": "Ordner erfolgreich gelöscht", + "@deleteFoldersSuccessfully": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "createNewFolderFailure": "Fehler beim Erstellen eines neuen Ordners", + "@createNewFolderFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "deleteFoldersFailure": "Fehler beim Löschen der Ordner", + "@deleteFoldersFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "ruleFilterAddressCcField": "Cc", + "@ruleFilterAddressCcField": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "exchange": "Austausch", + "@exchange": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "selected": "Ausgewählt", + "@selected": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "page_name": "Twake Mail", + "@page_name": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "starred": "Wichtig", + "@starred": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "allTime": "Seit jeher", + "@allTime": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "clearAll": "Alles leeren", + "@clearAll": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "app_name": "Twake Mail", + "@app_name": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "quickStyles": "Schnellformatvorlagen", + "@quickStyles": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "titleQuickStyles": "Schnellformatvorlagen", + "@titleQuickStyles": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "un_star": "Markierung entfernen", + "@un_star": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "notSelected": "Nicht ausgewählt", + "@notSelected": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageLocalCopyEnable": "Lokale Kopie beibehalten aktivieren.", + "@toastMessageLocalCopyEnable": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "with_starred": "Mit Stern markiert", + "@with_starred": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "no_internet_connection_try_again_later": "Keine Internetverbindung, versuche es später.", + "@no_internet_connection_try_again_later": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageCannotFoundIdentityWhenSendReceipt": "Die angegebene ID konnte nicht gefunden werden", + "@toastMessageCannotFoundIdentityWhenSendReceipt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "emailRuleSettingExplanation": "Erstellen von Regeln zur Verwaltung eingehender Nachrichten. Sie wählen sowohl die Bedingung, die eine Regel auslöst, als auch die Aktion, die die Regel ausführt.", + "@emailRuleSettingExplanation": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "empty_trash_folder": "Papierkorb leeren", + "@empty_trash_folder": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageAddRecipientsSuccessfully": "Die E-Mails wurden der Empfängerliste hinzugefügt.", + "@toastMessageAddRecipientsSuccessfully": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "renameFolderFailure": "Fehler beim Umbenennen des Ordners", + "@renameFolderFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "mark_as_starred": "Als wichtig markieren", + "@mark_as_starred": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From 63894032413ea6645488945cd0210494d2119eb0 Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 15 Oct 2024 13:18:50 +0700 Subject: [PATCH 05/15] Add suggestion for `From/To` dialog when input is new email address --- .../mixin/auto_complete_result_mixin.dart | 46 ++++++++++ .../presentation/composer_controller.dart | 88 ++++++------------- .../presentation/contact_controller.dart | 64 +++++++------- .../auto_complete_result_mixin_test.dart | 59 +++++++++++++ 4 files changed, 166 insertions(+), 91 deletions(-) create mode 100644 lib/features/base/mixin/auto_complete_result_mixin.dart create mode 100644 test/features/base/mixin/auto_complete_result_mixin_test.dart diff --git a/lib/features/base/mixin/auto_complete_result_mixin.dart b/lib/features/base/mixin/auto_complete_result_mixin.dart new file mode 100644 index 0000000000..9119bd85a5 --- /dev/null +++ b/lib/features/base/mixin/auto_complete_result_mixin.dart @@ -0,0 +1,46 @@ + +import 'dart:async'; + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:get/get_utils/src/get_utils/get_utils.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:model/model.dart'; +import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart'; +import 'package:tmail_ui_user/features/composer/domain/state/get_device_contact_suggestions_state.dart'; + +mixin AutoCompleteResultMixin { + + FutureOr> handleAutoCompleteResultState({ + required Either resultState, + required String queryString, + }) { + return resultState.fold( + (failure) => [], + (success) => handleAutoCompleteSuccess(success, queryString) + ); + } + + List handleAutoCompleteSuccess(Success success, String queryString) { + List listEmailAddress = []; + + if (success is GetAutoCompleteSuccess) { + listEmailAddress = success.listEmailAddress; + } else if (success is GetDeviceContactSuggestionsSuccess) { + listEmailAddress = success.listEmailAddress; + } + + if (listEmailAddress.isEmpty && GetUtils.isEmail(queryString)) { + return [EmailAddress(queryString, queryString)]; + } + + bool isEmailExist = listEmailAddress + .any((email) => email.emailAddress == queryString); + if (GetUtils.isEmail(queryString) && !isEmailExist) { + listEmailAddress.insert(0, EmailAddress(queryString, queryString)); + } + + return listEmailAddress; + } +} \ No newline at end of file diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 62a30e80c3..b3ec9a78df 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -34,14 +34,13 @@ import 'package:super_tag_editor/tag_editor.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/base/before_reconnect_handler.dart'; import 'package:tmail_ui_user/features/base/before_reconnect_manager.dart'; +import 'package:tmail_ui_user/features/base/mixin/auto_complete_result_mixin.dart'; import 'package:tmail_ui_user/features/base/state/base_ui_state.dart'; import 'package:tmail_ui_user/features/base/state/button_state.dart'; import 'package:tmail_ui_user/features/composer/domain/exceptions/compose_email_exception.dart'; import 'package:tmail_ui_user/features/composer/domain/model/contact_suggestion_source.dart'; import 'package:tmail_ui_user/features/composer/domain/state/download_image_as_base64_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/generate_email_state.dart'; -import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart'; -import 'package:tmail_ui_user/features/composer/domain/state/get_device_contact_suggestions_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/restore_email_inline_images_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; @@ -106,7 +105,9 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/universal_import/html_stub.dart' as html; -class ComposerController extends BaseController with DragDropFileMixin implements BeforeReconnectHandler { +class ComposerController extends BaseController + with DragDropFileMixin, AutoCompleteResultMixin + implements BeforeReconnectHandler { final mailboxDashBoardController = Get.find(); final networkConnectionController = Get.find(); @@ -1105,75 +1106,44 @@ class ComposerController extends BaseController with DragDropFileMixin implement } } - Future> getAutoCompleteSuggestion(String word) async { - log('ComposerController::getAutoCompleteSuggestion(): $word | $_contactSuggestionSource'); + Future> getAutoCompleteSuggestion(String queryString) async { + log('ComposerController::getAutoCompleteSuggestion(): $queryString | $_contactSuggestionSource'); _getAllAutoCompleteInteractor = getBinding(); _getAutoCompleteInteractor = getBinding(); _getDeviceContactSuggestionsInteractor = getBinding(); + final autoCompletePattern = AutoCompletePattern( + word: queryString, + accountId: mailboxDashBoardController.accountId.value); + if (_contactSuggestionSource == ContactSuggestionSource.all) { if (_getAllAutoCompleteInteractor != null) { return await _getAllAutoCompleteInteractor! - .execute(AutoCompletePattern(word: word, accountId: mailboxDashBoardController.accountId.value)) - .then((value) => value.fold( - (failure) => [], - (success) => _getAutoCompleteSuccess(success, word) - )); + .execute(autoCompletePattern) + .then((value) => handleAutoCompleteResultState( + resultState: value, + queryString: queryString, + ) + ); } else if (_getDeviceContactSuggestionsInteractor != null) { return await _getDeviceContactSuggestionsInteractor! - .execute(AutoCompletePattern(word: word, accountId: mailboxDashBoardController.accountId.value)) - .then((value) => value.fold( - (failure) => [], - (success) => _getAutoCompleteSuccess(success, word) - )); + .execute(autoCompletePattern) + .then((value) => handleAutoCompleteResultState( + resultState: value, + queryString: queryString, + ) + ); } else { return []; } } else { - if (_getAutoCompleteInteractor == null) { - return []; - } else { - return await _getAutoCompleteInteractor! - .execute(AutoCompletePattern(word: word, accountId: mailboxDashBoardController.accountId.value)) - .then((value) => value.fold( - (failure) => [], - (success) => _getAutoCompleteSuccess(success, word) - )); - } - } - } - - List _getAutoCompleteSuccess(Success success, String word) { - if (success is GetAutoCompleteSuccess) { - if (success.listEmailAddress.isEmpty == true && GetUtils.isEmail(word)) { - final unknownEmailAddress = EmailAddress(word, word); - return [unknownEmailAddress]; - } - if (GetUtils.isEmail(word)) { - bool isContainsTypedEmail = success.listEmailAddress.any((emailAddress) => emailAddress.email == word); - if (!isContainsTypedEmail) { - final unknownEmailAddress = EmailAddress(word, word); - success.listEmailAddress.insert(0, unknownEmailAddress); - return success.listEmailAddress; - } - } - return success.listEmailAddress; - } else if (success is GetDeviceContactSuggestionsSuccess) { - if (success.listEmailAddress.isEmpty == true && GetUtils.isEmail(word)) { - final unknownEmailAddress = EmailAddress(word, word); - return [unknownEmailAddress]; - } - if (GetUtils.isEmail(word)) { - bool isContainsTypedEmail = success.listEmailAddress.any((emailAddress) => emailAddress.email == word); - if (!isContainsTypedEmail) { - final unknownEmailAddress = EmailAddress(word, word); - success.listEmailAddress.insert(0, unknownEmailAddress); - return success.listEmailAddress; - } - } - return success.listEmailAddress; - } else { - return []; + return await _getAutoCompleteInteractor + ?.execute(autoCompletePattern) + .then((value) => handleAutoCompleteResultState( + resultState: value, + queryString: queryString, + ) + ) ?? []; } } diff --git a/lib/features/contact/presentation/contact_controller.dart b/lib/features/contact/presentation/contact_controller.dart index 283285585a..cf4467667c 100644 --- a/lib/features/contact/presentation/contact_controller.dart +++ b/lib/features/contact/presentation/contact_controller.dart @@ -16,9 +16,8 @@ import 'package:model/autocomplete/auto_complete_pattern.dart'; import 'package:model/extensions/email_address_extension.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/base/mixin/auto_complete_result_mixin.dart'; import 'package:tmail_ui_user/features/composer/domain/model/contact_suggestion_source.dart'; -import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart'; -import 'package:tmail_ui_user/features/composer/domain/state/get_device_contact_suggestions_state.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_all_autocomplete_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_device_contact_suggestions_interactor.dart'; @@ -28,8 +27,9 @@ import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; +import 'package:tmail_ui_user/main/utils/app_config.dart'; -class ContactController extends BaseController { +class ContactController extends BaseController with AutoCompleteResultMixin { final TextEditingController textInputSearchController = TextEditingController(); final FocusNode textInputSearchFocus = FocusNode(); @@ -113,14 +113,16 @@ class ContactController extends BaseController { } Future _handleDeBounceTimeSearchContact(String value) async { - if (value.trim().isEmpty) { + final queryStringTrimmed = value.trim(); + + if (queryStringTrimmed.length < AppConfig.limitCharToStartSearch) { searchStatus.value = SearchStatus.INACTIVE; return; } searchStatus.value = SearchStatus.ACTIVE; searchViewState.value = Right(SearchingState()); - searchQuery.value = SearchQuery(value); + searchQuery.value = SearchQuery(queryStringTrimmed); await _searchContactByNameOrEmail(searchQuery.value.value); searchViewState.value = Right(UIState.idle); } @@ -150,46 +152,44 @@ class ContactController extends BaseController { searchedContactList.value = listContact; } - Future> _getAutoCompleteSuggestion(String query) async { + Future> _getAutoCompleteSuggestion(String queryString) async { _getAllAutoCompleteInteractor = getBinding(); _getAutoCompleteInteractor = getBinding(); _getDeviceContactSuggestionsInteractor = getBinding(); + final autoCompletePattern = AutoCompletePattern( + word: queryString, + limit: 30, + accountId: _accountId); + if (_contactSuggestionSource == ContactSuggestionSource.all) { if (_getAllAutoCompleteInteractor != null) { return await _getAllAutoCompleteInteractor! - .execute(AutoCompletePattern(word: query, limit: 30, accountId: _accountId)) - .then((value) => value.fold( - (failure) => [], - (success) => success is GetAutoCompleteSuccess - ? success.listEmailAddress - : [] - )); + .execute(autoCompletePattern) + .then((value) => handleAutoCompleteResultState( + resultState: value, + queryString: queryString, + ) + ); } else if (_getDeviceContactSuggestionsInteractor != null) { return await _getDeviceContactSuggestionsInteractor! - .execute(AutoCompletePattern(word: query, limit: 30, accountId: _accountId)) - .then((value) => value.fold( - (failure) => [], - (success) => success is GetDeviceContactSuggestionsSuccess - ? success.listEmailAddress - : [] - )); + .execute(autoCompletePattern) + .then((value) => handleAutoCompleteResultState( + resultState: value, + queryString: queryString, + ) + ); } else { return []; } } else { - if (_getAutoCompleteInteractor == null) { - return []; - } else { - return await _getAutoCompleteInteractor! - .execute(AutoCompletePattern(word: query, limit: 30, accountId: _accountId)) - .then((value) => value.fold( - (failure) => [], - (success) => success is GetAutoCompleteSuccess - ? success.listEmailAddress - : [] - )); - } + return await _getAutoCompleteInteractor + ?.execute(autoCompletePattern) + .then((value) => handleAutoCompleteResultState( + resultState: value, + queryString: queryString, + ) + ) ?? []; } } diff --git a/test/features/base/mixin/auto_complete_result_mixin_test.dart b/test/features/base/mixin/auto_complete_result_mixin_test.dart new file mode 100644 index 0000000000..ee8954cb36 --- /dev/null +++ b/test/features/base/mixin/auto_complete_result_mixin_test.dart @@ -0,0 +1,59 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:tmail_ui_user/features/base/mixin/auto_complete_result_mixin.dart'; +import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart'; +import 'package:tmail_ui_user/features/composer/domain/state/get_device_contact_suggestions_state.dart'; + +class AutoCompleteResult with AutoCompleteResultMixin {} + +void main() { + late AutoCompleteResult autoCompleteResult; + + setUp(() { + autoCompleteResult = AutoCompleteResult(); + }); + + group('handleAutoCompleteSuccess::test', () { + test('SHOULD return list of EmailAddress from GetAutoCompleteSuccess', () { + final mockEmailAddress = EmailAddress('Test User', 'test@example.com'); + final success = GetAutoCompleteSuccess([mockEmailAddress]); + final result = autoCompleteResult.handleAutoCompleteSuccess(success, 'query'); + + expect(result, [mockEmailAddress]); + }); + + test('SHOULD return list of EmailAddress from GetDeviceContactSuggestionsSuccess', () { + final mockEmailAddress = EmailAddress('Contact User', 'contact@example.com'); + final success = GetDeviceContactSuggestionsSuccess([mockEmailAddress]); + final result = autoCompleteResult.handleAutoCompleteSuccess(success, 'query'); + + expect(result, [mockEmailAddress]); + }); + + test('SHOULD return query email address if list is empty and query is a valid email', () { + final success = GetAutoCompleteSuccess([]); + final result = autoCompleteResult.handleAutoCompleteSuccess(success, 'newemail@example.com'); + + expect(result, [EmailAddress('newemail@example.com', 'newemail@example.com')]); + }); + + test('SHOULD add query email address to the start if not present and is a valid email', () { + final mockEmailAddress = EmailAddress('Existing User', 'existing@example.com'); + final success = GetAutoCompleteSuccess([mockEmailAddress]); + final result = autoCompleteResult.handleAutoCompleteSuccess(success, 'newemail@example.com'); + + expect(result, [ + EmailAddress('newemail@example.com', 'newemail@example.com'), + mockEmailAddress + ]); + }); + + test('SHOULD not add query email address if already present', () { + final mockEmailAddress = EmailAddress('Existing User', 'existing@example.com'); + final success = GetAutoCompleteSuccess([mockEmailAddress]); + final result = autoCompleteResult.handleAutoCompleteSuccess(success, 'existing@example.com'); + + expect(result, [mockEmailAddress]); + }); + }); +} From e68aa930a07353537e46a5cb350a266046728be4 Mon Sep 17 00:00:00 2001 From: Florian DANIEL aka Facyla Date: Wed, 16 Oct 2024 08:11:51 +0000 Subject: [PATCH 06/15] Translated using Weblate (French) Currently translated at 100.0% (640 of 640 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/fr/ --- lib/l10n/intl_fr.arb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 0a387cdf43..19d031ad48 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -4222,7 +4222,7 @@ "placeholders_order": [], "placeholders": {} }, - "youAreOffline": "Vous êtes hors ligne. Il semble que vous n'êtes pas connecté.", + "youAreOffline": "Vous êtes hors ligne. Veuillez vérifier votre connexion.", "@youAreOffline": { "type": "text", "placeholders_order": [], @@ -4239,5 +4239,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "findEmails": "Trouver des messages", + "@findEmails": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From eecb342b165a019cd9c015b795dd37f41f82ed67 Mon Sep 17 00:00:00 2001 From: Taisiya Prudentova Date: Wed, 16 Oct 2024 08:11:31 +0000 Subject: [PATCH 07/15] Translated using Weblate (Russian) Currently translated at 100.0% (640 of 640 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/ru/ --- lib/l10n/intl_ru.arb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb index d6579185dc..100b737fd7 100644 --- a/lib/l10n/intl_ru.arb +++ b/lib/l10n/intl_ru.arb @@ -4257,5 +4257,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "findEmails": "Найти письма", + "@findEmails": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From 8ccbd8a69d2d47a20f1ec6533631af8ea793ca3b Mon Sep 17 00:00:00 2001 From: "Dat H. Pham" Date: Wed, 16 Oct 2024 05:01:39 +0000 Subject: [PATCH 08/15] Translated using Weblate (Vietnamese) Currently translated at 100.0% (640 of 640 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/vi/ --- lib/l10n/intl_vi.arb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/l10n/intl_vi.arb b/lib/l10n/intl_vi.arb index 6407c1c895..5dd4043404 100644 --- a/lib/l10n/intl_vi.arb +++ b/lib/l10n/intl_vi.arb @@ -4245,5 +4245,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "findEmails": "Tìm kiếm email", + "@findEmails": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From 401f0b97fb803aa4761056e7fd8df959c85e320a Mon Sep 17 00:00:00 2001 From: Dat Vu Date: Wed, 16 Oct 2024 17:56:20 +0700 Subject: [PATCH 09/15] Change logos to beta and move position version on web (#3203) --- assets/images/ic_logo_with_text_beta.svg | 49 ++++++++++++++++++ .../presentation/resources/image_paths.dart | 1 + env.file | 3 +- .../application_logo_with_text_widget.dart | 14 ++++- .../presentation/mailbox_view_web.dart | 51 ++++++++++++------- .../navigation_bar/navigation_bar_widget.dart | 3 +- .../menu/manage_account_menu_view.dart | 17 +++++++ .../quotas/presentation/quotas_view.dart | 6 ++- lib/main/utils/app_config.dart | 5 ++ 9 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 assets/images/ic_logo_with_text_beta.svg diff --git a/assets/images/ic_logo_with_text_beta.svg b/assets/images/ic_logo_with_text_beta.svg new file mode 100644 index 0000000000..0fc447edc2 --- /dev/null +++ b/assets/images/ic_logo_with_text_beta.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart index 075cc5b544..ce2516630c 100644 --- a/core/lib/presentation/resources/image_paths.dart +++ b/core/lib/presentation/resources/image_paths.dart @@ -196,6 +196,7 @@ class ImagePaths { String get icEventCanceled => _getImagePath('ic_event_canceled.svg'); String get icFormatQuote => _getImagePath('ic_format_quote.svg'); String get icLogoWithText => _getImagePath('ic_logo_with_text.svg'); + String get icLogoWithTextBeta => _getImagePath('ic_logo_with_text_beta.svg'); String get icTMailLogo => _getImagePath('ic_tmail_logo.svg'); String get icLoginGraphic => _getImagePath('ic_login_graphic.svg'); String get icCancel => _getImagePath('ic_cancel.svg'); diff --git a/env.file b/env.file index dee54041f4..f3ff169d6c 100644 --- a/env.file +++ b/env.file @@ -5,4 +5,5 @@ OIDC_SCOPES=openid,profile,email,offline_access APP_GRID_AVAILABLE=supported FCM_AVAILABLE=supported IOS_FCM=supported -FORWARD_WARNING_MESSAGE= \ No newline at end of file +FORWARD_WARNING_MESSAGE= +PLATFORM=other \ No newline at end of file diff --git a/lib/features/base/widget/application_logo_with_text_widget.dart b/lib/features/base/widget/application_logo_with_text_widget.dart index 800aac90fe..ee7d0827a1 100644 --- a/lib/features/base/widget/application_logo_with_text_widget.dart +++ b/lib/features/base/widget/application_logo_with_text_widget.dart @@ -1,22 +1,32 @@ import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; +import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:tmail_ui_user/main/utils/app_config.dart'; class ApplicationLogoWidthTextWidget extends StatelessWidget { final ImagePaths _imagePaths = Get.find(); final VoidCallback? onTapAction; + final EdgeInsetsGeometry? margin; - ApplicationLogoWidthTextWidget({super.key, this.onTapAction}); + ApplicationLogoWidthTextWidget({ + super.key, + this.onTapAction, + this.margin, + }); @override Widget build(BuildContext context) { return TMailButtonWidget.fromIcon( - icon: _imagePaths.icLogoWithText, + icon: PlatformInfo.isWeb && !AppConfig.isSaasPlatForm + ? _imagePaths.icLogoWithTextBeta + : _imagePaths.icLogoWithText, iconSize: 33, padding: EdgeInsets.zero, + margin: margin, backgroundColor: Colors.transparent, hoverColor: Colors.transparent, onTapActionCallback: onTapAction, diff --git a/lib/features/mailbox/presentation/mailbox_view_web.dart b/lib/features/mailbox/presentation/mailbox_view_web.dart index 88d40f1611..60c54f8b99 100644 --- a/lib/features/mailbox/presentation/mailbox_view_web.dart +++ b/lib/features/mailbox/presentation/mailbox_view_web.dart @@ -13,6 +13,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_item import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_loading_bar_widget.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget.dart'; import 'package:tmail_ui_user/features/quotas/presentation/quotas_view.dart'; +import 'package:tmail_ui_user/features/quotas/presentation/styles/quotas_view_styles.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; @@ -31,8 +32,15 @@ class MailboxView extends BaseMailboxView { backgroundColor: controller.responsiveUtils.isWebDesktop(context) ? AppColor.colorBgDesktop : Colors.white, - body: Column(children: [ - if (!controller.responsiveUtils.isDesktop(context)) _buildLogoApp(context), + body: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + if (!controller.responsiveUtils.isDesktop(context)) + ApplicationLogoWidthTextWidget( + margin: const EdgeInsetsDirectional.only( + top: 16, + bottom: 16, + start: 16, + ), + ), if (!controller.responsiveUtils.isDesktop(context)) const Divider( color: AppColor.colorDividerMailbox, @@ -50,27 +58,34 @@ class MailboxView extends BaseMailboxView { child: _buildListMailbox(context), ), )), - const QuotasView(), + const QuotasView( + padding: EdgeInsetsDirectional.only( + start: QuotasViewStyles.padding, + top: QuotasViewStyles.padding, + ), + ), + Container( + color: AppColor.colorBgMailbox, + width: double.infinity, + alignment: controller.responsiveUtils.isDesktop(context) + ? AlignmentDirectional.centerStart + : AlignmentDirectional.center, + padding: const EdgeInsets.all(16), + child: ApplicationVersionWidget( + padding: EdgeInsets.zero, + title: '${AppLocalizations.of(context).version.toLowerCase()} ', + textStyle: Theme.of(context).textTheme.bodySmall?.copyWith( + fontSize: 13, + color: AppColor.colorTextBody, + fontWeight: FontWeight.normal + ), + ), + ), ]), ) ); } - Widget _buildLogoApp(BuildContext context) { - return Container( - color: Colors.white, - padding: EdgeInsetsDirectional.only( - top: controller.responsiveUtils.isDesktop(context) ? 25 : 16, - bottom: controller.responsiveUtils.isDesktop(context) ? 25 : 16, - start: controller.responsiveUtils.isDesktop(context) ? 32 : 16, - ), - child: Row(children: [ - ApplicationLogoWidthTextWidget(), - const ApplicationVersionWidget() - ]) - ); - } - Widget _buildListMailbox(BuildContext context) { final mailboxListWidget = SingleChildScrollView( controller: controller.mailboxListScrollController, diff --git a/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart b/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart index ad13899bd7..21d4ba7c65 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart @@ -3,7 +3,6 @@ import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/views/image/avatar_builder.dart'; import 'package:flutter/material.dart'; import 'package:tmail_ui_user/features/base/widget/application_logo_with_text_widget.dart'; -import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/navigation_bar_style.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_grid_dashboard_icon.dart'; @@ -41,7 +40,7 @@ class NavigationBarWidget extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ ApplicationLogoWidthTextWidget(onTapAction: onTapApplicationLogoAction), - const ApplicationVersionWidget() + const Spacer(), ], ), ), diff --git a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart index df8e3a8714..9c5fe7c8be 100644 --- a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart +++ b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart @@ -129,6 +129,23 @@ class ManageAccountMenuView extends GetWidget { ] ), )), + Container( + color: AppColor.colorBgMailbox, + width: double.infinity, + alignment: controller.responsiveUtils.isDesktop(context) + ? AlignmentDirectional.centerStart + : AlignmentDirectional.center, + padding: const EdgeInsets.all(16), + child: ApplicationVersionWidget( + padding: EdgeInsets.zero, + title: '${AppLocalizations.of(context).version.toLowerCase()} ', + textStyle: Theme.of(context).textTheme.bodySmall?.copyWith( + fontSize: 13, + color: AppColor.colorTextBody, + fontWeight: FontWeight.normal + ), + ), + ), ] ) ), diff --git a/lib/features/quotas/presentation/quotas_view.dart b/lib/features/quotas/presentation/quotas_view.dart index 0143887e88..ed054d7bf3 100644 --- a/lib/features/quotas/presentation/quotas_view.dart +++ b/lib/features/quotas/presentation/quotas_view.dart @@ -8,7 +8,9 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class QuotasView extends GetWidget { - const QuotasView({Key? key}) : super(key: key); + final EdgeInsetsGeometry? padding; + + const QuotasView({Key? key, this.padding}) : super(key: key); @override Widget build(BuildContext context) { @@ -17,7 +19,7 @@ class QuotasView extends GetWidget { final octetQuota = controller.octetsQuota.value!; return LayoutBuilder(builder: (context, constraints) { return Container( - padding: const EdgeInsetsDirectional.only( + padding: padding ?? const EdgeInsetsDirectional.only( start: QuotasViewStyles.padding, top: QuotasViewStyles.padding, bottom: QuotasViewStyles.bottomPadding diff --git a/lib/main/utils/app_config.dart b/lib/main/utils/app_config.dart index bff358776c..a883e1a223 100644 --- a/lib/main/utils/app_config.dart +++ b/lib/main/utils/app_config.dart @@ -14,6 +14,7 @@ class AppConfig { static const String appFCMConfigurationPath = "configurations/env.fcm"; static const String iOSKeychainSharingGroupId = 'KUT463DS29.com.linagora.ios.teammail.shared'; static const String iOSKeychainSharingService = 'com.linagora.ios.teammail.sessions'; + static const String saasPlatform = 'saas'; static String get baseUrl => dotenv.get('SERVER_URL', fallback: ''); static String get domainRedirectUrl => dotenv.get('DOMAIN_REDIRECT_URL', fallback: ''); @@ -61,4 +62,8 @@ class AppConfig { return forwardWarningMessage; } + + static String get _platformEnv => dotenv.get('PLATFORM', fallback: 'other'); + + static bool get isSaasPlatForm => _platformEnv == saasPlatform; } \ No newline at end of file From 691b9fdff24066b8c489e63c9992c951a47019a1 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 16 Oct 2024 12:06:54 +0700 Subject: [PATCH 10/15] Bump version to v0.13.3 --- CHANGELOG.md | 25 +++++++++++++++++++++++++ pubspec.yaml | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe7e387163..3a6c0684b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## [0.13.3] - 2024-10-16 +### Fixed +- \#3002 \[SEARCH\] More filters +- \#3004 \[SEARCH\] Fix open close advanced search looses data +- \#3005 \[SEARCH\] Easily clear From and To search result header +- \#3006 \[SEARCH\] mail address handling in quick search bar +- \#3007 \[SEARCH\] Support drag and drop between From & To field +- \#3025 \[SEARCH\] Mark as read/unread/important/unimportant action refresh email view, reset selection in Search +- \#3192 \[SEARCH\] Update highlight style as design +- \[SEARCH\] Add suggestion for From/To dialog when input is new email address +- \#3045 Hide compose button situationally on mobile +- Show app version on login view +- \#2983 Fix download EML with special character +- Fix alignment receive time in email view +- Remove space when subject is empty or null +- Remove blink blink of next & previous button in Email View +- Fix hyperlink iOS still show full link +- Replace dart:ui to dart:ui\_web when platformViewRegistry in dart:ui is deprecated +- \#3183 Clean up draft after email sent +- \#3034 Prevent duplicate draft warning +- \#3171 Fix duplicate signature button on Composer view changed +- Simplified the prebuild script +- Translation vi, ru, fr, de + ## [0.13.2] - 2024-09-18 ### Added - User guide @@ -613,6 +637,7 @@ - \#1512 remove plain text input for signature - \#1469 remove animation when navigating screen +[0.13.3]: https://github.com/linagora/tmail-flutter/releases/tag/v0.13.3 [0.11.4002]: https://github.com/linagora/tmail-flutter/releases/tag/v0.11.4002 [0.11.4001]: https://github.com/linagora/tmail-flutter/releases/tag/v0.11.4001 [0.11.3]: https://github.com/linagora/tmail-flutter/releases/tag/v0.11.3 diff --git a/pubspec.yaml b/pubspec.yaml index 0e3f360dcc..2a24cf35ba 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.13.2 +version: 0.13.3 environment: sdk: ">=3.0.0 <4.0.0" From 193f1fd2eeecba0ad7951ea4c3934ffb4530594d Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 17 Oct 2024 09:59:00 +0700 Subject: [PATCH 11/15] Add adr for deploy platform configuration --- docs/configuration/platform_configuration.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docs/configuration/platform_configuration.md diff --git a/docs/configuration/platform_configuration.md b/docs/configuration/platform_configuration.md new file mode 100644 index 0000000000..5120b4238c --- /dev/null +++ b/docs/configuration/platform_configuration.md @@ -0,0 +1,16 @@ +## Configuration for platform + +### Context +- TwakeMail has actually been deployed on many different environments. + +### How to config + +1. Environments + +- `sass`: SaaS platform +- `other`: Other platform + +2. Active field PLATFORM in [env.file](https://github.com/linagora/tmail-flutter/blob/master/env.file) +``` +PLATFORM=saas +``` From 4281ff65b08c2242a4f9456ddb3b7b493efb3074 Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 17 Oct 2024 10:03:10 +0700 Subject: [PATCH 12/15] Bump version to `v0.13.4` --- CHANGELOG.md | 8 ++++++++ pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a6c0684b2..e6e5e3ec21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.13.4] - 2024-10-17 +### Added +- Configuration for deploy platform + +### Fixed +- Change logos to beta and move position of version label on web + ## [0.13.3] - 2024-10-16 ### Fixed - \#3002 \[SEARCH\] More filters @@ -637,6 +644,7 @@ - \#1512 remove plain text input for signature - \#1469 remove animation when navigating screen +[0.13.4]: https://github.com/linagora/tmail-flutter/releases/tag/v0.13.4 [0.13.3]: https://github.com/linagora/tmail-flutter/releases/tag/v0.13.3 [0.11.4002]: https://github.com/linagora/tmail-flutter/releases/tag/v0.11.4002 [0.11.4001]: https://github.com/linagora/tmail-flutter/releases/tag/v0.11.4001 diff --git a/pubspec.yaml b/pubspec.yaml index 2a24cf35ba..fa81fcad4d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.13.3 +version: 0.13.4 environment: sdk: ">=3.0.0 <4.0.0" From f64a697793d702d387cf287f221023d91980499c Mon Sep 17 00:00:00 2001 From: Dat PHAM HOANG Date: Thu, 17 Oct 2024 16:01:07 +0700 Subject: [PATCH 13/15] Only show beta tag in saas platform --- lib/features/base/widget/application_logo_with_text_widget.dart | 2 +- lib/main/utils/app_config.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/features/base/widget/application_logo_with_text_widget.dart b/lib/features/base/widget/application_logo_with_text_widget.dart index ee7d0827a1..0917a1cd7d 100644 --- a/lib/features/base/widget/application_logo_with_text_widget.dart +++ b/lib/features/base/widget/application_logo_with_text_widget.dart @@ -21,7 +21,7 @@ class ApplicationLogoWidthTextWidget extends StatelessWidget { @override Widget build(BuildContext context) { return TMailButtonWidget.fromIcon( - icon: PlatformInfo.isWeb && !AppConfig.isSaasPlatForm + icon: PlatformInfo.isWeb && AppConfig.isSaasPlatForm ? _imagePaths.icLogoWithTextBeta : _imagePaths.icLogoWithText, iconSize: 33, diff --git a/lib/main/utils/app_config.dart b/lib/main/utils/app_config.dart index a883e1a223..c03faff1f0 100644 --- a/lib/main/utils/app_config.dart +++ b/lib/main/utils/app_config.dart @@ -65,5 +65,5 @@ class AppConfig { static String get _platformEnv => dotenv.get('PLATFORM', fallback: 'other'); - static bool get isSaasPlatForm => _platformEnv == saasPlatform; + static bool get isSaasPlatForm => _platformEnv.toLowerCase() == saasPlatform; } \ No newline at end of file From f5540885a23efe982143090315988939d8c92347 Mon Sep 17 00:00:00 2001 From: chrismaster Date: Thu, 17 Oct 2024 17:06:33 +0000 Subject: [PATCH 14/15] Translated using Weblate (German) Currently translated at 99.6% (638 of 640 strings) Translation: Linagora/TeamMail Translate-URL: https://hosted.weblate.org/projects/linagora/teammail/de/ --- lib/l10n/intl_de.arb | 546 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 545 insertions(+), 1 deletion(-) diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index 61a3207624..42e42ad32c 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -2377,7 +2377,7 @@ "placeholders_order": [], "placeholders": {} }, - "pleaseChooseAnImageSizeCorrectly": "Bitte wählen Sie eine Bildgröße <= {maxSize} KB aus", + "pleaseChooseAnImageSizeCorrectly": "Bitte wählen Sie ein Bild mit einer Größe von weniger als {maxSize}KB aus", "@pleaseChooseAnImageSizeCorrectly": { "type": "text", "placeholders_order": [ @@ -3566,5 +3566,549 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "pleaseAllowNotifications": "Bitte erlauben Sie Benachrichtigungen von Twake Mail in den Einstellungen des Geräts", + "@pleaseAllowNotifications": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "markAsSpamFailed": "Als Spam markieren ist fehlgeschlagen", + "@markAsSpamFailed": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageEmptyFolderDialog": "Die Nachrichten im Ordner {folder} werden dauerhaft gelöscht und Sie werden sie nicht wiederherstellen können", + "@messageEmptyFolderDialog": { + "type": "text", + "placeholders_order": [ + "folder" + ], + "placeholders": { + "folder": {} + } + }, + "findEmails": "E-Mails finden", + "@findEmails": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "emailReadReceiptsToggleDescription": "Immer Lesebestätigungen für ausgehende Nachrichten anfordern", + "@emailReadReceiptsToggleDescription": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageEventActionBannerAttendeeTentative": " hat mit 'Vielleicht' auf diese Einladung geantwortet", + "@messageEventActionBannerAttendeeTentative": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youAreOffline": "Sie sind offline. Es sieht so aus, als ob Sie nicht verbunden sind.", + "@youAreOffline": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "notification": "Benachrichtigung", + "@notification": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "emailReadReceiptsSettingExplanation": "Lesebestätigungen sind Benachrichtigungen, die an Ihre Benutzer gesendet und von ihnen empfangen werden können, um zu bestätigen, dass E-Mails gelesen wurden.", + "@emailReadReceiptsSettingExplanation": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "textBodySendReceiptToSender": "Die Nachricht wurde von {receiver} um {time} gelesen\n\nSubject: {subject} \n\nAchtung: Diese Empfangsbestätigung bestätigt lediglich, dass die Nachricht auf dem Computer des Empfängers angezeigt wurde. Es gibt keine Garantie, dass der Empfänger die Nachricht gelesen oder den Inhalt verstanden hat.", + "@textBodySendReceiptToSender": { + "type": "text", + "placeholders_order": [ + "receiver", + "subject", + "time" + ], + "placeholders": { + "receiver": {}, + "subject": {}, + "time": {} + } + }, + "discardChanges": "Änderungen verwerfen", + "@discardChanges": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "appTitlePushNotification": "Twake Mail", + "@appTitlePushNotification": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "saveEmailAsDraftFailure": "Fehler beim Speichern Ihrer Nachricht als Entwurf.", + "@saveEmailAsDraftFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogOfflineModeOnIOS": "Die Nachricht wird in der Sende-Warteschlange sein. Sie können es erneut versuchen, wenn Sie online sind.", + "@messageDialogOfflineModeOnIOS": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "bannerProgressingRecoveryMessage": "Die Wiederherstellung ist im Gange. Sie können Twake Mail weiterhin verwenden", + "@bannerProgressingRecoveryMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "emailReadReceipts": "Lesebestätigungen für E-Mails", + "@emailReadReceipts": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "loadingPleaseWait": "Lädt... Bitte warten!", + "@loadingPleaseWait": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "tryAgain": "Versuchen Sie es erneut", + "@tryAgain": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "starIt": "Mit einem Stern markieren", + "@starIt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "bannerMessageSendingQueueViewOnIOS": "Ihre Nachrichten wurden aufgrund von Netzwerkproblemen nicht gesendet. Sie sind sicher gespeichert. Sobald Sie wieder online sind, können Sie sie erneut senden, bearbeiten oder löschen.", + "@bannerMessageSendingQueueViewOnIOS": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "emptyTrash": "Papierkorb leeren", + "@emptyTrash": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "moveConversation": "Verschiebe {numberOfConversation} Nachrichten", + "@moveConversation": { + "type": "text", + "placeholders_order": [ + "numberOfConversation" + ], + "placeholders": { + "numberOfConversation": {} + } + }, + "open": "Öffnen", + "@open": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "progress": "Fortschritt", + "@progress": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "teamMailBoxes": "Team-Postfächer", + "@teamMailBoxes": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "creatingMessage": "Nachricht wird erstellt", + "@creatingMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "notSelectedMailboxToMoveMessage": "Bitte wählen Sie ein Postfach, um die Nachricht zu verschieben", + "@notSelectedMailboxToMoveMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "warningMessageWhenExceedGenerallySizeInComposer": "Ihre Nachricht ist größer als die üblicherweise von Drittanbieter-E-Mail-Systemen akzeptierte Größe. Wenn Sie das Senden dieser Nachricht bestätigen, besteht das Risiko, dass sie vom Empfängersystem abgelehnt wird.", + "@warningMessageWhenExceedGenerallySizeInComposer": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "continueAction": "Fortfahren", + "@continueAction": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "reconnect": "Erneut verbinden", + "@reconnect": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "sendMessageFailureWithSetErrorTypeOverQuota": "Fehler beim Senden Ihrer Nachricht, da das Quotalimit überschritten wurde.", + "@sendMessageFailureWithSetErrorTypeOverQuota": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "showLess": "Weniger anzeigen", + "@showLess": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "saveEmailAsDraftFailureWithSetErrorTypeTooLarge": "Fehler beim Speichern Ihrer Nachricht als Entwurf, da sie zu groß ist.", + "@saveEmailAsDraftFailureWithSetErrorTypeTooLarge": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "restoreDeletedMessageSuccess": "Gelöschte Nachrichten erfolgreich wiederhergestellt", + "@restoreDeletedMessageSuccess": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "dialogMessageSessionHasExpired": "Die aktuelle Sitzung ist abgelaufen. Bitte stellen Sie die Verbindung zum Server wieder her", + "@dialogMessageSessionHasExpired": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "saveMessage": "Nachricht speichern", + "@saveMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "clean": "Bereinigen", + "@clean": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "turnOnRequestReadReceipt": "Lesebestätigung anfordern einschalten", + "@turnOnRequestReadReceipt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "showNotifications": "Benachrichtigungen anzeigen", + "@showNotifications": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "goToSettings": "Zu den Einstellungen gehen", + "@goToSettings": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "savingMessage": "Nachricht wird gespeichert", + "@savingMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "canceling": "Wird abgebrochen", + "@canceling": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "savingMessageToDraftFolder": "Nachricht wird im Entwurfsordner gespeichert", + "@savingMessageToDraftFolder": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "closeAnyway": "Trotzdem schließen", + "@closeAnyway": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "sendMessageFailureWithSetErrorTypeTooLarge": "Fehler beim Senden Ihrer Nachricht, da sie zu groß ist.", + "@sendMessageFailureWithSetErrorTypeTooLarge": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogDeleteSendingEmail": "Das Löschen einer Offline-E-Mail wird deren Inhalt dauerhaft entfernen. Sie können diese Aktion nicht rückgängig machen und die E-Mail nicht aus dem Papierkorb wiederherstellen.", + "@messageDialogDeleteSendingEmail": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "delivering": "Zustellen", + "@delivering": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "clearFolder": "Ordner leeren", + "@clearFolder": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageMarkAsReadFolderAllFailure": "Der Ordner \"{folderName}\" konnte nicht als gelesen markiert werden", + "@toastMessageMarkAsReadFolderAllFailure": { + "type": "text", + "placeholders_order": [ + "folderName" + ], + "placeholders": { + "folderName": {} + } + }, + "warningMessageWhenSendEmailFailure": "Das Senden der Nachricht ist fehlgeschlagen.\nEin Fehler ist beim Versenden der E-Mail aufgetreten.", + "@warningMessageWhenSendEmailFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "warningMessageWhenSaveEmailToDraftsFailure": "Das Speichern der Nachricht im Entwurfsordner ist fehlgeschlagen.\nEin Fehler ist beim Speichern der E-Mail aufgetreten.", + "@warningMessageWhenSaveEmailToDraftsFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "quotaWarningBannerMessage": "Bald werden Sie keine E-Mails mehr in Tmail senden können. Bitte bereinigen Sie Ihren Speicher oder erweitern Sie ihn, um alle Funktionen in Tmail weiterhin nutzen zu können.", + "@quotaWarningBannerMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "turnOffRequestReadReceipt": "Lesebestätigung anfordern ausschalten", + "@turnOffRequestReadReceipt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "emptySpamFolderFailed": "Das Leeren des Spam-Ordners ist fehlgeschlagen", + "@emptySpamFolderFailed": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "regards": "Mit freundlichen Grüßen", + "@regards": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "allowsTwakeMailToNotifyYouWhenANewMessageArrivesOnYourPhone": "Erlaubt Twake Mail, Sie zu benachrichtigen, wenn eine neue Nachricht auf Ihrem Telefon ankommt", + "@allowsTwakeMailToNotifyYouWhenANewMessageArrivesOnYourPhone": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "saveEmailAsDraftFailureWithSetErrorTypeOverQuota": "\"Fehler beim Speichern Ihrer Nachricht als Entwurf, da das Quotalimit überschritten wurde.", + "@saveEmailAsDraftFailureWithSetErrorTypeOverQuota": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "folderVisibilitySubtitle": "Ordner anzeigen/ausblenden, einschließlich Ihrer persönlichen Ordner und Team-Postfächer.", + "@folderVisibilitySubtitle": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "sendMessageFailure": "Fehler beim Senden Ihrer Nachricht.", + "@sendMessageFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "generalSignatureImageUploadError": "Beim Hochladen des Bildes ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.", + "@generalSignatureImageUploadError": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "restoreDeletedMessageCanceled": "Wiederherstellung der gelöschten Nachricht abgebrochen", + "@restoreDeletedMessageCanceled": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "sMimeGoodSignatureMessage": "Die Authentizität dieser Nachricht wurde durch eine SMime-Signatur verifiziert.", + "@sMimeGoodSignatureMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "quotaErrorBannerMessage": "Bald werden Sie keine E-Mails mehr in Tmail senden können. Bitte bereinigen Sie Ihren Speicher oder erweitern Sie ihn, um alle Funktionen von Tmail nutzen zu können.", + "@quotaErrorBannerMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageConfirmationDialogDeleteMultipleFolder": "{numberOfMailbox} Ordner, alle darin enthaltenen Unterordner und Nachrichten werden gelöscht und können nicht wiederhergestellt werden. Möchten Sie den Löschvorgang fortsetzen?", + "@messageConfirmationDialogDeleteMultipleFolder": { + "type": "text", + "placeholders_order": [ + "numberOfMailbox" + ], + "placeholders": { + "numberOfMailbox": {} + } + }, + "status": "Status", + "@status": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "spamFolderNotFound": "Spam-Ordner nicht gefunden", + "@spamFolderNotFound": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "bannerMessageSendingQueueView": "Nachrichten im Ordner 'Sende-Warteschlange' werden gesendet oder geplant, wenn eine Verbindung besteht.", + "@bannerMessageSendingQueueView": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "sessionExpired": "Sitzung abgelaufen", + "@sessionExpired": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "emptySpamFolder": "Spam-Ordner leeren", + "@emptySpamFolder": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogWhenStoreSendingEmailThird": "E-Mails. Sie werden zugestellt, sobald Sie eine Verbindung zum Internet herstellen. Um diese E-Mails vor dem Senden zu bearbeiten, gehen Sie zu dem/der ", + "@messageDialogWhenStoreSendingEmailThird": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "noSuitableBrowserForOIDC": "Kein geeigneter Browser für OIDC, bitte wenden Sie sich an Ihren Systemadministrator", + "@noSuitableBrowserForOIDC": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotAddedConditionToRule": "Sie haben der Regel keine Bedingung hinzugefügt.", + "@youHaveNotAddedConditionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "showMore": "Mehr anzeigen (+{count})", + "@showMore": { + "type": "text", + "placeholders_order": [ + "count" + ], + "placeholders": { + "count": {} + } + }, + "requestReadReceiptHasBeenDisabled": "Lesebestätigung anfordern wurde deaktiviert", + "@requestReadReceiptHasBeenDisabled": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "sendingMessage": "Nachricht wird gesendet", + "@sendingMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "requestReadReceiptHasBeenEnabled": "Lesebestätigung anfordern wurde aktiviert", + "@requestReadReceiptHasBeenEnabled": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "thisImageCannotBePastedIntoTheEditor": "Dieses Bild kann nicht in den Editor eingefügt werden.", + "@thisImageCannotBePastedIntoTheEditor": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageWarningDialogForForwardsToOtherDomains": "Sie leiten E-Mails an eine andere Domain weiter. Dies könnte ein Sicherheitsrisiko darstellen oder als illegale Datenextraktion angesehen werden.", + "@messageWarningDialogForForwardsToOtherDomains": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotAddedActionToRule": "Sie haben der Regel keine Aktion hinzugefügt.", + "@youHaveNotAddedActionToRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "sMimeBadSignatureMessage": "Die Überprüfung der SMime-Signatur dieser Nachricht ist fehlgeschlagen.", + "@sMimeBadSignatureMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "thisFileCannotBePicked": "Diese Datei kann nicht ausgewählt werden.", + "@thisFileCannotBePicked": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "mailToAttendees": "E-Mail an Teilnehmer", + "@mailToAttendees": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "canNotUploadFileToSignature": "Diese Datei kann nicht zur Signatur hochgeladen werden", + "@canNotUploadFileToSignature": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "warningMessageWhenClickCloseComposer": "Diese Nachricht im Entwurfsordner speichern und den Editor schließen?", + "@warningMessageWhenClickCloseComposer": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "notificationsDisabled": "Benachrichtigungen deaktiviert", + "@notificationsDisabled": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youHaveNotSelectedAnyActionForRule": "Sie haben keine Aktion für die Regel ausgewählt.", + "@youHaveNotSelectedAnyActionForRule": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } From 124c4ce09a773fcb317015b5ab7714c958e295f2 Mon Sep 17 00:00:00 2001 From: florentos17 Date: Tue, 22 Oct 2024 16:43:16 +0200 Subject: [PATCH 15/15] TF-3149 corrected typos and added clarification to identity management `Name` field (#3216) --- docs/user-guide/profile.md | 62 +++++++++---------- .../presentation/identity_creator_view.dart | 2 +- lib/l10n/intl_messages.arb | 8 ++- lib/main/localizations/app_localizations.dart | 6 ++ 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/docs/user-guide/profile.md b/docs/user-guide/profile.md index 720f0a31d3..d2c1da3504 100644 --- a/docs/user-guide/profile.md +++ b/docs/user-guide/profile.md @@ -1,11 +1,11 @@ # Profile {#profile} -After logged in your Tmail account, click on avatar on top right then select option "Manage account" +After logging in to your Tmail account, click on avatar on top right then select option "Manage account" ![image](https://github.com/user-attachments/assets/3771e3f7-8071-466b-9bed-30424e29ae7a) -On Mobile, after you loggin TeanMail application, click on hamburger button => then select Manage account, the Settings screen will be displayed. +On Mobile, after you log in to the TMail application, click on hamburger button => then select Manage account, the Settings screen will be displayed. ![Frame 13 (1)](https://github.com/user-attachments/assets/7ae8b5c2-ef36-4340-8282-d9a827e8508a) @@ -27,19 +27,19 @@ The profile page allows you to: ## Identities Email identities allow you to manage multiple personas from a single email account. This can be useful for personal, professional, or organizational purposes. Each identity can have its own name and signature. -When you're in Profle page, you can see your identity list +When you're in Profile page, you can see your identity list ### 1. Create a new identity #### On Web -- (1) Click on "Create New Identity" button -- (2) Enter the name for the identity. -- (3) Email: Specify the email address associated with this identity. You can select one email from drop-down list. -- (4) Reply to: Specify the email address that will appear on recepient's composer when he reply to your email -- (5) BCC: When you compose a new email wiht this identity, the emails in this field will be added to "Bcc" field of composer automatically +- (1) Click on "Create New Identity" button. +- (2) Enter the name for the identity, which is to be displayed to recipients. +- (3) Email: Specify the email address associated with this identity. You can select one email from drop-down list. +- (4) Reply to: Specify the email address that will appear on your recipient's composer when he replies to your email. +- (5) Bcc to: When you compose a new email with this identity, the emails in this field will be added to "Bcc" field of composer automatically - (6) Customize the signature if needed. -- (7) Set as default identity: When an identity is set as dedault, its settings such as signature, BCC... will be used when you compose a new email. You can still change to a non default identity by selecting it in the composer. +- (7) Set as default identity: When an identity is set as default, its settings such as signature, BCC... will be used when you compose a new email. You can still change to a non default identity by selecting it in the composer. - (8) Click button Create to save the new identity. ![image](https://github.com/linagora/tmail-flutter/assets/68209176/44f74874-2eff-4aa5-97e5-a267d5a26b71) @@ -55,12 +55,12 @@ When you're in Profle page, you can see your identity list - (1) Click on "Create New Identity" button - (2) Enter the name for the identity. - (3) Email: Specify the email address associated with this identity. You can select one email from drop-down list. -- (4) Reply to: Specify the email address that will appear on recepient's composer when he reply to your email -- (5) BCC: When you compose a new email wiht this identity, the emails in this field will be added to "Bcc" field of composer automatically +- (4) Reply to: Specify the email address that will appear on the recipient's composer when he replies to your email +- (5) BCC: When you compose a new email with this identity, the emails in this field will be added to "Bcc" field of composer automatically - (6) Customize the signature if needed. -- (7) Set as default identity: When an identity is set as dedault, its settings such as signature, BCC... will be used when you compose a new email. You can still change to a non default identity by selecting it in the composer. +- (7) Set as default identity: When an identity is set as default, its settings such as signature, BCC... will be used when you compose a new email. You can still change to a non default identity by selecting it in the composer. - (8) Click button Create to save the new identity. -- (9) - You can include an image in signature of the identity, .eg company logo, product logo, project logo.... The image is sent in every email, so it should be an small image (less than 16KB). +- (9) You can include an image in signature of the identity, .eg company logo, product logo, project logo.... The image is sent in every email, so it should be a small image (less than 16KB). ![Frame 8 (1)](https://github.com/linagora/tmail-flutter/assets/68209176/81057675-e258-45d6-baac-752047634fbf) @@ -170,7 +170,7 @@ When you're in Profle page, you can see your identity list ## Email read receipts - To find out when an email that you sent was opened, you can request a read receipt. A read receipt is sent to you as an email with the time and date of when your message was opened. -- This setting allows you to automaticaly enable the read receipt for any email that you sent: +- This setting allows you to automatically enable the read receipt for any email that you sent: ![image](https://github.com/user-attachments/assets/82802328-c9c7-4dc7-84f6-d17c9bf2d5f7) @@ -197,16 +197,16 @@ When you're in Profle page, you can see your identity list (1) Enter the email address to which you want to forward your emails. You can input multiple email addresses -(2) Click `Add recipient` buton to save your changes, there will be a successfull notification +(2) Click `Add recipient` button to save your changes, there will be a successful notification (3) Choose whether to keep a copy of forwarded emails in your original inbox: By default, the toggle is enabled. - - When you enable this toggele, when a new email arrives in your inbox, it is automatically forwaded to the list of recipients below and the email is till in your inbox. This could be helpful in some cases as: + - When you enable this toggle, when a new email arrives in your inbox, it is automatically forwarded to the list of recipients below and the email is till in your inbox. This could be helpful in some cases as: - Consolidating Emails: Forward emails from multiple accounts to a central inbox for easier management. - Backup: Automatically forward emails to a backup email address - Forward emails at work to a personal mailbox in your vacation to ensure you don't lose important messages. - Handle your departure - ... - - When you disable the toggle, when a new email arrives in, it is automatically forwaded to the list of recipients below and the email is not kept in your inbox. + - When you disable the toggle, when a new email arrives in, it is automatically forwarded to the list of recipients below and the email is not kept in your inbox. ![Group 15 (2)](https://github.com/user-attachments/assets/dc0c9be1-aae6-49a5-ad5d-63f998e737c0) @@ -223,7 +223,7 @@ When you're in Profle page, you can see your identity list #### On Web - If you no longer wish to forward your email, you can remove the forwarding email address. -- You can click Delete icon in each forwading address or select multiple addersses (1) then click button `Remove` (2) +- You can click Delete icon in each forwarding address or select multiple addresses (1) then click button `Remove` (2) - Confirm the deletion (3) ![Group 17 (1)](https://github.com/user-attachments/assets/4489b283-e051-4963-90da-c5baf2284d87) @@ -231,7 +231,7 @@ When you're in Profle page, you can see your identity list #### On Mobile -- You can click Delete icon in each forwading addess (1) or select multiple addesses (2) then click button `Remove` (3) +- You can click Delete icon in each forwarding address (1) or select multiple addresses (2) then click button `Remove` (3) - Confirm the deletion ![Frame 18 (1)](https://github.com/user-attachments/assets/b4696bf4-3ece-40bf-9164-dee6e3a339d6) @@ -241,7 +241,7 @@ When you're in Profle page, you can see your identity list - Automatic vacation replies are messages that are sent automatically to anyone who emails you while you're on vacation. - Setting up automatic vacation reply is a convenient way to inform your contacts that you're away and won't be able to respond to emails promptly. -- On Manage accout page, YOu can select tab "Vacation" on left menu to access vacation reply settings +- On Manage account page, YOu can select tab "Vacation" on left menu to access vacation reply settings ![image](https://github.com/linagora/tmail-flutter/assets/68209176/f2743333-bc42-4cc7-a50e-81121c43a355) @@ -256,14 +256,14 @@ When you're in Profle page, you can see your identity list - (1) Turn on the toggle :`Automatically reply to messages when they are received` - (2) Setting the Date Range: Specify the start and end dates/times for your automatic replies. This ensures that the messages are sent only during your vacation period. -- End date is optional. If you can turn off the toggle `Vacation stops at', it means the vacation does not have an end date and your vacation responder will work until you turn it off or change the setting. +- End date is optional. If you can turn off the toggle `Vacation stops at`, it means the vacation does not have an end date and your vacation responder will work until you turn it off or change the setting. - (3) Subject: Input the automatic reply email's subject - (4) Compose your vacation reply message. Rich-text options are available - (5) Save changes. You need to click this button so that your input is applied. ![image](https://github.com/linagora/tmail-flutter/assets/68209176/8bf8aba2-4a1c-4e0f-baca-af02c9fe9ebf) -When the vacation is enabled, there will be a vacation banner in every screen until the vacation ends or you turn off it: +When the vacation is enabled, there will be a vacation banner in every screen until the vacation ends or until you turn it off : - (1) When you click on `Turn off`, the vacation responder is disabled immediately and the banner disappears - (2) When you click on `Vacation setting`, it will open vacation setting page. @@ -290,7 +290,7 @@ When the vacation is enabled, there will be a vacation banner in every screen un ### 2. Receive vacation automatic reply -- When a person sends an email when your vacation mode is enabled, he will receive an automatic reply with the subject and message body which are inputed in your vacation setting screen +- When a person sends an email when your vacation mode is enabled, he will receive an automatic reply with the subject and message body which are inputted in your vacation setting screen ![image](https://github.com/user-attachments/assets/a8c4100c-4fdf-4f05-b0f9-47a3788a0dbf) @@ -299,10 +299,10 @@ When the vacation is enabled, there will be a vacation banner in every screen un - Hiding and showing folders is a useful feature that allows you to customize the view of your mailbox and focus on the folders that are most important to you. - This feature is particularly useful when you have numerous folders but want to focus on specific ones. -- On Manage accout page, YOu can select tab "Folder visibility" on left menu to access Folder visibility settings -- You can change the visibility of personal foder and team-mailbox +- On Manage account page, YOu can select tab "Folder visibility" on left menu to access Folder visibility settings +- You can change the visibility of personal folder and team-mailbox - You cannot change the visibility of system folder (Inbox, Archive, Draft, Outbox, Sent, Trash, Spam, Templates) -- In the folder list, If a folder is currently hiden, there will be a button `Show` next to it. If you click on this button, the folder will be shown on the left folder menu of your mailbox +- In the folder list, If a folder is currently hidden, there will be a button `Show` next to it. If you click on this button, the folder will be shown on the left folder menu of your mailbox - In the folder list, If a folder is currently shown, there will be a button `Hide` next to it. If you click on this button, the folder will be hidden on the left folder menu of your mailbox ![Group 18 (1)](https://github.com/user-attachments/assets/f3c5046f-71a2-4660-b52f-6a344f2a5796) @@ -322,10 +322,10 @@ When the vacation is enabled, there will be a vacation banner in every screen un ## Language settings -- Language setting determinse the language in which you view content, communicate, and interact with TwakeMail application -- By default, the language of the browser (for web) or system language (for mobile) will be used when you first logged-in TwakeMail and you can change it to your prefered language -- On Manage accout page, YOu can select tab "Language and regions" on left menu to access Language settings -- Then you can select the language that you want, it will be applied immediately to your Twake-Mail account. +- Language setting determine the language in which you view content, communicate, and interact with TwakeMail application +- By default, the language of the browser (for web) or system language (for mobile) will be used when you first logged-in TwakeMail and you can change it to your preferred language +- On Manage account page, YOu can select tab "Language and regions" on left menu to access Language settings +- Then you can select the language that you want, it will be applied immediately to your TwakeMail account. ![image](https://github.com/user-attachments/assets/3ba8d626-8630-4ec2-8057-186f8ee33c0e) @@ -333,7 +333,7 @@ When the vacation is enabled, there will be a vacation banner in every screen un ## Logout -- When you click on Sign-out button on Left menu of Manage account page, you will be logged out immedialtely and redirected to Log-in screen: +- When you click on Sign-out button on Left menu of Manage account page, you will be logged out immediately and redirected to Log-in screen: ![Group 20 (1)](https://github.com/user-attachments/assets/937aee13-0a9c-424b-a125-115e560c5735) diff --git a/lib/features/identity_creator/presentation/identity_creator_view.dart b/lib/features/identity_creator/presentation/identity_creator_view.dart index 4ec89c2444..2d633c0e0d 100644 --- a/lib/features/identity_creator/presentation/identity_creator_view.dart +++ b/lib/features/identity_creator/presentation/identity_creator_view.dart @@ -49,7 +49,7 @@ class IdentityCreatorView extends GetWidget padding: const EdgeInsetsDirectional.symmetric(vertical: 12, horizontal: 24), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Obx(() => IdentityInputFieldBuilder( - AppLocalizations.of(context).name, + AppLocalizations.of(context).nameToBeDisplayed, controller.errorNameIdentity.value, AppLocalizations.of(context).required, editingController: controller.inputNameIdentityController, diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index cc68d12fd7..1ba341cfd8 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2024-09-18T01:15:29.034686", + "@@last_modified": "2024-10-21T09:30:30.005573", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -1226,6 +1226,12 @@ "placeholders_order": [], "placeholders": {} }, + "nameToBeDisplayed": "Name to be displayed to recipients", + "@nameToBeDisplayed": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, "reply_to": "Reply to", "@reply_to": { "type": "text", diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index b818e230e9..fbe1485074 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -1259,6 +1259,12 @@ class AppLocalizations { name: 'name'); } + String get nameToBeDisplayed { + return Intl.message( + 'Name to be displayed to recipients', + name: 'nameToBeDisplayed'); + } + String get reply_to { return Intl.message( 'Reply to',