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/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_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_style_tag_outside_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/remove_tooltip_link_transformers.dart';
@@ -67,6 +68,7 @@ class TransformConfiguration {
if (PlatformInfo.isWeb)
const RemoveTooltipLinkTransformer(),
const RemoveLazyLoadingForBackgroundImageTransformer(),
const RemoveLazyLoadingImageTransformer(),
const RemoveCollapsedSignatureButtonTransformer(),
const RemoveStyleTagOutsideTransformer(),
const RemoveMaxWidthInImageStyleTransformer(),
@@ -1,6 +1,12 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.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 {
final String appName;
@@ -39,6 +45,30 @@ class EmailPrint with EquatableMixin {
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
List<Object?> get props => [
appName,
@@ -14,7 +14,6 @@ class PrintEmailInteractor {
Stream<Either<Failure, Success>> execute(EmailPrint emailPrint) async* {
try {
yield Right(PrintEmailLoading());
final htmlContentTransformed = await _transformHtmlEmailContent(emailPrint.emailContent);
final newEmailPrint = emailPrint.fromEmailContent(htmlContentTransformed);
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:model/email/presentation_email.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
class EmailUIAction extends UIAction {
@@ -22,4 +24,20 @@ class RefreshChangeEmailAction 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;
Identity? _identitySelected;
EmailLoaded? _currentEmailLoaded;
PrintEmailAction? _printEmailAction;
final StreamController<Either<Failure, Success>> _downloadProgressStateController =
StreamController<Either<Failure, Success>>.broadcast();
@@ -209,6 +210,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
_handleParseCalendarEventSuccess(success);
} else if (success is PrintEmailLoading) {
_showMessageWhenStartingEmailPrinting();
} else if (success is PrintEmailSuccess) {
_handlePrintEmailSuccess(success);
}
}
@@ -230,7 +233,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} else if (failure is GetEmailContentFailure) {
emailLoadedViewState.value = Left<Failure, Success>(failure);
} else if (failure is PrintEmailFailure) {
_showMessageWhenEmailPrintingFailed();
_showMessageWhenEmailPrintingFailed(failure);
}
}
@@ -527,6 +530,13 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
emailContents.value = success.htmlEmailContent;
}
if (_printEmailAction != null) {
_handlePrintEmailWhenEmailContentLoaded(
action: _printEmailAction!,
emailLoaded: _currentEmailLoaded!
);
}
if (PlatformInfo.isMobile) {
final detailedEmail = DetailedEmail(
emailId: currentEmail!.id!,
@@ -586,6 +596,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
calendarEvent.value = null;
eventActions.clear();
emailUnsubscribe.value = null;
_printEmailAction = null;
if (isEmailClosing) {
emailLoadedViewState.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) {
final emailPrint = EmailPrint(
appName: AppLocalizations.of(context).app_name,
userName: mailboxDashBoardController.userProfile.value?.email ?? '',
emailInformation: email.toEmail(),
attachments: _currentEmailLoaded?.attachments,
emailContent: _currentEmailLoaded?.htmlContent ?? '',
locale: Localizations.localeOf(context).toLanguageTag(),
fromPrefix: AppLocalizations.of(context).from_email_address_prefix,
toPrefix: AppLocalizations.of(context).to_email_address_prefix,
ccPrefix: AppLocalizations.of(context).cc_email_address_prefix,
bccPrefix: AppLocalizations.of(context).bcc_email_address_prefix,
replyToPrefix: AppLocalizations.of(context).replyToEmailAddressPrefix,
titleAttachment: AppLocalizations.of(context).attachments.toLowerCase(),
toAddress: email.to?.listEmailAddressToString(isFullEmailAddress: true),
ccAddress: email.cc?.listEmailAddressToString(isFullEmailAddress: true),
bccAddress: email.bcc?.listEmailAddressToString(isFullEmailAddress: true),
replyToAddress: email.replyTo?.listEmailAddressToString(isFullEmailAddress: true),
if (_printEmailAction != null) {
log('SingleEmailController::_printEmail: Print email started');
return;
}
_printEmailAction = PrintEmailAction(
context: context,
userEmail: mailboxDashBoardController.userEmail,
email: email
);
consumeState(Stream.value(Right(PrintEmailLoading())));
if (_currentEmailLoaded == null) {
log('SingleEmailController::_printEmail: Email content loading');
return;
}
_handlePrintEmailWhenEmailContentLoaded(
action: _printEmailAction!,
emailLoaded: _currentEmailLoaded!
);
consumeState(_printEmailInteractor.execute(emailPrint));
}
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) {
appToast.showToastErrorMessage(
currentOverlayContext!,
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;
}
String get userEmail => userProfile.value?.email ?? '';
@override
void onClose() {
_emailReceiveManager.closeEmailReceiveManagerStream();