TF-1809: Handle sync data from cache and network when get email contents
(cherry picked from commit 896059cd5b29c62c2cf34621fe35d7b23a54acf4)
This commit is contained in:
@@ -55,6 +55,16 @@ class FileUtils {
|
||||
return await file.writeAsString(content, mode: FileMode.append);
|
||||
}
|
||||
|
||||
Future<void> deleteFile(String filePath) async {
|
||||
final file = File(filePath);
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
log("FileUtils()::deleteFile: $file");
|
||||
} else {
|
||||
log("FileUtils()::deleteFile: File does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getContentFromFile({
|
||||
required String nameFile,
|
||||
String? folderPath,
|
||||
|
||||
@@ -20,7 +20,8 @@ class CachingConstants {
|
||||
|
||||
static const String fcmCacheBoxName = 'fcm_cache_box';
|
||||
static const String detailedEmailCacheBoxName = 'detailed_email_cache_box';
|
||||
static const String emailContentFolderName = 'email_content';
|
||||
static const String newEmailContentFolderName = 'new_email';
|
||||
static const String openedEmailContentFolderNamee = 'opened_email';
|
||||
static const String openedEmailCacheBoxName = 'opened_email_cache_box';
|
||||
|
||||
static const int maxNumberNewEmailsForOffline = 10;
|
||||
|
||||
@@ -140,7 +140,7 @@ class ComposerController extends BaseController {
|
||||
List<Attachment> initialAttachments = <Attachment>[];
|
||||
String? _textEditorWeb;
|
||||
String? _initTextEditor;
|
||||
List<EmailContent>? _emailContents;
|
||||
String? _emailContents;
|
||||
double? maxWithEditor;
|
||||
late Worker uploadInlineImageWorker;
|
||||
|
||||
@@ -281,6 +281,8 @@ class ComposerController extends BaseController {
|
||||
_pickFileSuccess(success);
|
||||
} else if (success is GetEmailContentSuccess) {
|
||||
_getEmailContentSuccess(success);
|
||||
} else if (success is GetEmailContentFromCacheSuccess) {
|
||||
_getEmailContentOffLineSuccess(success);
|
||||
} else if (success is GetAllIdentitiesSuccess) {
|
||||
_handleGetAllIdentitiesSuccess(success);
|
||||
} else if (success is DownloadImageAsBase64Success) {
|
||||
@@ -595,7 +597,7 @@ class ComposerController extends BaseController {
|
||||
log('ComposerController::getEmailContentQuotedAsHtml(): headerEmailQuoted: $headerEmailQuoted');
|
||||
final headerEmailQuotedAsHtml = headerEmailQuoted != null ? headerEmailQuoted.addBlockTag('cite') : '';
|
||||
|
||||
final trustAsHtml = arguments.emailContents?.asHtmlString ?? '';
|
||||
final trustAsHtml = arguments.emailContents ?? '';
|
||||
final emailQuotedHtml = '${HtmlExtension.editorStartTags}$headerEmailQuotedAsHtml${trustAsHtml.addBlockQuoteTag()}';
|
||||
|
||||
return emailQuotedHtml;
|
||||
@@ -1108,8 +1110,7 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
|
||||
if(arguments.emailContents != null && arguments.emailContents!.isNotEmpty) {
|
||||
_emailContents = arguments.emailContents;
|
||||
emailContentsViewState.value = Right(GetEmailContentSuccess(_emailContents!, [], [], null));
|
||||
emailContentsViewState.value = Right(GetEmailContentFromCacheSuccess(arguments.emailContents!, []));
|
||||
} else {
|
||||
final session = mailboxDashBoardController.sessionCurrent;
|
||||
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(jmapUrl: _dynamicUrlInterceptors.jmapUrl);
|
||||
@@ -1128,6 +1129,16 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
void _getEmailContentOffLineSuccess(GetEmailContentFromCacheSuccess success) {
|
||||
if (success.attachments.isNotEmpty) {
|
||||
initialAttachments = success.attachments;
|
||||
uploadController.initializeUploadAttachments(
|
||||
success.attachments.listAttachmentsDisplayedOutSide);
|
||||
}
|
||||
emailContentsViewState.value = Right(success);
|
||||
_emailContents = success.emailContentString;
|
||||
}
|
||||
|
||||
void _getEmailContentSuccess(GetEmailContentSuccess success) {
|
||||
if (success.attachments.isNotEmpty) {
|
||||
initialAttachments = success.attachments;
|
||||
@@ -1135,10 +1146,10 @@ class ComposerController extends BaseController {
|
||||
success.attachments.listAttachmentsDisplayedOutSide);
|
||||
}
|
||||
emailContentsViewState.value = Right(success);
|
||||
_emailContents = success.emailContents;
|
||||
_emailContents = success.emailContents.asHtmlString;
|
||||
}
|
||||
|
||||
String? getEmailContentDraftsAsHtml() => _emailContents?.asHtmlString;
|
||||
String? getEmailContentDraftsAsHtml() => _emailContents;
|
||||
|
||||
String getEmailAddressSender() {
|
||||
final arguments = composerArguments.value;
|
||||
|
||||
@@ -124,7 +124,7 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
final fileSaved = await _fileUtils.saveToFile(
|
||||
nameFile: detailedEmail.emailId.asString,
|
||||
content: detailedEmail.htmlEmailContent ?? '',
|
||||
folderPath: detailedEmail.folderPath
|
||||
folderPath: detailedEmail.newEmailFolderPath
|
||||
);
|
||||
log('EmailHiveCacheDataSourceImpl::storeDetailedEmailToCache():fileSavedPath: ${fileSaved.path}');
|
||||
final detailedEmailSaved = detailedEmail.fromEmailContentPath(fileSaved.path);
|
||||
@@ -163,7 +163,7 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
final task = HiveTask(
|
||||
runnable: () async {
|
||||
|
||||
final detailedEmailExisted = await _openedEmailCacheManager.isOpenedDetailEmailCached(accountId, session.username, detailedEmail);
|
||||
final detailedEmailExisted = await _openedEmailCacheManager.isOpenedDetailEmailCached(accountId, session.username, detailedEmail.emailId);
|
||||
log('EmailHiveCacheDataSourceImpl::storeOpenedEmail():detailedEmailExisted: $detailedEmailExisted');
|
||||
|
||||
if (detailedEmailExisted) {
|
||||
@@ -173,7 +173,7 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
final fileSaved = await _fileUtils.saveToFile(
|
||||
nameFile: detailedEmail.emailId.asString,
|
||||
content: detailedEmail.htmlEmailContent ?? '',
|
||||
folderPath: detailedEmail.folderPath
|
||||
folderPath: detailedEmail.openedEmailFolderPath
|
||||
);
|
||||
|
||||
log('EmailHiveCacheDataSourceImpl::storeOpenedEmail():fileSavedPath: ${fileSaved.path}');
|
||||
@@ -196,7 +196,7 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
|
||||
final emailContent = await _fileUtils.getContentFromFile(
|
||||
nameFile: emailId.asString,
|
||||
folderPath: CachingConstants.emailContentFolderName
|
||||
folderPath: CachingConstants.openedEmailContentFolderNamee
|
||||
);
|
||||
|
||||
return detailedEmailHiveCache?.toDetailedEmailWithContent(emailContent);
|
||||
|
||||
@@ -205,7 +205,7 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DetailedEmail> getOpenedEmail(Session session, AccountId accountId, EmailId emailId) {
|
||||
throw UnimplementedError();
|
||||
Future<DetailedEmail?> getOpenedEmail(Session session, AccountId accountId, EmailId emailId) {
|
||||
return emailDataSource[DataSourceType.hiveCache]!.getOpenedEmail(session, accountId, emailId);
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,13 @@ import 'package:tmail_ui_user/features/offline_mode/model/attachment_hive_cache.
|
||||
extension AttachmentExtension on AttachmentHiveCache {
|
||||
Attachment toAttachment() {
|
||||
return Attachment(
|
||||
partId: PartId(partId!),
|
||||
blobId: Id(blobId!),
|
||||
size: UnsignedInt(size!),
|
||||
name: name,
|
||||
type: MediaType.parse(type!),
|
||||
cid: cid,
|
||||
disposition: disposition?.toContentDisposition(),
|
||||
partId: partId != null ? PartId(partId!) : null,
|
||||
blobId: blobId != null ? Id(blobId!) : null,
|
||||
size: size != null ? UnsignedInt(size!) : null,
|
||||
name: name,
|
||||
type: type != null ? MediaType.parse(type!) : null,
|
||||
cid: cid,
|
||||
disposition: disposition?.toContentDisposition(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,9 @@ extension DetailedEmailExtension on DetailedEmail {
|
||||
);
|
||||
}
|
||||
|
||||
String get folderPath => CachingConstants.emailContentFolderName;
|
||||
String get newEmailFolderPath => CachingConstants.newEmailContentFolderName;
|
||||
|
||||
String get openedEmailFolderPath => CachingConstants.openedEmailContentFolderNamee;
|
||||
|
||||
DetailedEmail fromEmailContentPath(String path) {
|
||||
return DetailedEmail(
|
||||
|
||||
@@ -96,5 +96,5 @@ abstract class EmailRepository {
|
||||
|
||||
Future<void> storeOpenedEmail(Session session, AccountId accountId, DetailedEmail detailedEmail);
|
||||
|
||||
Future<DetailedEmail> getOpenedEmail(Session session, AccountId accountId, EmailId emailId);
|
||||
Future<DetailedEmail?> getOpenedEmail(Session session, AccountId accountId, EmailId emailId);
|
||||
}
|
||||
@@ -26,6 +26,22 @@ class GetEmailContentSuccess extends UIState {
|
||||
];
|
||||
}
|
||||
|
||||
class GetEmailContentFromCacheSuccess extends UIState {
|
||||
final String emailContentString;
|
||||
final List<Attachment> attachments;
|
||||
|
||||
GetEmailContentFromCacheSuccess(
|
||||
this.emailContentString,
|
||||
this.attachments,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
emailContentString,
|
||||
attachments,
|
||||
];
|
||||
}
|
||||
|
||||
class GetEmailContentFailure extends FeatureFailure {
|
||||
final dynamic exception;
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
|
||||
|
||||
class GetOpenedEmailLoading extends UIState {}
|
||||
|
||||
class GetOpenedEmailSuccess extends UIState {
|
||||
final DetailedEmail detailedEmail;
|
||||
|
||||
GetOpenedEmailSuccess(this.detailedEmail);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [detailedEmail];
|
||||
}
|
||||
|
||||
class GetOpenedEmailFailure extends FeatureFailure {
|
||||
|
||||
GetOpenedEmailFailure(dynamic exception) : super(exception: exception);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [exception];
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
@@ -28,37 +30,85 @@ class GetEmailContentInteractor {
|
||||
) async* {
|
||||
try {
|
||||
yield Right<Failure, Success>(GetEmailContentLoading());
|
||||
final email = await emailRepository.getEmailContent(session, accountId, emailId);
|
||||
|
||||
if (email.emailContentList.isNotEmpty) {
|
||||
final newEmailContents = await emailRepository.transformEmailContent(
|
||||
email.emailContentList,
|
||||
email.allAttachments.listAttachmentsDisplayedInContent,
|
||||
baseDownloadUrl,
|
||||
accountId,
|
||||
draftsEmail: draftsEmail
|
||||
);
|
||||
|
||||
final newEmailContentsDisplayed = BuildUtils.isWeb && !composeEmail
|
||||
? await emailRepository.addTooltipWhenHoverOnLink(newEmailContents)
|
||||
: newEmailContents;
|
||||
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess(
|
||||
newEmailContents,
|
||||
newEmailContentsDisplayed,
|
||||
email.allAttachments,
|
||||
email
|
||||
));
|
||||
} else if (email.allAttachments.isNotEmpty) {
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess([], [], email.allAttachments, email));
|
||||
} else if (email.headers?.isNotEmpty == true) {
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess([], [], [], email));
|
||||
if (!BuildUtils.isWeb) {
|
||||
yield* _tryToGetOpenedEmailCache(session, accountId, emailId, baseDownloadUrl, composeEmail: composeEmail, draftsEmail: draftsEmail);
|
||||
} else {
|
||||
yield Left(GetEmailContentFailure(null));
|
||||
yield* _getContentEmailFromServer(session, accountId, emailId, baseDownloadUrl, composeEmail: composeEmail, draftsEmail: draftsEmail);
|
||||
}
|
||||
} catch (e) {
|
||||
log('GetEmailContentInteractor::execute(): exception = $e');
|
||||
yield Left(GetEmailContentFailure(e));
|
||||
}
|
||||
}
|
||||
|
||||
Stream<Either<Failure, Success>> _getContentEmailFromServer(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String? baseDownloadUrl,
|
||||
{
|
||||
bool composeEmail = false,
|
||||
bool draftsEmail = false
|
||||
}
|
||||
) async* {
|
||||
final email = await emailRepository.getEmailContent(session, accountId, emailId);
|
||||
|
||||
if (email.emailContentList.isNotEmpty) {
|
||||
final newEmailContents = await emailRepository.transformEmailContent(
|
||||
email.emailContentList,
|
||||
email.allAttachments.listAttachmentsDisplayedInContent,
|
||||
baseDownloadUrl,
|
||||
accountId,
|
||||
draftsEmail: draftsEmail
|
||||
);
|
||||
|
||||
final newEmailContentsDisplayed = BuildUtils.isWeb && !composeEmail
|
||||
? await emailRepository.addTooltipWhenHoverOnLink(newEmailContents)
|
||||
: newEmailContents;
|
||||
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess(
|
||||
newEmailContents,
|
||||
newEmailContentsDisplayed,
|
||||
email.allAttachments,
|
||||
email
|
||||
));
|
||||
} else if (email.allAttachments.isNotEmpty) {
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess([], [], email.allAttachments, email));
|
||||
} else if (email.headers?.isNotEmpty == true) {
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess([], [], [], email));
|
||||
} else {
|
||||
yield Left(GetEmailContentFailure(null));
|
||||
}
|
||||
}
|
||||
|
||||
Stream<Either<Failure, Success>> _tryToGetOpenedEmailCache(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String? baseDownloadUrl,
|
||||
{
|
||||
bool composeEmail = false,
|
||||
bool draftsEmail = false
|
||||
}
|
||||
) async* {
|
||||
log('GetEmailContentInteractor::_getOpenedEmailCache():');
|
||||
try {
|
||||
final detailedEmail = await emailRepository.getOpenedEmail(session, accountId, emailId);
|
||||
if (detailedEmail != null) {
|
||||
yield Right<Failure, Success>(GetEmailContentFromCacheSuccess(
|
||||
detailedEmail.htmlEmailContent ?? "",
|
||||
detailedEmail.attachments ?? [],
|
||||
));
|
||||
} else {
|
||||
yield* _getContentEmailFromServer(session, accountId, emailId, baseDownloadUrl, composeEmail: composeEmail, draftsEmail: draftsEmail);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e is PathNotFoundException) {
|
||||
yield* _getContentEmailFromServer(session, accountId, emailId, baseDownloadUrl, composeEmail: composeEmail, draftsEmail: draftsEmail);
|
||||
} else {
|
||||
yield Left<Failure, Success>(GetEmailContentFailure(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +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/session/session.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/get_opened_email_from_cache_state.dart';
|
||||
|
||||
class GetOpenedEmailFromCacheInteractor {
|
||||
final EmailRepository _emailRepository;
|
||||
|
||||
GetOpenedEmailFromCacheInteractor(this._emailRepository);
|
||||
|
||||
Stream<Either<Failure, Success>> execute(Session session, AccountId accountId, EmailId emailId) async* {
|
||||
try {
|
||||
yield Right<Failure, Success>(GetOpenedEmailLoading());
|
||||
final detailedEmail = await _emailRepository.getOpenedEmail(session, accountId, emailId);
|
||||
yield Right<Failure, Success>(GetOpenedEmailSuccess(detailedEmail));
|
||||
} catch (e) {
|
||||
yield Left<Failure, Success>(GetOpenedEmailFailure(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,11 +100,11 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
|
||||
final emailAddressExpandMode = ExpandMode.COLLAPSE.obs;
|
||||
final attachmentsExpandMode = ExpandMode.COLLAPSE.obs;
|
||||
final emailContents = <EmailContent>[].obs;
|
||||
final emailContents = RxnString();
|
||||
final attachments = <Attachment>[].obs;
|
||||
EmailId? _currentEmailId;
|
||||
Identity? _identitySelected;
|
||||
List<EmailContent>? initialEmailContents;
|
||||
String? initialEmailContents;
|
||||
|
||||
final ScrollController scrollControllerAttachment = ScrollController();
|
||||
|
||||
@@ -150,6 +150,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
super.handleSuccessViewState(success);
|
||||
if (success is GetEmailContentSuccess) {
|
||||
_getEmailContentSuccess(success);
|
||||
} else if (success is GetEmailContentFromCacheSuccess) {
|
||||
_getEmailContentOffLineSuccess(success);
|
||||
} else if (success is MarkAsEmailReadSuccess) {
|
||||
_markAsEmailReadSuccess(success);
|
||||
} else if (success is ExportAttachmentSuccess) {
|
||||
@@ -356,6 +358,12 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
}
|
||||
}
|
||||
|
||||
void _getEmailContentOffLineSuccess(GetEmailContentFromCacheSuccess success) {
|
||||
emailContents.value = success.emailContentString;
|
||||
attachments.value = success.attachments;
|
||||
initialEmailContents = success.emailContentString;
|
||||
}
|
||||
|
||||
void _getEmailContentSuccess(GetEmailContentSuccess success) {
|
||||
if(emailSupervisorController.presentationEmailsLoaded.length > ThreadConstants.defaultLimit.value.toInt()) {
|
||||
emailSupervisorController.popFirstEmailQueue();
|
||||
@@ -370,8 +378,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
));
|
||||
|
||||
if (success.emailCurrent?.id == currentEmail?.id) {
|
||||
emailContents.value = success.emailContentsDisplayed;
|
||||
initialEmailContents = success.emailContents;
|
||||
emailContents.value = success.emailContentsDisplayed.asHtmlString;
|
||||
initialEmailContents = success.emailContents.asHtmlString;
|
||||
attachments.value = success.attachments;
|
||||
|
||||
if (!BuildUtils.isWeb) {
|
||||
@@ -379,7 +387,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
emailId: currentEmail!.id!,
|
||||
attachments: attachments,
|
||||
headers: currentEmail?.emailHeader,
|
||||
htmlEmailContent: emailContents.asHtmlString
|
||||
htmlEmailContent: emailContents.value
|
||||
);
|
||||
|
||||
_storeOpenedEmailToCache(
|
||||
@@ -414,8 +422,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
void _resetToOriginalValue() {
|
||||
attachmentsExpandMode.value = ExpandMode.COLLAPSE;
|
||||
emailAddressExpandMode.value = ExpandMode.COLLAPSE;
|
||||
emailContents.clear();
|
||||
initialEmailContents?.clear();
|
||||
emailContents.value = null;
|
||||
initialEmailContents = null;
|
||||
attachments.clear();
|
||||
}
|
||||
|
||||
@@ -1133,7 +1141,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
presentationEmail: mailboxDashBoardController.selectedEmail.value!,
|
||||
emailContents: initialEmailContents,
|
||||
attachments: emailActionType == EmailActionType.forward ? attachments : null,
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role);
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role
|
||||
);
|
||||
|
||||
mailboxDashBoardController.goToComposer(arguments);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import 'package:model/email/attachment.dart';
|
||||
import 'package:model/email/email_action_type.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:model/extensions/list_attachment_extension.dart';
|
||||
import 'package:model/extensions/list_email_content_extension.dart';
|
||||
import 'package:model/extensions/presentation_email_extension.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/custom_scroll_behavior.dart';
|
||||
@@ -441,20 +440,20 @@ class EmailView extends GetWidget<SingleEmailController> {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Obx(() {
|
||||
if (controller.emailContents.isNotEmpty) {
|
||||
final allEmailContents = controller.emailContents.asHtmlString;
|
||||
if (controller.emailContents.value != null) {
|
||||
final allEmailContents = controller.emailContents.value;
|
||||
|
||||
if (BuildUtils.isWeb) {
|
||||
return HtmlContentViewerOnWeb(
|
||||
widthContent: constraints.maxWidth,
|
||||
heightContent: responsiveUtils.getSizeScreenHeight(context),
|
||||
contentHtml: allEmailContents,
|
||||
contentHtml: allEmailContents ?? "",
|
||||
controller: HtmlViewerControllerForWeb(),
|
||||
mailtoDelegate: (uri) => controller.openMailToLink(uri));
|
||||
} else {
|
||||
return HtmlContentViewer(
|
||||
heightContent: responsiveUtils.getSizeScreenHeight(context),
|
||||
contentHtml: allEmailContents,
|
||||
contentHtml: allEmailContents ?? "",
|
||||
mailtoDelegate: (uri) async => controller.openMailToLink(uri),
|
||||
onScrollHorizontalEnd: controller.toggleScrollPhysicsPagerView,
|
||||
onWebViewLoaded: (isScrollPageViewActivated) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'package:tmail_ui_user/main/routes/router_arguments.dart';
|
||||
class ComposerArguments extends RouterArguments {
|
||||
final EmailActionType emailActionType;
|
||||
final PresentationEmail? presentationEmail;
|
||||
final List<EmailContent>? emailContents;
|
||||
final String? emailContents;
|
||||
final List<SharedMediaFile>? listSharedMediaFile;
|
||||
final EmailAddress? emailAddress;
|
||||
final List<Attachment>? attachments;
|
||||
|
||||
+2
-2
@@ -240,7 +240,7 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
cc: success.composerCache.cc,
|
||||
bcc: success.composerCache.bcc,
|
||||
),
|
||||
emailContents: success.composerCache.emailContentList,
|
||||
emailContents: success.composerCache.emailContentList.asHtmlString,
|
||||
);
|
||||
openComposerOverlay(composerArguments);
|
||||
}
|
||||
@@ -350,7 +350,7 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
_emailReceiveManager.clearPendingEmailContent();
|
||||
final arguments = ComposerArguments(
|
||||
emailActionType: EmailActionType.edit,
|
||||
emailContents: [emailContent],
|
||||
emailContents: [emailContent].asHtmlString,
|
||||
mailboxRole: selectedMailbox.value?.role);
|
||||
goToComposer(arguments);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/file_utils.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||
import 'package:model/extensions/account_id_extensions.dart';
|
||||
@@ -12,8 +13,9 @@ import 'package:tmail_ui_user/features/offline_mode/model/detailed_email_hive_ca
|
||||
class DetailedEmailCacheManager {
|
||||
|
||||
final DetailedEmailHiveCacheClient _cacheClient;
|
||||
final FileUtils _fileUtils;
|
||||
|
||||
DetailedEmailCacheManager(this._cacheClient);
|
||||
DetailedEmailCacheManager(this._cacheClient, this._fileUtils);
|
||||
|
||||
Future<DetailedEmailHiveCache> handleStoreDetailedEmail(
|
||||
AccountId accountId,
|
||||
@@ -23,9 +25,14 @@ class DetailedEmailCacheManager {
|
||||
final listDetailedEmails = await getAllDetailedEmails(accountId, userName);
|
||||
|
||||
if (listDetailedEmails.length >= CachingConstants.maxNumberNewEmailsForOffline) {
|
||||
final latestEmail = listDetailedEmails.last;
|
||||
log('DetailedEmailCacheManager::handleStoreDetailedEmail():latestEmail: $latestEmail');
|
||||
await removeDetailedEmail(accountId, userName, latestEmail.emailId);
|
||||
final lastElementsListEmail = listDetailedEmails.sublist(CachingConstants.maxNumberNewEmailsForOffline, listDetailedEmails.length);
|
||||
for (var email in lastElementsListEmail) {
|
||||
log('DetailedEmailCacheManager::handleStoreDetailedEmail():latestEmail: $email');
|
||||
if (email.emailContentPath != null) {
|
||||
await _deleteFileExisted(email.emailContentPath!);
|
||||
}
|
||||
await removeDetailedEmail(accountId, userName, email.emailId);
|
||||
}
|
||||
}
|
||||
await insertDetailedEmail(accountId, userName, detailedEmailCache);
|
||||
|
||||
@@ -58,4 +65,8 @@ class DetailedEmailCacheManager {
|
||||
log('DetailedEmailCacheManager::getAllDetailedEmails():SIZE: ${detailedEmailCacheList.length}');
|
||||
return detailedEmailCacheList;
|
||||
}
|
||||
|
||||
Future<void> _deleteFileExisted(String pathFile) async {
|
||||
await _fileUtils.deleteFile(pathFile);
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,9 @@ class OpenedEmailCacheManager {
|
||||
OpenedEmailCacheManager(this._cacheClient, this._fileUtils);
|
||||
|
||||
Future<void> insertDetailedEmail(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
DetailedEmailHiveCache detailedEmailCache
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
DetailedEmailHiveCache detailedEmailCache
|
||||
) {
|
||||
final keyCache = TupleKey(detailedEmailCache.emailId, accountId.asString, userName.value).encodeKey;
|
||||
log('OpenedEmailCacheManager::insertDetailedEmail(): $keyCache');
|
||||
@@ -31,9 +31,9 @@ class OpenedEmailCacheManager {
|
||||
}
|
||||
|
||||
Future<void> removeDetailedEmail(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
String emailId
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
String emailId
|
||||
) {
|
||||
final keyCache = TupleKey(emailId, accountId.asString, userName.value).encodeKey;
|
||||
log('OpenedEmailCacheManager::removeDetailedEmail(): $keyCache');
|
||||
@@ -48,35 +48,40 @@ class OpenedEmailCacheManager {
|
||||
}
|
||||
|
||||
Future<void> storeOpenedEmail(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
DetailedEmail detailedEmail
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
DetailedEmail detailedEmail
|
||||
) async {
|
||||
final listDetailedEmails = await getAllDetailedEmails(accountId, userName);
|
||||
|
||||
if (listDetailedEmails.length >= CachingConstants.maxNumberOpenedEmailsForOffline) {
|
||||
final latestEmail = listDetailedEmails.last;
|
||||
log('OpenedEmailCacheManager::handleStoreDetailedEmail():latestEmail: $latestEmail');
|
||||
await removeDetailedEmail(accountId, userName, latestEmail.emailId);
|
||||
final lastElementsListEmail = listDetailedEmails.sublist(CachingConstants.maxNumberOpenedEmailsForOffline, listDetailedEmails.length);
|
||||
for (var email in lastElementsListEmail) {
|
||||
log('OpenedEmailCacheManager::handleStoreDetailedEmail():latestEmail: $email');
|
||||
if (email.emailContentPath != null) {
|
||||
await _deleteFileExisted(email.emailContentPath!);
|
||||
}
|
||||
await removeDetailedEmail(accountId, userName, email.emailId);
|
||||
}
|
||||
}
|
||||
await insertDetailedEmail(accountId, userName, detailedEmail.toHiveCache());
|
||||
}
|
||||
|
||||
Future<bool> isOpenedDetailEmailCached(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
DetailedEmail detailedEmail
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
EmailId emailId
|
||||
) async {
|
||||
final emailContentPathExists = await _isFileExisted(detailedEmail);
|
||||
final detailedEmailCacheExists = await getDetailEmailExistedInCache(accountId, userName, detailedEmail.emailId);
|
||||
final emailContentPathExists = await _isFileExisted(emailId);
|
||||
final detailedEmailCacheExists = await getDetailEmailExistedInCache(accountId, userName, emailId);
|
||||
|
||||
return emailContentPathExists == true && detailedEmailCacheExists != null;
|
||||
}
|
||||
|
||||
Future<bool?> _isFileExisted(DetailedEmail detailedEmail) async {
|
||||
Future<bool?> _isFileExisted(EmailId emailId) async {
|
||||
final fileSaved = await _fileUtils.isFileExisted(
|
||||
nameFile: detailedEmail.emailId.asString,
|
||||
folderPath: detailedEmail.folderPath,
|
||||
nameFile: emailId.asString,
|
||||
folderPath: CachingConstants.openedEmailContentFolderNamee,
|
||||
);
|
||||
log('OpenedEmailCacheManager::_getDetailedEmailCache():_getEmailContentPath: $fileSaved');
|
||||
return fileSaved;
|
||||
@@ -93,4 +98,7 @@ class OpenedEmailCacheManager {
|
||||
return detailedEmailCache;
|
||||
}
|
||||
|
||||
Future<void> _deleteFileExisted(String pathFile) async {
|
||||
await _fileUtils.deleteFile(pathFile);
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ class LocalBindings extends Bindings {
|
||||
Get.put(FCMCacheManager(Get.find<FcmCacheClient>(),Get.find<FCMSubscriptionCacheClient>()));
|
||||
Get.put(HiveCacheVersionClient(Get.find<SharedPreferences>(), Get.find<CacheExceptionThrower>()));
|
||||
Get.put(DetailedEmailHiveCacheClient());
|
||||
Get.put(DetailedEmailCacheManager(Get.find<DetailedEmailHiveCacheClient>()));
|
||||
Get.put(DetailedEmailCacheManager(Get.find<DetailedEmailHiveCacheClient>(), Get.find<FileUtils>()));
|
||||
Get.put(OpenedEmailHiveCacheClient());
|
||||
Get.put(OpenedEmailCacheManager(Get.find<OpenedEmailHiveCacheClient>(), Get.find<FileUtils>()));
|
||||
Get.put(CachingManager(
|
||||
|
||||
Reference in New Issue
Block a user