TF-1923 Fix logic store opened email
(cherry picked from commit 8d9c8d3ee8ea519e683d5a7cbb5b080d2f78e292)
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user