From 0556445f9774d751a952cdf76c78326d7a8f7440 Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Wed, 31 May 2023 21:56:10 +0700 Subject: [PATCH] TF-1842: Trigger `handleBackgroundTask` when finish task on `WorkObserver` (cherry picked from commit 36c2826c1d84d76fc76dda278b4d1ef33ecab2b1) --- .../controller/work_scheduler_controller.dart | 10 ++-- .../observer/sending_email_observer.dart | 59 ++++++++++++------- .../offline_mode/observer/work_observer.dart | 6 +- lib/main/localizations/app_localizations.dart | 7 +++ 4 files changed, 56 insertions(+), 26 deletions(-) diff --git a/lib/features/offline_mode/controller/work_scheduler_controller.dart b/lib/features/offline_mode/controller/work_scheduler_controller.dart index e110e32f3..0193e3f10 100644 --- a/lib/features/offline_mode/controller/work_scheduler_controller.dart +++ b/lib/features/offline_mode/controller/work_scheduler_controller.dart @@ -1,4 +1,4 @@ - +import 'dart:async'; import 'package:collection/collection.dart'; import 'package:core/utils/app_logger.dart'; import 'package:tmail_ui_user/features/offline_mode/config/work_manager_constants.dart'; @@ -54,6 +54,7 @@ class WorkSchedulerController { } Future handleBackgroundTask(String taskName, Map? inputData) async { + final completer = Completer(); log('WorkSchedulerController::handleBackgroundTask():taskName: $taskName | inputData: $inputData'); try { if (inputData != null && inputData.isNotEmpty) { @@ -63,14 +64,15 @@ class WorkSchedulerController { final matchedType = WorkerType.values.firstWhereOrNull((type) => type.name == workerType); if (matchedType != null) { - await matchedType.usingObserver().bindDI(); - await matchedType.usingObserver().observe(taskName, dataObject); + await matchedType.usingObserver().bindDI(completer); + await matchedType.usingObserver().observe(taskName, dataObject, completer); } } } catch (e) { + completer.completeError(e); logError('WorkSchedulerController::handleBackgroundTask():EXCEPTION: $e'); } - return Future.value(true); + return completer.future; } Future cancelByWorkType(WorkerType type) => Workmanager().cancelByTag(type.name); diff --git a/lib/features/offline_mode/observer/sending_email_observer.dart b/lib/features/offline_mode/observer/sending_email_observer.dart index cc0ad6453..449101c59 100644 --- a/lib/features/offline_mode/observer/sending_email_observer.dart +++ b/lib/features/offline_mode/observer/sending_email_observer.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'package:core/data/network/config/dynamic_url_interceptors.dart'; import 'package:core/presentation/extensions/uri_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; @@ -6,14 +7,17 @@ import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/utils/app_toast.dart'; import 'package:core/utils/app_logger.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:model/oidc/token_oidc.dart'; import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart'; import 'package:tmail_ui_user/features/composer/domain/extensions/sending_email_extension.dart'; import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart'; +import 'package:tmail_ui_user/features/email/domain/state/delete_sending_email_state.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/delete_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/home/presentation/home_bindings.dart'; import 'package:tmail_ui_user/features/login/data/network/config/authorization_interceptors.dart'; @@ -37,6 +41,7 @@ class SendingEmailObserver extends WorkObserver { Session? _currentSession; UserName? _userName; SendingEmail? _sendingEmail; + EmailId? _emailId; AppToast? _appToast; ImagePaths? _imagePaths; @@ -47,6 +52,8 @@ class SendingEmailObserver extends WorkObserver { GetSessionInteractor? _getSessionInteractor; DeleteSendingEmailInteractor? _deleteSendingEmailInteractor; + Completer? _completer; + static SendingEmailObserver? _instance; SendingEmailObserver._(); @@ -54,16 +61,17 @@ class SendingEmailObserver extends WorkObserver { factory SendingEmailObserver() => _instance ??= SendingEmailObserver._(); @override - Future observe(String taskId, Map inputData) async { + Future observe(String taskId, Map inputData, Completer completer) async { log('SendingEmailObserver::observe():taskId: $taskId | inputData: $inputData'); + _completer = completer; _sendingEmail = SendingEmail.fromJson(inputData); - log('SendingEmailObserver::observe():_sendingEmail: $_sendingEmail'); + _emailId = EmailId(Id(taskId)); + log('SendingEmailObserver::observe():_sendingEmail: $_sendingEmail | EmailId: $_emailId'); _getAuthenticatedAccount(); - return Future.value(); } @override - Future bindDI() async { + Future bindDI(Completer completer) async { return await _initialAppConfig(); } @@ -102,10 +110,12 @@ class SendingEmailObserver extends WorkObserver { _handleGetAccountByBasicAuthSuccess(success); } else if (success is SendEmailSuccess) { _handleSendEmailSuccess(success); + } else if (success is DeleteSendingEmailSuccess) { + _handleDeleteSendingEmailSuccess(); } } - Future _getInteractorBindings() { + Future _getInteractorBindings() async { try { _getAuthenticatedAccountInteractor = getBinding(); _dynamicUrlInterceptors = getBinding(); @@ -117,8 +127,9 @@ class SendingEmailObserver extends WorkObserver { _deleteSendingEmailInteractor = getBinding(); } catch (e) { logError('SendingEmailObserver::_getInteractorBindings(): ${e.toString()}'); + return _completer?.completeError(false); } - return Future.value(null); + return _completer?.complete(true); } void _handleGetAuthenticatedAccountSuccess(GetAuthenticatedAccountSuccess success) { @@ -139,7 +150,7 @@ class SendingEmailObserver extends WorkObserver { void _getAuthenticatedAccount() { if (_getAuthenticatedAccountInteractor != null) { - consumeState(_getAuthenticatedAccountInteractor!.execute(needToReopen: true)); + consumeState(_getAuthenticatedAccountInteractor!.execute()); } else { _clearDataQueue(); logError('SendingEmailObserver::_getAuthenticatedAccount():_getAuthenticatedAccountInteractor is null'); @@ -151,8 +162,8 @@ class SendingEmailObserver extends WorkObserver { _userName = success.session.username; final jmapUrl = _dynamicUrlInterceptors?.jmapUrl; final apiUrl = jmapUrl != null - ? success.session.apiUrl.toQualifiedUrl(baseUrl: Uri.parse(jmapUrl)).toString() - : success.session.apiUrl.toString(); + ? success.session.apiUrl.toQualifiedUrl(baseUrl: Uri.parse(jmapUrl)).toString() + : success.session.apiUrl.toString(); log('SendingEmailObserver::_handleGetSessionSuccess():jmapUrl: $jmapUrl | apiUrl: $apiUrl'); if (apiUrl.isNotEmpty) { _dynamicUrlInterceptors?.changeBaseUrl(apiUrl); @@ -176,16 +187,17 @@ class SendingEmailObserver extends WorkObserver { void _sendEmailAction() { log('SendingEmailObserver::_sendEmailAction()'); + + final mailboxRequestNotNull = _sendingEmail?.mailboxNameRequest != null && _sendingEmail?.creationIdRequest != null; + if (_sendEmailInteractor != null && _sendingEmail != null && _currentSession != null && _currentAccountId != null) { consumeState(_sendEmailInteractor!.execute( _currentSession!, _currentAccountId!, _sendingEmail!.toEmailRequest(), - mailboxRequest: CreateNewMailboxRequest( - _sendingEmail!.creationIdRequest!, - _sendingEmail!.mailboxNameRequest!, - isSubscribed: true, - ) + mailboxRequest: mailboxRequestNotNull + ? CreateNewMailboxRequest(_sendingEmail!.creationIdRequest!, _sendingEmail!.mailboxNameRequest!) + : null )); } else { logError('SendingEmailObserver::_sendEmailAction():_sendEmailInteractor is null'); @@ -204,29 +216,36 @@ class SendingEmailObserver extends WorkObserver { _getSessionAction(); } - void _handleSendEmailSuccess(SendEmailSuccess success) { + void _handleSendEmailSuccess(SendEmailSuccess success) async { + log("SendingEmailObserver::_handleSendEmailSuccess()"); + _deleteSendingEmailAction(); if (currentOverlayContext != null && currentContext != null) { _appToast?.showToastSuccessMessage( currentOverlayContext!, - AppLocalizations.of(currentContext!).message_has_been_sent_successfully, + AppLocalizations.of(currentContext!).messageHasBeenSentSuccessfully, leadingSVGIcon: _imagePaths?.icSendSuccessToast); - _deleteSendingEmailAction(); } } void _deleteSendingEmailAction() { - if (_deleteSendingEmailInteractor != null && _currentSession != null && _currentAccountId != null && _sendingEmail != null) { + if (_deleteSendingEmailInteractor != null && _currentSession != null && _currentAccountId != null && _emailId != null) { consumeState(_deleteSendingEmailInteractor!.execute( _currentAccountId!, _currentSession!.username, - _sendingEmail!.email.id!, + _emailId!, )); } else { logError('SendingEmailObserver::_deleteSendingEmailAction():_deleteSendingEmailInteractor is null'); } } - void _clearDataQueue() { + void _handleDeleteSendingEmailSuccess() async { + log('SendingEmailObserver::_handleDeleteSendingEmailSuccess(): Success'); + return _completer?.complete(true); + } + + void _clearDataQueue() async { _sendingEmail = null; + return _completer?.completeError(false); } } \ No newline at end of file diff --git a/lib/features/offline_mode/observer/work_observer.dart b/lib/features/offline_mode/observer/work_observer.dart index 33a3c1c9b..3c1265745 100644 --- a/lib/features/offline_mode/observer/work_observer.dart +++ b/lib/features/offline_mode/observer/work_observer.dart @@ -1,13 +1,15 @@ +import 'dart:async'; + import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:core/utils/app_logger.dart'; import 'package:dartz/dartz.dart'; abstract class WorkObserver { - Future bindDI(); + Future bindDI(Completer completer); - Future observe(String taskId, Map inputData); + Future observe(String taskId, Map inputData, Completer completer); void consumeState(Stream> newStateStream) { newStateStream.listen( diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 08108ac9b..7358484b2 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -2946,4 +2946,11 @@ class AppLocalizations { name: 'openMailboxMenu' ); } + + String get messageHasBeenSentSuccessfully { + return Intl.message( + 'Message has been sent successfully.', + name: 'messageHasBeenSentSuccessfully', + ); + } } \ No newline at end of file