TF-2785 Fix print feature empty when clicked too early

This commit is contained in:
dab246
2024-04-08 13:35:54 +07:00
committed by Dat H. Pham
parent 4c4a02ce7a
commit 6f10eacbb3
7 changed files with 128 additions and 22 deletions
@@ -0,0 +1,19 @@
import 'package:core/data/network/dio_client.dart';
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
import 'package:html/dom.dart';
class RemoveLazyLoadingImageTransformer extends DomTransformer {
const RemoveLazyLoadingImageTransformer();
@override
Future<void> process({
required Document document,
required DioClient dioClient,
Map<String, String>? mapUrlDownloadCID,
}) async {
final elements = document.querySelectorAll('img[loading]');
await Future.wait(elements.map((element) async {
element.attributes.remove('loading');
}));
}
}
@@ -9,6 +9,7 @@ import 'package:core/presentation/utils/html_transformer/dom/blockquoted_transfo
import 'package:core/presentation/utils/html_transformer/dom/image_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/image_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/remove_collapsed_signature_button_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_collapsed_signature_button_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/remove_lazy_loading_for_background_image_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_lazy_loading_for_background_image_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/remove_lazy_loading_image_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/remove_max_width_in_image_style_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_max_width_in_image_style_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/remove_style_tag_outside_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_style_tag_outside_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/remove_tooltip_link_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_tooltip_link_transformers.dart';
@@ -67,6 +68,7 @@ class TransformConfiguration {
if (PlatformInfo.isWeb) if (PlatformInfo.isWeb)
const RemoveTooltipLinkTransformer(), const RemoveTooltipLinkTransformer(),
const RemoveLazyLoadingForBackgroundImageTransformer(), const RemoveLazyLoadingForBackgroundImageTransformer(),
const RemoveLazyLoadingImageTransformer(),
const RemoveCollapsedSignatureButtonTransformer(), const RemoveCollapsedSignatureButtonTransformer(),
const RemoveStyleTagOutsideTransformer(), const RemoveStyleTagOutsideTransformer(),
const RemoveMaxWidthInImageStyleTransformer(), const RemoveMaxWidthInImageStyleTransformer(),
@@ -1,6 +1,12 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.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/extensions/list_email_address_extension.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
import 'package:tmail_ui_user/features/email/presentation/model/email_loaded.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailPrint with EquatableMixin { class EmailPrint with EquatableMixin {
final String appName; final String appName;
@@ -39,6 +45,30 @@ class EmailPrint with EquatableMixin {
this.replyToAddress, this.replyToAddress,
}); });
factory EmailPrint.generate({
required PrintEmailAction printEmailAction,
required EmailLoaded emailLoaded
}) {
return EmailPrint(
appName: AppLocalizations.of(printEmailAction.context).app_name,
userName: printEmailAction.userEmail,
emailInformation: printEmailAction.email.toEmail(),
attachments: emailLoaded.attachments,
emailContent: emailLoaded.htmlContent,
locale: Localizations.localeOf(printEmailAction.context).toLanguageTag(),
fromPrefix: AppLocalizations.of(printEmailAction.context).from_email_address_prefix,
toPrefix: AppLocalizations.of(printEmailAction.context).to_email_address_prefix,
ccPrefix: AppLocalizations.of(printEmailAction.context).cc_email_address_prefix,
bccPrefix: AppLocalizations.of(printEmailAction.context).bcc_email_address_prefix,
replyToPrefix: AppLocalizations.of(printEmailAction.context).replyToEmailAddressPrefix,
titleAttachment: AppLocalizations.of(printEmailAction.context).attachments.toLowerCase(),
toAddress: printEmailAction.email.to?.listEmailAddressToString(isFullEmailAddress: true),
ccAddress: printEmailAction.email.cc?.listEmailAddressToString(isFullEmailAddress: true),
bccAddress: printEmailAction.email.bcc?.listEmailAddressToString(isFullEmailAddress: true),
replyToAddress: printEmailAction.email.replyTo?.listEmailAddressToString(isFullEmailAddress: true),
);
}
@override @override
List<Object?> get props => [ List<Object?> get props => [
appName, appName,
@@ -14,7 +14,6 @@ class PrintEmailInteractor {
Stream<Either<Failure, Success>> execute(EmailPrint emailPrint) async* { Stream<Either<Failure, Success>> execute(EmailPrint emailPrint) async* {
try { try {
yield Right(PrintEmailLoading());
final htmlContentTransformed = await _transformHtmlEmailContent(emailPrint.emailContent); final htmlContentTransformed = await _transformHtmlEmailContent(emailPrint.emailContent);
final newEmailPrint = emailPrint.fromEmailContent(htmlContentTransformed); final newEmailPrint = emailPrint.fromEmailContent(htmlContentTransformed);
await emailRepository.printEmail(newEmailPrint); await emailRepository.printEmail(newEmailPrint);
@@ -1,5 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:model/email/presentation_email.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart'; import 'package:tmail_ui_user/features/base/action/ui_action.dart';
class EmailUIAction extends UIAction { class EmailUIAction extends UIAction {
@@ -22,4 +24,20 @@ class RefreshChangeEmailAction extends EmailUIAction {
class CloseEmailDetailedViewToRedirectToTheInboxAction extends EmailUIAction {} class CloseEmailDetailedViewToRedirectToTheInboxAction extends EmailUIAction {}
class CloseEmailDetailedViewAction extends EmailUIAction {} class CloseEmailDetailedViewAction extends EmailUIAction {}
class PrintEmailAction extends EmailUIAction {
final BuildContext context;
final String userEmail;
final PresentationEmail email;
PrintEmailAction({
required this.context,
required this.userEmail,
required this.email
});
@override
List<Object?> get props => [context, userEmail, email];
}
@@ -131,6 +131,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
EmailId? _currentEmailId; EmailId? _currentEmailId;
Identity? _identitySelected; Identity? _identitySelected;
EmailLoaded? _currentEmailLoaded; EmailLoaded? _currentEmailLoaded;
PrintEmailAction? _printEmailAction;
final StreamController<Either<Failure, Success>> _downloadProgressStateController = final StreamController<Either<Failure, Success>> _downloadProgressStateController =
StreamController<Either<Failure, Success>>.broadcast(); StreamController<Either<Failure, Success>>.broadcast();
@@ -209,6 +210,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
_handleParseCalendarEventSuccess(success); _handleParseCalendarEventSuccess(success);
} else if (success is PrintEmailLoading) { } else if (success is PrintEmailLoading) {
_showMessageWhenStartingEmailPrinting(); _showMessageWhenStartingEmailPrinting();
} else if (success is PrintEmailSuccess) {
_handlePrintEmailSuccess(success);
} }
} }
@@ -230,7 +233,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} else if (failure is GetEmailContentFailure) { } else if (failure is GetEmailContentFailure) {
emailLoadedViewState.value = Left<Failure, Success>(failure); emailLoadedViewState.value = Left<Failure, Success>(failure);
} else if (failure is PrintEmailFailure) { } else if (failure is PrintEmailFailure) {
_showMessageWhenEmailPrintingFailed(); _showMessageWhenEmailPrintingFailed(failure);
} }
} }
@@ -527,6 +530,13 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
emailContents.value = success.htmlEmailContent; emailContents.value = success.htmlEmailContent;
} }
if (_printEmailAction != null) {
_handlePrintEmailWhenEmailContentLoaded(
action: _printEmailAction!,
emailLoaded: _currentEmailLoaded!
);
}
if (PlatformInfo.isMobile) { if (PlatformInfo.isMobile) {
final detailedEmail = DetailedEmail( final detailedEmail = DetailedEmail(
emailId: currentEmail!.id!, emailId: currentEmail!.id!,
@@ -586,6 +596,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
calendarEvent.value = null; calendarEvent.value = null;
eventActions.clear(); eventActions.clear();
emailUnsubscribe.value = null; emailUnsubscribe.value = null;
_printEmailAction = null;
if (isEmailClosing) { if (isEmailClosing) {
emailLoadedViewState.value = Right(UIState.idle); emailLoadedViewState.value = Right(UIState.idle);
viewState.value = Right(UIState.idle); viewState.value = Right(UIState.idle);
@@ -1597,25 +1608,27 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void _printEmail(BuildContext context, PresentationEmail email) { void _printEmail(BuildContext context, PresentationEmail email) {
final emailPrint = EmailPrint( if (_printEmailAction != null) {
appName: AppLocalizations.of(context).app_name, log('SingleEmailController::_printEmail: Print email started');
userName: mailboxDashBoardController.userProfile.value?.email ?? '', return;
emailInformation: email.toEmail(), }
attachments: _currentEmailLoaded?.attachments,
emailContent: _currentEmailLoaded?.htmlContent ?? '', _printEmailAction = PrintEmailAction(
locale: Localizations.localeOf(context).toLanguageTag(), context: context,
fromPrefix: AppLocalizations.of(context).from_email_address_prefix, userEmail: mailboxDashBoardController.userEmail,
toPrefix: AppLocalizations.of(context).to_email_address_prefix, email: email
ccPrefix: AppLocalizations.of(context).cc_email_address_prefix, );
bccPrefix: AppLocalizations.of(context).bcc_email_address_prefix, consumeState(Stream.value(Right(PrintEmailLoading())));
replyToPrefix: AppLocalizations.of(context).replyToEmailAddressPrefix,
titleAttachment: AppLocalizations.of(context).attachments.toLowerCase(), if (_currentEmailLoaded == null) {
toAddress: email.to?.listEmailAddressToString(isFullEmailAddress: true), log('SingleEmailController::_printEmail: Email content loading');
ccAddress: email.cc?.listEmailAddressToString(isFullEmailAddress: true), return;
bccAddress: email.bcc?.listEmailAddressToString(isFullEmailAddress: true), }
replyToAddress: email.replyTo?.listEmailAddressToString(isFullEmailAddress: true),
_handlePrintEmailWhenEmailContentLoaded(
action: _printEmailAction!,
emailLoaded: _currentEmailLoaded!
); );
consumeState(_printEmailInteractor.execute(emailPrint));
} }
void _showMessageWhenStartingEmailPrinting() { void _showMessageWhenStartingEmailPrinting() {
@@ -1628,11 +1641,34 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
void _showMessageWhenEmailPrintingFailed() { void _handlePrintEmailSuccess(PrintEmailSuccess success) {
_printEmailAction = null;
}
void _showMessageWhenEmailPrintingFailed(PrintEmailFailure failure) {
_printEmailAction = null;
if (currentOverlayContext != null && currentContext != null) { if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage( appToast.showToastErrorMessage(
currentOverlayContext!, currentOverlayContext!,
AppLocalizations.of(currentContext!).printingFailed); AppLocalizations.of(currentContext!).printingFailed);
} }
} }
void _handlePrintEmailWhenEmailContentLoaded({
required PrintEmailAction action,
required EmailLoaded emailLoaded
}) {
if (action.email.id != emailLoaded.emailCurrent?.id) {
log('SingleEmailController::_handlePrintEmailInQueue: Print email action NOT matched email id');
_printEmailAction = null;
return;
}
consumeState(
_printEmailInteractor.execute(
EmailPrint.generate(printEmailAction: action, emailLoaded: emailLoaded)
)
);
}
} }
@@ -2485,6 +2485,8 @@ class MailboxDashBoardController extends ReloadableController {
isRecoveringDeletedMessage.value = true; isRecoveringDeletedMessage.value = true;
} }
String get userEmail => userProfile.value?.email ?? '';
@override @override
void onClose() { void onClose() {
_emailReceiveManager.closeEmailReceiveManagerStream(); _emailReceiveManager.closeEmailReceiveManagerStream();