TF-1923 Fix logic store opened email

(cherry picked from commit 8d9c8d3ee8ea519e683d5a7cbb5b080d2f78e292)
This commit is contained in:
dab246
2023-06-20 23:32:53 +07:00
committed by Dat H. Pham
parent 002a543865
commit 4ea620cc2b
11 changed files with 86 additions and 70 deletions
@@ -1135,8 +1135,8 @@ class ComposerController extends BaseController {
_emailContents = arguments.emailContents; _emailContents = arguments.emailContents;
emailContentsViewState.value = Right( emailContentsViewState.value = Right(
GetEmailContentSuccess( GetEmailContentSuccess(
emailContents: _emailContents!, emailContent: _emailContents!,
emailContentsDisplayed: [], emailContentDisplayed: '',
attachments: [], attachments: [],
emailCurrent: arguments.presentationEmail?.toEmail() emailCurrent: arguments.presentationEmail?.toEmail()
) )
@@ -1166,7 +1166,7 @@ class ComposerController extends BaseController {
success.attachments.listAttachmentsDisplayedOutSide); success.attachments.listAttachmentsDisplayedOutSide);
} }
emailContentsViewState.value = Right(success); emailContentsViewState.value = Right(success);
_emailContents = success.emailContentString; _emailContents = success.emailContent;
} }
void _getEmailContentSuccess(GetEmailContentSuccess success) { void _getEmailContentSuccess(GetEmailContentSuccess success) {
@@ -1176,7 +1176,7 @@ class ComposerController extends BaseController {
success.attachments.listAttachmentsDisplayedOutSide); success.attachments.listAttachmentsDisplayedOutSide);
} }
emailContentsViewState.value = Right(success); emailContentsViewState.value = Right(success);
_emailContents = success.emailContents; _emailContents = success.emailContent;
} }
String getEmailAddressSender() { String getEmailAddressSender() {
@@ -282,7 +282,7 @@ class ComposerView extends BaseComposerView {
child: loadingWidget, child: loadingWidget,
); );
} else if (success is GetEmailContentSuccess) { } else if (success is GetEmailContentSuccess) {
var contentHtml = success.emailContents; var contentHtml = success.emailContent;
if (contentHtml.isEmpty == true) { if (contentHtml.isEmpty == true) {
contentHtml = HtmlExtension.editorStartTags; contentHtml = HtmlExtension.editorStartTags;
} }
@@ -400,7 +400,7 @@ class ComposerView extends BaseComposerView {
child: loadingWidget, child: loadingWidget,
); );
} else if (success is GetEmailContentSuccess) { } else if (success is GetEmailContentSuccess) {
var contentHtml = success.emailContents; var contentHtml = success.emailContent;
if (contentHtml.isEmpty == true) { if (contentHtml.isEmpty == true) {
contentHtml = HtmlExtension.editorStartTags; contentHtml = HtmlExtension.editorStartTags;
} }
@@ -173,12 +173,6 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
return Future.sync(() async { return Future.sync(() async {
final task = HiveTask( final task = HiveTask(
runnable: () async { runnable: () async {
final detailedEmailExisted = await _openedEmailCacheManager.isOpenedEmailAlreadyStored(accountId, session.username, detailedEmail.emailId);
if (detailedEmailExisted) {
return Future.value();
}
final fileSaved = await _fileUtils.saveToFile( final fileSaved = await _fileUtils.saveToFile(
nameFile: detailedEmail.emailId.asString, nameFile: detailedEmail.emailId.asString,
content: detailedEmail.htmlEmailContent ?? '', content: detailedEmail.htmlEmailContent ?? '',
@@ -4,3 +4,5 @@ class NotFoundStoredOpenedEmailException implements Exception {}
class NotFoundStoredNewEmailException implements Exception {} class NotFoundStoredNewEmailException implements Exception {}
class NotFoundStoredEmailException implements Exception {} class NotFoundStoredEmailException implements Exception {}
class OpenedEmailAlreadyStoredException implements Exception {}
@@ -2,46 +2,45 @@ import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/email/attachment.dart'; import 'package:model/email/attachment.dart';
import 'package:model/email/email_content.dart';
class GetEmailContentLoading extends LoadingState {} class GetEmailContentLoading extends LoadingState {}
class GetEmailContentSuccess extends UIState { class GetEmailContentSuccess extends UIState {
final String emailContents; final String emailContent;
final List<EmailContent> emailContentsDisplayed; final String emailContentDisplayed;
final List<Attachment> attachments; final List<Attachment> attachments;
final Email? emailCurrent; final Email? emailCurrent;
GetEmailContentSuccess({ GetEmailContentSuccess({
required this.emailContents, required this.emailContent,
required this.emailContentsDisplayed, required this.emailContentDisplayed,
required this.attachments, required this.attachments,
required this.emailCurrent required this.emailCurrent
}); });
@override @override
List<Object?> get props => [ List<Object?> get props => [
emailContents, emailContent,
emailContentsDisplayed, emailContentDisplayed,
attachments, attachments,
emailCurrent emailCurrent
]; ];
} }
class GetEmailContentFromCacheSuccess extends UIState { class GetEmailContentFromCacheSuccess extends UIState {
final String emailContentString; final String emailContent;
final List<Attachment> attachments; final List<Attachment> attachments;
final Email? emailCurrent; final Email? emailCurrent;
GetEmailContentFromCacheSuccess({ GetEmailContentFromCacheSuccess({
required this.emailContentString, required this.emailContent,
required this.attachments, required this.attachments,
this.emailCurrent this.emailCurrent
}); });
@override @override
List<Object?> get props => [ List<Object?> get props => [
emailContentString, emailContent,
attachments, attachments,
emailCurrent, emailCurrent,
]; ];
@@ -67,15 +67,15 @@ class GetEmailContentInteractor {
: newEmailContents; : newEmailContents;
yield Right<Failure, Success>(GetEmailContentSuccess( yield Right<Failure, Success>(GetEmailContentSuccess(
emailContents: newEmailContents.asHtmlString, emailContent: newEmailContents.asHtmlString,
emailContentsDisplayed: newEmailContentsDisplayed, emailContentDisplayed: newEmailContentsDisplayed.asHtmlString,
attachments: email.allAttachments, attachments: email.allAttachments,
emailCurrent: email emailCurrent: email
)); ));
} else { } else {
yield Right<Failure, Success>(GetEmailContentSuccess( yield Right<Failure, Success>(GetEmailContentSuccess(
emailContents: '', emailContent: '',
emailContentsDisplayed: [], emailContentDisplayed: '',
attachments: email.allAttachments, attachments: email.allAttachments,
emailCurrent: email emailCurrent: email
)); ));
@@ -99,7 +99,7 @@ class GetEmailContentInteractor {
try { try {
final detailedEmail = await emailRepository.getStoredOpenedEmail(session, accountId, emailId); final detailedEmail = await emailRepository.getStoredOpenedEmail(session, accountId, emailId);
yield Right<Failure, Success>(GetEmailContentFromCacheSuccess( yield Right<Failure, Success>(GetEmailContentFromCacheSuccess(
emailContentString: detailedEmail.htmlEmailContent ?? "", emailContent: detailedEmail.htmlEmailContent ?? "",
attachments: detailedEmail.attachments ?? [], attachments: detailedEmail.attachments ?? [],
emailCurrent: Email( emailCurrent: Email(
id: emailId, id: emailId,
@@ -132,7 +132,7 @@ class GetEmailContentInteractor {
try { try {
final detailedEmail = await emailRepository.getStoredNewEmail(session, accountId, emailId); final detailedEmail = await emailRepository.getStoredNewEmail(session, accountId, emailId);
yield Right<Failure, Success>(GetEmailContentFromCacheSuccess( yield Right<Failure, Success>(GetEmailContentFromCacheSuccess(
emailContentString: detailedEmail.htmlEmailContent ?? "", emailContent: detailedEmail.htmlEmailContent ?? "",
attachments: detailedEmail.attachments ?? [], attachments: detailedEmail.attachments ?? [],
emailCurrent: Email( emailCurrent: Email(
id: emailId, id: emailId,
@@ -1,8 +1,10 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.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/session/session.dart';
import 'package:tmail_ui_user/features/email/domain/exceptions/email_cache_exceptions.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart'; import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/store_opened_email_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/store_opened_email_state.dart';
@@ -19,10 +21,27 @@ class StoreOpenedEmailInteractor {
) async* { ) async* {
try { try {
yield Right<Failure, Success>(StoreOpenedEmailLoading()); yield Right<Failure, Success>(StoreOpenedEmailLoading());
await _emailRepository.storeOpenedEmail(session, accountId, detailedEmail); final isOpenedEmailExist = await _isOpenedEmailAlreadyStored(session, accountId, detailedEmail);
yield Right<Failure, Success>(StoreOpenedEmailSuccess()); log('StoreOpenedEmailInteractor::execute():isOpenedEmailExist: $isOpenedEmailExist');
if (!isOpenedEmailExist) {
await _emailRepository.storeOpenedEmail(session, accountId, detailedEmail);
yield Right<Failure, Success>(StoreOpenedEmailSuccess());
} else {
yield Left<Failure, Success>(StoreOpenedEmailFailure(OpenedEmailAlreadyStoredException()));
}
} catch (e) { } catch (e) {
yield Left<Failure, Success>(StoreOpenedEmailFailure(e)); yield Left<Failure, Success>(StoreOpenedEmailFailure(e));
} }
} }
Future<bool> _isOpenedEmailAlreadyStored(Session session, AccountId accountId, DetailedEmail detailedEmail) async {
try {
final storedOpenEmail = await _emailRepository.getStoredOpenedEmail(session, accountId, detailedEmail.emailId);
log('StoreOpenedEmailInteractor::isOpenedEmailAlreadyStored():storedOpenEmail: $storedOpenEmail');
return true;
} catch (err) {
logError('StoreOpenedEmailInteractor::isOpenedEmailAlreadyStored():EXCEPTION: $err');
return false;
}
}
} }
@@ -151,7 +151,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
if (success is GetEmailContentSuccess) { if (success is GetEmailContentSuccess) {
_getEmailContentSuccess(success); _getEmailContentSuccess(success);
} else if (success is GetEmailContentFromCacheSuccess) { } else if (success is GetEmailContentFromCacheSuccess) {
_getEmailContentOffLineSuccess(success); _getEmailContentOfflineSuccess(success);
} else if (success is MarkAsEmailReadSuccess) { } else if (success is MarkAsEmailReadSuccess) {
_markAsEmailReadSuccess(success); _markAsEmailReadSuccess(success);
} else if (success is ExportAttachmentSuccess) { } else if (success is ExportAttachmentSuccess) {
@@ -350,8 +350,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
await Future.delayed(const Duration(milliseconds: 300)); await Future.delayed(const Duration(milliseconds: 300));
consumeState(Stream.value(Right<Failure, Success>( consumeState(Stream.value(Right<Failure, Success>(
GetEmailContentSuccess( GetEmailContentSuccess(
emailContents: emailLoaded.emailContents, emailContent: emailLoaded.emailContent,
emailContentsDisplayed: emailLoaded.emailContentsDisplayed, emailContentDisplayed: emailLoaded.emailContentDisplayed,
attachments: emailLoaded.attachments, attachments: emailLoaded.attachments,
emailCurrent: emailLoaded.emailCurrent emailCurrent: emailLoaded.emailCurrent
) )
@@ -361,28 +361,47 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
void _getEmailContentOffLineSuccess(GetEmailContentFromCacheSuccess success) { void _getEmailContentOfflineSuccess(GetEmailContentFromCacheSuccess success) {
emailContents.value = success.emailContentString; if (emailSupervisorController.presentationEmailsLoaded.length > ThreadConstants.defaultLimit.value.toInt()) {
attachments.value = success.attachments;
initialEmailContents = success.emailContentString;
}
void _getEmailContentSuccess(GetEmailContentSuccess success) {
if(emailSupervisorController.presentationEmailsLoaded.length > ThreadConstants.defaultLimit.value.toInt()) {
emailSupervisorController.popFirstEmailQueue(); emailSupervisorController.popFirstEmailQueue();
} }
emailSupervisorController.popEmailQueue(success.emailCurrent?.id); emailSupervisorController.popEmailQueue(success.emailCurrent?.id);
emailSupervisorController.pushEmailQueue(EmailLoaded( emailSupervisorController.pushEmailQueue(EmailLoaded(
success.emailContents, success.emailContent,
success.emailContentsDisplayed.toList(), success.emailContent,
success.attachments.toList(), success.attachments.toList(),
success.emailCurrent, success.emailCurrent,
)); ));
if (success.emailCurrent?.id == currentEmail?.id) { if (success.emailCurrent?.id == currentEmail?.id) {
emailContents.value = success.emailContentsDisplayed.asHtmlString; emailContents.value = success.emailContent;
initialEmailContents = success.emailContents; initialEmailContents = success.emailContent;
attachments.value = success.attachments;
final isShowMessageReadReceipt = success.emailCurrent?.hasReadReceipt(mailboxDashBoardController.mapMailboxById) == true;
if (isShowMessageReadReceipt) {
_handleReadReceipt();
}
}
}
void _getEmailContentSuccess(GetEmailContentSuccess success) {
if (emailSupervisorController.presentationEmailsLoaded.length > ThreadConstants.defaultLimit.value.toInt()) {
emailSupervisorController.popFirstEmailQueue();
}
emailSupervisorController.popEmailQueue(success.emailCurrent?.id);
emailSupervisorController.pushEmailQueue(EmailLoaded(
success.emailContent,
success.emailContentDisplayed,
success.attachments.toList(),
success.emailCurrent,
));
if (success.emailCurrent?.id == currentEmail?.id) {
emailContents.value = success.emailContentDisplayed;
initialEmailContents = success.emailContent;
attachments.value = success.attachments; attachments.value = success.attachments;
if (PlatformInfo.isMobile) { if (PlatformInfo.isMobile) {
@@ -1,24 +1,24 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart'; import 'package:model/email/attachment.dart';
class EmailLoaded with EquatableMixin { class EmailLoaded with EquatableMixin {
final String emailContents; final String emailContent;
final List<EmailContent> emailContentsDisplayed; final String emailContentDisplayed;
final List<Attachment> attachments; final List<Attachment> attachments;
final Email? emailCurrent; final Email? emailCurrent;
EmailLoaded( EmailLoaded(
this.emailContents, this.emailContent,
this.emailContentsDisplayed, this.emailContentDisplayed,
this.attachments, this.attachments,
this.emailCurrent, this.emailCurrent,
); );
@override @override
List<Object?> get props => [ List<Object?> get props => [
emailContents, emailContent,
emailContentsDisplayed, emailContentDisplayed,
attachments, attachments,
emailCurrent emailCurrent
]; ];
@@ -69,23 +69,6 @@ class OpenedEmailCacheManager {
return detailedEmailCache; return detailedEmailCache;
} }
Future<bool> isOpenedEmailAlreadyStored(
AccountId accountId,
UserName userName,
EmailId emailId
) async {
final listResult = await Future.wait([
getStoredOpenedEmail(accountId, userName, emailId),
_fileUtils.isFileExisted(
nameFile: emailId.asString,
folderPath: CachingConstants.openedEmailContentFolderName)
], eagerError: true);
final emailContentPathExists = listResult.last as bool;
return emailContentPathExists;
}
Future<DetailedEmailHiveCache> getStoredOpenedEmail( Future<DetailedEmailHiveCache> getStoredOpenedEmail(
AccountId accountId, AccountId accountId,
UserName userName, UserName userName,