diff --git a/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart index 57c3639f5..76fd69258 100644 --- a/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart @@ -254,9 +254,9 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource { } @override - Future> getAllSendingEmails(AccountId accountId, UserName userName) { + Future> getAllSendingEmails(AccountId accountId, UserName userName, {bool needToReopen = false}) { return Future.sync(() async { - final sendingEmailsCache = await _sendingEmailCacheManager.getAllSendingEmails(accountId, userName); + final sendingEmailsCache = await _sendingEmailCacheManager.getAllSendingEmails(accountId, userName, needToReopen: needToReopen); return sendingEmailsCache.toSendingEmails(); }).catchError(_exceptionThrower.throwException); } 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 b986fca5e..a723d9a1b 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -443,7 +443,7 @@ class MailboxDashBoardController extends ReloadableController { _getVacationResponse(); spamReportController.getSpamReportStateAction(); if (PlatformInfo.isMobile) { - _getAllSendingEmails(); + getAllSendingEmails(); } if (!BuildUtils.isWeb && !_notificationManager.isNotificationClickedOnTerminate) { _handleClickLocalNotificationOnTerminated(); @@ -1225,7 +1225,7 @@ class MailboxDashBoardController extends ReloadableController { _getVacationResponse(); spamReportController.getSpamReportStateAction(); if (PlatformInfo.isMobile) { - _getAllSendingEmails(); + getAllSendingEmails(); } } @@ -1830,7 +1830,7 @@ class MailboxDashBoardController extends ReloadableController { } _addSendingEmailToSendingQueue(success.sendingEmail); - _getAllSendingEmails(); + getAllSendingEmails(); } void _addSendingEmailToSendingQueue(SendingEmail sendingEmail) async { @@ -1853,12 +1853,13 @@ class MailboxDashBoardController extends ReloadableController { } } - void _getAllSendingEmails() { + void getAllSendingEmails({bool needToReopen = false}) { if (accountId.value != null && sessionCurrent != null) { - log('MailboxDashBoardController::_getAllSendingEmails():accountId: ${accountId.value} | userName: ${sessionCurrent?.username}'); + log('MailboxDashBoardController::getAllSendingEmails():accountId: ${accountId.value} | userName: ${sessionCurrent?.username}'); consumeState(_getAllSendingEmailInteractor.execute( accountId.value!, - sessionCurrent!.username + sessionCurrent!.username, + needToReopen: needToReopen )); } } @@ -1866,6 +1867,15 @@ class MailboxDashBoardController extends ReloadableController { void _handleGetAllSendingEmailsSuccess(GetAllSendingEmailSuccess success) { log('MailboxDashBoardController::_handleGetAllSendingEmailsSuccess():COUNT: ${success.sendingEmails.length}'); listSendingEmails.value = success.sendingEmails; + + if (success.sendingEmails.isEmpty && dashboardRoute.value == DashboardRoutes.sendingQueue) { + _openDefaultMailbox(); + } + } + + void _openDefaultMailbox() { + dispatchRoute(DashboardRoutes.thread); + dispatchMailboxUIAction(SelectMailboxDefaultAction()); } @override diff --git a/lib/features/offline_mode/exceptions/workmanager_exception.dart b/lib/features/offline_mode/exceptions/workmanager_exception.dart index b765fad07..d3d8e7901 100644 --- a/lib/features/offline_mode/exceptions/workmanager_exception.dart +++ b/lib/features/offline_mode/exceptions/workmanager_exception.dart @@ -1 +1,3 @@ -class SendingEmailFromWorkmanagerException implements Exception {} \ No newline at end of file +class UnableToGetDataFromInWorkManagerException implements Exception {} + +class UnableBindingInWorkManagerException implements Exception {} \ No newline at end of file diff --git a/lib/features/offline_mode/manager/sending_email_cache_manager.dart b/lib/features/offline_mode/manager/sending_email_cache_manager.dart index a7087b133..5e488b035 100644 --- a/lib/features/offline_mode/manager/sending_email_cache_manager.dart +++ b/lib/features/offline_mode/manager/sending_email_cache_manager.dart @@ -24,8 +24,15 @@ class SendingEmailCacheManager { return _hiveCacheClient.insertItem(keyCache, sendingEmailHiveCache); } - Future> getAllSendingEmails(AccountId accountId, UserName userName) async { - final sendingEmailsCache = await _hiveCacheClient.getListByTupleKey(accountId.asString, userName.value); + Future> getAllSendingEmails( + AccountId accountId, + UserName userName, + {bool needToReopen = false} + ) async { + final sendingEmailsCache = await _hiveCacheClient.getListByTupleKey( + accountId.asString, + userName.value, + needToReopen: needToReopen); log('SendingEmailCacheManager::getAllSendingEmails():COUNT: ${sendingEmailsCache.length}'); sendingEmailsCache.sortByLatestTime(); return sendingEmailsCache; diff --git a/lib/features/offline_mode/observer/sending_email_observer.dart b/lib/features/offline_mode/observer/sending_email_observer.dart index ca459cabe..a4c40c400 100644 --- a/lib/features/offline_mode/observer/sending_email_observer.dart +++ b/lib/features/offline_mode/observer/sending_email_observer.dart @@ -26,8 +26,10 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/m import 'package:tmail_ui_user/features/offline_mode/biding/sending_email_biding.dart'; import 'package:tmail_ui_user/features/offline_mode/exceptions/workmanager_exception.dart'; import 'package:tmail_ui_user/features/offline_mode/observer/work_observer.dart'; +import 'package:tmail_ui_user/features/offline_mode/scheduler/worker_state.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_config.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_manager.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart'; import 'package:tmail_ui_user/features/session/domain/state/get_session_state.dart'; import 'package:tmail_ui_user/features/session/domain/usecases/get_session_interactor.dart'; import 'package:tmail_ui_user/main/bindings/main_bindings.dart'; @@ -46,6 +48,7 @@ class SendingEmailObserver extends WorkObserver { AuthorizationInterceptors? _authorizationInterceptors; GetSessionInteractor? _getSessionInteractor; DeleteSendingEmailInteractor? _deleteSendingEmailInteractor; + SendingQueueIsolateManager? _sendingQueueIsolateManager; Completer? _completer; @@ -115,9 +118,10 @@ class SendingEmailObserver extends WorkObserver { _getSessionInteractor = getBinding(); _sendEmailInteractor = getBinding(); _deleteSendingEmailInteractor = getBinding(); + _sendingQueueIsolateManager = getBinding(); } catch (e) { logError('SendingEmailObserver::_getInteractorBindings(): ${e.toString()}'); - return _completer?.completeError(false); + _completer?.completeError(UnableBindingInWorkManagerException()); } } @@ -227,12 +231,15 @@ class SendingEmailObserver extends WorkObserver { void _handleDeleteSendingEmailSuccess() async { log('SendingEmailObserver::_handleDeleteSendingEmailSuccess(): Success'); _showLocalNotification(); - return _completer?.complete(true); + _sendingQueueIsolateManager?.addEvent(WorkerState.success.name); + _completer?.complete(true); } void _clearDataQueue() async { + log('SendingEmailObserver::_clearDataQueue():'); _sendingEmail = null; - _completer?.completeError(SendingEmailFromWorkmanagerException()); + _sendingQueueIsolateManager?.addEvent(WorkerState.failed.name); + _completer?.completeError(UnableToGetDataFromInWorkManagerException()); } void _showLocalNotification() { diff --git a/lib/features/offline_mode/scheduler/worker_state.dart b/lib/features/offline_mode/scheduler/worker_state.dart new file mode 100644 index 000000000..a5ba60cf9 --- /dev/null +++ b/lib/features/offline_mode/scheduler/worker_state.dart @@ -0,0 +1,5 @@ + +enum WorkerState { + success, + failed; +} \ No newline at end of file diff --git a/lib/features/sending_queue/data/repository/sending_queue_repository_impl.dart b/lib/features/sending_queue/data/repository/sending_queue_repository_impl.dart index c155935f9..97c1eb8a3 100644 --- a/lib/features/sending_queue/data/repository/sending_queue_repository_impl.dart +++ b/lib/features/sending_queue/data/repository/sending_queue_repository_impl.dart @@ -11,7 +11,7 @@ class SendingQueueRepositoryImpl extends SendingQueueRepository { SendingQueueRepositoryImpl(this._emailHiveCacheDataSourceImpl); @override - Future> getAllSendingEmails(AccountId accountId, UserName userName) { - return _emailHiveCacheDataSourceImpl.getAllSendingEmails(accountId, userName); + Future> getAllSendingEmails(AccountId accountId, UserName userName, {bool needToReopen = false}) { + return _emailHiveCacheDataSourceImpl.getAllSendingEmails(accountId, userName, needToReopen: needToReopen); } } \ No newline at end of file diff --git a/lib/features/sending_queue/domain/repository/sending_queue_repository.dart b/lib/features/sending_queue/domain/repository/sending_queue_repository.dart index c55163faa..c9da2fef6 100644 --- a/lib/features/sending_queue/domain/repository/sending_queue_repository.dart +++ b/lib/features/sending_queue/domain/repository/sending_queue_repository.dart @@ -4,5 +4,5 @@ import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; abstract class SendingQueueRepository { - Future> getAllSendingEmails(AccountId accountId, UserName userName); + Future> getAllSendingEmails(AccountId accountId, UserName userName, {bool needToReopen = false}); } \ No newline at end of file diff --git a/lib/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart b/lib/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart index ad2e1bf9b..0f590fbdd 100644 --- a/lib/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart +++ b/lib/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart @@ -11,10 +11,10 @@ class GetAllSendingEmailInteractor { GetAllSendingEmailInteractor(this._sendingQueueRepository); - Stream> execute(AccountId accountId, UserName userName) async* { + Stream> execute(AccountId accountId, UserName userName, {bool needToReopen = false}) async* { try { yield Right(GetAllSendingEmailLoading()); - final sendingEmails = await _sendingQueueRepository.getAllSendingEmails(accountId, userName); + final sendingEmails = await _sendingQueueRepository.getAllSendingEmails(accountId, userName, needToReopen: needToReopen); yield Right(GetAllSendingEmailSuccess(sendingEmails)); } catch (e) { yield Left(GetAllSendingEmailFailure(e)); diff --git a/lib/features/sending_queue/presentation/sending_queue_controller.dart b/lib/features/sending_queue/presentation/sending_queue_controller.dart index 13c54bb0c..bf1f45397 100644 --- a/lib/features/sending_queue/presentation/sending_queue_controller.dart +++ b/lib/features/sending_queue/presentation/sending_queue_controller.dart @@ -1,22 +1,54 @@ +import 'package:collection/collection.dart'; +import 'package:core/utils/app_logger.dart'; import 'package:flutter/cupertino.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/offline_mode/scheduler/worker_state.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; class SendingQueueController extends BaseController { final dashboardController = getBinding(); + final sendingQueueIsolateManager = getBinding(); final listSendingEmailController = ScrollController(); + @override + void onInit() { + super.onInit(); + sendingQueueIsolateManager?.initial( + onData: _handleSendingQueueEvent, + onError: (error, stackTrace) { + logError('SendingQueueController::onInit():onError:error: $error | stackTrace: $stackTrace'); + } + ); + } + + void _handleSendingQueueEvent(Object? event) { + log('SendingQueueController::_handleSendingQueueEvent():event: $event'); + if (event is String) { + final workState = WorkerState.values.firstWhereOrNull((state) => state.name == event); + log('SendingQueueController::_handleSendingQueueEvent():workState: $workState'); + if (workState != null) { + _refreshSendingQueue(needToReopen: true); + } + } + } + + void _refreshSendingQueue({bool needToReopen = false}) { + dashboardController?.getAllSendingEmails(needToReopen: needToReopen); + } + void openMailboxMenu() { - dashboardController!.openMailboxMenuDrawer(); + dashboardController?.openMailboxMenuDrawer(); } @override void onClose() { listSendingEmailController.dispose(); + sendingQueueIsolateManager?.release(); super.onClose(); } } \ No newline at end of file diff --git a/lib/main/bindings/core/core_bindings.dart b/lib/main/bindings/core/core_bindings.dart index 77a61cdfb..f1aa7fd88 100644 --- a/lib/main/bindings/core/core_bindings.dart +++ b/lib/main/bindings/core/core_bindings.dart @@ -5,10 +5,12 @@ import 'package:core/presentation/utils/app_toast.dart'; import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/utils/config/app_config_loader.dart'; import 'package:core/utils/file_utils.dart'; +import 'package:core/utils/platform_info.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart'; import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; import 'package:uuid/uuid.dart'; @@ -24,6 +26,7 @@ class CoreBindings extends Bindings { _bindingDeviceManager(); _bindingReceivingSharingStream(); _bindingUtils(); + _bindingIsolate(); } void _bindingAppImagePaths() { @@ -61,4 +64,10 @@ class CoreBindings extends Bindings { Get.put(AppConfigLoader()); Get.put(FileUtils()); } + + void _bindingIsolate() { + if (PlatformInfo.isMobile) { + Get.put(SendingQueueIsolateManager()); + } + } } \ No newline at end of file