diff --git a/lib/features/composer/presentation/extensions/email_action_type_extension.dart b/lib/features/composer/presentation/extensions/email_action_type_extension.dart index 7dfbcef63..362507bb3 100644 --- a/lib/features/composer/presentation/extensions/email_action_type_extension.dart +++ b/lib/features/composer/presentation/extensions/email_action_type_extension.dart @@ -34,6 +34,8 @@ extension EmailActionTypeExtension on EmailActionType { return AppLocalizations.of(context).moved_to_trash; case EmailActionType.moveToSpam: return AppLocalizations.of(context).marked_as_spam; + case EmailActionType.unSpam: + return AppLocalizations.of(context).marked_as_not_spam; default: return ''; } diff --git a/lib/features/email/presentation/email_controller.dart b/lib/features/email/presentation/email_controller.dart index e37b7e322..0cfb2d880 100644 --- a/lib/features/email/presentation/email_controller.dart +++ b/lib/features/email/presentation/email_controller.dart @@ -435,6 +435,22 @@ class EmailController extends BaseController { } } + void unSpam(BuildContext context, PresentationEmail email) async { + final accountId = mailboxDashBoardController.accountId.value; + final spamMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleSpam); + final inboxMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleInbox); + + if (accountId != null && spamMailboxId != null && inboxMailboxId != null) { + _moveToSpamAction(context, accountId, MoveToMailboxRequest( + [email.id], + spamMailboxId, + inboxMailboxId, + MoveAction.moving, + EmailActionType.unSpam) + ); + } + } + void _moveToSpamAction(BuildContext context, AccountId accountId, MoveToMailboxRequest moveRequest) { backToThreadView(context); mailboxDashBoardController.moveToMailbox(accountId, moveRequest); @@ -480,6 +496,10 @@ class EmailController extends BaseController { popBack(); moveToSpam(context, presentationEmail); break; + case EmailActionType.unSpam: + popBack(); + unSpam(context, presentationEmail); + break; default: break; } diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index 0acd82ddc..553da86c1 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -109,6 +109,8 @@ class ThreadController extends BaseController { AccountId? get _accountId => mailboxDashBoardController.accountId.value; + PresentationMailbox? get currentMailbox => mailboxDashBoardController.selectedMailbox.value; + ThreadController( this._getEmailsInMailboxInteractor, this._refreshAllEmailsInMailboxInteractor, @@ -551,7 +553,7 @@ class ThreadController extends BaseController { refreshAllEmail(); } - void moveSelectedMultipleEmailToMailboxAction(List listEmail) async { + void moveSelectedMultipleEmailToMailbox(List listEmail) async { final currentMailbox = mailboxDashBoardController.selectedMailbox.value; if (currentMailbox != null && _accountId != null) { final listEmailIds = listEmail.map((email) => email.id).toList(); @@ -561,15 +563,22 @@ class ThreadController extends BaseController { ); if (destinationMailbox != null && destinationMailbox is PresentationMailbox) { - if (destinationMailbox.role == PresentationMailbox.roleTrash) { - _moveSelectedEmailMultipleToTrash(_accountId!, MoveToMailboxRequest( + if (destinationMailbox.isTrash) { + _moveSelectedEmailMultipleToTrashAction(_accountId!, MoveToMailboxRequest( listEmailIds, currentMailbox.id, destinationMailbox.id, MoveAction.moving, EmailActionType.moveToTrash)); + } else if (destinationMailbox.isSpam) { + _moveSelectedEmailMultipleToSpamAction(_accountId!, MoveToMailboxRequest( + listEmailIds, + currentMailbox.id, + destinationMailbox.id, + MoveAction.moving, + EmailActionType.moveToSpam)); } else { - _moveSelectedEmailMultipleToMailbox(_accountId!, MoveToMailboxRequest( + _moveSelectedEmailMultipleToMailboxAction(_accountId!, MoveToMailboxRequest( listEmailIds, currentMailbox.id, destinationMailbox.id, @@ -581,7 +590,7 @@ class ThreadController extends BaseController { } } - void _moveSelectedEmailMultipleToMailbox(AccountId accountId, MoveToMailboxRequest moveRequest) { + void _moveSelectedEmailMultipleToMailboxAction(AccountId accountId, MoveToMailboxRequest moveRequest) { cancelSelectEmail(); consumeState(_moveMultipleEmailToMailboxInteractor.execute(accountId, moveRequest)); } @@ -636,13 +645,13 @@ class ThreadController extends BaseController { _refreshEmailChanges(); } - void moveSelectedMultipleEmailToTrashAction(List listEmail) async { + void moveSelectedMultipleEmailToTrash(List listEmail) async { final currentMailbox = mailboxDashBoardController.selectedMailbox.value; final trashMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleTrash); if (currentMailbox != null && _accountId != null && trashMailboxId != null) { final listEmailIds = listEmail.map((email) => email.id).toList(); - _moveSelectedEmailMultipleToTrash(_accountId!, MoveToMailboxRequest( + _moveSelectedEmailMultipleToTrashAction(_accountId!, MoveToMailboxRequest( listEmailIds, currentMailbox.id, trashMailboxId, @@ -652,11 +661,48 @@ class ThreadController extends BaseController { } } - void _moveSelectedEmailMultipleToTrash(AccountId accountId, MoveToMailboxRequest moveRequest) { + void _moveSelectedEmailMultipleToTrashAction(AccountId accountId, MoveToMailboxRequest moveRequest) { cancelSelectEmail(); consumeState(_moveMultipleEmailToMailboxInteractor.execute(accountId, moveRequest)); } + void moveSelectedMultipleEmailToSpam(List listEmail) async { + final currentMailbox = mailboxDashBoardController.selectedMailbox.value; + final spamMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleSpam); + + if (currentMailbox != null && _accountId != null && spamMailboxId != null) { + final listEmailIds = listEmail.map((email) => email.id).toList(); + _moveSelectedEmailMultipleToSpamAction(_accountId!, MoveToMailboxRequest( + listEmailIds, + currentMailbox.id, + spamMailboxId, + MoveAction.moving, + EmailActionType.moveToSpam) + ); + } + } + + void _moveSelectedEmailMultipleToSpamAction(AccountId accountId, MoveToMailboxRequest moveRequest) { + cancelSelectEmail(); + consumeState(_moveMultipleEmailToMailboxInteractor.execute(accountId, moveRequest)); + } + + void unSpamSelectedMultipleEmail(List listEmail) async { + final spamMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleSpam); + final inboxMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleInbox); + + if (inboxMailboxId != null && _accountId != null && spamMailboxId != null) { + final listEmailIds = listEmail.map((email) => email.id).toList(); + _moveSelectedEmailMultipleToMailboxAction(_accountId!, MoveToMailboxRequest( + listEmailIds, + spamMailboxId, + inboxMailboxId, + MoveAction.moving, + EmailActionType.unSpam) + ); + } + } + void _revertedToOriginalMailbox(MoveToMailboxRequest newMoveRequest) { if (_accountId != null) { consumeState(_moveMultipleEmailToMailboxInteractor.execute(_accountId!, newMoveRequest)); @@ -800,14 +846,20 @@ class ThreadController extends BaseController { markAsStarSelectedMultipleEmail(selectionEmail); break; case EmailActionType.moveToMailbox: - moveSelectedMultipleEmailToMailboxAction(selectionEmail); + moveSelectedMultipleEmailToMailbox(selectionEmail); break; case EmailActionType.moveToTrash: - moveSelectedMultipleEmailToTrashAction(selectionEmail); + moveSelectedMultipleEmailToTrash(selectionEmail); break; case EmailActionType.deletePermanently: deleteSelectionEmailsPermanently(context, DeleteActionType.multiple, selectedEmails: selectionEmail); break; + case EmailActionType.moveToSpam: + moveSelectedMultipleEmailToSpam(selectionEmail); + break; + case EmailActionType.unSpam: + unSpamSelectedMultipleEmail(selectionEmail); + break; default: break; } diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index 322bc8aa2..e60ca2418 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -201,30 +201,39 @@ class ThreadView extends GetWidget with UserSettingPopupMenuMi SizedBox(width: 30), buildIconWeb( icon: SvgPicture.asset(controller.listEmailSelected.isAllEmailRead ? _imagePaths.icUnread : _imagePaths.icRead, fit: BoxFit.fill), - tooltip: controller.listEmailSelected.isAllEmailRead ? AppLocalizations.of(context).unread : AppLocalizations.of(context).read, + tooltip: controller.listEmailSelected.isAllEmailRead ? AppLocalizations.of(context).mark_as_unread : AppLocalizations.of(context).mark_as_read, onTap: () => controller.pressEmailSelectionAction( context, controller.listEmailSelected.isAllEmailRead ? EmailActionType.markAsUnread : EmailActionType.markAsRead, controller.listEmailSelected)), buildIconWeb( icon: SvgPicture.asset(controller.listEmailSelected.isAllEmailStarred ? _imagePaths.icUnStar : _imagePaths.icStar, fit: BoxFit.fill), - tooltip: controller.listEmailSelected.isAllEmailStarred ? AppLocalizations.of(context).not_starred : AppLocalizations.of(context).starred, + tooltip: controller.listEmailSelected.isAllEmailStarred ? AppLocalizations.of(context).un_star : AppLocalizations.of(context).star, onTap: () => controller.pressEmailSelectionAction( context, controller.listEmailSelected.isAllEmailStarred ? EmailActionType.markAsStarred : EmailActionType.unMarkAsStarred, controller.listEmailSelected)), - buildIconWeb( - icon: SvgPicture.asset(_imagePaths.icMove, fit: BoxFit.fill), - tooltip: AppLocalizations.of(context).move, - onTap: () => controller.pressEmailSelectionAction(context, EmailActionType.moveToMailbox, controller.listEmailSelected)), + if (controller.currentMailbox?.isDrafts == false) + buildIconWeb( + icon: SvgPicture.asset(_imagePaths.icMove, fit: BoxFit.fill), + tooltip: AppLocalizations.of(context).move, + onTap: () => controller.pressEmailSelectionAction(context, EmailActionType.moveToMailbox, controller.listEmailSelected)), + if (controller.currentMailbox?.isDrafts == false) + buildIconWeb( + icon: SvgPicture.asset(controller.currentMailbox?.isSpam == true ? _imagePaths.icNotSpam : _imagePaths.icSpam, + fit: BoxFit.fill), + tooltip: controller.currentMailbox?.isSpam == true ? AppLocalizations.of(context).un_spam : AppLocalizations.of(context).mark_as_spam, + onTap: () => controller.currentMailbox?.isSpam == true + ? controller.pressEmailSelectionAction(context, EmailActionType.unSpam, controller.listEmailSelected) + : controller.pressEmailSelectionAction(context, EmailActionType.moveToSpam, controller.listEmailSelected)), buildIconWeb( icon: SvgPicture.asset(_imagePaths.icDelete, fit: BoxFit.fill), - tooltip: controller.mailboxDashBoardController.selectedMailbox.value?.role != PresentationMailbox.roleTrash - ? AppLocalizations.of(context).move_to_trash - : AppLocalizations.of(context).delete_permanently, - onTap: () => controller.mailboxDashBoardController.selectedMailbox.value?.role != PresentationMailbox.roleTrash - ? controller.pressEmailSelectionAction(context, EmailActionType.moveToTrash, controller.listEmailSelected) - : controller.deleteSelectionEmailsPermanently(context, DeleteActionType.multiple, selectedEmails: controller.listEmailSelected)), + tooltip: controller.currentMailbox?.isTrash == true + ? AppLocalizations.of(context).delete_permanently + : AppLocalizations.of(context).move_to_trash, + onTap: () => controller.currentMailbox?.isTrash == true + ? controller.deleteSelectionEmailsPermanently(context, DeleteActionType.multiple, selectedEmails: controller.listEmailSelected) + : controller.pressEmailSelectionAction(context, EmailActionType.moveToTrash, controller.listEmailSelected)), ]); } @@ -241,7 +250,8 @@ class ThreadView extends GetWidget with UserSettingPopupMenuMi _responsiveUtils, controller.listEmailSelected, controller.mailboxDashBoardController.selectedMailbox.value) - ..addOnPressEmailSelectionActionClick((actionType, selectionEmail) => controller.pressEmailSelectionAction(context, actionType, selectionEmail))) + ..addOnPressEmailSelectionActionClick((actionType, selectionEmail) => + controller.pressEmailSelectionAction(context, actionType, selectionEmail))) .build()), ]); } else { @@ -594,7 +604,7 @@ class ThreadView extends GetWidget with UserSettingPopupMenuMi itemBuilder: (context, index) => Obx(() => (EmailTileBuilder( context, listPresentationEmail[index], - controller.mailboxDashBoardController.selectedMailbox.value?.role, + controller.currentMailbox?.role, controller.currentSelectMode.value, controller.mailboxDashBoardController.searchState.value.searchStatus, controller.searchQuery) diff --git a/lib/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart b/lib/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart index 61b5d0ead..48c69ac20 100644 --- a/lib/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart +++ b/lib/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart @@ -24,7 +24,7 @@ class AppBarThreadWidgetBuilder { final BuildContext _context; final ImagePaths _imagePaths; final ResponsiveUtils _responsiveUtils; - final PresentationMailbox? _presentationMailbox; + final PresentationMailbox? _currentMailbox; final List _listSelectionEmail; final SelectMode _selectMode; final FilterMessageOption _filterMessageOption; @@ -33,7 +33,7 @@ class AppBarThreadWidgetBuilder { this._context, this._imagePaths, this._responsiveUtils, - this._presentationMailbox, + this._currentMailbox, this._listSelectionEmail, this._selectMode, this._filterMessageOption, @@ -80,7 +80,7 @@ class AppBarThreadWidgetBuilder { if (!_responsiveUtils.isTabletLarge(_context)) _buildMenuButton(), if (_responsiveUtils.isTabletLarge(_context)) SizedBox(width: 16), Expanded(child: Text( - '${_presentationMailbox?.name?.name.capitalizeFirstEach ?? ''}', + '${_currentMailbox?.name?.name.capitalizeFirstEach ?? ''}', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 21, color: Colors.black, fontWeight: FontWeight.bold))), @@ -109,18 +109,28 @@ class AppBarThreadWidgetBuilder { onTap: () => _onEmailSelectionAction?.call( _listSelectionEmail.isAllEmailStarred ? EmailActionType.unMarkAsStarred : EmailActionType.markAsStarred, _listSelectionEmail)), - buildIconWeb( - icon: SvgPicture.asset(_imagePaths.icMove, fit: BoxFit.fill), - tooltip: AppLocalizations.of(_context).move, - onTap: () => _onEmailSelectionAction?.call(EmailActionType.moveToMailbox, _listSelectionEmail)), + if (_currentMailbox?.isDrafts == false) + buildIconWeb( + icon: SvgPicture.asset(_imagePaths.icMove, fit: BoxFit.fill), + tooltip: AppLocalizations.of(_context).move, + onTap: () => _onEmailSelectionAction?.call(EmailActionType.moveToMailbox, _listSelectionEmail)), + if (_currentMailbox?.isDrafts == false) + buildIconWeb( + icon: SvgPicture.asset(_currentMailbox?.isSpam == true + ? _imagePaths.icNotSpam : _imagePaths.icSpam, + fit: BoxFit.fill), + tooltip: _currentMailbox?.isSpam == true ? AppLocalizations.of(_context).un_spam : AppLocalizations.of(_context).mark_as_spam, + onTap: () => _currentMailbox?.isSpam == true + ? _onEmailSelectionAction?.call(EmailActionType.unSpam, _listSelectionEmail) + : _onEmailSelectionAction?.call(EmailActionType.moveToSpam, _listSelectionEmail)), buildIconWeb( icon: SvgPicture.asset(_imagePaths.icDelete, fit: BoxFit.fill), - tooltip: _presentationMailbox?.role != PresentationMailbox.roleTrash + tooltip: _currentMailbox?.role != PresentationMailbox.roleTrash ? AppLocalizations.of(_context).move_to_trash : AppLocalizations.of(_context).delete_permanently, - onTap: () => _presentationMailbox?.role != PresentationMailbox.roleTrash - ? _onEmailSelectionAction?.call(EmailActionType.moveToTrash, _listSelectionEmail) - : _onEmailSelectionAction?.call(EmailActionType.deletePermanently, _listSelectionEmail)), + onTap: () => _currentMailbox?.isTrash == true + ? _onEmailSelectionAction?.call(EmailActionType.deletePermanently, _listSelectionEmail) + : _onEmailSelectionAction?.call(EmailActionType.moveToTrash, _listSelectionEmail)), ]); } @@ -265,7 +275,7 @@ class AppBarThreadWidgetBuilder { margin: EdgeInsets.zero, constraints: BoxConstraints(maxWidth: _getMaxWidthAppBarTitle()), child: Text( - '${_presentationMailbox?.name?.name.capitalizeFirstEach ?? ''}', + '${_currentMailbox?.name?.name.capitalizeFirstEach ?? ''}', maxLines: 1, overflow: GetPlatform.isWeb ? TextOverflow.clip : TextOverflow.ellipsis, style: TextStyle(fontSize: 21, color: AppColor.colorNameEmail, fontWeight: FontWeight.w700)) diff --git a/lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart b/lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart index 6bf58a547..f7e7e41c7 100644 --- a/lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart +++ b/lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart @@ -68,28 +68,46 @@ class BottomBarThreadSelectionWidget { _listSelectionEmail.isAllEmailStarred ? EmailActionType.unMarkAsStarred : EmailActionType.markAsStarred, _listSelectionEmail); }}) - ..text(_listSelectionEmail.isAllEmailStarred ? AppLocalizations.of(_context).not_starred : AppLocalizations.of(_context).starred, + ..text(_listSelectionEmail.isAllEmailStarred ? AppLocalizations.of(_context).un_star : AppLocalizations.of(_context).star, isVertical: _responsiveUtils.isMobile(_context))) .build()), - Expanded(child: (ButtonBuilder(_imagePaths.icMove) - ..key(Key('button_move_email')) - ..paddingIcon(EdgeInsets.all(8)) - ..textStyle(TextStyle(fontSize: 12, color: AppColor.colorTextButton)) - ..onPressActionClick(() { - if (_onPressEmailSelectionActionClick != null) { - _onPressEmailSelectionActionClick!(EmailActionType.moveToMailbox, _listSelectionEmail); - }}) - ..text(AppLocalizations.of(_context).move, isVertical: _responsiveUtils.isMobile(_context))) - .build()), + if (_currentMailbox?.isDrafts == false) + Expanded(child: (ButtonBuilder(_imagePaths.icMove) + ..key(Key('button_move_to_mailbox')) + ..paddingIcon(EdgeInsets.all(8)) + ..textStyle(TextStyle(fontSize: 12, color: AppColor.colorTextButton)) + ..onPressActionClick(() { + if (_onPressEmailSelectionActionClick != null) { + _onPressEmailSelectionActionClick!(EmailActionType.moveToMailbox, _listSelectionEmail); + }}) + ..text(AppLocalizations.of(_context).move, isVertical: _responsiveUtils.isMobile(_context))) + .build()), + if (_currentMailbox?.isDrafts == false) + Expanded(child: (ButtonBuilder(_currentMailbox?.isSpam == true ? _imagePaths.icNotSpam : _imagePaths.icSpam) + ..key(Key('button_move_to_spam')) + ..paddingIcon(EdgeInsets.all(8)) + ..textStyle(TextStyle(fontSize: 12, color: AppColor.colorTextButton)) + ..onPressActionClick(() { + if (_currentMailbox?.isSpam == true) { + _onPressEmailSelectionActionClick?.call(EmailActionType.unSpam, _listSelectionEmail); + } else { + _onPressEmailSelectionActionClick?.call(EmailActionType.moveToSpam, _listSelectionEmail); + } + }) + ..text(_currentMailbox?.isSpam == true + ? AppLocalizations.of(_context).un_spam + : AppLocalizations.of(_context).spam, + isVertical: _responsiveUtils.isMobile(_context))) + .build()), Expanded(child: (ButtonBuilder(_imagePaths.icDelete) ..key(Key('button_delete_email')) ..paddingIcon(EdgeInsets.all(8)) ..textStyle(TextStyle(fontSize: 12, color: AppColor.colorTextButton)) ..onPressActionClick(() { - if (_currentMailbox?.role != PresentationMailbox.roleTrash) { - _onPressEmailSelectionActionClick?.call(EmailActionType.moveToTrash, _listSelectionEmail); - } else { + if (_currentMailbox?.isTrash == true) { _onPressEmailSelectionActionClick?.call(EmailActionType.deletePermanently, _listSelectionEmail); + } else { + _onPressEmailSelectionActionClick?.call(EmailActionType.moveToTrash, _listSelectionEmail); } }) ..text(AppLocalizations.of(_context).delete, isVertical: _responsiveUtils.isMobile(_context))) diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 4896d9353..095393a63 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-04-15T15:46:44.683811", + "@@last_modified": "2022-04-15T16:53:02.138499", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -1053,5 +1053,47 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "mark_as_spam": "Mark as spam", + "@mark_as_spam": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "remove_from_spam": "Remove from spam", + "@remove_from_spam": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "marked_as_spam": "Marked as spam", + "@marked_as_spam": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "marked_as_not_spam": "Marked as not spam", + "@marked_as_not_spam": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "star": "Star", + "@star": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "un_star": "Unstar", + "@un_star": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "un_spam": "Unspam", + "@un_spam": { + "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 1198f6ead..ea2ca6f2a 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -1126,4 +1126,31 @@ class AppLocalizations { ); } + String get marked_as_not_spam { + return Intl.message( + 'Marked as not spam', + name: 'marked_as_not_spam', + ); + } + + String get star { + return Intl.message( + 'Star', + name: 'star', + ); + } + + String get un_star { + return Intl.message( + 'Unstar', + name: 'un_star', + ); + } + + String get un_spam { + return Intl.message( + 'Unspam', + name: 'un_spam', + ); + } } \ No newline at end of file