TF-1915 SendingState of SendingEmail updates according to the work done in WorkManager when network connectivity is restored

(cherry picked from commit 744c8bc8dc8a82cb3afb75aead5a744adaae5501)
This commit is contained in:
dab246
2023-06-09 15:23:22 +07:00
committed by Dat Vu
parent 20168f5e8d
commit 6aa87ff012
51 changed files with 523 additions and 374 deletions
+1 -1
View File
@@ -116,7 +116,7 @@ class CachingManager {
}
Future<void> _clearSendingEmailCache() async {
final listSendingEmails = await _sendingEmailCacheManager.getAllSendingEmails();
final listSendingEmails = await _sendingEmailCacheManager.getAllSendingEmails(needToReopen: true);
final sendingIds = listSendingEmails.map((sendingEmail) => sendingEmail.sendingId).toSet().toList();
if (sendingIds.isNotEmpty) {
await Future.wait(
@@ -131,8 +131,12 @@ abstract class HiveCacheClient<T> {
});
}
Future<void> deleteItem(String key) {
Future<void> deleteItem(String key, {bool needToReopen = false}) {
return Future.sync(() async {
if (needToReopen) {
await closeBox();
}
final boxItem = encryption
? await openBoxEncryption()
: await openBox();
@@ -1,7 +1,7 @@
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
extension EmailRequestExtension on EmailRequest {
SendingEmail toSendingEmail(String sendingId, {CreateNewMailboxRequest? mailboxRequest}) {
@@ -13,6 +13,7 @@ class EmailRequest with EquatableMixin {
final EmailId? emailIdAnsweredOrForwarded;
final IdentityId? identityId;
final EmailActionType emailActionType;
final String? storedSendingId;
EmailRequest({
required this.email,
@@ -21,6 +22,7 @@ class EmailRequest with EquatableMixin {
this.identityId,
this.emailIdDestroyed,
this.emailIdAnsweredOrForwarded,
this.storedSendingId,
});
@override
@@ -30,7 +32,8 @@ class EmailRequest with EquatableMixin {
identityId,
emailIdDestroyed,
emailIdAnsweredOrForwarded,
emailActionType
emailActionType,
storedSendingId,
];
bool get isEmailAnswered => emailIdAnsweredOrForwarded != null &&
@@ -1,13 +1,9 @@
import 'package:core/core.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:tmail_ui_user/features/base/state/ui_action_state.dart';
class SendingEmailState extends UIState {
SendingEmailState();
@override
List<Object?> get props => [];
}
class SendEmailLoading extends UIState {}
class SendEmailSuccess extends UIActionState {
@@ -21,9 +17,8 @@ class SendEmailSuccess extends UIActionState {
}
class SendEmailFailure extends FeatureFailure {
final dynamic exception;
SendEmailFailure(this.exception);
SendEmailFailure(dynamic exception) : super(exception: exception);
@override
List<Object?> get props => [exception];
@@ -22,7 +22,7 @@ class SendEmailInteractor {
{CreateNewMailboxRequest? mailboxRequest}
) async* {
try {
yield Right<Failure, Success>(SendingEmailState());
yield Right<Failure, Success>(SendEmailLoading());
final listState = await Future.wait([
_mailboxRepository.getMailboxState(session, accountId),
@@ -33,7 +33,6 @@ import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:rich_text_composer/rich_text_composer.dart';
import 'package:super_tag_editor/tag_editor.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/composer/domain/extensions/sending_email_extension.dart';
import 'package:tmail_ui_user/features/composer/domain/model/contact_suggestion_source.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/state/download_image_as_base64_state.dart';
@@ -49,7 +48,6 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/email_ac
import 'package:tmail_ui_user/features/composer/presentation/model/image_source.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/inline_image.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/sending_email_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
@@ -61,6 +59,9 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_ident
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/identity_extension.dart';
import 'package:tmail_ui_user/features/network_status_handle/presentation/network_connnection_controller.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/extensions/sending_email_extension.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_arguments.dart';
import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
import 'package:tmail_ui_user/features/upload/domain/state/attachment_upload_state.dart';
import 'package:tmail_ui_user/features/upload/domain/state/local_file_picker_state.dart';
@@ -615,8 +616,7 @@ class ComposerController extends BaseController {
{
bool asDrafts = false,
MailboxId? draftMailboxId,
MailboxId? outboxMailboxId,
ComposerArguments? arguments
MailboxId? outboxMailboxId
}
) async {
Set<EmailAddress> listFromEmailAddress = {EmailAddress(null, userProfile.email)};
@@ -663,10 +663,7 @@ class ComposerController extends BaseController {
final generatePartId = PartId(_uuid.v1());
final isUpdateSendingEmail = arguments?.sendingEmail != null;
return Email(
id: isUpdateSendingEmail ? EmailId(Id(arguments!.sendingEmail!.sendingId)) : null,
mailboxIds: mailboxIds.isNotEmpty ? mailboxIds : null,
from: listFromEmailAddress,
to: listToEmailAddress.toSet(),
@@ -804,11 +801,11 @@ class ComposerController extends BaseController {
final userProfile = mailboxDashBoardController.userProfile.value;
if (arguments != null && accountId != null && userProfile != null && session != null) {
final email = await _generateEmail(context, userProfile, outboxMailboxId: outboxMailboxId, arguments: arguments);
final createdEmail = await _generateEmail(context, userProfile, outboxMailboxId: outboxMailboxId);
final emailRequest = arguments.sendingEmail != null
? arguments.sendingEmail!.toEmailRequest(emailEdit: email)
? arguments.sendingEmail!.toEmailRequest(newEmail: createdEmail)
: EmailRequest(
email: email,
email: createdEmail,
sentMailboxId: sentMailboxId,
identityId: identitySelected.value?.id,
emailIdDestroyed: arguments.emailActionType == EmailActionType.edit
@@ -826,7 +823,9 @@ class ComposerController extends BaseController {
accountId,
emailRequest,
mailboxRequest,
isUpdateSendingEmail: arguments.sendingEmail != null,
sendingEmailActionType: arguments.sendingEmail != null
? SendingEmailActionType.edit
: SendingEmailActionType.create,
);
uploadController.clearInlineFileUploaded();
@@ -16,10 +16,10 @@ import 'package:model/email/attachment.dart';
import 'package:model/email/mark_star_action.dart';
import 'package:model/email/read_actions.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
abstract class EmailDataSource {
Future<Email> getEmailContent(Session session, AccountId accountId, EmailId emailId);
@@ -90,9 +90,9 @@ abstract class EmailDataSource {
Future<DetailedEmail?> getIncomingEmailedStored(Session session, AccountId accountId, EmailId emailId);
Future<void> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail);
Future<SendingEmail> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail);
Future<void> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail);
Future<SendingEmail> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail newSendingEmail);
Future<List<SendingEmail>> getAllSendingEmails(AccountId accountId, UserName userName);
@@ -12,12 +12,12 @@ import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
class EmailDataSourceImpl extends EmailDataSource {
@@ -190,7 +190,7 @@ class EmailDataSourceImpl extends EmailDataSource {
}
@override
Future<void> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail) {
Future<SendingEmail> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail) {
throw UnimplementedError();
}
@@ -205,7 +205,7 @@ class EmailDataSourceImpl extends EmailDataSource {
}
@override
Future<void> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail) {
Future<SendingEmail> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail newSendingEmail) {
throw UnimplementedError();
}
}
@@ -21,9 +21,7 @@ import 'package:model/email/mark_star_action.dart';
import 'package:model/email/read_actions.dart';
import 'package:model/extensions/email_id_extensions.dart';
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
import 'package:tmail_ui_user/features/composer/domain/extensions/sending_email_extension.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
import 'package:tmail_ui_user/features/email/domain/extensions/detailed_email_extension.dart';
import 'package:tmail_ui_user/features/email/domain/extensions/detailed_email_hive_cache_extension.dart';
@@ -31,11 +29,14 @@ import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/offline_mode/extensions/list_sending_email_hive_cache_extension.dart';
import 'package:tmail_ui_user/features/offline_mode/extensions/sending_email_hive_cache_extension.dart';
import 'package:tmail_ui_user/features/offline_mode/hive_worker/hive_task.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/extensions/sending_email_extension.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/email_cache_extension.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/email_extension.dart';
@@ -247,9 +248,10 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
}
@override
Future<void> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail) {
Future<SendingEmail> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail) {
return Future.sync(() async {
return await _sendingEmailCacheManager.storeSendingEmail(accountId, userName, sendingEmail.toHiveCache());
final sendingEmailsCache = await _sendingEmailCacheManager.storeSendingEmail(accountId, userName, sendingEmail.toHiveCache());
return sendingEmailsCache.toSendingEmail();
}).catchError(_exceptionThrower.throwException);
}
@@ -262,16 +264,17 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
}
@override
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId) {
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId, {bool needToReopen = false}) {
return Future.sync(() async {
return await _sendingEmailCacheManager.deleteSendingEmail(accountId, userName, sendingId);
return await _sendingEmailCacheManager.deleteSendingEmail(accountId, userName, sendingId, needToReopen: needToReopen);
}).catchError(_exceptionThrower.throwException);
}
@override
Future<void> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail) {
Future<SendingEmail> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail newSendingEmail, {bool needToReopen = false}) {
return Future.sync(() async {
return await _sendingEmailCacheManager.updateSendingEmail(accountId, userName, sendingEmail.toHiveCache());
final sendingEmailsCache = await _sendingEmailCacheManager.updateSendingEmail(accountId, userName, newSendingEmail.toHiveCache(), needToReopen: needToReopen);
return sendingEmailsCache.toSendingEmail();
}).catchError(_exceptionThrower.throwException);
}
}
@@ -11,7 +11,6 @@ import 'package:dio/dio.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/account/account_request.dart';
import 'package:model/download/download_task_id.dart';
@@ -20,7 +19,6 @@ import 'package:model/email/email_content.dart';
import 'package:model/email/mark_star_action.dart';
import 'package:model/email/read_actions.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
@@ -221,28 +219,4 @@ class EmailRepositoryImpl extends EmailRepository {
Future<Email?> getEmailStored(Session session, AccountId accountId, EmailId emailId) {
return emailDataSource[DataSourceType.hiveCache]!.getEmailStored(session, accountId, emailId);
}
@override
Future<void> storeSendingEmail(
AccountId accountId,
UserName userName,
SendingEmail sendingEmail
) {
return emailDataSource[DataSourceType.hiveCache]!.storeSendingEmail(accountId, userName, sendingEmail);
}
@override
Future<void> updateSendingEmail(
AccountId accountId,
UserName userName,
SendingEmail sendingEmail
) async {
return emailDataSource[DataSourceType.hiveCache]!.updateSendingEmail(accountId, userName, sendingEmail);
}
@override
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId) {
return emailDataSource[DataSourceType.hiveCache]!.deleteSendingEmail(accountId, userName, sendingId);
}
}
@@ -8,7 +8,6 @@ import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:jmap_dart_client/jmap/account_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:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:model/account/account_request.dart';
@@ -18,7 +17,6 @@ import 'package:model/email/email_content.dart';
import 'package:model/email/mark_star_action.dart';
import 'package:model/email/read_actions.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
@@ -101,10 +99,4 @@ abstract class EmailRepository {
Future<void> storeOpenedEmail(Session session, AccountId accountId, DetailedEmail detailedEmail);
Future<DetailedEmail?> getOpenedEmail(Session session, AccountId accountId, EmailId emailId);
Future<void> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail);
Future<void> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail);
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId);
}
@@ -1,7 +1,7 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
class StoreSendingEmailLoading extends UIState {}
@@ -1,28 +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/user_name.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/update_sending_email_state.dart';
class StoreSendingEmailInteractor {
final EmailRepository _emailRepository;
StoreSendingEmailInteractor(this._emailRepository);
Stream<Either<Failure, Success>> execute(
AccountId accountId,
UserName userName,
SendingEmail sendingEmail,
) async* {
try {
yield Right<Failure, Success>(UpdateSendingEmailLoading());
await _emailRepository.storeSendingEmail(accountId, userName, sendingEmail);
yield Right<Failure, Success>(UpdateSendingEmailSuccess(sendingEmail));
} catch (e) {
yield Left<Failure, Success>(UpdateSendingEmailFailure(e));
}
}
}
@@ -1,28 +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/user_name.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/store_sending_email_state.dart';
class UpdateSendingEmailInteractor {
final EmailRepository _emailRepository;
UpdateSendingEmailInteractor(this._emailRepository);
Stream<Either<Failure, Success>> execute(
AccountId accountId,
UserName userName,
SendingEmail sendingEmail,
) async* {
try {
yield Right<Failure, Success>(StoreSendingEmailLoading());
await _emailRepository.updateSendingEmail(accountId, userName, sendingEmail);
yield Right<Failure, Success>(StoreSendingEmailSuccess(sendingEmail));
} catch (e) {
yield Left<Failure, Success>(StoreSendingEmailFailure(e));
}
}
}
@@ -2,7 +2,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
class ComposerArguments extends RouterArguments {
@@ -6,7 +6,7 @@ import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
@@ -1,4 +1,3 @@
import 'package:core/core.dart';
import 'package:core/data/model/source_type/data_source_type.dart';
import 'package:core/data/network/dio_client.dart';
import 'package:core/utils/config/app_config_loader.dart';
@@ -10,7 +9,6 @@ import 'package:tmail_ui_user/features/caching/clients/state_cache_client.dart';
import 'package:tmail_ui_user/features/composer/data/repository/contact_repository_impl.dart';
import 'package:tmail_ui_user/features/composer/domain/repository/contact_repository.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/store_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart';
@@ -105,6 +103,8 @@ import 'package:tmail_ui_user/features/quotas/presentation/quotas_controller_bin
import 'package:tmail_ui_user/features/search/email/domain/usecases/refresh_changes_search_email_interactor.dart';
import 'package:tmail_ui_user/features/search/email/presentation/search_email_bindings.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/store_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/bindings/sending_queue_bindings.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_controller.dart';
@@ -179,6 +179,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<GetEmailByIdInteractor>(),
Get.find<SendEmailInteractor>(),
Get.find<StoreSendingEmailInteractor>(),
Get.find<UpdateSendingEmailInteractor>(),
Get.find<GetAllSendingEmailInteractor>(),
Get.find<StoreSessionInteractor>(),
));
@@ -333,7 +334,6 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<EmailRepository>(),
Get.find<MailboxRepository>()
));
Get.lazyPut(() => StoreSendingEmailInteractor(Get.find<EmailRepository>()));
SendingQueueInteractorBindings().dependencies();
Get.lazyPut(() => StoreSessionInteractor(Get.find<SessionRepository>()));
}
@@ -14,7 +14,6 @@ import 'package:jmap_dart_client/jmap/core/capability/mail_capability.dart';
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
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/mailbox/mailbox.dart';
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
@@ -27,15 +26,11 @@ import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dar
import 'package:tmail_ui_user/features/composer/domain/exceptions/set_email_method_exception.dart';
import 'package:tmail_ui_user/features/composer/domain/extensions/email_request_extension.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/sending_email_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/state/store_sending_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/update_sending_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/store_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
@@ -100,8 +95,14 @@ import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_ema
import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_mailbox_state_to_refresh_interactor.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_manager.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/services/fcm_service.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/state/get_all_sending_email_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/state/update_sending_email_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/store_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_arguments.dart';
import 'package:tmail_ui_user/features/session/domain/usecases/store_session_interactor.dart';
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
@@ -156,6 +157,7 @@ class MailboxDashBoardController extends ReloadableController {
final GetEmailByIdInteractor _getEmailByIdInteractor;
final SendEmailInteractor _sendEmailInteractor;
final StoreSendingEmailInteractor _storeSendingEmailInteractor;
final UpdateSendingEmailInteractor _updateSendingEmailInteractor;
final GetAllSendingEmailInteractor _getAllSendingEmailInteractor;
final StoreSessionInteractor _storeSessionInteractor;
@@ -228,6 +230,7 @@ class MailboxDashBoardController extends ReloadableController {
this._getEmailByIdInteractor,
this._sendEmailInteractor,
this._storeSendingEmailInteractor,
this._updateSendingEmailInteractor,
this._getAllSendingEmailInteractor,
this._storeSessionInteractor,
) : super(
@@ -279,7 +282,7 @@ class MailboxDashBoardController extends ReloadableController {
@override
void handleSuccessViewState(Success success) {
super.handleSuccessViewState(success);
if (success is SendingEmailState) {
if (success is SendEmailLoading) {
if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastMessage(
currentOverlayContext!,
@@ -1204,7 +1207,7 @@ class MailboxDashBoardController extends ReloadableController {
result.accountId,
result.emailRequest,
result.mailboxRequest,
isUpdateSendingEmail: result.isUpdateSendingEmail
result.sendingEmailActionType
);
}
}
@@ -1327,7 +1330,7 @@ class MailboxDashBoardController extends ReloadableController {
result.accountId,
result.emailRequest,
result.mailboxRequest,
isUpdateSendingEmail: result.isUpdateSendingEmail ?? false,
result.sendingEmailActionType
);
}
}
@@ -1761,7 +1764,7 @@ class MailboxDashBoardController extends ReloadableController {
AccountId accountId,
EmailRequest emailRequest,
CreateNewMailboxRequest? mailboxRequest,
{bool? isUpdateSendingEmail = false}
SendingEmailActionType sendingEmailActionType
) {
if (PlatformInfo.isMobile) {
if (networkConnectionController.isNetworkConnectionAvailable()) {
@@ -1772,11 +1775,13 @@ class MailboxDashBoardController extends ReloadableController {
mailboxRequest: mailboxRequest
));
} else {
if (currentContext != null && isUpdateSendingEmail == false) {
_showActionSendingEmail(session, accountId, emailRequest, mailboxRequest);
} else {
_handleUpdateSendingEmail(session, accountId, emailRequest, mailboxRequest);
}
_handleSendingEmailWhenNoNetwork(
session,
accountId,
emailRequest,
mailboxRequest,
sendingEmailActionType
);
}
} else {
consumeState(_sendEmailInteractor.execute(
@@ -1788,104 +1793,104 @@ class MailboxDashBoardController extends ReloadableController {
}
}
void _handleSendingEmailWhenNoNetwork(
Session session,
AccountId accountId,
EmailRequest emailRequest,
CreateNewMailboxRequest? mailboxRequest,
SendingEmailActionType sendingEmailActionType
) {
switch(sendingEmailActionType) {
case SendingEmailActionType.create:
_showConfirmDialogStoreSendingEmail(session, accountId, emailRequest, mailboxRequest);
break;
case SendingEmailActionType.edit:
_handleUpdateSendingEmail(session, accountId, emailRequest, mailboxRequest);
break;
case SendingEmailActionType.delete:
break;
}
}
void _handleStoreSendingEmail(
Session session,
AccountId accountId,
EmailRequest emailRequest,
CreateNewMailboxRequest? mailboxRequest,
) {
final currentEmailId = emailRequest.email.id?.id.value;
final sendingEmail = emailRequest.toSendingEmail(
emailRequest.email.id != null ? currentEmailId! : _uuid.v1(),
mailboxRequest: mailboxRequest
);
_storeSendingEmail(accountId, session.username, sendingEmail);
final sendingEmail = emailRequest.toSendingEmail(_uuid.v1(), mailboxRequest: mailboxRequest);
consumeState(_storeSendingEmailInteractor.execute(
accountId,
session.username,
sendingEmail
));
}
void _handleUpdateSendingEmail(
Session session,
AccountId accountId,
EmailRequest emailRequest,
CreateNewMailboxRequest? mailboxRequest,
Session session,
AccountId accountId,
EmailRequest emailRequest,
CreateNewMailboxRequest? mailboxRequest,
) {
final currentEmailId = emailRequest.email.id?.id.value;
final sendingEmail = emailRequest.toSendingEmail(
emailRequest.email.id != null ? currentEmailId! : _uuid.v1(),
mailboxRequest: mailboxRequest
);
_updateSendingEmail(accountId, session.username, sendingEmail);
final storedSendingId = emailRequest.storedSendingId;
if (storedSendingId != null) {
final sendingEmail = emailRequest.toSendingEmail(storedSendingId, mailboxRequest: mailboxRequest);
consumeState(_updateSendingEmailInteractor.execute(
accountId,
session.username,
sendingEmail
));
} else {
logError('MailboxDashBoardController::_handleUpdateSendingEmail(): StoredSendingId is null');
}
}
void _showActionSendingEmail(
void _showConfirmDialogStoreSendingEmail(
Session session,
AccountId accountId,
EmailRequest emailRequest,
CreateNewMailboxRequest? mailboxRequest
) {
showConfirmDialogAction(
currentContext!,
'',
AppLocalizations.of(currentContext!).proceed,
onConfirmAction: () {
_handleStoreSendingEmail(session, accountId, emailRequest, mailboxRequest);
},
title: AppLocalizations.of(currentContext!).youAreInOfflineMode,
icon: SvgPicture.asset(_imagePaths.icDialogOfflineMode),
alignCenter: true,
messageStyle: const TextStyle(
currentContext!,
'',
AppLocalizations.of(currentContext!).proceed,
onConfirmAction: () {
_handleStoreSendingEmail(session, accountId, emailRequest, mailboxRequest);
},
title: AppLocalizations.of(currentContext!).youAreInOfflineMode,
icon: SvgPicture.asset(_imagePaths.icDialogOfflineMode),
alignCenter: true,
messageStyle: const TextStyle(
color: AppColor.colorTitleSendingItem,
fontSize: 15,
fontWeight: FontWeight.normal
),
listTextSpan: [
TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailFirst),
TextSpan(
text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailSecond,
style: const TextStyle(
color: AppColor.colorTitleSendingItem,
fontSize: 15,
fontWeight: FontWeight.normal
fontWeight: FontWeight.w600
),
),
listTextSpan: [
TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailFirst),
TextSpan(
text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailSecond,
style: const TextStyle(
color: AppColor.colorTitleSendingItem,
fontSize: 15,
fontWeight: FontWeight.w600
),
TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailThird),
TextSpan(
text: AppLocalizations.of(currentContext!).sendingQueue,
style: const TextStyle(
color: AppColor.colorTitleSendingItem,
fontSize: 15,
fontWeight: FontWeight.w600
),
TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailThird),
TextSpan(
text: AppLocalizations.of(currentContext!).sendingQueue,
style: const TextStyle(
color: AppColor.colorTitleSendingItem,
fontSize: 15,
fontWeight: FontWeight.w600
),
),
TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailTail)
]
),
TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailTail)
]
);
}
void _storeSendingEmail(
AccountId accountId,
UserName userName,
SendingEmail sendingEmail,
) {
log('MailboxDashBoardController::_storeSendingEmail():sendingEmail: $sendingEmail');
consumeState(_storeSendingEmailInteractor.execute(
accountId,
userName,
sendingEmail));
}
void _updateSendingEmail(
AccountId accountId,
UserName userName,
SendingEmail sendingEmail
) {
log('MailboxDashBoardController::_storeSendingEmail():sendingEmail: $sendingEmail');
consumeState(_storeSendingEmailInteractor.execute(
accountId,
userName,
sendingEmail));
}
void _handleStoreSendingEmailSuccess(StoreSendingEmailSuccess success) async {
void _handleStoreSendingEmailSuccess(StoreSendingEmailSuccess success) {
_addSendingEmailToSendingQueue(success.sendingEmail);
getAllSendingEmails();
if (currentOverlayContext != null && currentContext != null) {
@@ -1898,19 +1903,11 @@ class MailboxDashBoardController extends ReloadableController {
}
void _handleUpdateSendingEmailSuccess(UpdateSendingEmailSuccess success) async {
_cancelSendingEmailToSendingQueue(success.sendingEmail);
_addSendingEmailToSendingQueue(success.sendingEmail);
await WorkSchedulerController().cancelByUniqueId(success.newSendingEmail.sendingId);
_addSendingEmailToSendingQueue(success.newSendingEmail);
getAllSendingEmails();
}
void _cancelSendingEmailToSendingQueue(SendingEmail sendingEmail) async {
try {
await WorkSchedulerController().cancelByUniqueId(sendingEmail.sendingId);
} catch (e) {
logError('MailboxDashBoardController::_cancelSendingEmailToSendingQueue(): EXCEPTION: $e');
}
}
void _addSendingEmailToSendingQueue(SendingEmail sendingEmail) async {
log('MailboxDashBoardController::_addSendingEmailToSendingQueue():sendingEmail: $sendingEmail');
final worker = worker_scheduler.Worker(
@@ -14,7 +14,6 @@ import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/delete_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart';
@@ -34,7 +33,7 @@ import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dar
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart';
class SendingEmailBindings extends InteractorsBindings {
class SendEmailInteractorBindings extends InteractorsBindings {
@override
void bindingsDataSource() {
@@ -76,11 +75,7 @@ class SendingEmailBindings extends InteractorsBindings {
@override
void bindingsInteractor() {
Get.lazyPut(() => SendEmailInteractor(
Get.find<EmailRepository>(),
Get.find<MailboxRepository>()
));
Get.lazyPut(() => DeleteSendingEmailInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => SendEmailInteractor(Get.find<EmailRepository>(), Get.find<MailboxRepository>()));
}
@override
@@ -1,3 +1 @@
class UnableToGetDataFromInWorkManagerException implements Exception {}
class UnableBindingInWorkManagerException implements Exception {}
class CannotCompleteTaskInWorkManagerException implements Exception {}
@@ -1,8 +1,8 @@
import 'package:jmap_dart_client/jmap/core/extensions/date_time_extension.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/offline_mode/extensions/sending_email_hive_cache_extension.dart';
import 'package:tmail_ui_user/features/offline_mode/model/sending_email_hive_cache.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
extension ListSendingEmailHiveCacheExtension on List<SendingEmailHiveCache> {
@@ -8,8 +8,9 @@ import 'package:jmap_dart_client/http/converter/mailbox_id_nullable_converter.da
import 'package:jmap_dart_client/http/converter/mailbox_name_converter.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/email/email_action_type.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/offline_mode/model/sending_email_hive_cache.dart';
import 'package:tmail_ui_user/features/offline_mode/model/sending_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
extension SendingEmailHiveCacheExtension on SendingEmailHiveCache {
@@ -24,7 +25,8 @@ extension SendingEmailHiveCacheExtension on SendingEmailHiveCache {
emailIdAnsweredOrForwarded: const EmailIdNullableConverter().fromJson(emailIdAnsweredOrForwarded),
identityId: const IdentityIdNullableConverter().fromJson(identityId),
mailboxNameRequest: const MailboxNameConverter().fromJson(mailboxNameRequest),
creationIdRequest: const IdNullableConverter().fromJson(creationIdRequest)
creationIdRequest: const IdNullableConverter().fromJson(creationIdRequest),
sendingState: SendingState.values.firstWhere((value) => value.name == sendingState)
);
}
}
@@ -7,6 +7,7 @@ import 'package:tmail_ui_user/features/caching/clients/sending_email_hive_cache_
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
import 'package:tmail_ui_user/features/offline_mode/extensions/list_sending_email_hive_cache_extension.dart';
import 'package:tmail_ui_user/features/offline_mode/model/sending_email_hive_cache.dart';
import 'package:tmail_ui_user/features/sending_queue/data/exceptions/sending_queue_exceptions.dart';
class SendingEmailCacheManager {
@@ -14,14 +15,21 @@ class SendingEmailCacheManager {
SendingEmailCacheManager(this._hiveCacheClient);
Future<void> storeSendingEmail(
Future<SendingEmailHiveCache> storeSendingEmail(
AccountId accountId,
UserName userName,
SendingEmailHiveCache sendingEmailHiveCache
) {
) async {
final keyCache = TupleKey(sendingEmailHiveCache.sendingId, accountId.asString, userName.value).encodeKey;
log('SendingEmailCacheManager::storeSendingEmail():keyCache: $keyCache | sendingEmailHiveCache: $sendingEmailHiveCache');
return _hiveCacheClient.insertItem(keyCache, sendingEmailHiveCache);
await _hiveCacheClient.insertItem(keyCache, sendingEmailHiveCache);
final newSendingEmailHiveCache = await _hiveCacheClient.getItem(keyCache);
if (newSendingEmailHiveCache != null) {
log('SendingEmailCacheManager::storeSendingEmail():sendingId: ${newSendingEmailHiveCache.sendingId} | sendingState: ${newSendingEmailHiveCache.sendingState}');
return newSendingEmailHiveCache;
} else {
throw NotFoundSendingEmailHiveObject();
}
}
Future<List<SendingEmailHiveCache>> getAllSendingEmailsByTupleKey(
@@ -41,15 +49,21 @@ class SendingEmailCacheManager {
Future<void> deleteSendingEmail(
AccountId accountId,
UserName userName,
String sendingId
) {
String sendingId,
{bool needToReopen = false}
) async {
final keyCache = TupleKey(sendingId, accountId.asString, userName.value).encodeKey;
log('SendingEmailCacheManager::deleteSendingEmail():keyCache: $keyCache');
return _hiveCacheClient.deleteItem(keyCache);
await _hiveCacheClient.deleteItem(keyCache, needToReopen: needToReopen);
final storedSendingEmail = await _hiveCacheClient.getItem(keyCache);
if (storedSendingEmail != null) {
log('SendingEmailCacheManager::deleteSendingEmail():sendingId: ${storedSendingEmail.sendingId}');
throw ExistSendingEmailHiveObject();
}
}
Future<List<SendingEmailHiveCache>> getAllSendingEmails() async {
final sendingEmailsCache = await _hiveCacheClient.getAll(needToReopen: true);
Future<List<SendingEmailHiveCache>> getAllSendingEmails({bool needToReopen = false}) async {
final sendingEmailsCache = await _hiveCacheClient.getAll(needToReopen: needToReopen);
log('SendingEmailCacheManager::getAllSendingEmails():COUNT: ${sendingEmailsCache.length}');
sendingEmailsCache.sortByLatestTime();
return sendingEmailsCache;
@@ -57,13 +71,21 @@ class SendingEmailCacheManager {
Future<void> clearAllSendingEmails() => _hiveCacheClient.clearAllData();
Future<void> updateSendingEmail(
Future<SendingEmailHiveCache> updateSendingEmail(
AccountId accountId,
UserName userName,
SendingEmailHiveCache sendingEmailHiveCache
SendingEmailHiveCache sendingEmailHiveCache,
{bool needToReopen = false}
) async {
final keyCache = TupleKey(sendingEmailHiveCache.sendingId, accountId.asString, userName.value).encodeKey;
log('SendingEmailCacheManager::updateSendingEmail():keyCache: $keyCache | sendingEmailHiveCache: $sendingEmailHiveCache');
return await _hiveCacheClient.updateItem(keyCache, sendingEmailHiveCache, needToReopen: true);
await _hiveCacheClient.updateItem(keyCache, sendingEmailHiveCache, needToReopen: needToReopen);
final newSendingEmailHiveCache = await _hiveCacheClient.getItem(keyCache);
if (newSendingEmailHiveCache != null) {
log('SendingEmailCacheManager::updateSendingEmail():sendingId: ${newSendingEmailHiveCache.sendingId} | sendingState: ${newSendingEmailHiveCache.sendingState}');
return newSendingEmailHiveCache;
} else {
throw NotFoundSendingEmailHiveObject();
}
}
}
@@ -5,15 +5,13 @@ import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/model.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';
import 'package:tmail_ui_user/features/login/domain/state/get_authenticated_account_state.dart';
@@ -22,12 +20,18 @@ import 'package:tmail_ui_user/features/login/domain/state/get_stored_token_oidc_
import 'package:tmail_ui_user/features/login/domain/usecases/get_authenticated_account_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart';
import 'package:tmail_ui_user/features/offline_mode/biding/sending_email_biding.dart';
import 'package:tmail_ui_user/features/offline_mode/bindings/sending_email_interactor_bindings.dart';
import 'package:tmail_ui_user/features/offline_mode/exceptions/workmanager_exception.dart';
import 'package:tmail_ui_user/features/offline_mode/model/sending_state.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/domain/extensions/sending_email_extension.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/state/update_sending_email_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart';
import 'package:tmail_ui_user/features/session/domain/extensions/session_extensions.dart';
import 'package:tmail_ui_user/features/session/domain/state/get_session_state.dart';
@@ -39,7 +43,6 @@ class SendingEmailObserver extends WorkObserver {
AccountId? _currentAccountId;
Session? _currentSession;
UserName? _userName;
SendingEmail? _sendingEmail;
SendEmailInteractor? _sendEmailInteractor;
@@ -49,6 +52,7 @@ class SendingEmailObserver extends WorkObserver {
GetSessionInteractor? _getSessionInteractor;
DeleteSendingEmailInteractor? _deleteSendingEmailInteractor;
SendingQueueIsolateManager? _sendingQueueIsolateManager;
UpdateSendingEmailInteractor? _updateSendingEmailInteractor;
Completer<bool>? _completer;
@@ -69,10 +73,6 @@ class SendingEmailObserver extends WorkObserver {
@override
Future<void> bindDI() async {
return await _initialAppConfig();
}
Future<void> _initialAppConfig() async {
await Future.wait([
MainBindings().dependencies(),
HiveCacheConfig().setUp()
@@ -81,7 +81,7 @@ class SendingEmailObserver extends WorkObserver {
await Future.sync(() {
HomeBindings().dependencies();
MailboxDashBoardBindings().dependencies();
SendingEmailBindings().dependencies();
SendEmailInteractorBindings().dependencies();
});
return await _getInteractorBindings();
@@ -89,15 +89,26 @@ class SendingEmailObserver extends WorkObserver {
@override
void handleFailureViewState(Failure failure) {
_clearDataQueue();
log('SendingEmailObserver::_handleFailureViewState(): $failure');
if (failure is SendEmailFailure) {
_updateStoredSendingEmail(SendingState.error);
} else if (failure is DeleteSendingEmailFailure) {
_showLocalNotification();
_updateStoredSendingEmail(SendingState.error);
} else if (failure is GetAuthenticatedAccountFailure ||
failure is NoAuthenticatedAccountFailure ||
failure is GetSessionFailure ||
failure is GetStoredTokenOidcFailure ||
failure is GetCredentialFailure ||
failure is UpdateSendingEmailFailure) {
_invokeCompleteWorkManager();
}
}
@override
void handleSuccessViewState(Success success) {
if (success is GetAuthenticatedAccountSuccess) {
_handleGetAuthenticatedAccountSuccess(success);
} else if (success is GetSessionSuccess) {
log('SendingEmailObserver::handleSuccessViewState(): $success');
if (success is GetSessionSuccess) {
_handleGetSessionSuccess(success);
} else if (success is GetStoredTokenOidcSuccess) {
_handleGetAccountByOidcSuccess(success);
@@ -107,9 +118,17 @@ class SendingEmailObserver extends WorkObserver {
_handleSendEmailSuccess(success);
} else if (success is DeleteSendingEmailSuccess) {
_handleDeleteSendingEmailSuccess();
} else if (success is UpdateSendingEmailSuccess) {
_handleUpdateStoredSendingEmailSuccess(success);
}
}
@override
void handleOnError(Object? error, StackTrace stackTrace) {
super.handleOnError(error, stackTrace);
_invokeCompleteWorkManager();
}
Future<void> _getInteractorBindings() async {
try {
_getAuthenticatedAccountInteractor = getBinding<GetAuthenticatedAccountInteractor>();
@@ -119,25 +138,18 @@ class SendingEmailObserver extends WorkObserver {
_sendEmailInteractor = getBinding<SendEmailInteractor>();
_deleteSendingEmailInteractor = getBinding<DeleteSendingEmailInteractor>();
_sendingQueueIsolateManager = getBinding<SendingQueueIsolateManager>();
_updateSendingEmailInteractor = getBinding<UpdateSendingEmailInteractor>();
} catch (e) {
logError('SendingEmailObserver::_getInteractorBindings(): ${e.toString()}');
_completer?.completeError(UnableBindingInWorkManagerException());
_invokeCompleteWorkManager();
}
}
void _handleGetAuthenticatedAccountSuccess(GetAuthenticatedAccountSuccess success) {
_currentAccountId = success.account.accountId;
_userName = success.account.userName;
_dynamicUrlInterceptors?.changeBaseUrl(success.account.apiUrl);
log('SendingEmailObserver::_handleGetAuthenticatedAccountSuccess():_currentAccountId: $_currentAccountId | _userName: $_userName');
}
void _getSessionAction() {
if (_getSessionInteractor != null) {
consumeState(_getSessionInteractor!.execute());
} else {
_clearDataQueue();
logError('SendingEmailObserver::_getSessionAction():_getSessionInteractor is null');
_invokeCompleteWorkManager();
}
}
@@ -145,27 +157,29 @@ class SendingEmailObserver extends WorkObserver {
if (_getAuthenticatedAccountInteractor != null) {
consumeState(_getAuthenticatedAccountInteractor!.execute());
} else {
_clearDataQueue();
logError('SendingEmailObserver::_getAuthenticatedAccount():_getAuthenticatedAccountInteractor is null');
_invokeCompleteWorkManager();
}
}
void _handleGetSessionSuccess(GetSessionSuccess success) {
void _handleGetSessionSuccess(GetSessionSuccess success) async {
_currentSession = success.session;
_userName = success.session.username;
_currentAccountId = success.session.personalAccount.accountId;
final apiUrl = success.session.getQualifiedApiUrl(baseUrl: _dynamicUrlInterceptors?.jmapUrl);
log('SendingEmailObserver::_handleGetSessionSuccess():apiUrl: $apiUrl');
if (apiUrl.isNotEmpty) {
_dynamicUrlInterceptors?.changeBaseUrl(apiUrl);
_sendEmailAction();
_updateStoredSendingEmail(SendingState.delivering);
await Future.delayed(
const Duration(milliseconds: 2000),
_sendEmailAction
);
} else {
_clearDataQueue();
logError('SendingEmailObserver::_handleGetSessionSuccess():apiUrl is null');
_invokeCompleteWorkManager();
}
}
void _handleGetAccountByBasicAuthSuccess(GetCredentialViewState credentialViewState) {
log('SendingEmailObserver::_handleGetAccountByBasicAuthSuccess()');
_dynamicUrlInterceptors?.setJmapUrl(credentialViewState.baseUrl.toString());
_authorizationInterceptors?.setBasicAuthorization(
credentialViewState.userName.value,
@@ -176,11 +190,9 @@ 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) {
if (_sendEmailInteractor != null && _isDataParameterNotNull) {
consumeState(_sendEmailInteractor!.execute(
_currentSession!,
_currentAccountId!,
@@ -190,61 +202,100 @@ class SendingEmailObserver extends WorkObserver {
: null
));
} else {
_clearDataQueue();
logError('SendingEmailObserver::_sendEmailAction():_sendEmailInteractor is null');
_updateStoredSendingEmail(SendingState.error);
}
}
void _handleGetAccountByOidcSuccess(GetStoredTokenOidcSuccess storedTokenOidcSuccess) {
log('FcmMessageController::_handleGetAccountByOidcSuccess():');
_dynamicUrlInterceptors?.setJmapUrl(storedTokenOidcSuccess.baseUrl.toString());
_authorizationInterceptors?.setTokenAndAuthorityOidc(
newToken: storedTokenOidcSuccess.tokenOidc.toToken(),
newConfig: storedTokenOidcSuccess.oidcConfiguration
);
_dynamicUrlInterceptors?.changeBaseUrl(storedTokenOidcSuccess.baseUrl.toString());
_getSessionAction();
}
void _handleSendEmailSuccess(SendEmailSuccess success) async {
log("SendingEmailObserver::_handleSendEmailSuccess()");
void _handleSendEmailSuccess(SendEmailSuccess success) {
_deleteSendingEmailAction();
}
void _deleteSendingEmailAction() {
if (_deleteSendingEmailInteractor != null && _currentSession != null && _currentAccountId != null && _sendingEmail != null) {
log('SendingEmailObserver::_deleteSendingEmailAction():');
if (_deleteSendingEmailInteractor != null && _isDataParameterNotNull) {
consumeState(_deleteSendingEmailInteractor!.execute(
_currentAccountId!,
_currentSession!.username,
_sendingEmail!.sendingId,
needToReopen: true
));
} else {
_clearDataQueue();
logError('SendingEmailObserver::_deleteSendingEmailAction():_deleteSendingEmailInteractor is null');
log('SendingEmailObserver::_deleteSendingEmailAction(): NOT CALLED');
_updateStoredSendingEmail(SendingState.error);
}
}
void _handleDeleteSendingEmailSuccess() async {
log('SendingEmailObserver::_handleDeleteSendingEmailSuccess(): Success');
_showLocalNotification();
_sendingQueueIsolateManager?.addEvent(WorkerState.success.name);
_completer?.complete(true);
}
void _clearDataQueue() async {
log('SendingEmailObserver::_clearDataQueue():');
_sendingEmail = null;
_sendingQueueIsolateManager?.addEvent(WorkerState.failed.name);
_completer?.completeError(UnableToGetDataFromInWorkManagerException());
await Future.delayed(
const Duration(milliseconds: 1000),
() {
_completer?.complete(true);
_completer = null;
}
);
}
void _showLocalNotification() {
log('SendingEmailObserver::_showLocalNotification():SendingId: ${_sendingEmail?.sendingId}');
LocalNotificationManager.instance.showPushNotification(
id: _sendingEmail?.sendingId ?? '',
title: LocalNotificationConfig.messageHasBeenSentSuccessfully,
message: _sendingEmail?.presentationEmail.preview
title: _sendingEmail?.email.subject ?? LocalNotificationConfig.messageHasBeenSentSuccessfully,
message: _sendingEmail?.presentationEmail.emailContentList.asHtmlString,
isInboxStyle: false
);
}
bool get _isDataParameterNotNull => _currentSession != null && _currentAccountId != null && _sendingEmail != null;
void _updateStoredSendingEmail(SendingState newState) {
log('SendingEmailObserver::_updateStoredSendingEmail():');
if (_updateSendingEmailInteractor != null && _isDataParameterNotNull) {
consumeState(_updateSendingEmailInteractor!.execute(
_currentAccountId!,
_currentSession!.username,
_sendingEmail!.updatingSendingState(newState),
needToReopen: true
));
} else {
_invokeCompleteWorkManager();
}
}
void _handleUpdateStoredSendingEmailSuccess(UpdateSendingEmailSuccess success) {
log('SendingEmailObserver::_handleUpdateStoredSendingEmailSuccess():sendingState: ${success.newSendingEmail.sendingState}');
switch (success.newSendingEmail.sendingState) {
case SendingState.ready:
break;
case SendingState.delivering:
_sendingQueueIsolateManager?.addEvent(WorkerState.pending.name);
break;
case SendingState.error:
_invokeCompleteWorkManager();
break;
}
}
void _invokeCompleteWorkManager() async {
log('SendingEmailObserver::_invokeCompleteWorkManager():');
_sendingEmail = null;
_sendingQueueIsolateManager?.addEvent(WorkerState.failed.name);
await Future.delayed(
const Duration(milliseconds: 1000),
() {
_completer?.completeError(CannotCompleteTaskInWorkManagerException());
_completer = null;
}
);
}
}
@@ -12,10 +12,7 @@ abstract class WorkObserver {
void consumeState(Stream<Either<Failure, Success>> newStateStream) {
newStateStream.listen(
_handleStateStream,
onError: (error, stackTrace) {
logError('WorkObserver::consumeState():onError:error: $error');
logError('WorkObserver::consumeState():onError:stackTrace: $stackTrace');
}
onError: handleOnError
);
}
@@ -26,4 +23,8 @@ abstract class WorkObserver {
void handleFailureViewState(Failure failure) {}
void handleSuccessViewState(Success success) {}
void handleOnError(Object? error, StackTrace stackTrace) {
logError('WorkObserver::handleOnError():error: $error | stackTrace: $stackTrace');
}
}
@@ -1,5 +1,6 @@
enum WorkerState {
pending,
success,
failed;
}
@@ -131,24 +131,35 @@ class LocalNotificationManager {
required String title,
String? message,
EmailAddress? emailAddress,
String? payload
String? payload,
bool isInboxStyle = true
}) async {
final inboxStyleInformation = InboxStyleInformation(
[message?.addBlockTag('p', attribute: 'style="color:#6D7885;"') ?? ''],
htmlFormatLines: true,
contentTitle: title,
htmlFormatContentTitle: true,
summaryText: (emailAddress?.asString() ?? '').addBlockTag('b'),
htmlFormatSummaryText: true,
);
if (isInboxStyle) {
final inboxStyleInformation = InboxStyleInformation(
[message?.addBlockTag('p', attribute: 'style="color:#6D7885;"') ?? ''],
htmlFormatLines: true,
contentTitle: title,
htmlFormatContentTitle: true,
summaryText: (emailAddress?.asString() ?? '').addBlockTag('b'),
htmlFormatSummaryText: true,
);
await _localNotificationsPlugin.show(
id.hashCode,
title,
message,
LocalNotificationConfig.instance.generateNotificationDetails(styleInformation: inboxStyleInformation),
payload: payload
);
await _localNotificationsPlugin.show(
id.hashCode,
title,
message,
LocalNotificationConfig.instance.generateNotificationDetails(styleInformation: inboxStyleInformation),
payload: payload
);
} else {
await _localNotificationsPlugin.show(
id.hashCode,
title,
message,
LocalNotificationConfig.instance.generateNotificationDetails(),
payload: payload
);
}
}
Future<void> removeNotification(String id) {
@@ -0,0 +1,4 @@
class NotFoundSendingEmailHiveObject implements Exception {}
class ExistSendingEmailHiveObject implements Exception {}
@@ -1,7 +1,7 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart';
class SendingQueueRepositoryImpl extends SendingQueueRepository {
@@ -16,7 +16,17 @@ class SendingQueueRepositoryImpl extends SendingQueueRepository {
}
@override
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId) {
return _emailHiveCacheDataSourceImpl.deleteSendingEmail(accountId, userName, sendingId);
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId, {bool needToReopen = false}) {
return _emailHiveCacheDataSourceImpl.deleteSendingEmail(accountId, userName, sendingId, needToReopen: needToReopen);
}
@override
Future<SendingEmail> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail newSendingEmail, {bool needToReopen = false}) {
return _emailHiveCacheDataSourceImpl.updateSendingEmail(accountId, userName, newSendingEmail, needToReopen: needToReopen);
}
@override
Future<SendingEmail> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail) {
return _emailHiveCacheDataSourceImpl.storeSendingEmail(accountId, userName, sendingEmail);
}
}
@@ -5,8 +5,9 @@ import 'package:model/extensions/identity_id_extension.dart';
import 'package:model/extensions/mailbox_id_extension.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/offline_mode/model/sending_email_hive_cache.dart';
import 'package:tmail_ui_user/features/offline_mode/model/sending_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
extension SendingEmailExtension on SendingEmail {
SendingEmailHiveCache toHiveCache() {
@@ -25,14 +26,15 @@ extension SendingEmailExtension on SendingEmail {
);
}
EmailRequest toEmailRequest({Email? emailEdit}) {
EmailRequest toEmailRequest({Email? newEmail}) {
return EmailRequest(
email: emailEdit ?? email,
email: newEmail ?? email,
emailActionType: emailActionType,
sentMailboxId: sentMailboxId,
emailIdDestroyed: emailIdDestroyed,
emailIdAnsweredOrForwarded: emailIdAnsweredOrForwarded,
identityId: identityId
identityId: identityId,
storedSendingId: sendingId
);
}
@@ -69,4 +71,21 @@ extension SendingEmailExtension on SendingEmail {
selectMode: SelectMode.INACTIVE
);
}
SendingEmail updatingSendingState(SendingState newState) {
return SendingEmail(
sendingId: sendingId,
email: email,
emailActionType: emailActionType,
createTime: createTime,
sentMailboxId: sentMailboxId,
emailIdDestroyed: emailIdDestroyed,
emailIdAnsweredOrForwarded: emailIdAnsweredOrForwarded,
identityId: identityId,
mailboxNameRequest: mailboxNameRequest,
creationIdRequest: creationIdRequest,
sendingState: newState,
selectMode: selectMode
);
}
}
@@ -1,10 +1,14 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
abstract class SendingQueueRepository {
Future<List<SendingEmail>> getAllSendingEmails(AccountId accountId, UserName userName, {bool needToReopen = false});
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId);
Future<SendingEmail> storeSendingEmail(AccountId accountId, UserName userName, SendingEmail sendingEmail);
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId, {bool needToReopen = false});
Future<SendingEmail> updateSendingEmail(AccountId accountId, UserName userName, SendingEmail newSendingEmail, {bool needToReopen = false});
}
@@ -0,0 +1,13 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class DeleteSendingEmailLoading extends UIState {}
class DeleteSendingEmailSuccess extends UIState {}
class DeleteSendingEmailFailure extends FeatureFailure {
DeleteSendingEmailFailure(dynamic exception) : super(exception: exception);
@override
List<Object?> get props => [exception];
}
@@ -1,7 +1,7 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
class GetAllSendingEmailLoading extends UIState {}
@@ -0,0 +1,23 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
class StoreSendingEmailLoading extends UIState {}
class StoreSendingEmailSuccess extends UIState {
final SendingEmail sendingEmail;
StoreSendingEmailSuccess(this.sendingEmail);
@override
List<Object?> get props => [sendingEmail];
}
class StoreSendingEmailFailure extends FeatureFailure {
StoreSendingEmailFailure(dynamic exception) : super(exception: exception);
@override
List<Object?> get props => [exception];
}
@@ -1,21 +1,21 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
class UpdateSendingEmailLoading extends UIState {}
class UpdateSendingEmailSuccess extends UIState {
final SendingEmail newSendingEmail;
final SendingEmail sendingEmail;
UpdateSendingEmailSuccess(this.sendingEmail);
UpdateSendingEmailSuccess(this.newSendingEmail);
@override
List<Object?> get props => [sendingEmail];
List<Object?> get props => [newSendingEmail];
}
class UpdateSendingEmailFailure extends FeatureFailure {
UpdateSendingEmailFailure(dynamic exception) : super(exception: exception);
@override
@@ -3,19 +3,18 @@ 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/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_sending_email_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart';
class DeleteSendingEmailInteractor {
final EmailRepository _emailRepository;
final SendingQueueRepository _sendingQueueRepository;
DeleteSendingEmailInteractor(this._emailRepository);
DeleteSendingEmailInteractor(this._sendingQueueRepository);
Stream<Either<Failure, Success>> execute(AccountId accountId, UserName userName, String sendingId) async* {
Stream<Either<Failure, Success>> execute(AccountId accountId, UserName userName, String sendingId, {bool needToReopen = false}) async* {
try {
yield Right<Failure, Success>(DeleteSendingEmailLoading());
await _emailRepository.deleteSendingEmail(accountId, userName, sendingId);
await _sendingQueueRepository.deleteSendingEmail(accountId, userName, sendingId, needToReopen: needToReopen);
yield Right<Failure, Success>(DeleteSendingEmailSuccess());
} catch (e) {
yield Left<Failure, Success>(DeleteSendingEmailFailure(e));
@@ -0,0 +1,28 @@
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/user_name.dart';
import 'package:tmail_ui_user/features/email/domain/state/store_sending_email_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart';
class StoreSendingEmailInteractor {
final SendingQueueRepository _sendingQueueRepository;
StoreSendingEmailInteractor(this._sendingQueueRepository);
Stream<Either<Failure, Success>> execute(
AccountId accountId,
UserName userName,
SendingEmail sendingEmail,
) async* {
try {
yield Right<Failure, Success>(StoreSendingEmailLoading());
final storedSendingEmail = await _sendingQueueRepository.storeSendingEmail(accountId, userName, sendingEmail);
yield Right<Failure, Success>(StoreSendingEmailSuccess(storedSendingEmail));
} catch (e) {
yield Left<Failure, Success>(StoreSendingEmailFailure(e));
}
}
}
@@ -0,0 +1,29 @@
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/user_name.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/state/update_sending_email_state.dart';
class UpdateSendingEmailInteractor {
final SendingQueueRepository _sendingQueueRepository;
UpdateSendingEmailInteractor(this._sendingQueueRepository);
Stream<Either<Failure, Success>> execute(
AccountId accountId,
UserName userName,
SendingEmail newSendingEmail,
{bool needToReopen = false}
) async* {
try {
yield Right<Failure, Success>(UpdateSendingEmailLoading());
final storedSendingEmail = await _sendingQueueRepository.updateSendingEmail(accountId, userName, newSendingEmail, needToReopen: needToReopen);
yield Right<Failure, Success>(UpdateSendingEmailSuccess(storedSendingEmail));
} catch (e) {
yield Left<Failure, Success>(UpdateSendingEmailFailure(e));
}
}
}
@@ -6,6 +6,7 @@ import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cac
import 'package:tmail_ui_user/features/sending_queue/data/repository/sending_queue_repository_impl.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_multiple_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_single_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
@@ -13,6 +14,8 @@ import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/store_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
@@ -36,9 +39,12 @@ class SendingQueueInteractorBindings extends InteractorsBindings {
@override
void bindingsInteractor() {
Get.lazyPut(() => StoreSendingEmailInteractor(Get.find<SendingQueueRepository>()));
Get.lazyPut(() => GetAllSendingEmailInteractor(Get.find<SendingQueueRepository>()));
Get.lazyPut(() => DeleteSingleSendingEmailInteractor(Get.find<SendingQueueRepository>()));
Get.lazyPut(() => DeleteMultipleSendingEmailInteractor(Get.find<DeleteSingleSendingEmailInteractor>()));
Get.lazyPut(() => DeleteSendingEmailInteractor(Get.find<SendingQueueRepository>()));
Get.lazyPut(() => UpdateSendingEmailInteractor(Get.find<SendingQueueRepository>()));
}
@override
@@ -1,6 +1,6 @@
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/sending_queue/domain/extensions/sending_email_extension.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
extension ListSendingEmailExtension on List<SendingEmail> {
List<SendingEmail> toggleSelection({required SendingEmail sendingEmailSelected}) =>
@@ -1,9 +1,10 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum SendingEmailActionType {
create,
edit,
delete;
@@ -13,6 +14,8 @@ enum SendingEmailActionType {
return AppLocalizations.of(context).delete;
case SendingEmailActionType.edit:
return AppLocalizations.of(context).edit;
case SendingEmailActionType.create:
return '';
}
}
@@ -22,6 +25,8 @@ enum SendingEmailActionType {
return 'button_delete_sending_email';
case SendingEmailActionType.edit:
return 'button_edit_sending_email';
case SendingEmailActionType.create:
return '';
}
}
@@ -31,6 +36,8 @@ enum SendingEmailActionType {
return AppColor.colorDeletePermanentlyButton;
case SendingEmailActionType.edit:
return AppColor.primaryColor;
case SendingEmailActionType.create:
return Colors.transparent;
}
}
@@ -40,6 +47,8 @@ enum SendingEmailActionType {
return AppColor.colorDeletePermanentlyButton;
case SendingEmailActionType.edit:
return AppColor.primaryColor;
case SendingEmailActionType.create:
return Colors.transparent;
}
}
}
@@ -2,6 +2,7 @@ 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/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart';
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
class SendingEmailArguments extends RouterArguments {
@@ -9,7 +10,7 @@ class SendingEmailArguments extends RouterArguments {
final AccountId accountId;
final EmailRequest emailRequest;
final CreateNewMailboxRequest? mailboxRequest;
final bool? isUpdateSendingEmail;
final SendingEmailActionType sendingEmailActionType;
SendingEmailArguments(
this.session,
@@ -17,10 +18,16 @@ class SendingEmailArguments extends RouterArguments {
this.emailRequest,
this.mailboxRequest,
{
this.isUpdateSendingEmail
this.sendingEmailActionType = SendingEmailActionType.create
}
);
@override
List<Object?> get props => [session, accountId, emailRequest, mailboxRequest, isUpdateSendingEmail];
List<Object?> get props => [
session,
accountId,
emailRequest,
mailboxRequest,
sendingEmailActionType
];
}
@@ -13,10 +13,11 @@ import 'package:model/extensions/list_email_content_extension.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/network_status_handle/presentation/network_connnection_controller.dart';
import 'package:tmail_ui_user/features/offline_mode/scheduler/worker_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/controller/work_scheduler_controller.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/state/delete_multiple_sending_email_state.dart';
@@ -31,6 +32,7 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
final DeleteMultipleSendingEmailInteractor _deleteMultipleSendingEmailInteractor;
final dashboardController = getBinding<MailboxDashBoardController>();
final _networkConnectionController = getBinding<NetworkConnectionController>();
final _sendingQueueIsolateManager = getBinding<SendingQueueIsolateManager>();
final _imagePaths = getBinding<ImagePaths>();
final _appToast = getBinding<AppToast>();
@@ -112,10 +114,12 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
_deleteSendingEmailAction(context, listSendingEmails);
break;
case SendingEmailActionType.edit:
if (dashboardController?.networkConnectionController.isNetworkConnectionAvailable() == false) {
if (_networkConnectionController?.isNetworkConnectionAvailable() == false) {
_editSendingEmailAction(listSendingEmails.first);
}
break;
case SendingEmailActionType.create:
break;
}
}
@@ -174,7 +178,7 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
_appToast!.showToastSuccessMessage(
currentOverlayContext!,
AppLocalizations.of(currentContext!).deleteSomeOfflineEmailSuccessfully
AppLocalizations.of(currentContext!).messageHaveBeenDeletedSuccessfully
);
_refreshSendingQueue();
@@ -182,6 +186,8 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
}
void _editSendingEmailAction(SendingEmail sendingEmail) {
disableSelectionMode();
final arguments = ComposerArguments(
emailActionType: EmailActionType.edit,
presentationEmail: sendingEmail.presentationEmail,
@@ -1,7 +1,7 @@
import 'package:core/core.dart';
import 'package:flutter/cupertino.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
class SendingQueueUtils {
@@ -8,7 +8,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_utils.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
@@ -4,7 +4,7 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/button/button_builder.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/extensions/list_sending_email_extension.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart';
@@ -9,7 +9,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_utils.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/sending_state_widget.dart';
+3 -3
View File
@@ -1,5 +1,5 @@
{
"@@last_modified": "2023-06-08T16:53:26.593398",
"@@last_modified": "2023-06-09T10:30:29.843203",
"initializing_data": "Initializing data...",
"@initializing_data": {
"type": "text",
@@ -2882,8 +2882,8 @@
"placeholders_order": [],
"placeholders": {}
},
"deleteSomeOfflineEmailSuccessfully": "Delete some offline email successfully.",
"@deleteSomeOfflineEmailSuccessfully": {
"messageHaveBeenDeletedSuccessfully": "Messages have been deleted successfully",
"@messageHaveBeenDeletedSuccessfully": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
@@ -2968,10 +2968,10 @@ class AppLocalizations {
);
}
String get deleteSomeOfflineEmailSuccessfully {
String get messageHaveBeenDeletedSuccessfully {
return Intl.message(
'Delete some offline email successfully.',
name: 'deleteSomeOfflineEmailSuccessfully',
'Messages have been deleted successfully',
name: 'messageHaveBeenDeletedSuccessfully',
);
}