diff --git a/core/lib/presentation/views/button/button_builder.dart b/core/lib/presentation/views/button/button_builder.dart index d7ace5e6f..a1025d2e3 100644 --- a/core/lib/presentation/views/button/button_builder.dart +++ b/core/lib/presentation/views/button/button_builder.dart @@ -109,7 +109,7 @@ class ButtonBuilder { child: Container( key: _key, alignment: Alignment.center, - color: _decoration == null ? _colorButton ?? Colors.white : null, + color: _decoration == null ? _colorButton : null, decoration: _decoration, width: _maxWidth, padding: _padding ?? EdgeInsets.zero, diff --git a/lib/features/base/base_controller.dart b/lib/features/base/base_controller.dart index deaeffd16..fd7b0ad5b 100644 --- a/lib/features/base/base_controller.dart +++ b/lib/features/base/base_controller.dart @@ -6,6 +6,7 @@ abstract class BaseController extends GetxController { final viewState = Rx>(Right(UIState.idle)); void consumeState(Stream> newStateStream) async { + log('BaseController::consumeState():'); newStateStream.listen( (state) => onData(state), onError: (error) => onError(error), diff --git a/lib/features/base/base_mailbox_controller.dart b/lib/features/base/base_mailbox_controller.dart index a89ad6dba..0c459043f 100644 --- a/lib/features/base/base_mailbox_controller.dart +++ b/lib/features/base/base_mailbox_controller.dart @@ -14,7 +14,6 @@ abstract class BaseMailboxController extends BaseController { BaseMailboxController(this._treeBuilder); - final allMailboxNodeList = [].obs; final folderMailboxTree = MailboxTree(MailboxNode.root()).obs; final defaultMailboxTree = MailboxTree(MailboxNode.root()).obs; @@ -24,6 +23,15 @@ abstract class BaseMailboxController extends BaseController { folderMailboxTree.value = tupleTree.value2; } + Future refreshTree(List allMailbox) async { + final tupleTree = await _treeBuilder.generateMailboxTreeInUIAfterRefreshChanges( + allMailbox, defaultMailboxTree.value, folderMailboxTree.value); + defaultMailboxTree.firstRebuild = true; + folderMailboxTree.firstRebuild = true; + defaultMailboxTree.value = tupleTree.value1; + folderMailboxTree.value = tupleTree.value2; + } + void toggleMailboxFolder(MailboxNode selectedMailboxNode) { final newExpandMode = selectedMailboxNode.expandMode == ExpandMode.COLLAPSE ? ExpandMode.EXPAND diff --git a/lib/features/email/presentation/email_bindings.dart b/lib/features/email/presentation/email_bindings.dart index afa6b844e..af1cb70ca 100644 --- a/lib/features/email/presentation/email_bindings.dart +++ b/lib/features/email/presentation/email_bindings.dart @@ -35,7 +35,6 @@ class EmailBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), - Get.find(), Get.find(), Get.find(), Get.find(), diff --git a/lib/features/email/presentation/email_controller.dart b/lib/features/email/presentation/email_controller.dart index 4858c7f56..bdc6c8510 100644 --- a/lib/features/email/presentation/email_controller.dart +++ b/lib/features/email/presentation/email_controller.dart @@ -45,12 +45,12 @@ class EmailController extends BaseController { final mailboxDashBoardController = Get.find(); final responsiveUtils = Get.find(); final imagePaths = Get.find(); + final _appToast = Get.find(); final GetEmailContentInteractor _getEmailContentInteractor; final MarkAsEmailReadInteractor _markAsEmailReadInteractor; final DownloadAttachmentsInteractor _downloadAttachmentsInteractor; final DeviceManager _deviceManager; - final AppToast _appToast; final ExportAttachmentInteractor _exportAttachmentInteractor; final MoveToMailboxInteractor _moveToMailboxInteractor; final MarkAsStarEmailInteractor _markAsStarEmailInteractor; @@ -72,7 +72,6 @@ class EmailController extends BaseController { this._markAsEmailReadInteractor, this._downloadAttachmentsInteractor, this._deviceManager, - this._appToast, this._exportAttachmentInteractor, this._moveToMailboxInteractor, this._markAsStarEmailInteractor, @@ -83,12 +82,12 @@ class EmailController extends BaseController { void onReady() { super.onReady(); mailboxDashBoardController.selectedEmail.listen((presentationEmail) { + log('EmailController::onReady(): ${presentationEmail.toString()}'); if (_currentEmailId != presentationEmail?.id) { - _clearEmailContent(); _currentEmailId = presentationEmail?.id; - final accountId = mailboxDashBoardController.accountId.value; - if (accountId != null && presentationEmail != null) { - _getEmailContentAction(accountId, presentationEmail.id); + _resetToOriginalValue(); + if (presentationEmail != null) { + _getEmailContentAction(presentationEmail.id); if (presentationEmail.isUnReadEmail()) { markAsEmailRead(presentationEmail, ReadActions.markAsRead); } @@ -103,9 +102,12 @@ class EmailController extends BaseController { super.onClose(); } - void _getEmailContentAction(AccountId accountId, EmailId emailId) async { + void _getEmailContentAction(EmailId emailId) async { + final accountId = mailboxDashBoardController.accountId.value; final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(); - consumeState(_getEmailContentInteractor.execute(accountId, emailId, baseDownloadUrl)); + if (accountId != null && baseDownloadUrl != null) { + consumeState(_getEmailContentInteractor.execute(accountId, emailId, baseDownloadUrl)); + } } @override @@ -153,7 +155,7 @@ class EmailController extends BaseController { attachments.value = success.attachments; } - void _clearEmailContent() { + void _resetToOriginalValue() { attachmentsExpandMode.value = ExpandMode.COLLAPSE; emailAddressExpandMode.value = ExpandMode.COLLAPSE; isDisplayFullEmailAddress.value = false; @@ -185,9 +187,6 @@ class EmailController extends BaseController { } void _markAsEmailReadSuccess(Success success) { - if (success is MarkAsEmailReadSuccess) { - mailboxDashBoardController.setSelectedEmail(success.updatedEmail.toPresentationEmail(selectMode: SelectMode.ACTIVE)); - } mailboxDashBoardController.dispatchState(Right(success)); if (success is MarkAsEmailReadSuccess @@ -496,9 +495,7 @@ class EmailController extends BaseController { } void backToThreadView(BuildContext context) { - attachmentsExpandMode.value = ExpandMode.COLLAPSE; - emailAddressExpandMode.value = ExpandMode.COLLAPSE; - isDisplayFullEmailAddress.value = false; + mailboxDashBoardController.clearSelectedEmail(); if (responsiveUtils.isDesktop(context) || responsiveUtils.isTabletLarge(context)) { mailboxDashBoardController.dispatchRoute(AppRoutes.THREAD); } else { diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index a286714f2..d11e08f89 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -31,29 +31,35 @@ class EmailView extends GetView with UserSettingPopupMenuMixin { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: responsiveUtils.isDesktop(context) ? AppColor.colorBgDesktop : Colors.white, - body: Container( - padding: EdgeInsets.zero, - margin: EdgeInsets.zero, - decoration: responsiveUtils.isTabletLarge(context) - ? BoxDecoration(border: Border(left: BorderSide(color: AppColor.colorLineLeftEmailView, width: 1.0))) - : null, - child: SafeArea( - right: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context), - left: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (responsiveUtils.isDesktop(context)) - Container( - color: Colors.white, - padding: EdgeInsets.only(right: 10, top: 16, bottom: 10), - child: _buildHeader(context)), - Expanded(child: _buildBody(context)), - ] - ) - ), + return WillPopScope( + onWillPop: () async { + emailController.backToThreadView(context); + return true; + }, + child: Scaffold( + backgroundColor: responsiveUtils.isDesktop(context) ? AppColor.colorBgDesktop : Colors.white, + body: Container( + padding: EdgeInsets.zero, + margin: EdgeInsets.zero, + decoration: responsiveUtils.isTabletLarge(context) + ? BoxDecoration(border: Border(left: BorderSide(color: AppColor.colorLineLeftEmailView, width: 1.0))) + : null, + child: SafeArea( + right: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context), + left: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (responsiveUtils.isDesktop(context)) + Container( + color: Colors.white, + padding: EdgeInsets.only(right: 10, top: 16, bottom: 10), + child: _buildHeader(context)), + Expanded(child: _buildBody(context)), + ] + ) + ), + ) ) ); } diff --git a/lib/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart b/lib/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart new file mode 100644 index 000000000..2a5285d75 --- /dev/null +++ b/lib/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart @@ -0,0 +1,25 @@ +import 'package:core/core.dart'; +import 'package:jmap_dart_client/jmap/core/state.dart'; +import 'package:model/mailbox/presentation_mailbox.dart'; + +class RefreshChangesAllMailboxSuccess extends UIState { + final List mailboxList; + final State? currentMailboxState; + + RefreshChangesAllMailboxSuccess({ + required this.mailboxList, + required this.currentMailboxState + }); + + @override + List get props => [mailboxList, currentMailboxState]; +} + +class RefreshChangesAllMailboxFailure extends FeatureFailure { + final exception; + + RefreshChangesAllMailboxFailure(this.exception); + + @override + List get props => [exception]; +} \ No newline at end of file diff --git a/lib/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart b/lib/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart index 66d8dee68..f9716a2ac 100644 --- a/lib/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart +++ b/lib/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart @@ -5,7 +5,7 @@ import 'package:jmap_dart_client/jmap/core/state.dart' as jmapState; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; -import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart'; class RefreshAllMailboxInteractor { final MailboxRepository _mailboxRepository; @@ -20,7 +20,7 @@ class RefreshAllMailboxInteractor { .refresh(accountId, currentState) .map(_toGetMailboxState); } catch (e) { - yield Left(GetAllMailboxFailure(e)); + yield Left(RefreshChangesAllMailboxFailure(e)); } } @@ -29,7 +29,7 @@ class RefreshAllMailboxInteractor { ?.map((mailbox) => mailbox.toPresentationMailbox()).toList() ?? List.empty(); - return Right(GetAllMailboxSuccess( + return Right(RefreshChangesAllMailboxSuccess( mailboxList: mailboxList, currentMailboxState: mailboxResponse.state) ); diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 667b9d886..87a978481 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -17,11 +17,13 @@ import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_draft import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; +import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/create_new_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/rename_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/search_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbox_interactor.dart'; @@ -107,18 +109,22 @@ class MailboxController extends BaseMailboxController { mailboxDashBoardController.viewState.listen((state) { state.map((success) { - if (success is MarkAsEmailReadSuccess || - success is MarkAsMultipleEmailReadAllSuccess || - success is MarkAsMultipleEmailReadHasSomeEmailFailure) { + log('MailboxController::onReady(): ${success.runtimeType}'); + + if (success is MarkAsMultipleEmailReadAllSuccess + || success is MarkAsMultipleEmailReadHasSomeEmailFailure) { + mailboxDashBoardController.clearState(); refreshMailboxChanges(); } else if (success is MoveMultipleEmailToMailboxAllSuccess || success is MoveMultipleEmailToMailboxHasSomeEmailFailure) { mailboxDashBoardController.clearState(); refreshMailboxChanges(); - } else if (success is SaveEmailAsDraftsSuccess - || success is RemoveEmailDraftsSuccess - || success is SendEmailSuccess - || success is UpdateEmailDraftsSuccess) { + } else if (success is MarkAsEmailReadSuccess + || success is MoveToMailboxSuccess + || success is SaveEmailAsDraftsSuccess + || success is RemoveEmailDraftsSuccess + || success is SendEmailSuccess + || success is UpdateEmailDraftsSuccess) { refreshMailboxChanges(); } }); @@ -147,6 +153,13 @@ class MailboxController extends BaseMailboxController { currentMailboxState = success.currentMailboxState; await buildTree(allMailboxes); + _setUpMapMailboxIdDefault(allMailboxes, defaultMailboxTree.value, folderMailboxTree.value); + } else if (success is RefreshChangesAllMailboxSuccess) { + log('MailboxController::onData(): ${allMailboxes.length}'); + allMailboxes = success.mailboxList; + currentMailboxState = success.currentMailboxState; + await refreshTree(allMailboxes); + _setUpMapMailboxIdDefault(allMailboxes, defaultMailboxTree.value, folderMailboxTree.value); } }); @@ -171,10 +184,8 @@ class MailboxController extends BaseMailboxController { _searchMailboxSuccess(success); } else if (success is DeleteMultipleMailboxSuccess) { _deleteMailboxSuccess(success); - } else if (success is GetAllMailboxSuccess) { - if (isSearchActive()) { - _searchMailboxAction(allMailboxes, searchQuery.value); - } + } else if ((success is GetAllMailboxSuccess || success is RefreshChangesAllMailboxSuccess) && isSearchActive()) { + _searchMailboxAction(allMailboxes, searchQuery.value); } else if (success is RenameMailboxSuccess) { refreshMailboxChanges(); } diff --git a/lib/features/mailbox/presentation/model/mailbox_tree_builder.dart b/lib/features/mailbox/presentation/model/mailbox_tree_builder.dart index 8fe5bcc90..612217ff4 100644 --- a/lib/features/mailbox/presentation/model/mailbox_tree_builder.dart +++ b/lib/features/mailbox/presentation/model/mailbox_tree_builder.dart @@ -75,4 +75,54 @@ class TreeBuilder { defaultTree.root.childrenItems?.sort((thisMailbox, thatMailbox) => thisMailbox.compareTo(thatMailbox)); return Tuple2(defaultTree, folderTree); } + + Future> generateMailboxTreeInUIAfterRefreshChanges( + List allMailboxes, + MailboxTree defaultTreeBeforeChanges, + MailboxTree folderTreeBeforeChanges, + ) async { + final Map mailboxDictionary = HashMap(); + + final newDefaultTree = MailboxTree(MailboxNode.root()); + final newFolderTree = MailboxTree(MailboxNode.root()); + + allMailboxes.forEach((mailbox) { + final mailboxNodeBeforeChanges = defaultTreeBeforeChanges.findNode((node) => node.item.id == mailbox.id) ?? + folderTreeBeforeChanges.findNode((node) => node.item.id == mailbox.id); + if (mailboxNodeBeforeChanges != null) { + mailboxDictionary[mailbox.id] = MailboxNode( + mailbox, + expandMode: mailboxNodeBeforeChanges.expandMode, + selectMode: mailboxNodeBeforeChanges.selectMode); + } else { + mailboxDictionary[mailbox.id] = MailboxNode(mailbox); + } + }); + + allMailboxes.forEach((mailbox) { + final parentId = mailbox.parentId; + final parentNode = mailboxDictionary[parentId]; + final node = mailboxDictionary[mailbox.id]; + if (node != null) { + if (parentNode != null) { + parentNode.addChildNode(node); + parentNode.childrenItems?.sortByCompare( + (node) => node.item.name, + (name, other) => name?.compareAlphabetically(other) ?? -1 + ); + } else { + var tree = mailbox.hasRole() ? newDefaultTree : newFolderTree; + + tree.root.addChildNode(node); + tree.root.childrenItems?.sortByCompare( + (node) => node.item.name, + (name, other) => name?.compareAlphabetically(other) ?? -1 + ); + } + } + }); + + newDefaultTree.root.childrenItems?.sort((thisMailbox, thatMailbox) => thisMailbox.compareTo(thatMailbox)); + return Tuple2(newDefaultTree, newFolderTree); + } } \ No newline at end of file diff --git a/lib/features/thread/domain/state/refresh_changes_all_email_state.dart b/lib/features/thread/domain/state/refresh_changes_all_email_state.dart new file mode 100644 index 000000000..2d847ef7d --- /dev/null +++ b/lib/features/thread/domain/state/refresh_changes_all_email_state.dart @@ -0,0 +1,22 @@ +import 'package:core/core.dart'; +import 'package:jmap_dart_client/jmap/core/state.dart'; +import 'package:model/model.dart'; + +class RefreshChangesAllEmailSuccess extends UIState { + final List emailList; + final State? currentEmailState; + + RefreshChangesAllEmailSuccess({required this.emailList, this.currentEmailState}); + + @override + List get props => [emailList, currentEmailState]; +} + +class RefreshChangesAllEmailFailure extends FeatureFailure { + final exception; + + RefreshChangesAllEmailFailure(this.exception); + + @override + List get props => [exception]; +} \ No newline at end of file diff --git a/lib/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor.dart b/lib/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor.dart index a236c6c48..7a440fa8e 100644 --- a/lib/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor.dart +++ b/lib/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor.dart @@ -6,9 +6,9 @@ import 'package:jmap_dart_client/jmap/core/sort/comparator.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'; import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'; -import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.dart'; import 'package:model/model.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; +import 'package:tmail_ui_user/features/thread/domain/state/refresh_changes_all_email_state.dart'; class RefreshChangesEmailsInMailboxInteractor { final ThreadRepository threadRepository; @@ -40,7 +40,7 @@ class RefreshChangesEmailsInMailboxInteractor { filterOption: filterOption) .map(_toGetEmailState); } catch (e) { - yield Left(GetAllEmailFailure(e)); + yield Left(RefreshChangesAllEmailFailure(e)); } } @@ -48,7 +48,7 @@ class RefreshChangesEmailsInMailboxInteractor { final presentationEmailList = emailResponse.emailList ?.map((email) => email.toPresentationEmail()).toList() ?? List.empty(); - return Right(GetAllEmailSuccess( + return Right(RefreshChangesAllEmailSuccess( emailList: presentationEmailList, currentEmailState: emailResponse.state)); } diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index 91274c357..6f53522b6 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -36,6 +36,7 @@ import 'package:tmail_ui_user/features/thread/domain/state/load_more_emails_stat import 'package:tmail_ui_user/features/thread/domain/state/mark_as_multiple_email_read_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/mark_as_star_multiple_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/move_multiple_email_to_mailbox_state.dart'; +import 'package:tmail_ui_user/features/thread/domain/state/refresh_changes_all_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/search_more_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/get_emails_in_mailbox_interactor.dart'; @@ -125,21 +126,18 @@ class ThreadController extends BaseController { mailboxDashBoardController.viewState.listen((state) { state.map((success) { - if (success is MarkAsEmailReadSuccess - || success is MarkAsMultipleEmailReadAllSuccess - || success is MarkAsMultipleEmailReadHasSomeEmailFailure - || success is MoveToMailboxSuccess - || success is MarkAsStarEmailSuccess) { - cancelSelectEmail(); - _refreshEmailChanges(); - } else if (success is SearchEmailNewQuery){ - _searchEmail(); + log('ThreadController::onReady(): ${success.runtimeType}'); + + if (success is SearchEmailNewQuery){ mailboxDashBoardController.clearState(); - } else if (success is SaveEmailAsDraftsSuccess + _searchEmail(); + } else if (success is MarkAsEmailReadSuccess + || success is MoveToMailboxSuccess + || success is MarkAsStarEmailSuccess + || success is SaveEmailAsDraftsSuccess || success is RemoveEmailDraftsSuccess || success is SendEmailSuccess || success is UpdateEmailDraftsSuccess) { - cancelSelectEmail(); _refreshEmailChanges(); } }); @@ -175,6 +173,8 @@ class ThreadController extends BaseController { (success) { if (success is GetAllEmailSuccess) { _getAllEmailSuccess(success); + } else if (success is RefreshChangesAllEmailSuccess) { + _refreshChangesAllEmailSuccess(success); } else if (success is LoadMoreEmailsSuccess) { _loadMoreEmailsSuccess(success); } else if (success is SearchEmailSuccess) { @@ -194,7 +194,7 @@ class ThreadController extends BaseController { (failure) { if (failure is MarkAsMultipleEmailReadAllFailure || failure is MarkAsMultipleEmailReadFailure) { - _markAsSelectedEmailReadFailure(failure); + _markAsReadSelectedMultipleEmailFailure(failure); } else if (failure is MarkAsStarMultipleEmailAllFailure || failure is MarkAsStarMultipleEmailFailure) { _markAsStarMultipleEmailFailure(failure); @@ -203,7 +203,7 @@ class ThreadController extends BaseController { (success) { if (success is MarkAsMultipleEmailReadAllSuccess || success is MarkAsMultipleEmailReadHasSomeEmailFailure) { - _markAsSelectedEmailReadSuccess(success); + _markAsReadSelectedMultipleEmailSuccess(success); } else if (success is MoveMultipleEmailToMailboxAllSuccess || success is MoveMultipleEmailToMailboxHasSomeEmailFailure) { _moveSelectedMultipleEmailToMailboxSuccess(success); @@ -242,6 +242,12 @@ class ThreadController extends BaseController { emailList.value = success.emailList; } + void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) { + log('ThreadController::_refreshChangesAllEmailSuccess(): ${success.emailList.length}'); + _currentEmailState = success.currentEmailState; + emailList.value = success.emailList; + } + void _getAllEmailAction(AccountId accountId, {MailboxId? mailboxId}) { log('ThreadController::_getAllEmailAction(): mailboxId = $mailboxId'); consumeState(_getEmailsInMailboxInteractor.execute( @@ -431,13 +437,10 @@ class ThreadController extends BaseController { currentSelectMode.value = SelectMode.INACTIVE; } - void markAsSelectedEmailRead(List listPresentationEmail, {bool fromContextMenuAction = false}) { - if (fromContextMenuAction) { - popBack(); - } + void markAsReadSelectedMultipleEmail(List listPresentationEmail) { + cancelSelectEmail(); final readAction = listPresentationEmail.isAllEmailRead ? ReadActions.markAsUnread : ReadActions.markAsRead; - final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value; if (_accountId != null && mailboxCurrent != null) { final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList(); @@ -445,9 +448,7 @@ class ThreadController extends BaseController { } } - void _markAsSelectedEmailReadSuccess(Success success) { - cancelSelectEmail(); - + void _markAsReadSelectedMultipleEmailSuccess(Success success) { mailboxDashBoardController.dispatchState(Right(success)); ReadActions? readActions; @@ -467,11 +468,14 @@ class ThreadController extends BaseController { message: message, icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast); } + + _refreshEmailChanges(); } - void _markAsSelectedEmailReadFailure(Failure failure) { - cancelSelectEmail(); - _appToast.showErrorToast(AppLocalizations.of(currentContext!).an_error_occurred); + void _markAsReadSelectedMultipleEmailFailure(Failure failure) { + if (currentContext != null) { + _appToast.showErrorToast(AppLocalizations.of(currentContext!).an_error_occurred); + } } void openFilterMessagesCupertinoActionSheet(BuildContext context, List actionTiles, {Widget? cancelButton}) { @@ -514,6 +518,8 @@ class ThreadController extends BaseController { if (currentMailbox != null && _accountId != null) { popBack(); + cancelSelectEmail(); + final listEmailIds = listEmail.map((email) => email.id).toList(); final destinationMailbox = await push( AppRoutes.DESTINATION_PICKER, @@ -538,7 +544,6 @@ class ThreadController extends BaseController { } void _moveSelectedMultipleEmailToMailboxSuccess(Success success) { - cancelSelectEmail(); mailboxDashBoardController.dispatchState(Right(success)); String? destinationPath; @@ -603,16 +608,10 @@ class ThreadController extends BaseController { _refreshEmailChanges(); } - void markAsStarSelectedMultipleEmail(List listPresentationEmail, - {bool fromContextMenuAction = false, MarkStarAction? markStarAction}) { - if (fromContextMenuAction) { - popBack(); - } - - final starAction = markStarAction != null - ? markStarAction - : listPresentationEmail.isAllEmailStarred ? MarkStarAction.unMarkStar : MarkStarAction.markStar; + void markAsStarSelectedMultipleEmail(List listPresentationEmail) { + cancelSelectEmail(); + final starAction = listPresentationEmail.isAllEmailStarred ? MarkStarAction.unMarkStar : MarkStarAction.markStar; final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value; if (_accountId != null && mailboxCurrent != null) { final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList(); @@ -621,9 +620,6 @@ class ThreadController extends BaseController { } void _markAsStarMultipleEmailSuccess(Success success) { - cancelSelectEmail(); - _refreshEmailChanges(); - MarkStarAction? markStarAction; int countMarkStarSuccess = 0; @@ -640,10 +636,11 @@ class ThreadController extends BaseController { ? AppLocalizations.of(currentContext!).marked_unstar_multiple_item(countMarkStarSuccess) : AppLocalizations.of(currentContext!).marked_star_multiple_item(countMarkStarSuccess)); } + + _refreshEmailChanges(); } void _markAsStarMultipleEmailFailure(Failure failure) { - cancelSelectEmail(); if (currentContext != null) { _appToast.showErrorToast(AppLocalizations.of(currentContext!).an_error_occurred); } @@ -716,7 +713,7 @@ class ThreadController extends BaseController { switch(actionType) { case EmailActionType.markAsRead: case EmailActionType.markAsUnread: - markAsSelectedEmailRead(selectionEmail); + markAsReadSelectedMultipleEmail(selectionEmail); break; case EmailActionType.markAsStar: case EmailActionType.markAsUnStar: diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index 29207b68c..16b1af0ea 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -144,7 +144,7 @@ class ThreadView extends GetWidget with UserSettingPopupMenuMi : controller.emailList.allEmailUnread; if (listEmail.isNotEmpty) { - controller.markAsSelectedEmailRead(listEmail); + controller.markAsReadSelectedMultipleEmail(listEmail); } }) ..text(AppLocalizations.of(context).mark_all_as_read, isVertical: false)) diff --git a/lib/features/thread/presentation/widgets/email_tile_builder.dart b/lib/features/thread/presentation/widgets/email_tile_builder.dart index 0d94c29d3..14e1134ed 100644 --- a/lib/features/thread/presentation/widgets/email_tile_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_builder.dart @@ -111,9 +111,9 @@ class EmailTileBuilder { Padding( padding: EdgeInsets.only(left: 8), child: (ButtonBuilder(_imagePaths.icAttachment) - ..paddingIcon(EdgeInsets.zero) - ..size(16)) - .build()), + ..paddingIcon(EdgeInsets.zero) + ..size(16)) + .build()), Padding( padding: EdgeInsets.only(right: 4, left: 8), child: Text( @@ -122,9 +122,9 @@ class EmailTileBuilder { overflow:TextOverflow.ellipsis, style: TextStyle(fontSize: 13, color: AppColor.colorContentEmail))), (ButtonBuilder(_imagePaths.icChevron) - ..paddingIcon(EdgeInsets.zero) - ..size(16)) - .build(), + ..paddingIcon(EdgeInsets.zero) + ..size(16)) + .build(), ], ) ), @@ -169,9 +169,9 @@ class EmailTileBuilder { ), if (_presentationEmail.isFlaggedEmail() ) (ButtonBuilder(_imagePaths.icStar) - ..paddingIcon(EdgeInsets.zero) - ..size(15)) - .build(), + ..paddingIcon(EdgeInsets.zero) + ..size(15)) + .build(), ], )), Padding( diff --git a/test/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor_test.dart b/test/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor_test.dart index 2f890291c..0417b7550 100644 --- a/test/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor_test.dart +++ b/test/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor_test.dart @@ -12,7 +12,7 @@ import 'package:mockito/mockito.dart'; import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'; import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart'; import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'; -import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.dart'; +import 'package:tmail_ui_user/features/thread/domain/state/refresh_changes_all_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor.dart'; import '../../../../fixtures/account_fixtures.dart'; @@ -66,7 +66,7 @@ void main() { expect(states.length, equals(2)); expect(states, containsAllInOrder({ Right(RefreshingState()), - Right(GetAllEmailSuccess( + Right(RefreshChangesAllEmailSuccess( emailList: { EmailFixtures.email1.toPresentationEmail(), EmailFixtures.email2.toPresentationEmail(),