diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 963510eaa..0b03900a4 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -330,11 +330,13 @@ class MailboxController extends BaseMailboxController { : mailboxCurrent); } } else { - if (mapDefaultMailbox.containsKey(PresentationMailbox.roleInbox)) { - mailboxDashBoardController.setNewFirstSelectedMailbox(mapDefaultMailbox[PresentationMailbox.roleInbox]); - } else { - if (allMailbox.isNotEmpty) { - mailboxDashBoardController.setNewFirstSelectedMailbox(allMailbox.first); + if (!mailboxDashBoardController.searchController.isSearchEmailRunning) { + if (mapDefaultMailbox.containsKey(PresentationMailbox.roleInbox)) { + mailboxDashBoardController.setNewFirstSelectedMailbox(mapDefaultMailbox[PresentationMailbox.roleInbox]); + } else { + if (allMailbox.isNotEmpty) { + mailboxDashBoardController.setNewFirstSelectedMailbox(allMailbox.first); + } } } } diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart index ca3406f26..577a848b9 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:model/model.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart'; import 'package:tmail_ui_user/features/email/presentation/email_view.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; @@ -18,6 +17,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/icon_open_advanced_search_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/download/download_task_item_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/search_input_form_widget.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; @@ -114,16 +114,32 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Column(children: [ - if (controller.isSelectionEnabled()) - Padding( - padding: const EdgeInsets.all(12.0), - child: _buildListButtonTopBarSelection(context), - ) - else - Padding( - padding: const EdgeInsets.all(16.0), - child: _buildListButtonTopBar(context), - ), + Obx(() { + log('MailboxDashBoardView::build(): '); + if (controller.isSelectionEnabled()) { + return Padding( + padding: const EdgeInsets.all(12.0), + child: TopBarThreadSelection( + context, + controller.listEmailSelected, + controller.mapMailbox, + onCancelSelection: () => + controller.dispatchAction(CancelSelectionAllEmailAction()), + onEmailActionTypeAction: (listEmails, actionType) => + controller.dispatchAction( + HandleEmailActionTypeAction( + context, + listEmails, + actionType)), + ).build(), + ); + } else { + return Padding( + padding: const EdgeInsets.all(16.0), + child: _buildListButtonTopBar(context), + ); + } + }), const Divider(color: AppColor.colorDivider, height: 1), Expanded(child: ThreadView()) ]), @@ -319,116 +335,6 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { ]); } - Widget _buildListButtonTopBarSelection(BuildContext context) { - return Row(children: [ - buildIconWeb( - icon: SvgPicture.asset(imagePaths.icCloseComposer, color: AppColor.colorTextButton, fit: BoxFit.fill), - tooltip: AppLocalizations.of(context).cancel, - onTap: () => controller.dispatchAction(CancelSelectionAllEmailAction())), - Obx(() => Text( - AppLocalizations.of(context).count_email_selected(controller.listEmailSelected.length), - style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w500, color: AppColor.colorTextButton))), - const SizedBox(width: 30), - Obx(() => buildIconWeb( - icon: SvgPicture.asset( - controller.listEmailSelected.isAllEmailRead - ? imagePaths.icRead - : imagePaths.icUnread, - fit: BoxFit.fill), - tooltip: controller.listEmailSelected.isAllEmailRead - ? AppLocalizations.of(context).mark_as_unread - : AppLocalizations.of(context).mark_as_read, - onTap: () => controller.dispatchAction( - HandleEmailActionTypeAction(context, - controller.listEmailSelected, - controller.listEmailSelected.isAllEmailRead - ? EmailActionType.markAsUnread - : EmailActionType.markAsRead)))), - Obx(() => buildIconWeb( - icon: SvgPicture.asset( - controller.listEmailSelected.isAllEmailStarred - ? imagePaths.icUnStar - : imagePaths.icStar, - fit: BoxFit.fill), - tooltip: controller.listEmailSelected.isAllEmailStarred - ? AppLocalizations.of(context).un_star - : AppLocalizations.of(context).star, - onTap: () => controller.dispatchAction( - HandleEmailActionTypeAction(context, - controller.listEmailSelected, - controller.listEmailSelected.isAllEmailStarred - ? EmailActionType.markAsStarred - : EmailActionType.unMarkAsStarred)))), - Obx(() { - if (controller.selectedMailbox.value?.isDrafts == false) { - return buildIconWeb( - icon: SvgPicture.asset(imagePaths.icMove, fit: BoxFit.fill), - tooltip: AppLocalizations.of(context).move, - onTap: () => controller.dispatchAction( - HandleEmailActionTypeAction(context, - controller.listEmailSelected, - EmailActionType.moveToMailbox))); - } else { - return const SizedBox.shrink(); - } - }), - Obx(() { - if (controller.selectedMailbox.value?.isDrafts == false) { - return buildIconWeb( - icon: SvgPicture.asset( - controller.selectedMailbox.value?.isSpam == true - ? imagePaths.icNotSpam - : imagePaths.icSpam, - fit: BoxFit.fill), - tooltip: controller.selectedMailbox.value?.isSpam == true - ? AppLocalizations.of(context).un_spam - : AppLocalizations.of(context).mark_as_spam, - onTap: () { - if (controller.selectedMailbox.value?.isSpam == true) { - return controller.dispatchAction( - HandleEmailActionTypeAction(context, - controller.listEmailSelected, - EmailActionType.unSpam)); - } else { - return controller.dispatchAction( - HandleEmailActionTypeAction(context, - controller.listEmailSelected, - EmailActionType.moveToSpam)); - } - }); - } else { - return const SizedBox.shrink(); - } - }), - Obx(() => buildIconWeb( - icon: SvgPicture.asset( - canDeletePermanently ? imagePaths.icDeleteComposer : imagePaths.icDelete, - color: canDeletePermanently ? AppColor.colorDeletePermanentlyButton : AppColor.primaryColor, - width: 20, - height: 20, - fit: BoxFit.fill), - tooltip: canDeletePermanently - ? AppLocalizations.of(context).delete_permanently - : AppLocalizations.of(context).move_to_trash, - onTap: () { - if (canDeletePermanently) { - return controller.dispatchAction(HandleEmailActionTypeAction(context, - controller.listEmailSelected, - EmailActionType.deletePermanently)); - } else { - return controller.dispatchAction(HandleEmailActionTypeAction(context, - controller.listEmailSelected, - EmailActionType.moveToTrash)); - } - })), - ]); - } - - bool get canDeletePermanently { - return controller.selectedMailbox.value?.isTrash == true || - controller.selectedMailbox.value?.isDrafts == true; - } - Widget _buildMarkAsMailboxReadLoading(BuildContext context) { return Obx(() { final viewState = controller.viewStateMarkAsReadMailbox.value; diff --git a/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart b/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart index f5cec117f..3cd85c3b8 100644 --- a/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart +++ b/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart @@ -89,3 +89,21 @@ class SearchEmailFilter { }); } } + +extension SearchEmailFilterExtension on SearchEmailFilter { + + SearchEmailFilter toSearchEmailFilter({UTCDate? newBefore}) { + return SearchEmailFilter( + from: from, + to: to, + text: text, + subject: subject, + hasKeyword: hasKeyword, + notKeyword: notKeyword, + mailbox: mailbox, + emailReceiveTimeType: emailReceiveTimeType, + hasAttachment: hasAttachment, + before: newBefore, + ); + } +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart b/lib/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart new file mode 100644 index 000000000..35b9b3e8d --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart @@ -0,0 +1,138 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/views/button/icon_button_web.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/email/email_action_type.dart'; +import 'package:model/email/presentation_email.dart'; +import 'package:model/extensions/list_presentation_email_extension.dart'; +import 'package:model/mailbox/presentation_mailbox.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +typedef OnEmailActionTypeAction = Function(List listEmail, EmailActionType actionType); + +class TopBarThreadSelection { + + final imagePaths = Get.find(); + + final BuildContext context; + final List listEmail; + final Map mapMailbox; + final OnEmailActionTypeAction? onEmailActionTypeAction; + final VoidCallback? onCancelSelection; + + TopBarThreadSelection( + this.context, + this.listEmail, + this.mapMailbox, { + this.onEmailActionTypeAction, + this.onCancelSelection, + }); + + Widget build() { + final canDeletePermanently = listEmail.isAllCanDeletePermanently(mapMailbox); + final canSpamAndMove = listEmail.isAllCanSpamAndMove(mapMailbox); + final isAllSpam = listEmail.isAllSpam(mapMailbox); + final isAllBelongToTheSameMailbox = listEmail.isAllBelongToTheSameMailbox(mapMailbox); + + return Row(children: [ + buildIconWeb( + icon: SvgPicture.asset( + imagePaths.icCloseComposer, + color: AppColor.colorTextButton, + fit: BoxFit.fill), + tooltip: AppLocalizations.of(context).cancel, + onTap: onCancelSelection), + Text(AppLocalizations.of(context).count_email_selected(listEmail.length), + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: AppColor.colorTextButton)), + const SizedBox(width: 30), + buildIconWeb( + icon: SvgPicture.asset( + listEmail.isAllEmailRead + ? imagePaths.icRead + : imagePaths.icUnread, + fit: BoxFit.fill), + tooltip: listEmail.isAllEmailRead + ? AppLocalizations.of(context).mark_as_unread + : AppLocalizations.of(context).mark_as_read, + onTap: () => onEmailActionTypeAction?.call( + List.from(listEmail), + listEmail.isAllEmailRead + ? EmailActionType.markAsUnread + : EmailActionType.markAsRead)), + buildIconWeb( + icon: SvgPicture.asset( + listEmail.isAllEmailStarred + ? imagePaths.icUnStar + : imagePaths.icStar, + fit: BoxFit.fill), + tooltip: listEmail.isAllEmailStarred + ? AppLocalizations.of(context).un_star + : AppLocalizations.of(context).star, + onTap: () => onEmailActionTypeAction?.call( + List.from(listEmail), + listEmail.isAllEmailStarred + ? EmailActionType.unMarkAsStarred + : EmailActionType.markAsStarred)), + if (canSpamAndMove) + ...[ + buildIconWeb( + icon: SvgPicture.asset(imagePaths.icMove, fit: BoxFit.fill), + tooltip: AppLocalizations.of(context).move, + onTap: () => onEmailActionTypeAction?.call( + List.from(listEmail), + EmailActionType.moveToMailbox)), + buildIconWeb( + icon: SvgPicture.asset( + isAllSpam ? imagePaths.icNotSpam : imagePaths.icSpam, + fit: BoxFit.fill), + tooltip: isAllSpam + ? AppLocalizations.of(context).un_spam + : AppLocalizations.of(context).mark_as_spam, + onTap: () { + if (isAllSpam) { + onEmailActionTypeAction?.call( + List.from(listEmail), + EmailActionType.unSpam); + } else { + onEmailActionTypeAction?.call( + List.from(listEmail.listEmailCanSpam(mapMailbox)), + EmailActionType.moveToSpam); + } + }) + ], + if (isAllBelongToTheSameMailbox) + buildIconWeb( + icon: SvgPicture.asset( + canDeletePermanently + ? imagePaths.icDeleteComposer + : imagePaths.icDelete, + color: canDeletePermanently + ? AppColor.colorDeletePermanentlyButton + : AppColor.primaryColor, + width: 20, + height: 20, + fit: BoxFit.fill), + tooltip: canDeletePermanently + ? AppLocalizations.of(context).delete_permanently + : AppLocalizations.of(context).move_to_trash, + onTap: () { + if (canDeletePermanently) { + onEmailActionTypeAction?.call( + List.from(listEmail), + EmailActionType.deletePermanently); + } else { + onEmailActionTypeAction?.call( + List.from(listEmail), + EmailActionType.moveToTrash); + } + }), + ]); + } +} \ No newline at end of file diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index aa6346555..117f0e365 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -424,6 +424,7 @@ class ThreadController extends BaseController { final limit = emailList.isNotEmpty ? UnsignedInt(emailList.length) : ThreadConstants.defaultLimit; + searchController.searchEmailFilter.value = _searchEmailFilter.toSearchEmailFilter(newBefore: null); _searchEmail(limit: limit); } } else { @@ -513,9 +514,7 @@ class ThreadController extends BaseController { mailboxDashBoardController.listEmailSelected.value = listEmailSelected; } - List get listEmailSelected { - return emailList.where((email) => email.selectMode == SelectMode.ACTIVE).toList(); - } + List get listEmailSelected => emailList.listEmailSelected; bool _isUnSelectedAll() { return emailList.every((email) => email.selectMode == SelectMode.INACTIVE); @@ -527,13 +526,16 @@ class ThreadController extends BaseController { mailboxDashBoardController.listEmailSelected.clear(); } - void markAsReadSelectedMultipleEmail(List listPresentationEmail) { - final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList(); - final readAction = listPresentationEmail.isAllEmailRead ? ReadActions.markAsUnread : ReadActions.markAsRead; - final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value; - if (_accountId != null && mailboxCurrent != null) { + void markAsReadSelectedMultipleEmail( + List listPresentationEmail, + ReadActions readActions + ) { + if (_accountId != null) { cancelSelectEmail(); - consumeState(_markAsMultipleEmailReadInteractor.execute(_accountId!, listEmail, readAction)); + consumeState(_markAsMultipleEmailReadInteractor.execute( + _accountId!, + listPresentationEmail.listEmail, + readActions)); } } @@ -611,9 +613,11 @@ class ThreadController extends BaseController { } } - void moveSelectedMultipleEmailToMailbox(List listEmail) async { - final currentMailbox = mailboxDashBoardController.selectedMailbox.value; - if (currentMailbox != null && _accountId != null) { + void moveSelectedMultipleEmailToMailbox( + List listEmail, + PresentationMailbox currentMailbox + ) async { + if (_accountId != null) { final listEmailIds = listEmail.map((email) => email.id).toList(); final destinationMailbox = await push( AppRoutes.DESTINATION_PICKER, @@ -707,11 +711,13 @@ class ThreadController extends BaseController { _refreshEmailChanges(currentEmailState: currentEmailState); } - void moveSelectedMultipleEmailToTrash(List listEmail) async { - final currentMailbox = mailboxDashBoardController.selectedMailbox.value; + void moveSelectedMultipleEmailToTrash( + List listEmail, + PresentationMailbox currentMailbox + ) { final trashMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleTrash); - if (currentMailbox != null && _accountId != null && trashMailboxId != null) { + if (_accountId != null && trashMailboxId != null) { final listEmailIds = listEmail.map((email) => email.id).toList(); _moveSelectedEmailMultipleToTrashAction(_accountId!, MoveToMailboxRequest( listEmailIds, @@ -728,11 +734,13 @@ class ThreadController extends BaseController { consumeState(_moveMultipleEmailToMailboxInteractor.execute(accountId, moveRequest)); } - void moveSelectedMultipleEmailToSpam(List listEmail) async { - final currentMailbox = mailboxDashBoardController.selectedMailbox.value; + void moveSelectedMultipleEmailToSpam( + List listEmail, + PresentationMailbox currentMailbox + ) { final spamMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleSpam); - if (currentMailbox != null && _accountId != null && spamMailboxId != null) { + if (_accountId != null && spamMailboxId != null) { final listEmailIds = listEmail.map((email) => email.id).toList(); _moveSelectedEmailMultipleToSpamAction(_accountId!, MoveToMailboxRequest( listEmailIds, @@ -791,12 +799,16 @@ class ThreadController extends BaseController { _refreshEmailChanges(currentEmailState: success.currentEmailState); } - void markAsStarSelectedMultipleEmail(List listPresentationEmail) { - final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList(); - final starAction = listPresentationEmail.isAllEmailStarred ? MarkStarAction.unMarkStar : MarkStarAction.markStar; + void markAsStarSelectedMultipleEmail( + List listPresentationEmail, + MarkStarAction markStarAction + ) { if (_accountId != null) { cancelSelectEmail(); - consumeState(_markAsStarMultipleEmailInteractor.execute(_accountId!, listEmail, starAction)); + consumeState(_markAsStarMultipleEmailInteractor.execute( + _accountId!, + listPresentationEmail.listEmail, + markStarAction)); } } @@ -924,28 +936,52 @@ class ThreadController extends BaseController { void pressEmailSelectionAction(BuildContext context, EmailActionType actionType, List selectionEmail) { switch(actionType) { case EmailActionType.markAsRead: + markAsReadSelectedMultipleEmail(selectionEmail, ReadActions.markAsRead); + break; case EmailActionType.markAsUnread: - markAsReadSelectedMultipleEmail(selectionEmail); + markAsReadSelectedMultipleEmail(selectionEmail, ReadActions.markAsUnread); break; case EmailActionType.markAsStarred: + markAsStarSelectedMultipleEmail(selectionEmail, MarkStarAction.markStar); + break; case EmailActionType.unMarkAsStarred: - markAsStarSelectedMultipleEmail(selectionEmail); + markAsStarSelectedMultipleEmail(selectionEmail, MarkStarAction.unMarkStar); break; case EmailActionType.moveToMailbox: - moveSelectedMultipleEmailToMailbox(selectionEmail); + final mailboxContainCurrent = searchController.isSearchEmailRunning + ? selectionEmail.getCurrentMailboxContain(mailboxDashBoardController.mapMailbox) + : currentMailbox; + if (mailboxContainCurrent != null) { + moveSelectedMultipleEmailToMailbox(selectionEmail, mailboxContainCurrent); + } break; case EmailActionType.moveToTrash: - moveSelectedMultipleEmailToTrash(selectionEmail); + final mailboxContainCurrent = searchController.isSearchEmailRunning + ? selectionEmail.getCurrentMailboxContain(mailboxDashBoardController.mapMailbox) + : currentMailbox; + if (mailboxContainCurrent != null) { + moveSelectedMultipleEmailToTrash(selectionEmail, mailboxContainCurrent); + } break; case EmailActionType.deletePermanently: - deleteSelectionEmailsPermanently( - context, - DeleteActionType.multiple, - selectedEmails: selectionEmail, - presentationMailbox: currentMailbox); + final mailboxContainCurrent = searchController.isSearchEmailRunning + ? selectionEmail.getCurrentMailboxContain(mailboxDashBoardController.mapMailbox) + : currentMailbox; + if (mailboxContainCurrent != null) { + deleteSelectionEmailsPermanently( + context, + DeleteActionType.multiple, + selectedEmails: selectionEmail, + presentationMailbox: mailboxContainCurrent); + } break; case EmailActionType.moveToSpam: - moveSelectedMultipleEmailToSpam(selectionEmail); + final mailboxContainCurrent = searchController.isSearchEmailRunning + ? selectionEmail.getCurrentMailboxContain(mailboxDashBoardController.mapMailbox) + : currentMailbox; + if (mailboxContainCurrent != null) { + moveSelectedMultipleEmailToSpam(selectionEmail, mailboxContainCurrent); + } break; case EmailActionType.unSpam: unSpamSelectedMultipleEmail(selectionEmail); diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index fdf18e28a..503b27707 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -134,7 +134,7 @@ class ThreadView extends GetWidget with AppLoaderMixin, return Obx(() { if ((!BuildUtils.isWeb || (BuildUtils.isWeb && controller.isSelectionEnabled() && controller.isSearchActive() && !_responsiveUtils.isDesktop(context))) - && controller.listEmailSelected.isNotEmpty) { + && controller.emailList.listEmailSelected.isNotEmpty) { return Column(children: [ const Divider(color: AppColor.lineItemListColor, height: 1, thickness: 0.2), Padding( @@ -143,7 +143,7 @@ class ThreadView extends GetWidget with AppLoaderMixin, context, _imagePaths, _responsiveUtils, - controller.listEmailSelected, + controller.emailList.listEmailSelected, controller.mailboxDashBoardController.selectedMailbox.value) ..addOnPressEmailSelectionActionClick((actionType, selectionEmail) => controller.pressEmailSelectionAction(context, actionType, selectionEmail))) @@ -379,7 +379,7 @@ class ThreadView extends GetWidget with AppLoaderMixin, return (AppBarThreadWidgetBuilder( context, controller.currentMailbox, - controller.listEmailSelected, + controller.emailList.listEmailSelected, controller.mailboxDashBoardController.currentSelectMode.value, controller.mailboxDashBoardController.filterMessageOption.value) ..addOpenMailboxMenuActionClick(() => controller.openMailboxLeftMenu()) @@ -568,10 +568,13 @@ class ThreadView extends GetWidget with AppLoaderMixin, itemBuilder: (context, index) => Obx(() => (EmailTileBuilder( context, listPresentationEmail[index], - controller.currentMailbox?.role, controller.mailboxDashBoardController.currentSelectMode.value, controller.searchController.searchState.value.searchStatus, controller.searchQuery, + mailboxCurrent: controller.searchController.isSearchEmailRunning + ? listPresentationEmail[index].findMailboxContain( + controller.mailboxDashBoardController.mapMailbox) + : controller.currentMailbox, advancedSearchActivated: controller.searchController.isAdvancedSearchHasApply.isTrue) ..addOnPressEmailActionClick((action, email) => controller.pressEmailAction( diff --git a/lib/features/thread/presentation/widgets/email_tile_builder.dart b/lib/features/thread/presentation/widgets/email_tile_builder.dart index e12779680..60d1f75f9 100644 --- a/lib/features/thread/presentation/widgets/email_tile_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_builder.dart @@ -2,7 +2,6 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart'; @@ -17,7 +16,7 @@ class EmailTileBuilder { final PresentationEmail _presentationEmail; final BuildContext _context; final SelectMode _selectModeAll; - final Role? _mailboxRole; + final PresentationMailbox? mailboxCurrent; final SearchStatus _searchStatus; final SearchQuery? _searchQuery; final bool advancedSearchActivated; @@ -27,12 +26,12 @@ class EmailTileBuilder { EmailTileBuilder( this._context, this._presentationEmail, - this._mailboxRole, this._selectModeAll, this._searchStatus, this._searchQuery, { - this.advancedSearchActivated = false + this.mailboxCurrent, + this.advancedSearchActivated = false, } ); @@ -280,9 +279,9 @@ class EmailTileBuilder { } String _getInformationSender() { - if (_mailboxRole == PresentationMailbox.roleSent - || _mailboxRole == PresentationMailbox.roleDrafts - || _mailboxRole == PresentationMailbox.roleOutbox) { + if (mailboxCurrent?.isSent == true + || mailboxCurrent?.isDrafts == true + || mailboxCurrent?.isOutbox == true) { return _presentationEmail.recipientsName(); } return _presentationEmail.getSenderName(); diff --git a/lib/features/thread/presentation/widgets/email_tile_web_builder.dart b/lib/features/thread/presentation/widgets/email_tile_web_builder.dart index ab0d9ff94..e2b325f81 100644 --- a/lib/features/thread/presentation/widgets/email_tile_web_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_web_builder.dart @@ -3,7 +3,6 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart'; @@ -20,7 +19,7 @@ class EmailTileBuilder { final PresentationEmail _presentationEmail; final BuildContext _context; final SelectMode _selectModeAll; - final Role? _mailboxRole; + final PresentationMailbox? mailboxCurrent; final SearchStatus _searchStatus; final SearchQuery? _searchQuery; final bool advancedSearchActivated; @@ -34,11 +33,11 @@ class EmailTileBuilder { EmailTileBuilder( this._context, this._presentationEmail, - this._mailboxRole, this._selectModeAll, this._searchStatus, this._searchQuery, { + this.mailboxCurrent, this.advancedSearchActivated = false } ); @@ -577,7 +576,7 @@ class EmailTileBuilder { : EmailActionType.markAsRead, _presentationEmail)), const SizedBox(width: 5), - if (_mailboxRole != PresentationMailbox.roleDrafts) + if (mailboxCurrent?.isDrafts == false) ... [ buildIconWeb( minSize: 18, @@ -616,7 +615,7 @@ class EmailTileBuilder { : EmailActionType.moveToTrash, _presentationEmail)), const SizedBox(width: 5), - if (_mailboxRole != PresentationMailbox.roleDrafts) + if (mailboxCurrent?.isDrafts == false) buildIconWebHasPosition( _context, icon: SvgPicture.asset( @@ -641,8 +640,7 @@ class EmailTileBuilder { } bool get canDeletePermanently { - return _mailboxRole == PresentationMailbox.roleTrash || - _mailboxRole == PresentationMailbox.roleDrafts; + return mailboxCurrent?.isTrash == true || mailboxCurrent?.isDrafts == true; } Widget _buildDateTimeForDesktopScreen() { @@ -834,9 +832,9 @@ class EmailTileBuilder { } String _getInformationSender() { - if (_mailboxRole == PresentationMailbox.roleSent - || _mailboxRole == PresentationMailbox.roleDrafts - || _mailboxRole == PresentationMailbox.roleOutbox) { + if (mailboxCurrent?.isSent == true + || mailboxCurrent?.isDrafts == true + || mailboxCurrent?.isOutbox == true) { return _presentationEmail.recipientsName(); } return _presentationEmail.getSenderName(); diff --git a/model/lib/extensions/list_presentation_email_extension.dart b/model/lib/extensions/list_presentation_email_extension.dart index bb81cb32a..a93f6178f 100644 --- a/model/lib/extensions/list_presentation_email_extension.dart +++ b/model/lib/extensions/list_presentation_email_extension.dart @@ -1,5 +1,6 @@ import 'package:jmap_dart_client/jmap/mail/email/email.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/model.dart'; extension ListPresentationEmailExtension on List { @@ -7,6 +8,68 @@ extension ListPresentationEmailExtension on List { bool get isAllEmailStarred => every((email) => email.hasStarred); + List get listEmail => map((presentationEmail) => presentationEmail.toEmail()).toList(); + + List get listEmailSelected { + return where((email) => email.selectMode == SelectMode.ACTIVE).toList(); + } + + bool isAllCanDeletePermanently(Map mapMailbox) { + final listMailboxContain = map((email) => email.findMailboxContain(mapMailbox)) + .whereType() + .toList(); + final stateDelete = listMailboxContain.every((mailbox) => mailbox.isTrash) || + listMailboxContain.every((mailbox) => mailbox.isDrafts); + return stateDelete; + } + + bool isAllCanSpamAndMove(Map mapMailbox) { + final listMailboxContain = map((email) => email.findMailboxContain(mapMailbox)) + .whereType() + .toList(); + return listMailboxContain.every((mailbox) => !mailbox.isDrafts) && + isAllBelongToTheSameMailbox(mapMailbox); + } + + bool isAllSpam(Map mapMailbox) { + final listMailboxContain = map((email) => email.findMailboxContain(mapMailbox)) + .whereType() + .toList(); + return listMailboxContain.every((mailbox) => mailbox.isSpam); + } + + bool isAllBelongToTheSameMailbox(Map mapMailbox) { + if (isEmpty) { + return false; + } + final firstEmail = first; + final firstMailboxContain = firstEmail.findMailboxContain(mapMailbox); + if (firstMailboxContain != null) { + return every((email) { + final mailboxContain = email.findMailboxContain(mapMailbox); + return mailboxContain?.id == firstMailboxContain.id; + }); + } else { + return false; + } + } + + PresentationMailbox? getCurrentMailboxContain(Map mapMailbox) { + return first.findMailboxContain(mapMailbox); + } + + List listEmailCanSpam(Map mapMailbox) { + final newListEmails = map((email) { + final mailboxContain = email.findMailboxContain(mapMailbox); + if (mailboxContain?.isSpam == false) { + return email; + } else { + return null; + } + }).whereType().toList(); + return newListEmails; + } + List get allEmailUnread => where((email) => !email.hasRead).toList(); PresentationEmail? findEmail(EmailId emailId) { diff --git a/model/lib/mailbox/presentation_mailbox.dart b/model/lib/mailbox/presentation_mailbox.dart index 83d9710fa..2d27ece73 100644 --- a/model/lib/mailbox/presentation_mailbox.dart +++ b/model/lib/mailbox/presentation_mailbox.dart @@ -70,6 +70,8 @@ class PresentationMailbox with EquatableMixin { bool get isSent => role == roleSent; + bool get isOutbox => role == roleOutbox; + bool matchCountingRules() { if (isSpam || isTrash || isDrafts || isTemplates || isSent) { return false;