diff --git a/lib/features/mailbox/presentation/extensions/handle_action_required_tab_extension.dart b/lib/features/mailbox/presentation/extensions/handle_action_required_tab_extension.dart index 46491beef..80b3225fc 100644 --- a/lib/features/mailbox/presentation/extensions/handle_action_required_tab_extension.dart +++ b/lib/features/mailbox/presentation/extensions/handle_action_required_tab_extension.dart @@ -1,4 +1,3 @@ -import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart'; @@ -6,60 +5,33 @@ import 'package:tmail_ui_user/features/mailbox/presentation/extensions/list_mail import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; extension HandleActionRequiredTabExtension on BaseMailboxController { - void setUpActionRequiredFolder( - MailboxDashBoardController dashboardController, - ) { - if (!dashboardController.isAiCapabilitySupported) return; - - dashboardController.actionRequiredFolderController.getCountEmails( - session: dashboardController.sessionCurrent, - accountId: dashboardController.accountId.value, - ); - } - - void onActionRequiredFolderCountChanged(int count) { - if (count > 0) { - _addActionRequiredFolder(count); - } else { - _removeActionRequiredFolder(); - } - } - - void _addActionRequiredFolder(int count) { - final folder = _buildActionRequiredFolder(count); - - _addToDefaultMailboxTree(folder, count); + void addActionRequiredFolder() { + final folder = _buildActionRequiredFolder(); + _addToDefaultMailboxTree(folder); _addToAllMailboxes(folder); } - PresentationMailbox _buildActionRequiredFolder(int count) { + PresentationMailbox _buildActionRequiredFolder() { final base = PresentationMailbox.actionRequiredFolder; return base.copyWith( displayName: currentContext != null ? base.getDisplayName(currentContext!) : null, - unreadEmails: UnreadEmails(UnsignedInt(count)), ); } - void _addToDefaultMailboxTree(PresentationMailbox folder, int count) { + void _addToDefaultMailboxTree(PresentationMailbox folder) { final root = defaultMailboxTree.value.root; final children = List.from(root.childrenItems ?? []); - final result = children.insertAfterStarredOrInbox(MailboxNode(folder)); + children.insertAfterStarredOrInbox(MailboxNode(folder)); - if (result) { - defaultMailboxTree.value = MailboxTree( - root.copyWith(children: children), - ); - } else { - defaultMailboxTree.value.updateMailboxUnreadCountById(folder.id, count); - } + defaultMailboxTree.value = MailboxTree( + root.copyWith(children: children), + ); } void _addToAllMailboxes(PresentationMailbox folder) { @@ -67,27 +39,6 @@ extension HandleActionRequiredTabExtension on BaseMailboxController { allMailboxes.add(folder); } - void _removeActionRequiredFolder() { - final folder = PresentationMailbox.actionRequiredFolder; - - _removeFromDefaultMailboxTree(folder.id); - _removeFromAllMailboxes(folder.id); - } - - void _removeFromDefaultMailboxTree(MailboxId folderId) { - final root = defaultMailboxTree.value.root; - final children = List.from(root.childrenItems ?? []) - ..removeWhere((node) => node.item.id == folderId); - - defaultMailboxTree.value = MailboxTree( - root.copyWith(children: children), - ); - } - - void _removeFromAllMailboxes(MailboxId folderId) { - allMailboxes.removeWhere((mailbox) => mailbox.id == folderId); - } - bool _allMailboxesContains(MailboxId id) { return allMailboxes.any((mailbox) => mailbox.id == id); } diff --git a/lib/features/mailbox/presentation/extensions/list_mailbox_node_extension.dart b/lib/features/mailbox/presentation/extensions/list_mailbox_node_extension.dart index 2795e46b4..98d2a3ff8 100644 --- a/lib/features/mailbox/presentation/extensions/list_mailbox_node_extension.dart +++ b/lib/features/mailbox/presentation/extensions/list_mailbox_node_extension.dart @@ -15,8 +15,8 @@ extension ListMailboxNodeExtension on List { /// Insert [newNode] after Starred if present, /// otherwise after Inbox, otherwise at the beginning. - bool insertAfterStarredOrInbox(MailboxNode newNode) { - return insertAfterByPriority( + void insertAfterStarredOrInbox(MailboxNode newNode) { + insertAfterByPriority( newNode, [ _isStarred, @@ -27,22 +27,21 @@ extension ListMailboxNodeExtension on List { /// Insert [newNode] after the first mailbox matching [priorities]. /// If none match, inserts at the beginning. - bool insertAfterByPriority( + void insertAfterByPriority( MailboxNode newNode, List priorities, ) { - if (_containsMailbox(newNode)) return false; + if (_containsMailbox(newNode)) return; for (final predicate in priorities) { final index = indexWhere(predicate); if (index != -1) { insert(index + 1, newNode); - return true; + return; } } insert(0, newNode); - return true; } bool _isInbox(MailboxNode node) { diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index bb715a8b3..26300b6f8 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -86,6 +86,7 @@ import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_ma import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; @@ -264,16 +265,14 @@ class MailboxController extends BaseMailboxController viewState.value.fold( (failure) { if (failure is GetAllMailboxFailure) { - addFavoriteFolderToMailboxList(); - setUpActionRequiredFolder(mailboxDashBoardController); + autoCreateVirtualFolder(); mailboxDashBoardController.updateRefreshAllMailboxState(Left(RefreshAllMailboxFailure())); showRetryToast(failure); } }, (success) { if (success is GetAllMailboxSuccess) { - addFavoriteFolderToMailboxList(); - setUpActionRequiredFolder(mailboxDashBoardController); + autoCreateVirtualFolder(); mailboxDashBoardController.updateRefreshAllMailboxState(Right(RefreshAllMailboxSuccess())); _handleCreateDefaultFolderIfMissing(mailboxDashBoardController.mapDefaultMailboxIdByRole); _handleDataFromNavigationRouter(); @@ -282,8 +281,7 @@ class MailboxController extends BaseMailboxController _updateMailboxIdsBlockNotificationToKeychain(success.mailboxList); } } else if (success is CreateDefaultMailboxAllSuccess) { - addFavoriteFolderToMailboxList(); - setUpActionRequiredFolder(mailboxDashBoardController); + autoCreateVirtualFolder(); } }); } @@ -438,11 +436,6 @@ class MailboxController extends BaseMailboxController ); } }); - - ever( - mailboxDashBoardController.actionRequiredFolderController.actionRequiredFolderCount, - onActionRequiredFolderCountChanged, - ); } void _handleMarkEmailsAsReadOrUnread({ @@ -610,8 +603,7 @@ class MailboxController extends BaseMailboxController if (currentContext != null) { syncAllMailboxWithDisplayName(currentContext!); } - addFavoriteFolderToMailboxList(); - setUpActionRequiredFolder(mailboxDashBoardController); + autoCreateVirtualFolder(); _setMapMailbox(); _setOutboxMailbox(); _selectSelectedMailboxDefault(); @@ -1569,4 +1561,11 @@ class MailboxController extends BaseMailboxController ); } } + + void autoCreateVirtualFolder() { + addFavoriteFolderToMailboxList(); + if (mailboxDashBoardController.isAiCapabilitySupported) { + addActionRequiredFolder(); + } + } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/bindings/action_required_interactor_bindings.dart b/lib/features/mailbox_dashboard/presentation/bindings/action_required_interactor_bindings.dart deleted file mode 100644 index bf5aa08e0..000000000 --- a/lib/features/mailbox_dashboard/presentation/bindings/action_required_interactor_bindings.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:core/data/model/source_type/data_source_type.dart'; -import 'package:get/get.dart'; -import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; -import 'package:tmail_ui_user/features/caching/caching_manager.dart'; -import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart'; -import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/state_datasource_impl.dart'; -import 'package:tmail_ui_user/features/mailbox/data/local/state_cache_manager.dart'; -import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; -import 'package:tmail_ui_user/features/thread/data/datasource_impl/local_thread_datasource_impl.dart'; -import 'package:tmail_ui_user/features/thread/data/datasource_impl/thread_datasource_impl.dart'; -import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; -import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart'; -import 'package:tmail_ui_user/features/thread/data/network/thread_isolate_worker.dart'; -import 'package:tmail_ui_user/features/thread/data/repository/thread_repository_impl.dart'; -import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'; -import 'package:tmail_ui_user/features/thread/domain/usecases/get_count_unread_emails_in_folder_interactor.dart'; -import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; -import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; -import 'package:tmail_ui_user/main/utils/ios_sharing_manager.dart'; - -class ActionRequiredInteractorBindings extends InteractorsBindings { - @override - void bindingsDataSource() { - Get.lazyPut(() => Get.find()); - Get.lazyPut(() => Get.find()); - } - - @override - void bindingsDataSourceImpl() { - Get.lazyPut( - () => ThreadDataSourceImpl( - Get.find(), - Get.find(), - Get.find(), - ), - ); - Get.lazyPut( - () => LocalThreadDataSourceImpl( - Get.find(), - Get.find(), - Get.find(), - ), - ); - Get.lazyPut( - () => StateDataSourceImpl( - Get.find(), - Get.find(), - Get.find(), - ), - ); - } - - @override - void bindingsInteractor() { - Get.lazyPut( - () => GetCountUnreadEmailsInFolderInteractor( - Get.find(), - ), - ); - } - - @override - void bindingsRepository() { - Get.lazyPut(() => Get.find()); - } - - @override - void bindingsRepositoryImpl() { - Get.lazyPut( - () => ThreadRepositoryImpl( - { - DataSourceType.network: Get.find(), - DataSourceType.local: Get.find() - }, - Get.find(), - ), - ); - } -} diff --git a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart index c8b1fab2a..c4886dd99 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -106,7 +106,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_e import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_last_time_dismissed_spam_reported_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_spam_report_state_interactor.dart'; import 'package:tmail_ui_user/features/download/presentation/bindings/download_interactor_bindings.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; import 'package:tmail_ui_user/features/download/presentation/controllers/download_controller.dart'; @@ -210,8 +209,6 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => ComposerManager()); - Get.put(ActionRequiredFolderController()); - Get.put(MailboxDashBoardController( Get.find(), Get.find(), diff --git a/lib/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart deleted file mode 100644 index e48d7341f..000000000 --- a/lib/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:dartz/dartz.dart'; -import 'package:get/get.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/session/session.dart'; -import 'package:tmail_ui_user/features/base/base_controller.dart'; -import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/action_required_interactor_bindings.dart'; -import 'package:tmail_ui_user/features/thread/domain/exceptions/thread_exceptions.dart'; -import 'package:tmail_ui_user/features/thread/domain/state/get_count_emails_in_folder_state.dart'; -import 'package:tmail_ui_user/features/thread/domain/usecases/get_count_unread_emails_in_folder_interactor.dart'; -import 'package:tmail_ui_user/main/routes/route_navigation.dart'; - -class ActionRequiredFolderController extends BaseController { - final actionRequiredFolderCount = RxInt(0); - - GetCountUnreadEmailsInFolderInteractor? - _getCountUnreadEmailsInFolderInteractor; - - void injectBinding() { - ActionRequiredInteractorBindings().dependencies(); - - _getCountUnreadEmailsInFolderInteractor = - getBinding(); - } - - Future getCountEmails({ - required Session? session, - required AccountId? accountId, - }) async { - if (_getCountUnreadEmailsInFolderInteractor == null) { - consumeState(Stream.value( - Left(GetCountUnreadEmailsInFolderFailure(InteractorIsNullException())), - )); - return; - } - - if (session == null) { - consumeState(Stream.value( - Left(GetCountUnreadEmailsInFolderFailure(NotFoundSessionException())), - )); - return; - } - - if (accountId == null) { - consumeState(Stream.value( - Left(GetCountUnreadEmailsInFolderFailure(NotFoundAccountIdException())), - )); - return; - } - - consumeState(_getCountUnreadEmailsInFolderInteractor!.execute( - session: session, - accountId: accountId, - )); - } - - @override - void handleSuccessViewState(Success success) { - if (success is GetCountUnreadEmailsInFolderSuccess) { - actionRequiredFolderCount.value = success.count; - } else { - super.handleSuccessViewState(success); - } - } - - @override - void handleFailureViewState(Failure failure) { - if (failure is GetCountUnreadEmailsInFolderFailure) { - actionRequiredFolderCount.value = 0; - } else { - super.handleFailureViewState(failure); - } - } - - @override - void onClose() { - _getCountUnreadEmailsInFolderInteractor = null; - super.onClose(); - } -} 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 79b7f41b0..cb81c1890 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -117,7 +117,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_te import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_email_sort_order_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/download_ui_action.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart' as search; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart'; @@ -125,7 +124,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/cleanup_recent_search_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/delete_emails_in_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_action_type_for_email_selection.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_clear_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart'; @@ -239,8 +237,6 @@ class MailboxDashBoardController extends ReloadableController final getStoredOidcConfigurationInteractor = Get.find(); final getTokenOIDCInteractor = Get.find(); - final actionRequiredFolderController = - Get.find(); final MoveToMailboxInteractor _moveToMailboxInteractor; final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor; @@ -878,9 +874,6 @@ class MailboxDashBoardController extends ReloadableController if (PlatformInfo.isMobile) { injectFCMBindings(session, currentAccountId); } - if (isAiCapabilitySupported) { - actionRequiredFolderController.injectBinding(); - } _getVacationResponse(); spamReportController.getSpamReportStateAction(); diff --git a/lib/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart b/lib/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart index 4cd60763d..9c6b71da4 100644 --- a/lib/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart +++ b/lib/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart @@ -16,13 +16,4 @@ extension HandleAiActionExtension on MailboxDashBoardController { currentAccountId, ); } - - void autoRefreshCountEmailsInActionRequiredFolder() { - if (isAiCapabilitySupported) { - actionRequiredFolderController.getCountEmails( - session: sessionCurrent, - accountId: accountId.value, - ); - } - } } diff --git a/lib/features/search/mailbox/presentation/search_mailbox_controller.dart b/lib/features/search/mailbox/presentation/search_mailbox_controller.dart index 474642d06..be5e1fae2 100644 --- a/lib/features/search/mailbox/presentation/search_mailbox_controller.dart +++ b/lib/features/search/mailbox/presentation/search_mailbox_controller.dart @@ -69,6 +69,7 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_na import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_reactive_obx_variable_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; @@ -214,11 +215,11 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa super.onDone(); viewState.value.fold((failure) { if (failure is GetAllMailboxFailure) { - addFavoriteFolderToMailboxList(); + autoCreateVirtualFolder(); } }, (success) { if (success is GetAllMailboxSuccess) { - addFavoriteFolderToMailboxList(); + autoCreateVirtualFolder(); } }); } @@ -254,12 +255,6 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa ); } }); - - ever( - dashboardController - .actionRequiredFolderController.actionRequiredFolderCount, - onActionRequiredFolderCountChanged, - ); } void _registerInputFocusListener() { @@ -905,6 +900,13 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa FocusManager.instance.primaryFocus?.unfocus(); } + void autoCreateVirtualFolder() { + addFavoriteFolderToMailboxList(); + if (dashboardController.isAiCapabilitySupported) { + addActionRequiredFolder(); + } + } + @override void onClose() { textInputSearchController.dispose(); diff --git a/lib/features/thread/data/repository/thread_repository_impl.dart b/lib/features/thread/data/repository/thread_repository_impl.dart index 3052a5d47..f85eec412 100644 --- a/lib/features/thread/data/repository/thread_repository_impl.dart +++ b/lib/features/thread/data/repository/thread_repository_impl.dart @@ -16,7 +16,6 @@ import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart'; -import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart'; @@ -524,22 +523,4 @@ class ThreadRepositoryImpl extends ThreadRepository { ); yield emailResponse; } - - @override - Future getCountUnreadEmailsInFolder({ - required Session session, - required AccountId accountId, - }) async { - final networkDataSource = mapDataSource[DataSourceType.network]!; - final emailResponse = await networkDataSource.getAllEmail( - session, - accountId, - filter: EmailFilterCondition( - hasKeyword: KeyWordIdentifierExtension.needActionMail.value, - notKeyword: KeyWordIdentifier.emailSeen.value, - ), - properties: Properties({EmailProperty.id}), - ); - return emailResponse.emailList?.length ?? 0; - } } \ No newline at end of file diff --git a/lib/features/thread/domain/repository/thread_repository.dart b/lib/features/thread/domain/repository/thread_repository.dart index 35005de71..686b46c0a 100644 --- a/lib/features/thread/domain/repository/thread_repository.dart +++ b/lib/features/thread/domain/repository/thread_repository.dart @@ -93,9 +93,4 @@ abstract class ThreadRepository { ); Future clearEmailCacheAndStateCache(AccountId accountId, Session session); - - Future getCountUnreadEmailsInFolder({ - required Session session, - required AccountId accountId, - }); } \ No newline at end of file diff --git a/lib/features/thread/domain/state/get_count_emails_in_folder_state.dart b/lib/features/thread/domain/state/get_count_emails_in_folder_state.dart deleted file mode 100644 index a5b9420b4..000000000 --- a/lib/features/thread/domain/state/get_count_emails_in_folder_state.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; - -class GettingCountUnreadEmailsInFolder extends LoadingState {} - -class GetCountUnreadEmailsInFolderSuccess extends UIState { - final int count; - - GetCountUnreadEmailsInFolderSuccess({required this.count}); - - @override - List get props => [count]; -} - -class GetCountUnreadEmailsInFolderFailure extends FeatureFailure { - GetCountUnreadEmailsInFolderFailure(dynamic exception) - : super(exception: exception); -} diff --git a/lib/features/thread/domain/usecases/get_count_unread_emails_in_folder_interactor.dart b/lib/features/thread/domain/usecases/get_count_unread_emails_in_folder_interactor.dart deleted file mode 100644 index 00dc9b462..000000000 --- a/lib/features/thread/domain/usecases/get_count_unread_emails_in_folder_interactor.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:dartz/dartz.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/session/session.dart'; -import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'; -import 'package:tmail_ui_user/features/thread/domain/state/get_count_emails_in_folder_state.dart'; - -class GetCountUnreadEmailsInFolderInteractor { - final ThreadRepository _threadRepository; - - GetCountUnreadEmailsInFolderInteractor(this._threadRepository); - - Stream> execute({ - required Session session, - required AccountId accountId, - }) async* { - try { - yield Right(GettingCountUnreadEmailsInFolder()); - final count = await _threadRepository.getCountUnreadEmailsInFolder( - session: session, - accountId: accountId, - ); - yield Right(GetCountUnreadEmailsInFolderSuccess(count: count)); - } catch (e) { - yield Left(GetCountUnreadEmailsInFolderFailure(e)); - } - } -} diff --git a/lib/features/thread/presentation/extensions/handle_open_context_menu_filter_email_action_extension.dart b/lib/features/thread/presentation/extensions/handle_open_context_menu_filter_email_action_extension.dart index e23603828..3aeef0e6d 100644 --- a/lib/features/thread/presentation/extensions/handle_open_context_menu_filter_email_action_extension.dart +++ b/lib/features/thread/presentation/extensions/handle_open_context_menu_filter_email_action_extension.dart @@ -15,7 +15,8 @@ extension HandleOpenContextMenuFilterEmailActionExtension on ThreadController { ) { final popupMenuItems = [ FilterMessageOption.attachments, - FilterMessageOption.unread, + if (selectedMailbox?.isActionRequired != true) + FilterMessageOption.unread, if (selectedMailbox?.isFavorite != true) FilterMessageOption.starred, ].map((filterOption) { diff --git a/lib/features/thread/presentation/extensions/handle_pull_to_refresh_list_email_extension.dart b/lib/features/thread/presentation/extensions/handle_pull_to_refresh_list_email_extension.dart index fa8f5b85d..d7369c210 100644 --- a/lib/features/thread/presentation/extensions/handle_pull_to_refresh_list_email_extension.dart +++ b/lib/features/thread/presentation/extensions/handle_pull_to_refresh_list_email_extension.dart @@ -1,9 +1,11 @@ import 'package:core/utils/app_logger.dart'; import 'package:dartz/dartz.dart'; +import 'package:model/extensions/presentation_mailbox_extension.dart'; import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart'; +import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart'; import 'package:tmail_ui_user/features/thread/domain/state/clean_and_get_all_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/loading_more_status.dart'; @@ -38,7 +40,7 @@ extension HandlePullToRefreshListEmailExtension on ThreadController { consumeState(cleanAndGetEmailsInMailboxInteractor.execute( session, accountId, - limit: limitEmailFetchedInFolder, + limit: ThreadConstants.defaultLimit, sort: EmailSortOrderType.mostRecent.getSortOrder().toNullable(), emailFilter: getEmailFilterForLoadMailbox(), propertiesCreated: EmailUtils.getPropertiesForEmailGetMethod(session, accountId), @@ -47,7 +49,7 @@ extension HandlePullToRefreshListEmailExtension on ThreadController { accountId, ), getLatestChanges: true, - useCache: !shouldBypassCache, + useCache: selectedMailbox?.isVirtualFolder != true, )); } } \ 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 b349a7c7f..326ef294f 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -33,7 +33,6 @@ import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.d import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart' as search; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/move_emails_to_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_current_emails_flags_extension.dart'; @@ -506,11 +505,13 @@ class ThreadController extends BaseController with EmailActionController { } void _getAllEmailSuccess(GetAllEmailSuccess success) { + log('ThreadController::_getAllEmailSuccess: GetAllForMailboxId = ${success.currentMailboxId?.asString} | SELECTED_MAILBOX_ID = ${selectedMailboxId?.asString} | SELECTED_MAILBOX_NAME = ${selectedMailbox?.name?.name}'); mailboxDashBoardController.updateRefreshAllEmailState(Right(RefreshAllEmailSuccess())); + final currentMailboxId = success.currentMailboxId; + final isVirtualFolder = selectedMailbox?.isVirtualFolder == true; - if (success.currentMailboxId != selectedMailboxId && - selectedMailbox?.isVirtualFolder != true) { - log('ThreadController::_getAllEmailSuccess: GetAllForMailboxId = ${success.currentMailboxId?.asString} | SELECTED_MAILBOX_ID = ${selectedMailboxId?.asString} | SELECTED_MAILBOX_NAME = ${selectedMailbox?.name?.name}'); + if (currentMailboxId != null && + (isVirtualFolder || currentMailboxId != selectedMailboxId)) { return; } mailboxDashBoardController.setCurrentEmailState(success.currentEmailState); @@ -549,9 +550,12 @@ class ThreadController extends BaseController with EmailActionController { } void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) { - if (success.currentMailboxId != selectedMailboxId && - selectedMailbox?.isVirtualFolder != true) { - log('ThreadController::_refreshChangesAllEmailSuccess: RefreshedMailboxId = ${success.currentMailboxId?.asString} | SELECTED_MAILBOX_ID = ${selectedMailboxId?.asString} | SELECTED_MAILBOX_NAME = ${selectedMailbox?.name?.name}'); + log('ThreadController::_refreshChangesAllEmailSuccess: RefreshedMailboxId = ${success.currentMailboxId?.asString} | SELECTED_MAILBOX_ID = ${selectedMailboxId?.asString} | SELECTED_MAILBOX_NAME = ${selectedMailbox?.name?.name}'); + final currentMailboxId = success.currentMailboxId; + final isVirtualFolder = selectedMailbox?.isVirtualFolder == true; + + if (currentMailboxId != null && + (isVirtualFolder || currentMailboxId != selectedMailboxId)) { return; } mailboxDashBoardController.setCurrentEmailState(success.currentEmailState); @@ -576,14 +580,6 @@ class ThreadController extends BaseController with EmailActionController { } } - bool get shouldBypassCache => - selectedMailbox?.isVirtualFolder ?? false; - - UnsignedInt? get limitEmailFetchedInFolder => - selectedMailbox?.isActionRequired == true - ? null - : ThreadConstants.defaultLimit; - void getAllEmailAction({ bool getLatestChanges = true, }) { @@ -592,7 +588,7 @@ class ThreadController extends BaseController with EmailActionController { consumeState(_getEmailsInMailboxInteractor.execute( _session!, _accountId!, - limit: limitEmailFetchedInFolder, + limit: ThreadConstants.defaultLimit, sort: EmailSortOrderType.mostRecent.getSortOrder().toNullable(), emailFilter: getEmailFilterForLoadMailbox(), propertiesCreated: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!), @@ -601,7 +597,7 @@ class ThreadController extends BaseController with EmailActionController { _accountId!, ), getLatestChanges: getLatestChanges, - useCache: !shouldBypassCache, + useCache: selectedMailbox?.isVirtualFolder != true, )); } else { consumeState(Stream.value(Left(GetAllEmailFailure(NotFoundSessionException())))); @@ -789,7 +785,6 @@ class ThreadController extends BaseController with EmailActionController { } else { await _refreshChangeListEmail(); } - mailboxDashBoardController.autoRefreshCountEmailsInActionRequiredFolder(); } catch (e, stackTrace) { logWarning('ThreadController::_handleWebSocketMessage:Error processing state: $e'); onError(e, stackTrace); @@ -936,13 +931,13 @@ class ThreadController extends BaseController with EmailActionController { GetEmailRequest( _session!, _accountId!, - limit: limitEmailFetchedInFolder, + limit: ThreadConstants.defaultLimit, sort: EmailSortOrderType.mostRecent.getSortOrder().toNullable(), filterOption: mailboxDashBoardController.filterMessageOption.value, filter: getFilterConditionForLoadMailbox(oldestEmail: oldestEmail), properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!), lastEmailId: oldestEmail?.id, - useCache: !shouldBypassCache, + useCache: selectedMailbox?.isVirtualFolder != true, ) )); } diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index c64f64822..816741fd0 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -796,6 +796,7 @@ class ThreadView extends GetWidget isSearchActive: controller.isSearchActive, isFilterMessageActive: controller.mailboxDashBoardController.filterMessageOption.value != FilterMessageOption.all, isFavoriteFolder: controller.selectedMailbox?.isFavorite == true, + isActionRequiredFolder: controller.selectedMailbox?.isActionRequired == true, ), ); } diff --git a/lib/features/thread/presentation/widgets/empty_emails_widget.dart b/lib/features/thread/presentation/widgets/empty_emails_widget.dart index 8da822ed2..a9f508d2b 100644 --- a/lib/features/thread/presentation/widgets/empty_emails_widget.dart +++ b/lib/features/thread/presentation/widgets/empty_emails_widget.dart @@ -14,6 +14,7 @@ class EmptyEmailsWidget extends StatelessWidget { final bool isFilterMessageActive; final bool isNetworkConnectionAvailable; final bool isFavoriteFolder; + final bool isActionRequiredFolder; final _responsiveUtils = Get.find(); final _imagePaths = Get.find(); @@ -24,6 +25,7 @@ class EmptyEmailsWidget extends StatelessWidget { this.isFilterMessageActive = false, this.isNetworkConnectionAvailable = true, this.isFavoriteFolder = false, + this.isActionRequiredFolder = false, }) : super(key: key); @override @@ -82,9 +84,9 @@ class EmptyEmailsWidget extends StatelessWidget { if (isFilterMessageActive) return false; final showNetwork = isNetworkConnectionAvailable && !isSearchActive; - final showFavorite = isFavoriteFolder; + final isVirtualFolder = isFavoriteFolder || isActionRequiredFolder; - return showNetwork || showFavorite; + return showNetwork || isVirtualFolder; } String _getMessageEmptyEmail(AppLocalizations appLocalizations) { @@ -98,6 +100,8 @@ class EmptyEmailsWidget extends StatelessWidget { return appLocalizations.noEmailMatchYourCurrentFilter; } else if (isFavoriteFolder) { return appLocalizations.youDoNotHaveAnyFavoritesEmails; + } else if (isActionRequiredFolder) { + return appLocalizations.youDoNotHaveAnyActionRequiredEmails; } else { return appLocalizations.youDoNotHaveAnyEmailInYourCurrentFolder; } diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 192bcf0ac..bc29c9021 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2025-12-16T15:21:10.099014", + "@@last_modified": "2025-12-17T00:04:15.124514", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -5147,5 +5147,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "youDoNotHaveAnyActionRequiredEmails": "You don’t have any action required emails.", + "@youDoNotHaveAnyActionRequiredEmails": { + "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 547fab260..20fff982b 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -5471,4 +5471,11 @@ class AppLocalizations { name: 'actionRequiredMailboxDisplayName', ); } + + String get youDoNotHaveAnyActionRequiredEmails { + return Intl.message( + 'You don’t have any action required emails.', + name: 'youDoNotHaveAnyActionRequiredEmails', + ); + } } diff --git a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart index cb4ffe6a6..f786db1b7 100644 --- a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart +++ b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart @@ -57,7 +57,6 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_in import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart'; @@ -170,7 +169,6 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), - MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(), MockSpec(), MockSpec(), @@ -247,7 +245,6 @@ void main() { final appGridDashboardController = MockAppGridDashboardController(); final spamReportController = MockSpamReportController(); final networkConnectionController = MockNetworkConnectionController(); - final actionRequiredFolderController = MockActionRequiredFolderController(); // mock search controller direct dependencies final quickSearchEmailInteractor = MockQuickSearchEmailInteractor(); @@ -330,7 +327,6 @@ void main() { Get.put(appGridDashboardController); Get.put(spamReportController); Get.put(networkConnectionController); - Get.put(actionRequiredFolderController); Get.put(cachingManager); Get.put(languageCacheManager); Get.put(authorizationInterceptors); diff --git a/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart b/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart index 261b8eb61..e96daf350 100644 --- a/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart +++ b/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart @@ -54,7 +54,6 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_in import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart'; @@ -171,7 +170,6 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), - MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(), MockSpec(), MockSpec(), @@ -238,7 +236,6 @@ void main() { final appGridDashboardController = MockAppGridDashboardController(); final spamReportController = MockSpamReportController(); final networkConnectionController = MockNetworkConnectionController(); - final actionRequiredFolderController = MockActionRequiredFolderController(); final quickSearchEmailInteractor = MockQuickSearchEmailInteractor(); final saveRecentSearchInteractor = MockSaveRecentSearchInteractor(); @@ -326,7 +323,6 @@ void main() { Get.put(appGridDashboardController); Get.put(spamReportController); Get.put(networkConnectionController); - Get.put(actionRequiredFolderController); Get.put(cachingManager); Get.put(languageCacheManager); Get.put(authorizationInterceptors); diff --git a/test/features/search/verify_before_time_in_search_email_filter_test.dart b/test/features/search/verify_before_time_in_search_email_filter_test.dart index f434aa5b9..458cbb533 100644 --- a/test/features/search/verify_before_time_in_search_email_filter_test.dart +++ b/test/features/search/verify_before_time_in_search_email_filter_test.dart @@ -54,7 +54,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_email_sort_order_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/download_ui_action.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/action_required_folder_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; import 'package:tmail_ui_user/features/download/presentation/controllers/download_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; @@ -141,7 +140,6 @@ const fallbackGenerators = { MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(fallbackGenerators: fallbackGenerators), - MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(), MockSpec(), MockSpec(), @@ -209,7 +207,6 @@ void main() { final MockAppGridDashboardController appGridDashboardController = MockAppGridDashboardController(); final MockSpamReportController spamReportController = MockSpamReportController(); final MockNetworkConnectionController networkConnectionController = MockNetworkConnectionController(); - final MockActionRequiredFolderController actionRequiredFolderController = MockActionRequiredFolderController(); final composerManager = MockComposerManager(); late MailboxDashBoardController mailboxDashboardController; @@ -356,7 +353,6 @@ void main() { Get.put(appGridDashboardController); Get.put(spamReportController); Get.put(networkConnectionController); - Get.put(actionRequiredFolderController); Get.put(getSessionInteractor); Get.put(getAuthenticatedAccountInteractor); Get.put(updateAccountCacheInteractor);