diff --git a/lib/features/email/domain/state/mark_as_email_read_state.dart b/lib/features/email/domain/state/mark_as_email_read_state.dart index 68993137a..853e5187f 100644 --- a/lib/features/email/domain/state/mark_as_email_read_state.dart +++ b/lib/features/email/domain/state/mark_as_email_read_state.dart @@ -1,8 +1,10 @@ import 'package:core/core.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email.dart'; class MarkAsEmailReadSuccess extends UIState { + final EmailId emailId; - MarkAsEmailReadSuccess(); + MarkAsEmailReadSuccess(this.emailId); @override List get props => []; diff --git a/lib/features/email/domain/usecases/mark_as_email_read_interactor.dart b/lib/features/email/domain/usecases/mark_as_email_read_interactor.dart index 202d2ba4f..0dc503877 100644 --- a/lib/features/email/domain/usecases/mark_as_email_read_interactor.dart +++ b/lib/features/email/domain/usecases/mark_as_email_read_interactor.dart @@ -13,7 +13,7 @@ class MarkAsEmailReadInteractor { Future> execute(AccountId accountId, EmailId emailId, bool unread) async { try { final result = await emailRepository.markAsRead(accountId, emailId, unread); - return result ? Right(MarkAsEmailReadSuccess()) : Left(MarkAsEmailReadFailure(null)); + return result ? Right(MarkAsEmailReadSuccess(emailId)) : Left(MarkAsEmailReadFailure(null)); } catch (e) { return Left(MarkAsEmailReadFailure(e)); } diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index d0f914cae..d26988371 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -46,8 +46,9 @@ class MailboxController extends BaseController { mailboxDashBoardController.mailboxDashBoardAction.listen((action) { if (action is MarkAsEmailReadAction) { - _updateCountUnReadAllMailbox(action.presentationMailbox); - mailboxDashBoardController.clearMailboxDashBoardAction(); + _updateCountUnReadForMailbox(action.presentationMailbox, countUnreadChange: 1, isUnread: false); + } else if (action is MarkAsMultipleEmailReadAndUnreadAction) { + _updateCountUnReadForMailbox(action.presentationMailbox, countUnreadChange: action.listEmailId.length, isUnread: action.isUnread); } }); } @@ -133,15 +134,27 @@ class MailboxController extends BaseController { } } - void _updateCountUnReadAllMailbox(PresentationMailbox presentationMailbox) { + void _updateCountUnReadForMailbox( + PresentationMailbox presentationMailbox, + { + required int countUnreadChange, + required bool isUnread + } + ) { if (presentationMailbox.hasRole()) { - final newCountUnRead = presentationMailbox.unreadEmails != null - ? presentationMailbox.unreadEmails!.value.value - 1 + final currentCountUnread = presentationMailbox.unreadEmails != null + ? presentationMailbox.unreadEmails!.value.value : 0; - final newMailbox = presentationMailbox.toPresentationMailbox(countUnRead: UnsignedInt(newCountUnRead)); + num newCountUnread = 0; + if (isUnread) { + newCountUnread = currentCountUnread + countUnreadChange; + } else { + newCountUnread = currentCountUnread > countUnreadChange ? currentCountUnread - countUnreadChange : 0; + } + final newMailbox = presentationMailbox.toPresentationMailbox(countUnRead: UnsignedInt(newCountUnread)); final newDefaultMailboxList = defaultMailboxList .map((mailbox) => mailbox.id == presentationMailbox.id - ? mailbox.toPresentationMailbox(countUnRead: UnsignedInt(newCountUnRead)) + ? mailbox.toPresentationMailbox(countUnRead: UnsignedInt(newCountUnread)) : mailbox) .toList(); defaultMailboxList.value = newDefaultMailboxList; diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index 30db02f8c..574cade91 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -26,6 +26,7 @@ import 'package:tmail_ui_user/features/thread/domain/usecases/get_emails_in_mail import 'package:tmail_ui_user/features/thread/domain/usecases/mark_as_multiple_email_read_interactor.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/load_more_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/email_context_menu_action_builder.dart'; +import 'package:tmail_ui_user/main/actions/app_action.dart'; import 'package:tmail_ui_user/main/actions/email_action.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart'; @@ -69,9 +70,16 @@ class ThreadController extends BaseController { _currentMailboxId = selectedMailbox?.id; refreshGetAllEmailAction(); } else { - final emailCurrent = mailboxDashBoardController.selectedEmail.value; - if (Get.context != null && responsiveUtils.isDesktop(Get.context!) && emailCurrent != null) { - _updateStateUnReadEmail(emailCurrent.id, unRead: false); + final actionCurrent = mailboxDashBoardController.mailboxDashBoardAction.value; + if (actionCurrent is MarkAsEmailReadAction) { + final emailCurrent = mailboxDashBoardController.selectedEmail.value; + if (Get.context != null && responsiveUtils.isDesktop(Get.context!) && emailCurrent != null) { + _updateStateUnReadAllEmail([emailCurrent.id], isUnread: false); + } + mailboxDashBoardController.clearMailboxDashBoardAction(); + } else if (actionCurrent is MarkAsMultipleEmailReadAndUnreadAction) { + _updateStateUnReadAllEmail(actionCurrent.listEmailId, isUnread: actionCurrent.isUnread); + mailboxDashBoardController.clearMailboxDashBoardAction(); } } }); @@ -218,9 +226,9 @@ class ThreadController extends BaseController { currentSelectMode.value = SelectMode.INACTIVE; } - void _updateStateUnReadEmail(EmailId emailId, {required bool unRead}) { + void _updateStateUnReadAllEmail(List list, {required bool isUnread}) { final newEmailList = emailList - .map((email) => email.id == emailId ? email.markAsReadPresentationEmail(unRead: unRead) : email) + .map((email) => list.contains(email.id) ? email.markAsReadPresentationEmail(isUnread: isUnread) : email) .toList(); emailList.value = newEmailList; } @@ -238,8 +246,9 @@ class ThreadController extends BaseController { .toList(); final accountId = mailboxDashBoardController.accountId.value; + final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value; - if (accountId != null) { + if (accountId != null && mailboxCurrent != null) { _markAsMultipleEmailReadInteractor .execute(accountId, listEmailId, isUnread) .then((result) => result.fold( @@ -254,6 +263,7 @@ class ThreadController extends BaseController { }, (success) { cancelSelectEmail(); + final listEmailIdSuccess = _getListEmailIdMarkedAsReadSuccess(success); if (success is MarkAsEmailReadSuccess || success is MarkAsMultipleEmailReadAllSuccess @@ -263,11 +273,45 @@ class ThreadController extends BaseController { ? AppLocalizations.of(Get.context!).marked_multiple_item_as_unread(listEmail.length) : AppLocalizations.of(Get.context!).marked_multiple_item_as_read(listEmail.length)); } + + if (listEmailIdSuccess.isNotEmpty) { + _updateStateEmailAndCountUnReadMailbox(MarkAsMultipleEmailReadAndUnreadAction(listEmailIdSuccess, mailboxCurrent, isUnread)); + } } })); } } + List _getListEmailIdMarkedAsReadSuccess(Success success) { + final listEmailIdSuccess = []; + + if (success is MarkAsEmailReadSuccess) { + listEmailIdSuccess.add(success.emailId); + } else if (success is MarkAsMultipleEmailReadAllSuccess) { + success.resultList.forEach((either) { + either.map((success) { + if (success is MarkAsEmailReadSuccess) { + listEmailIdSuccess.add(success.emailId); + } + }); + }); + } else if (success is MarkAsMultipleEmailReadHasSomeEmailFailure) { + success.resultList.forEach((either) { + either.map((success) { + if (success is MarkAsEmailReadSuccess) { + listEmailIdSuccess.add(success.emailId); + } + }); + }); + } + + return listEmailIdSuccess; + } + + void _updateStateEmailAndCountUnReadMailbox(AppAction? appAction) { + mailboxDashBoardController.setMailboxDashBoardAction(appAction); + } + void openContextMenuSelectedEmail(BuildContext context, ImagePaths imagePaths, List listEmail) { (ContextMenuBuilder(context) ..addTiles(_contextMenuActionList(context, imagePaths, listEmail))) @@ -342,7 +386,7 @@ class ThreadController extends BaseController { void goToEmail(BuildContext context) async { final action = await push(AppRoutes.EMAIL); if (action is MarkAsEmailReadAction) { - _updateStateUnReadEmail(action.emailId, unRead: false); + _updateStateUnReadAllEmail([action.emailId], isUnread: false); mailboxDashBoardController.setMailboxDashBoardAction(action); } mailboxDashBoardController.clearSelectedEmail(); diff --git a/lib/main/actions/email_action.dart b/lib/main/actions/email_action.dart index 9932c5615..133212945 100644 --- a/lib/main/actions/email_action.dart +++ b/lib/main/actions/email_action.dart @@ -3,7 +3,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/main/actions/app_action.dart'; -class MarkAsEmailReadAction extends ActionOnline { +class MarkAsEmailReadAction extends ActionOffline { final EmailId emailId; final PresentationMailbox presentationMailbox; @@ -11,4 +11,15 @@ class MarkAsEmailReadAction extends ActionOnline { @override List get props => [emailId, presentationMailbox]; +} + +class MarkAsMultipleEmailReadAndUnreadAction extends ActionOffline { + final List listEmailId; + final PresentationMailbox presentationMailbox; + final bool isUnread; + + MarkAsMultipleEmailReadAndUnreadAction(this.listEmailId, this.presentationMailbox, this.isUnread); + + @override + List get props => [listEmailId, presentationMailbox, isUnread]; } \ No newline at end of file diff --git a/model/lib/extensions/presentation_email_extension.dart b/model/lib/extensions/presentation_email_extension.dart index efb91a13d..e3b346cad 100644 --- a/model/lib/extensions/presentation_email_extension.dart +++ b/model/lib/extensions/presentation_email_extension.dart @@ -14,10 +14,10 @@ extension PresentationEmailExtension on PresentationEmail { return ''; } - PresentationEmail markAsReadPresentationEmail({required bool unRead}) { + PresentationEmail markAsReadPresentationEmail({required bool isUnread}) { var newKeyWord = keywords; - if (unRead) { + if (isUnread) { newKeyWord?.removeWhere((key, value) => key == KeyWordIdentifier.emailSeen); } else { if (newKeyWord == null) {