diff --git a/lib/features/composer/domain/extensions/sending_email_extension.dart b/lib/features/composer/domain/extensions/sending_email_extension.dart index e6371f341..19926d695 100644 --- a/lib/features/composer/domain/extensions/sending_email_extension.dart +++ b/lib/features/composer/domain/extensions/sending_email_extension.dart @@ -3,6 +3,7 @@ import 'package:model/extensions/email_extension.dart'; import 'package:model/extensions/email_id_extensions.dart'; import 'package:model/extensions/identity_id_extension.dart'; import 'package:model/extensions/mailbox_id_extension.dart'; +import 'package:model/mailbox/select_mode.dart'; import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'; import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; import 'package:tmail_ui_user/features/offline_mode/model/sending_email_hive_cache.dart'; @@ -33,4 +34,36 @@ extension SendingEmailExtension on SendingEmail { identityId: identityId ); } + + SendingEmail toggleSelection() { + return SendingEmail( + sendingId: sendingId, + email: email, + emailActionType: emailActionType, + createTime: createTime, + sentMailboxId: sentMailboxId, + emailIdDestroyed: emailIdDestroyed, + emailIdAnsweredOrForwarded: emailIdAnsweredOrForwarded, + identityId: identityId, + mailboxNameRequest: mailboxNameRequest, + creationIdRequest: creationIdRequest, + selectMode: selectMode == SelectMode.INACTIVE ? SelectMode.ACTIVE : SelectMode.INACTIVE + ); + } + + SendingEmail unSelected() { + return SendingEmail( + sendingId: sendingId, + email: email, + emailActionType: emailActionType, + createTime: createTime, + sentMailboxId: sentMailboxId, + emailIdDestroyed: emailIdDestroyed, + emailIdAnsweredOrForwarded: emailIdAnsweredOrForwarded, + identityId: identityId, + mailboxNameRequest: mailboxNameRequest, + creationIdRequest: creationIdRequest, + selectMode: SelectMode.INACTIVE + ); + } } \ No newline at end of file diff --git a/lib/features/offline_mode/controller/work_scheduler_controller.dart b/lib/features/offline_mode/controller/work_scheduler_controller.dart index 71ba1f3cd..3bb84a0d1 100644 --- a/lib/features/offline_mode/controller/work_scheduler_controller.dart +++ b/lib/features/offline_mode/controller/work_scheduler_controller.dart @@ -77,7 +77,14 @@ class WorkSchedulerController { Future cancelByWorkType(WorkerType type) => Workmanager().cancelByTag(type.name); - Future cancelByUniqueId(String uniqueId) => Workmanager().cancelByUniqueName(uniqueId); + Future cancelByUniqueId(String uniqueId) { + try { + return Workmanager().cancelByUniqueName(uniqueId); + } catch (e) { + logError('WorkSchedulerController::cancelByUniqueId():EXCEPTION: $e'); + return Future.value(); + } + } Future cancelAll() => Workmanager().cancelAll(); } \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart b/lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart index 25cac8699..45e0cd413 100644 --- a/lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart +++ b/lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart @@ -1,5 +1,6 @@ import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_multiple_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_controller.dart'; class SendingQueueBindings extends Bindings { @@ -10,6 +11,6 @@ class SendingQueueBindings extends Bindings { } void _bindingsController() { - Get.put(SendingQueueController()); + Get.put(SendingQueueController(Get.find())); } } \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart b/lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart index 568f16ac9..e2b704ac6 100644 --- a/lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart +++ b/lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart @@ -5,6 +5,8 @@ import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart'; import 'package:tmail_ui_user/features/sending_queue/data/repository/sending_queue_repository_impl.dart'; import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_multiple_sending_email_interactor.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_single_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; @@ -35,6 +37,8 @@ class SendingQueueInteractorBindings extends InteractorsBindings { @override void bindingsInteractor() { Get.lazyPut(() => GetAllSendingEmailInteractor(Get.find())); + Get.lazyPut(() => DeleteSingleSendingEmailInteractor(Get.find())); + Get.lazyPut(() => DeleteMultipleSendingEmailInteractor(Get.find())); } @override diff --git a/lib/features/sending_queue/presentation/sending_queue_controller.dart b/lib/features/sending_queue/presentation/sending_queue_controller.dart index bf1f45397..c8abdd944 100644 --- a/lib/features/sending_queue/presentation/sending_queue_controller.dart +++ b/lib/features/sending_queue/presentation/sending_queue_controller.dart @@ -1,24 +1,47 @@ -import 'package:collection/collection.dart'; import 'package:core/utils/app_logger.dart'; -import 'package:flutter/cupertino.dart'; +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:core/presentation/utils/app_toast.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:model/mailbox/select_mode.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart'; +import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/offline_mode/scheduler/worker_state.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart'; +import 'package:tmail_ui_user/features/offline_mode/controller/work_scheduler_controller.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/state/delete_multiple_sending_email_state.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_multiple_sending_email_interactor.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/extensions/list_sending_email_extension.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; -class SendingQueueController extends BaseController { +class SendingQueueController extends BaseController with MessageDialogActionMixin { + + final DeleteMultipleSendingEmailInteractor _deleteMultipleSendingEmailInteractor; final dashboardController = getBinding(); - final sendingQueueIsolateManager = getBinding(); + final _sendingQueueIsolateManager = getBinding(); + final _imagePaths = getBinding(); + final _appToast = getBinding(); final listSendingEmailController = ScrollController(); + final selectionState = Rx(SelectMode.INACTIVE); + + SendingQueueController(this._deleteMultipleSendingEmailInteractor); + @override void onInit() { super.onInit(); - sendingQueueIsolateManager?.initial( + _sendingQueueIsolateManager?.initial( onData: _handleSendingQueueEvent, onError: (error, stackTrace) { logError('SendingQueueController::onInit():onError:error: $error | stackTrace: $stackTrace'); @@ -37,18 +60,140 @@ class SendingQueueController extends BaseController { } } + void handleOnLongPressAction(SendingEmail sendingEmail) { + final newListSendingEmail = dashboardController!.listSendingEmails.toggleSelection(sendingEmailSelected: sendingEmail); + dashboardController!.listSendingEmails.value = newListSendingEmail; + + selectionState.value = newListSendingEmail.isAllUnSelected() + ? SelectMode.INACTIVE + : SelectMode.ACTIVE; + } + + void toggleSelectionSendingEmail(SendingEmail sendingEmail) { + final newListSendingEmail = dashboardController!.listSendingEmails.toggleSelection(sendingEmailSelected: sendingEmail); + dashboardController!.listSendingEmails.value = newListSendingEmail; + + selectionState.value = newListSendingEmail.isAllUnSelected() + ? SelectMode.INACTIVE + : SelectMode.ACTIVE; + } + + bool get isAllUnSelected => dashboardController!.listSendingEmails.isAllUnSelected(); + void _refreshSendingQueue({bool needToReopen = false}) { - dashboardController?.getAllSendingEmails(needToReopen: needToReopen); + dashboardController!.getAllSendingEmails(needToReopen: needToReopen); } void openMailboxMenu() { - dashboardController?.openMailboxMenuDrawer(); + dashboardController!.openMailboxMenuDrawer(); + } + + void disableSelectionMode() { + final newListSendingEmail = dashboardController!.listSendingEmails.unAllSelected(); + dashboardController!.listSendingEmails.value = newListSendingEmail; + selectionState.value = SelectMode.INACTIVE; + } + + void handleSendingEmailActionType( + BuildContext context, + SendingEmailActionType actionType, + List listSendingEmails + ) { + switch(actionType) { + case SendingEmailActionType.delete: + _deleteSendingEmailAction(context, listSendingEmails); + break; + } + } + + void _deleteSendingEmailAction(BuildContext context, List listSendingEmails) { + showConfirmDialogAction( + context, + AppLocalizations.of(context).messageDialogDeleteSendingEmail, + AppLocalizations.of(currentContext!).delete, + title: AppLocalizations.of(currentContext!).deleteOfflineEmail, + icon: SvgPicture.asset(_imagePaths!.icDeleteDialogRecipients), + alignCenter: true, + messageStyle: const TextStyle( + color: AppColor.colorTitleSendingItem, + fontSize: 15, + fontWeight: FontWeight.normal + ), + titleStyle: const TextStyle( + color: AppColor.colorDeletePermanentlyButton, + fontSize: 20, + fontWeight: FontWeight.bold + ), + actionButtonColor: AppColor.colorDeletePermanentlyButton, + actionStyle: const TextStyle( + color: Colors.white, + fontSize: 17, + fontWeight: FontWeight.w500 + ), + cancelStyle: const TextStyle( + color: AppColor.colorDeletePermanentlyButton, + fontSize: 17, + fontWeight: FontWeight.w500 + ), + onConfirmAction: () => _handleDeleteSendingEmail(listSendingEmails), + ); + } + + void _handleDeleteSendingEmail(List listSendingEmails) async { + final accountId = dashboardController!.accountId.value; + final session = dashboardController!.sessionCurrent; + + if (accountId != null && session != null) { + final sendingIds = listSendingEmails.map((sendingEmail) => sendingEmail.sendingId).toSet().toList(); + + await Future.wait( + sendingIds.map((sendingId) => WorkSchedulerController().cancelByUniqueId(sendingId)), + eagerError: true + ); + + consumeState(_deleteMultipleSendingEmailInteractor.execute(accountId, session.username, sendingIds)); + } + } + + void _handleDeleteSendingEmailSuccess() { + if (currentContext != null && currentOverlayContext != null) { + selectionState.value = SelectMode.INACTIVE; + + _appToast!.showToastSuccessMessage( + currentOverlayContext!, + AppLocalizations.of(currentContext!).deleteSomeOfflineEmailSuccessfully + ); + + _refreshSendingQueue(); + } + } + + void _handleDeleteSendingEmailFailure() { + selectionState.value = SelectMode.INACTIVE; + } + + @override + void handleSuccessViewState(Success success) { + super.handleSuccessViewState(success); + if (success is DeleteMultipleSendingEmailAllSuccess || + success is DeleteMultipleSendingEmailHasSomeSuccess) { + _handleDeleteSendingEmailSuccess(); + } + } + + @override + void handleFailureViewState(Failure failure) { + super.handleFailureViewState(failure); + if (failure is DeleteMultipleSendingEmailAllFailure || + failure is DeleteMultipleSendingEmailFailure) { + _handleDeleteSendingEmailFailure(); + } } @override void onClose() { listSendingEmailController.dispose(); - sendingQueueIsolateManager?.release(); + _sendingQueueIsolateManager?.release(); super.onClose(); } } \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/sending_queue_view.dart b/lib/features/sending_queue/presentation/sending_queue_view.dart index 3de51bd99..720eafe61 100644 --- a/lib/features/sending_queue/presentation/sending_queue_view.dart +++ b/lib/features/sending_queue/presentation/sending_queue_view.dart @@ -8,6 +8,7 @@ import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_ import 'package:get/get.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/banner_message_sending_queue_widget.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/bottom_bar_sending_queue_widget.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart'; class SendingQueueView extends GetWidget with AppLoaderMixin { @@ -18,23 +19,32 @@ class SendingQueueView extends GetWidget with AppLoaderM Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, - body: GestureDetector( - onTap: FocusScope.of(context).unfocus, - child: SafeArea( - child: Column( - children: [ - AppBarSendingQueueWidget(onOpenMailboxMenu: controller.openMailboxMenu), - const Divider(color: AppColor.colorDividerComposer, height: 1), - const BannerMessageSendingQueueWidget(), - Expanded(child: _buildListSendingEmails(context)) - ] - ), + body: SafeArea( + child: Column( + children: [ + Obx(() => AppBarSendingQueueWidget( + listSendingEmails: controller.dashboardController!.listSendingEmails, + onOpenMailboxMenu: controller.openMailboxMenu, + onBackAction: controller.disableSelectionMode, + selectMode: controller.selectionState.value, + )), + const Divider(color: AppColor.colorDividerComposer, height: 1), + const BannerMessageSendingQueueWidget(), + Expanded(child: _buildListSendingEmails(context)), + Obx(() { + if (controller.isAllUnSelected) { + return const SizedBox.shrink(); + } else { + return BottomBarSendingQueueWidget( + listSendingEmails: controller.dashboardController!.listSendingEmails, + onHandleSendingEmailActionType: (actionType, listSendingEmails) => controller.handleSendingEmailActionType(context, actionType, listSendingEmails), + ); + } + }), + ] ), ), - floatingActionButton: ComposeFloatingButton( - scrollController: controller.listSendingEmailController, - onTap: () => controller.dashboardController!.goToComposer(ComposerArguments()) - ), + floatingActionButton: _buildFloatingButtonCompose(), ); } @@ -45,13 +55,37 @@ class SendingQueueView extends GetWidget with AppLoaderM controller: controller.listSendingEmailController, padding: EdgeInsets.zero, itemCount: controller.dashboardController!.listSendingEmails.length, - itemBuilder: (context, index) => SendingEmailTileWidget( - sendingEmail: controller.dashboardController!.listSendingEmails[index] - ) + itemBuilder: (context, index) { + return Obx(() => SendingEmailTileWidget( + sendingEmail: controller.dashboardController!.listSendingEmails[index], + selectMode: controller.selectionState.value, + onLongPressAction: controller.handleOnLongPressAction, + onSelectAction: controller.toggleSelectionSendingEmail, + )); + } ); } else { return const SizedBox.shrink(); } }); } + + Widget _buildFloatingButtonCompose() { + return Obx(() { + if (controller.isAllUnSelected) { + return ComposeFloatingButton( + scrollController: controller.listSendingEmailController, + onTap: () => controller.dashboardController!.goToComposer(ComposerArguments()) + ); + } else { + return Container( + padding: const EdgeInsets.only(bottom: 70), + child: ComposeFloatingButton( + scrollController: controller.listSendingEmailController, + onTap: () => controller.dashboardController!.goToComposer(ComposerArguments()) + ), + ); + } + }); + } } \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart b/lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart index 63887b65d..934058efe 100644 --- a/lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart +++ b/lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:model/mailbox/select_mode.dart'; +import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/utils/app_utils.dart'; @@ -15,12 +16,14 @@ class AppBarSendingQueueWidget extends StatelessWidget { final VoidCallback? onBackAction; final VoidCallback? onOpenMailboxMenu; final SelectMode selectMode; + final List listSendingEmails; const AppBarSendingQueueWidget({ super.key, + required this.listSendingEmails, this.onBackAction, this.onOpenMailboxMenu, - this.selectMode = SelectMode.INACTIVE, + this.selectMode = SelectMode.INACTIVE }); @override @@ -44,14 +47,40 @@ class AppBarSendingQueueWidget extends StatelessWidget { onTap: onOpenMailboxMenu ) else - buildIconWeb( - icon: SvgPicture.asset( - AppUtils.isDirectionRTL(context) ? imagePaths.icCollapseFolder : imagePaths.icBack, - colorFilter: AppColor.colorTextButton.asFilter(), - fit: BoxFit.fill + Padding( + padding: const EdgeInsets.only(left: 8), + child: Material( + color: Colors.transparent, + borderRadius: BorderRadius.circular(15), + child: InkWell( + onTap: onBackAction, + borderRadius: BorderRadius.circular(15), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset( + AppUtils.isDirectionRTL(context) ? imagePaths.icCollapseFolder : imagePaths.icBack, + colorFilter: AppColor.colorTextButton.asFilter(), + fit: BoxFit.fill + ), + const SizedBox(width: 8), + Text( + listSendingEmails.length.toString(), + maxLines: 1, + overflow: CommonTextStyle.defaultTextOverFlow, + softWrap: CommonTextStyle.defaultSoftWrap, + style: const TextStyle( + fontSize: 17, + color: AppColor.colorTextButton + ) + ) + ] + ), + ), + ), ), - tooltip: AppLocalizations.of(context).back, - onTap: onBackAction ), Expanded(child: Text( AppLocalizations.of(context).sendingQueue, diff --git a/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart b/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart index 6424971db..8c0b18a72 100644 --- a/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart +++ b/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart @@ -6,17 +6,26 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:model/extensions/presentation_email_extension.dart'; -import 'package:model/model.dart'; +import 'package:model/mailbox/select_mode.dart'; import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +typedef OnLongPressSendingEmailItemAction = void Function(SendingEmail); +typedef OnSelectSendingEmailItemAction = void Function(SendingEmail); + class SendingEmailTileWidget extends StatelessWidget { final SendingEmail sendingEmail; + final SelectMode selectMode; + final OnLongPressSendingEmailItemAction? onLongPressAction; + final OnSelectSendingEmailItemAction? onSelectAction; const SendingEmailTileWidget({ super.key, - required this.sendingEmail + required this.sendingEmail, + required this.selectMode, + this.onLongPressAction, + this.onSelectAction }); @override @@ -27,6 +36,7 @@ class SendingEmailTileWidget extends StatelessWidget { color: Colors.transparent, child: InkWell( onTap: () => {}, + onLongPress: () => onLongPressAction?.call(sendingEmail), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -34,14 +44,36 @@ class SendingEmailTileWidget extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( children: [ - SvgPicture.asset( - sendingEmail.presentationEmail.numberOfAllEmailAddress() == 1 - ? imagePath.icAvatarPersonal - : imagePath.icAvatarGroup, - fit: BoxFit.fill, - width: 60, - height: 60, - ), + if (selectMode == SelectMode.ACTIVE) + GestureDetector( + child: Container( + width: 60, + height: 60, + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(30)) + ), + alignment: Alignment.center, + child: SvgPicture.asset( + sendingEmail.isSelected + ? imagePath.icSelected + : imagePath.icUnSelected, + fit: BoxFit.fill, + width: 24, + height: 24 + ), + ), + onTap: () => onSelectAction?.call(sendingEmail), + ) + else + SvgPicture.asset( + sendingEmail.presentationEmail.numberOfAllEmailAddress() == 1 + ? imagePath.icAvatarPersonal + : imagePath.icAvatarGroup, + fit: BoxFit.fill, + width: 60, + height: 60, + ), const SizedBox(width: 8), Expanded(child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 91ef2f6a2..ded04f72a 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2023-06-01T13:42:51.121212", + "@@last_modified": "2023-06-05T09:10:02.535366", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -2863,5 +2863,29 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "messageHasBeenSentSuccessfully": "Message has been sent successfully.", + "@messageHasBeenSentSuccessfully": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "deleteOfflineEmail": "Delete offline email", + "@deleteOfflineEmail": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogDeleteSendingEmail": "Deleting an offline email will erase its content permanently. You won't be able to undo this action or recover the email from the Trash mailbox.", + "@messageDialogDeleteSendingEmail": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "deleteSomeOfflineEmailSuccessfully": "Delete some offline email successfully.", + "@deleteSomeOfflineEmailSuccessfully": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 7358484b2..19e2dbe8a 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -2953,4 +2953,25 @@ class AppLocalizations { name: 'messageHasBeenSentSuccessfully', ); } + + String get deleteOfflineEmail { + return Intl.message( + 'Delete offline email', + name: 'deleteOfflineEmail' + ); + } + + String get messageDialogDeleteSendingEmail { + return Intl.message( + 'Deleting an offline email will erase its content permanently. You won\'t be able to undo this action or recover the email from the Trash mailbox.', + name: 'messageDialogDeleteSendingEmail' + ); + } + + String get deleteSomeOfflineEmailSuccessfully { + return Intl.message( + 'Delete some offline email successfully.', + name: 'deleteSomeOfflineEmailSuccessfully', + ); + } } \ No newline at end of file