diff --git a/lib/features/mailbox/domain/state/clear_mailbox_state.dart b/lib/features/mailbox/domain/state/clear_mailbox_state.dart index b68f6a93a..14de78861 100644 --- a/lib/features/mailbox/domain/state/clear_mailbox_state.dart +++ b/lib/features/mailbox/domain/state/clear_mailbox_state.dart @@ -8,14 +8,16 @@ class ClearingMailbox extends LoadingState {} class ClearMailboxSuccess extends UIState { final UnsignedInt totalDeletedMessages; final MailboxId mailboxId; + final Role mailboxRole; - ClearMailboxSuccess(this.mailboxId, this.totalDeletedMessages); + ClearMailboxSuccess(this.mailboxId, this.mailboxRole, this.totalDeletedMessages); @override - List get props => [mailboxId, totalDeletedMessages]; + List get props => [mailboxId, mailboxRole, totalDeletedMessages]; } class ClearMailboxFailure extends FeatureFailure { + final Role mailboxRole; - ClearMailboxFailure(dynamic exception) : super(exception: exception); + ClearMailboxFailure(this.mailboxRole, {dynamic exception}) : super(exception: exception); } \ No newline at end of file diff --git a/lib/features/mailbox/domain/usecases/clear_mailbox_interactor.dart b/lib/features/mailbox/domain/usecases/clear_mailbox_interactor.dart index 7384baab0..99e5de7b4 100644 --- a/lib/features/mailbox/domain/usecases/clear_mailbox_interactor.dart +++ b/lib/features/mailbox/domain/usecases/clear_mailbox_interactor.dart @@ -16,6 +16,7 @@ class ClearMailboxInteractor { Session session, AccountId accountId, MailboxId mailboxId, + Role mailboxRole, ) async* { try { yield Right(ClearingMailbox()); @@ -24,9 +25,13 @@ class ClearMailboxInteractor { accountId, mailboxId, ); - yield Right(ClearMailboxSuccess(mailboxId, totalDeletedMessages)); + yield Right(ClearMailboxSuccess( + mailboxId, + mailboxRole, + totalDeletedMessages, + )); } catch (e) { - yield Left(ClearMailboxFailure(e)); + yield Left(ClearMailboxFailure(mailboxRole, exception: e)); } } } diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index c3cf184a0..9df33f011 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -492,6 +492,8 @@ class MailboxDashBoardController extends ReloadableController isSenderImportantFlagEnabled.value = true; } else if (failure is GetAllIdentitiesFailure) { _handleGetAllIdentitiesFailure(); + } else if (failure is ClearMailboxFailure) { + clearMailboxFailure(failure); } } @@ -1617,14 +1619,24 @@ class MailboxDashBoardController extends ReloadableController final trashMailboxId = trashFolderId ?? mapDefaultMailboxIdByRole[PresentationMailbox.roleTrash]; final accountId = this.accountId.value; - if (sessionCurrent == null || - accountId == null || - trashMailboxId == null) { + + if (accountId == null || sessionCurrent == null) { + consumeState(Stream.value(Left(EmptyTrashFolderFailure(NotFoundSessionException())))); + return; + } + + if (trashMailboxId == null) { + consumeState(Stream.value(Left(EmptyTrashFolderFailure(NotFoundMailboxException())))); return; } if (CapabilityIdentifier.jmapMailboxClear.isSupported(sessionCurrent!, accountId)) { - clearMailbox(sessionCurrent!, accountId, trashMailboxId); + clearMailbox( + sessionCurrent!, + accountId, + trashMailboxId, + PresentationMailbox.roleTrash, + ); } else { final totalEmailsInTrash = totalEmails == 0 ? mapMailboxById[trashMailboxId]?.countTotalEmails ?? 0 @@ -1647,11 +1659,8 @@ class MailboxDashBoardController extends ReloadableController emailIds: success.emailIds, affectedMailboxId: success.mailboxId, ); - if (currentOverlayContext != null && currentContext != null) { - appToast.showToastSuccessMessage( - currentOverlayContext!, - AppLocalizations.of(currentContext!).toast_message_empty_trash_folder_success); - } + + toastManager.showMessageSuccess(success); } void _deleteMultipleEmailsPermanently(List listEmails, {Function? onCancelSelectionEmail}) { @@ -2563,8 +2572,9 @@ class MailboxDashBoardController extends ReloadableController onCancelSelectionEmail?.call(); spamFolderId ??= spamMailboxId; + final accountId = this.accountId.value; - if (accountId.value == null || sessionCurrent == null) { + if (accountId == null || sessionCurrent == null) { consumeState(Stream.value(Left(EmptySpamFolderFailure(NotFoundSessionException())))); return; } @@ -2574,13 +2584,22 @@ class MailboxDashBoardController extends ReloadableController return; } - consumeState(_emptySpamFolderInteractor.execute( - sessionCurrent!, - accountId.value!, - spamFolderId, - totalEmails, - _progressStateController - )); + if (CapabilityIdentifier.jmapMailboxClear.isSupported(sessionCurrent!, accountId)) { + clearMailbox( + sessionCurrent!, + accountId, + spamFolderId, + PresentationMailbox.roleSpam, + ); + } else { + consumeState(_emptySpamFolderInteractor.execute( + sessionCurrent!, + accountId, + spamFolderId, + totalEmails, + _progressStateController, + )); + } } void _emptySpamFolderSuccess(EmptySpamFolderSuccess success) { @@ -2590,11 +2609,8 @@ class MailboxDashBoardController extends ReloadableController emailIds: success.emailIds, affectedMailboxId: success.mailboxId, ); - if (currentOverlayContext != null && currentContext != null) { - appToast.showToastSuccessMessage( - currentOverlayContext!, - AppLocalizations.of(currentContext!).toast_message_empty_trash_folder_success); - } + + toastManager.showMessageSuccess(success); } bool isEmptySpamBannerEnabledOnWeb( diff --git a/lib/features/mailbox_dashboard/presentation/extensions/handle_clear_mailbox_extension.dart b/lib/features/mailbox_dashboard/presentation/extensions/handle_clear_mailbox_extension.dart index a288e0f67..f78a2f5fc 100644 --- a/lib/features/mailbox_dashboard/presentation/extensions/handle_clear_mailbox_extension.dart +++ b/lib/features/mailbox_dashboard/presentation/extensions/handle_clear_mailbox_extension.dart @@ -6,31 +6,38 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; -import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; -import 'package:tmail_ui_user/main/routes/route_navigation.dart'; extension HandleClearMailboxExtension on MailboxDashBoardController { - void clearMailbox(Session session, AccountId accountId, MailboxId mailboxId) { + void clearMailbox( + Session session, + AccountId accountId, + MailboxId mailboxId, + Role mailboxRole, + ) { + viewStateMailboxActionProgress.value = Right(ClearingMailbox()); + consumeState(clearMailboxInteractor.execute( session, accountId, mailboxId, + mailboxRole, )); } void clearMailboxSuccess(ClearMailboxSuccess success) { viewStateMailboxActionProgress.value = Right(UIState.idle); - if (currentOverlayContext != null && currentContext != null) { - appToast.showToastSuccessMessage( - currentOverlayContext!, - AppLocalizations.of(currentContext!).toast_message_empty_trash_folder_success, - ); - } + toastManager.showMessageSuccess(success); if (selectedMailbox.value?.id == success.mailboxId) { emailsInCurrentMailbox.clear(); } } + + void clearMailboxFailure(ClearMailboxFailure failure) { + viewStateMailboxActionProgress.value = Right(UIState.idle); + + toastManager.showMessageFailure(failure); + } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart b/lib/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart index 083f353b9..f8f166782 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart @@ -3,6 +3,7 @@ import 'package:core/presentation/state/success.dart'; import 'package:dartz/dartz.dart'; import 'package:flutter/material.dart'; import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/mark_mailbox_as_read_loading_banner_style.dart'; import 'package:tmail_ui_user/features/thread/domain/state/empty_spam_folder_state.dart'; @@ -20,7 +21,7 @@ class MarkMailboxAsReadLoadingBanner extends StatelessWidget with AppLoaderMixin return viewState.fold( (failure) => const SizedBox.shrink(), (success) { - if (success is MarkAsMailboxReadLoading) { + if (success is MarkAsMailboxReadLoading || success is ClearingMailbox) { return Padding( padding: MarkMailboxAsReadLoadingBannerStyle.bannerMargin, child: horizontalLoadingWidget); diff --git a/lib/main/utils/toast_manager.dart b/lib/main/utils/toast_manager.dart index 18e2ac0db..7ba93ff6f 100644 --- a/lib/main/utils/toast_manager.dart +++ b/lib/main/utils/toast_manager.dart @@ -2,11 +2,13 @@ import 'dart:io'; import 'package:core/domain/exceptions/web_session_exception.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:core/utils/app_logger.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:model/email/email_action_type.dart'; +import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_action.dart'; import 'package:tmail_ui_user/features/email/domain/state/parse_email_by_blob_id_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/preview_email_from_eml_file_state.dart'; @@ -14,6 +16,7 @@ import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.d import 'package:tmail_ui_user/features/home/domain/state/get_session_state.dart'; import 'package:tmail_ui_user/features/login/data/network/oidc_error.dart'; import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart'; import 'package:tmail_ui_user/features/starting_page/domain/state/sign_in_twake_workplace_state.dart'; import 'package:tmail_ui_user/features/starting_page/domain/state/sign_up_twake_workplace_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/empty_spam_folder_state.dart'; @@ -73,9 +76,11 @@ class ToastManager { if (failure is GetSessionFailure) { message = getMessageByException(currentContext!, failure.exception) ?? AppLocalizations.of(currentContext!).unknownError; - } else if (failure is EmptySpamFolderFailure) { + } else if (failure is EmptySpamFolderFailure || + (failure is ClearMailboxFailure && failure.mailboxRole == PresentationMailbox.roleSpam)) { message = AppLocalizations.of(currentContext!).emptySpamFolderFailed; - } else if (failure is EmptyTrashFolderFailure) { + } else if (failure is EmptyTrashFolderFailure || + (failure is ClearMailboxFailure && failure.mailboxRole == PresentationMailbox.roleTrash)) { message = AppLocalizations.of(currentContext!).emptyTrashFolderFailed; } else if (failure is MoveMultipleEmailToMailboxFailure && failure.emailActionType == EmailActionType.moveToSpam @@ -109,4 +114,23 @@ class ToastManager { appToast.showToastErrorMessage(currentOverlayContext!, message!); } } + + void showMessageSuccess(Success success) { + if (currentContext == null || currentOverlayContext == null) { + logError('ToastManager::showMessageSuccess: Context is null'); + return; + } + + String? message; + + if (success is ClearMailboxSuccess || + success is EmptySpamFolderSuccess || + success is EmptyTrashFolderSuccess) { + message = AppLocalizations.of(currentContext!).toast_message_empty_trash_folder_success; + } + + if (message?.isNotEmpty == true) { + appToast.showToastSuccessMessage(currentOverlayContext!, message!); + } + } }