From ab2c32154e0da6450a9c1b422ac3428263def3ca Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 28 Feb 2024 17:13:53 +0700 Subject: [PATCH] TF-2520 Implement print email in email view Signed-off-by: dab246 --- .../dom/remove_tag_hidden_transformers.dart | 22 ++++++ .../transform_configuration.dart | 9 +++ .../presentation/composer_bindings.dart | 10 ++- .../print_file_datasource_impl.dart | 74 +++++++++++++++++++ .../repository/email_repository_impl.dart | 11 ++- .../email/domain/state/print_email_state.dart | 11 +++ .../usecases/print_email_interactor.dart | 39 ++++++++++ .../presentation/bindings/email_bindings.dart | 15 +++- .../controller/single_email_controller.dart | 35 ++++++++- .../bindings/mailbox_dashboard_bindings.dart | 11 +++ .../sending_email_interactor_bindings.dart | 11 +++ .../bindings/fcm_interactor_bindings.dart | 13 +++- lib/l10n/intl_messages.arb | 8 +- lib/main/bindings/core/core_bindings.dart | 4 + lib/main/localizations/app_localizations.dart | 7 ++ pubspec.lock | 56 ++++++++++++++ pubspec.yaml | 2 + 17 files changed, 330 insertions(+), 8 deletions(-) create mode 100644 core/lib/presentation/utils/html_transformer/dom/remove_tag_hidden_transformers.dart create mode 100644 lib/features/email/data/datasource_impl/print_file_datasource_impl.dart create mode 100644 lib/features/email/domain/state/print_email_state.dart create mode 100644 lib/features/email/domain/usecases/print_email_interactor.dart diff --git a/core/lib/presentation/utils/html_transformer/dom/remove_tag_hidden_transformers.dart b/core/lib/presentation/utils/html_transformer/dom/remove_tag_hidden_transformers.dart new file mode 100644 index 000000000..e57bb474d --- /dev/null +++ b/core/lib/presentation/utils/html_transformer/dom/remove_tag_hidden_transformers.dart @@ -0,0 +1,22 @@ +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 RemoveTagHiddenTransformer extends DomTransformer { + const RemoveTagHiddenTransformer(); + + @override + Future process({ + required Document document, + required DioClient dioClient, + Map? mapUrlDownloadCID, + }) async { + final elements = document.querySelectorAll('[style]'); + await Future.wait(elements.map((element) async { + var exStyle = element.attributes['style']; + if (exStyle?.contains('display: none') == true || exStyle?.contains('display:none') == true) { + element.remove(); + } + })); + } +} diff --git a/core/lib/presentation/utils/html_transformer/transform_configuration.dart b/core/lib/presentation/utils/html_transformer/transform_configuration.dart index 618aa7654..4ea2fda64 100644 --- a/core/lib/presentation/utils/html_transformer/transform_configuration.dart +++ b/core/lib/presentation/utils/html_transformer/transform_configuration.dart @@ -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_tag_hidden_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_tooltip_link_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/script_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/sigature_transformers.dart'; @@ -61,6 +62,14 @@ class TransformConfiguration { factory TransformConfiguration.forPreviewEmail() => TransformConfiguration.standardConfiguration; + factory TransformConfiguration.forPrintEmail() => TransformConfiguration.fromDomTransformers([ + if (PlatformInfo.isWeb) + const RemoveTooltipLinkTransformer(), + const RemoveLazyLoadingForBackgroundImageTransformer(), + const RemoveCollapsedSignatureButtonTransformer(), + const RemoveTagHiddenTransformer(), + ]); + /// Provides easy access to a standard configuration that does not block external images. static const TransformConfiguration standardConfiguration = TransformConfiguration( standardDomTransformers, diff --git a/lib/features/composer/presentation/composer_bindings.dart b/lib/features/composer/presentation/composer_bindings.dart index daba116bc..515c9e0b3 100644 --- a/lib/features/composer/presentation/composer_bindings.dart +++ b/lib/features/composer/presentation/composer_bindings.dart @@ -1,5 +1,4 @@ import 'package:core/core.dart'; -import 'package:core/utils/file_utils.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart'; @@ -20,9 +19,11 @@ import 'package:tmail_ui_user/features/composer/presentation/controller/rich_tex import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart'; import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart'; +import 'package:tmail_ui_user/features/email/data/datasource_impl/print_file_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart'; @@ -102,6 +103,11 @@ class ComposerBindings extends BaseBindings { Get.find(), Get.find() )); + Get.lazyPut(() => PrintFileDataSourceImpl( + Get.find(), + Get.find(), + Get.find() + )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.find(), Get.find(), @@ -122,6 +128,7 @@ class ComposerBindings extends BaseBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -144,6 +151,7 @@ class ComposerBindings extends BaseBindings { }, Get.find(), Get.find(), + Get.find(), )); } diff --git a/lib/features/email/data/datasource_impl/print_file_datasource_impl.dart b/lib/features/email/data/datasource_impl/print_file_datasource_impl.dart new file mode 100644 index 000000000..f769a5d2f --- /dev/null +++ b/lib/features/email/data/datasource_impl/print_file_datasource_impl.dart @@ -0,0 +1,74 @@ +import 'package:core/data/model/print_attachment.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/utils/app_logger.dart'; +import 'package:core/utils/print_utils.dart'; +import 'package:filesize/filesize.dart'; +import 'package:flutter/services.dart'; +import 'package:model/email/attachment.dart'; +import 'package:model/extensions/utc_date_extension.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart'; +import 'package:tmail_ui_user/features/email/domain/model/email_print.dart'; +import 'package:tmail_ui_user/features/email/presentation/extensions/attachment_extension.dart'; +import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; + +class PrintFileDataSourceImpl extends PrintFileDataSource { + + final PrintUtils _printUtils; + final ImagePaths _imagePaths; + final ExceptionThrower _exceptionThrower; + + PrintFileDataSourceImpl( + this._printUtils, + this._imagePaths, + this._exceptionThrower + ); + + @override + Future printEmailToPDF(EmailPrint emailPrint) { + return Future.sync(() async { + final sender = emailPrint.emailInformation.from?.isNotEmpty == true + ? emailPrint.emailInformation.from!.first + : null; + final receiveTime = emailPrint.emailInformation.receivedAt?.formatDateToLocal( + pattern: 'E, MMM d, yyyy \'at\' h:mm a', + locale: emailPrint.locale); + + final List listPrintAttachment = []; + + if (emailPrint.attachments?.isNotEmpty == true) { + await Future.forEach(emailPrint.attachments ?? [], (attachment) async { + final iconSvg = await rootBundle.loadString(attachment.getIcon(_imagePaths)); + final printAttachment = PrintAttachment( + iconSvg: iconSvg, + name: attachment.name ?? '', + size: filesize(attachment.size?.value) + ); + listPrintAttachment.add(printAttachment); + }); + } + + final result = await _printUtils.printEmailToPDF( + appName: emailPrint.appName, + userName: emailPrint.userName, + locale: emailPrint.locale, + title: emailPrint.emailInformation.subject ?? '', + emailContent: emailPrint.emailContent, + senderName: sender?.name ?? '', + senderEmailAddress: sender?.email ?? '', + dateTime: receiveTime ?? '', + toPrefix: emailPrint.toPrefix, + ccPrefix: emailPrint.ccPrefix, + bccPrefix: emailPrint.bccPrefix, + replyToPrefix: emailPrint.replyToPrefix, + toAddress: emailPrint.toAddress, + ccAddress: emailPrint.ccAddress, + bccAddress: emailPrint.bccAddress, + replyToAddress: emailPrint.replyToAddress, + titleAttachment: emailPrint.titleAttachment, + listAttachment: listPrintAttachment + ); + log('PrintFileDataSourceImpl::printEmailToPDF: RESULT = $result'); + return result; + }).catchError(_exceptionThrower.throwException); + } +} \ No newline at end of file diff --git a/lib/features/email/data/repository/email_repository_impl.dart b/lib/features/email/data/repository/email_repository_impl.dart index d73964cdd..2561e2dfe 100644 --- a/lib/features/email/data/repository/email_repository_impl.dart +++ b/lib/features/email/data/repository/email_repository_impl.dart @@ -23,7 +23,9 @@ import 'package:model/email/read_actions.dart'; import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'; import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart'; import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart'; +import 'package:tmail_ui_user/features/email/domain/model/email_print.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart'; import 'package:tmail_ui_user/features/email/domain/model/restore_deleted_message_request.dart'; import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; @@ -36,11 +38,13 @@ class EmailRepositoryImpl extends EmailRepository { final Map emailDataSource; final HtmlDataSource _htmlDataSource; final StateDataSource _stateDataSource; + final PrintFileDataSource _printFileDataSource; EmailRepositoryImpl( this.emailDataSource, this._htmlDataSource, - this._stateDataSource + this._stateDataSource, + this._printFileDataSource, ); @override @@ -228,4 +232,9 @@ class EmailRepositoryImpl extends EmailRepository { Future getRestoredDeletedMessage(EmailRecoveryActionId emailRecoveryActionId) { return emailDataSource[DataSourceType.network]!.getRestoredDeletedMessage(emailRecoveryActionId); } + + @override + Future printEmail(EmailPrint emailPrint) { + return _printFileDataSource.printEmailToPDF(emailPrint); + } } \ No newline at end of file diff --git a/lib/features/email/domain/state/print_email_state.dart b/lib/features/email/domain/state/print_email_state.dart new file mode 100644 index 000000000..bcd1b3703 --- /dev/null +++ b/lib/features/email/domain/state/print_email_state.dart @@ -0,0 +1,11 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class PrintEmailLoading extends LoadingState {} + +class PrintEmailSuccess extends UIState {} + +class PrintEmailFailure extends FeatureFailure { + + PrintEmailFailure({dynamic exception}) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/email/domain/usecases/print_email_interactor.dart b/lib/features/email/domain/usecases/print_email_interactor.dart new file mode 100644 index 000000000..93131846c --- /dev/null +++ b/lib/features/email/domain/usecases/print_email_interactor.dart @@ -0,0 +1,39 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:core/presentation/utils/html_transformer/transform_configuration.dart'; +import 'package:core/utils/app_logger.dart'; +import 'package:dartz/dartz.dart'; +import 'package:tmail_ui_user/features/email/domain/model/email_print.dart'; +import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; +import 'package:tmail_ui_user/features/email/domain/state/print_email_state.dart'; + +class PrintEmailInteractor { + final EmailRepository emailRepository; + + PrintEmailInteractor(this.emailRepository); + + Stream> execute(EmailPrint emailPrint) async* { + try { + yield Right(PrintEmailLoading()); + final htmlContentTransformed = await _transformHtmlEmailContent(emailPrint.emailContent); + final newEmailPrint = emailPrint.fromEmailContent(htmlContentTransformed); + await emailRepository.printEmail(newEmailPrint); + yield Right(PrintEmailSuccess()); + } catch (e) { + yield Left(PrintEmailFailure(exception: e)); + } + } + + Future _transformHtmlEmailContent(String emailContent) async { + try { + final htmlContentTransformed = await emailRepository.transformHtmlEmailContent( + emailContent, + TransformConfiguration.forPrintEmail()); + log('PrintEmailInteractor::_transformHtmlEmailContent: htmlContentTransformed: $htmlContentTransformed'); + return htmlContentTransformed; + } catch (e) { + logError('PrintEmailInteractor::_transformHtmlEmailContent: Exception: $e'); + return emailContent; + } + } +} \ No newline at end of file diff --git a/lib/features/email/presentation/bindings/email_bindings.dart b/lib/features/email/presentation/bindings/email_bindings.dart index ff9cf111a..1e1056ba7 100644 --- a/lib/features/email/presentation/bindings/email_bindings.dart +++ b/lib/features/email/presentation/bindings/email_bindings.dart @@ -1,12 +1,13 @@ import 'package:core/core.dart'; -import 'package:core/utils/file_utils.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart'; import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart'; +import 'package:tmail_ui_user/features/email/data/datasource_impl/print_file_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart'; @@ -19,6 +20,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/get_stored_email_st import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/view_attachment_for_web_interactor.dart'; import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart'; @@ -67,6 +69,7 @@ class EmailBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), + Get.find() )); } @@ -76,6 +79,7 @@ class EmailBindings extends BaseBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -98,6 +102,11 @@ class EmailBindings extends BaseBindings { Get.find(), Get.find() )); + Get.lazyPut(() => PrintFileDataSourceImpl( + Get.find(), + Get.find(), + Get.find() + )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.find(), Get.find(), @@ -141,6 +150,7 @@ class EmailBindings extends BaseBindings { Get.lazyPut(() => ViewAttachmentForWebInteractor( Get.find())); Get.lazyPut(() => StoreOpenedEmailInteractor(Get.find())); + Get.lazyPut(() => PrintEmailInteractor(Get.find())); IdentityInteractorsBindings().dependencies(); } @@ -165,7 +175,8 @@ class EmailBindings extends BaseBindings { DataSourceType.hiveCache: Get.find() }, Get.find(), - Get.find() + Get.find(), + Get.find(), )); } } \ No newline at end of file diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart index 269f0f4ba..505ff6946 100644 --- a/lib/features/email/presentation/controller/single_email_controller.dart +++ b/lib/features/email/presentation/controller/single_email_controller.dart @@ -30,6 +30,7 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/email_ac import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart'; import 'package:tmail_ui_user/features/email/domain/extensions/list_attachments_extension.dart'; import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart'; +import 'package:tmail_ui_user/features/email/domain/model/email_print.dart'; import 'package:tmail_ui_user/features/email/domain/model/event_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_action.dart'; @@ -54,6 +55,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_ import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/parse_calendar_event_interactor.dart'; +import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/send_receipt_to_sender_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/view_attachment_for_web_interactor.dart'; @@ -111,6 +113,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { final GetAllIdentitiesInteractor _getAllIdentitiesInteractor; final StoreOpenedEmailInteractor _storeOpenedEmailInteractor; final ViewAttachmentForWebInteractor _viewAttachmentForWebInteractor; + final PrintEmailInteractor _printEmailInteractor; CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor; SendReceiptToSenderInteractor? _sendReceiptToSenderInteractor; @@ -148,6 +151,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { this._getAllIdentitiesInteractor, this._storeOpenedEmailInteractor, this._viewAttachmentForWebInteractor, + this._printEmailInteractor, ); @override @@ -818,7 +822,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { mailboxDashBoardController.deleteDownloadTask(success.taskId); _downloadManager.openDownloadedFileWeb( - success.bytes, + success.bytes, success.attachment.type?.mimeType); } @@ -843,7 +847,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { } void _updateAttachmentsViewState( - Id? attachmentBlobId, + Id? attachmentBlobId, Either viewState) { if (attachmentBlobId != null) { attachmentsViewState[attachmentBlobId] = viewState; @@ -1090,6 +1094,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin { case EmailActionType.archiveMessage: archiveMessage(context, presentationEmail); break; + case EmailActionType.printAll: + _printEmail(context, presentationEmail); + break; default: break; } @@ -1578,4 +1585,28 @@ class SingleEmailController extends BaseController with AppLoaderMixin { void archiveMessage(BuildContext context, PresentationEmail email) { mailboxDashBoardController.archiveMessage(context, email); } + + void _printEmail(BuildContext context, PresentationEmail email) { + if (email.id != _currentEmailLoaded?.emailCurrent?.id) { + log('SingleEmailController::_printEmail: EMAIL ${email.id?.asString} NOT LOADED'); + } + 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(), + 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), + ); + consumeState(_printEmailInteractor.execute(emailPrint)); + } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart index 4eac17cec..46a3efda8 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -1,6 +1,8 @@ import 'package:core/data/model/source_type/data_source_type.dart'; +import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/utils/config/app_config_loader.dart'; import 'package:core/utils/file_utils.dart'; +import 'package:core/utils/print_utils.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart'; import 'package:tmail_ui_user/features/caching/clients/recent_search_cache_client.dart'; @@ -11,9 +13,11 @@ import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_inter import 'package:tmail_ui_user/features/composer/domain/usecases/update_email_drafts_interactor.dart'; import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart'; +import 'package:tmail_ui_user/features/email/data/datasource_impl/print_file_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart'; @@ -178,6 +182,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); @@ -206,6 +211,11 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find(), Get.find() )); + Get.lazyPut(() => PrintFileDataSourceImpl( + Get.find(), + Get.find(), + Get.find() + )); Get.lazyPut(() => MailboxDataSourceImpl( Get.find(), Get.find(), @@ -346,6 +356,7 @@ class MailboxDashBoardBindings extends BaseBindings { }, Get.find(), Get.find(), + Get.find(), )); Get.lazyPut(() => SearchRepositoryImpl(Get.find())); Get.lazyPut(() => ThreadRepositoryImpl( diff --git a/lib/features/offline_mode/bindings/sending_email_interactor_bindings.dart b/lib/features/offline_mode/bindings/sending_email_interactor_bindings.dart index 4048f3993..0565f17db 100644 --- a/lib/features/offline_mode/bindings/sending_email_interactor_bindings.dart +++ b/lib/features/offline_mode/bindings/sending_email_interactor_bindings.dart @@ -1,13 +1,17 @@ import 'package:core/data/model/source_type/data_source_type.dart'; +import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/utils/file_utils.dart'; +import 'package:core/utils/print_utils.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart'; import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart'; +import 'package:tmail_ui_user/features/email/data/datasource_impl/print_file_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart'; @@ -41,6 +45,7 @@ class SendEmailInteractorBindings extends InteractorsBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -62,6 +67,11 @@ class SendEmailInteractorBindings extends InteractorsBindings { Get.find(), Get.find(), Get.find())); + Get.lazyPut(() => PrintFileDataSourceImpl( + Get.find(), + Get.find(), + Get.find(), + )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.find(), Get.find(), @@ -93,6 +103,7 @@ class SendEmailInteractorBindings extends InteractorsBindings { }, Get.find(), Get.find(), + Get.find(), )); Get.lazyPut(() => MailboxRepositoryImpl( { diff --git a/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart b/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart index f8a668ecb..891e0f170 100644 --- a/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart +++ b/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart @@ -1,12 +1,16 @@ import 'package:core/data/model/source_type/data_source_type.dart'; +import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/utils/file_utils.dart'; +import 'package:core/utils/print_utils.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart'; +import 'package:tmail_ui_user/features/email/data/datasource_impl/print_file_datasource_impl.dart'; import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart'; @@ -71,6 +75,7 @@ class FcmInteractorBindings extends InteractorsBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -106,6 +111,11 @@ class FcmInteractorBindings extends InteractorsBindings { Get.find(), Get.find() )); + Get.lazyPut(() => PrintFileDataSourceImpl( + Get.find(), + Get.find(), + Get.find() + )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.find(), Get.find(), @@ -171,6 +181,7 @@ class FcmInteractorBindings extends InteractorsBindings { DataSourceType.hiveCache: Get.find() }, Get.find(), - Get.find())); + Get.find(), + Get.find())); } } diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index a912532cd..a21de10a5 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2024-02-28T08:48:33.734928", + "@@last_modified": "2024-02-28T17:05:44.385016", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -3659,5 +3659,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "replyToEmailAddressPrefix": "Reply-To", + "@replyToEmailAddressPrefix": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/bindings/core/core_bindings.dart b/lib/main/bindings/core/core_bindings.dart index f0c364914..57615c17f 100644 --- a/lib/main/bindings/core/core_bindings.dart +++ b/lib/main/bindings/core/core_bindings.dart @@ -6,9 +6,11 @@ import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/utils/config/app_config_loader.dart'; import 'package:core/utils/file_utils.dart'; import 'package:core/utils/platform_info.dart'; +import 'package:core/utils/print_utils.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:get/get.dart'; +import 'package:htmltopdfwidgets/htmltopdfwidgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; @@ -60,6 +62,8 @@ class CoreBindings extends Bindings { Get.put(CompressFileUtils()); Get.put(AppConfigLoader()); Get.put(FileUtils()); + Get.put(HTMLToPdf()); + Get.put(PrintUtils(Get.find(), Get.find())); } void _bindingIsolate() { diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 66e3ea8fd..221cfb909 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -3812,4 +3812,11 @@ class AppLocalizations { 'Print all', name: 'printAll'); } + + String get replyToEmailAddressPrefix { + return Intl.message( + 'Reply-To', + name: 'replyToEmailAddressPrefix', + ); + } } \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 0a07e03f1..d350fc2cd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -57,6 +57,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + barcode: + dependency: transitive + description: + name: barcode + sha256: "91b143666f7bb13636f716b6d4e412e372ab15ff7969799af8c9e30a382e9385" + url: "https://pub.dev" + source: hosted + version: "2.2.6" better_open_file: dependency: "direct main" description: @@ -65,6 +73,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.6.4" + bidi: + dependency: transitive + description: + name: bidi + sha256: "1a7d0c696324b2089f72e7671fd1f1f64fef44c980f3cebc84e803967c597b63" + url: "https://pub.dev" + source: hosted + version: "2.0.10" boolean_selector: dependency: transitive description: @@ -1030,6 +1046,14 @@ packages: url: "https://github.com/linagora/html-editor-enhanced.git" source: git version: "2.5.1" + htmltopdfwidgets: + dependency: "direct main" + description: + name: htmltopdfwidgets + sha256: "990e3002fbbfaf307555f1991bed61b6228d7053b7e1945815c7a68f56bbda81" + url: "https://pub.dev" + source: hosted + version: "1.0.3" http: dependency: transitive description: @@ -1334,6 +1358,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + pdf: + dependency: transitive + description: + name: pdf + sha256: "243f05342fc0bdf140eba5b069398985cdbdd3dbb1d776cf43d5ea29cc570ba6" + url: "https://pub.dev" + source: hosted + version: "3.10.8" + pdf_widget_wrapper: + dependency: transitive + description: + name: pdf_widget_wrapper + sha256: e9d31fd7782ce28ae346b127ea7d1cd748d799bddee379f31191693610e23749 + url: "https://pub.dev" + source: hosted + version: "1.0.1" percent_indicator: dependency: "direct main" description: @@ -1430,6 +1470,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + printing: + dependency: transitive + description: + name: printing + sha256: "1c99cab90ebcc1fff65831d264627d5b529359d563e53f33ab9b8117f2d280bc" + url: "https://pub.dev" + source: hosted + version: "5.12.0" process: dependency: transitive description: @@ -1454,6 +1502,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.3" + qr: + dependency: transitive + description: + name: qr + sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" quiver: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7747da9d7..fccf2c18f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -231,6 +231,8 @@ dependencies: mime: 1.0.4 + htmltopdfwidgets: 1.0.3 + dev_dependencies: flutter_test: sdk: flutter