diff --git a/core/lib/data/constants/constant.dart b/core/lib/data/constants/constant.dart index 1f66fa736..8ec6a6caa 100644 --- a/core/lib/data/constants/constant.dart +++ b/core/lib/data/constants/constant.dart @@ -2,4 +2,5 @@ class Constant { static const acceptHeaderDefault = 'application/json'; static const contentTypeHeaderDefault = 'application/json'; static const pdfMimeType = 'application/pdf'; + static const textHtmlMimeType = 'text/html'; } \ No newline at end of file diff --git a/core/lib/data/model/print_attachment.dart b/core/lib/data/model/print_attachment.dart index 7d0ddf3d3..29913120b 100644 --- a/core/lib/data/model/print_attachment.dart +++ b/core/lib/data/model/print_attachment.dart @@ -2,19 +2,19 @@ import 'package:equatable/equatable.dart'; class PrintAttachment with EquatableMixin { - final String iconSvg; + final String iconBase64Data; final String name; final String size; PrintAttachment({ - required this.iconSvg, + required this.iconBase64Data, required this.name, required this.size }); @override List get props => [ - iconSvg, + iconBase64Data, name, size ]; diff --git a/core/lib/utils/file_utils.dart b/core/lib/utils/file_utils.dart index aa9044205..f513fec90 100644 --- a/core/lib/utils/file_utils.dart +++ b/core/lib/utils/file_utils.dart @@ -1,7 +1,10 @@ +import 'dart:convert'; import 'dart:io'; + import 'package:core/domain/exceptions/download_file_exception.dart'; import 'package:core/utils/app_logger.dart'; import 'package:core/utils/platform_info.dart'; +import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; class FileUtils { @@ -111,4 +114,11 @@ class FileUtils { logError('FileUtils::removeFolder():EXCEPTION: $e'); } } + + Future convertImageAssetToBase64(String assetImage) async { + ByteData bytes = await rootBundle.load(assetImage); + final buffer = bytes.buffer; + final base64Data = base64Encode(Uint8List.view(buffer)); + return base64Data; + } } \ No newline at end of file diff --git a/core/lib/utils/html/html_interaction.dart b/core/lib/utils/html/html_interaction.dart index b5fb5ee9f..bf1c815c0 100644 --- a/core/lib/utils/html/html_interaction.dart +++ b/core/lib/utils/html/html_interaction.dart @@ -91,4 +91,13 @@ class HtmlInteraction { }); '''; + + static const String scriptHandleInvokePrinterOnBrowser = ''' + + '''; } \ No newline at end of file diff --git a/core/lib/utils/html/html_template.dart b/core/lib/utils/html/html_template.dart index 75f41fab3..e0ee7bef8 100644 --- a/core/lib/utils/html/html_template.dart +++ b/core/lib/utils/html/html_template.dart @@ -21,14 +21,47 @@ class HtmlTemplate { } '''; - static const String sampleHtmlDocument = ''' - - - - - - - - + static const String printDocumentCssStyle = ''' + '''; } \ No newline at end of file diff --git a/core/lib/utils/html/html_utils.dart b/core/lib/utils/html/html_utils.dart index 0ac9d7fc0..71207d99f 100644 --- a/core/lib/utils/html/html_utils.dart +++ b/core/lib/utils/html/html_utils.dart @@ -1,8 +1,10 @@ +import 'package:core/data/constants/constant.dart'; import 'package:core/presentation/extensions/html_extension.dart'; import 'package:core/utils/app_logger.dart'; import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; +import 'package:universal_html/html.dart' as html; class HtmlUtils { static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) { @@ -94,4 +96,31 @@ class HtmlUtils { '''; } + + static String createTemplateHtmlDocument({String? title}) { + return ''' + + + + + + + ${title != null ? '$title' : ''} + + + + '''; + } + + static String generateSVGImageData(String base64Data) => 'data:image/svg+xml;base64,$base64Data'; + + static void openNewTabHtmlDocument(String htmlDocument) { + final blob = html.Blob([htmlDocument], Constant.textHtmlMimeType); + + final url = html.Url.createObjectUrlFromBlob(blob); + + html.window.open(url, '_blank'); + + html.Url.revokeObjectUrl(url); + } } diff --git a/core/lib/utils/print_utils.dart b/core/lib/utils/print_utils.dart index f44a031a0..136a2f69f 100644 --- a/core/lib/utils/print_utils.dart +++ b/core/lib/utils/print_utils.dart @@ -2,319 +2,166 @@ import 'dart:async'; import 'package:core/data/model/print_attachment.dart'; -import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/utils/app_logger.dart'; -import 'package:flutter/services.dart'; -import 'package:htmltopdfwidgets/htmltopdfwidgets.dart' as pw; -import 'package:intl/intl.dart'; -import 'package:printing/printing.dart'; +import 'package:core/utils/file_utils.dart'; +import 'package:core/utils/html/html_interaction.dart'; +import 'package:core/utils/html/html_template.dart'; +import 'package:core/utils/html/html_utils.dart'; +import 'package:html/dom.dart'; +import 'package:html/parser.dart'; class PrintUtils { - final pw.HTMLToPdf _htmlToPdf; final ImagePaths _imagePaths; + final FileUtils _fileUtils; - PrintUtils(this._htmlToPdf, this._imagePaths); + PrintUtils(this._imagePaths, this._fileUtils); - Future _createEmailContentWidget(String htmlDocument) async { - try { - final List bodyWidgets = await _htmlToPdf.convert(htmlDocument); - - return pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - ...bodyWidgets - ] - ); - } catch (e) { - logError('PrintUtils::_createEmailContentWidget: Exception: $e'); - return pw.Text(htmlDocument); - } - } - - List _createBodyWidgets({ - required pw.Context context, - required String logoAppSvg, + Future _createUserInformationElement({ required String appName, required String userName, - required String title, - required String htmlDocument, + }) async { + final logoBase64Data = await _fileUtils.convertImageAssetToBase64(_imagePaths.icTMailLogo); + + return Element.html(''' + + + + + + + + +
$appName + $userName +
+ '''); + } + + Element get dividerElement => Element.html('
'); + + Element _createSubjectElement(String subject) { + return Element.html(''' + + + + + + +
+ $subject
+
+ '''); + } + + Element _createSenderElement({ required String senderName, required String senderEmailAddress, required String dateTime, + }) { + return Element.html(''' + + + $senderName <$senderEmailAddress> + + $dateTime + + '''); + } + + String _createRecipientHtmlTag(String prefix, String emailAddress) { + Element element = Element.html('
'); + element.text = '$prefix: $emailAddress'; + return element.outerHtml; + } + + Element _createRecipientsElement({ required String toPrefix, required String ccPrefix, required String bccPrefix, required String replyToPrefix, - required String titleAttachment, - required pw.Widget contentWidget, String? toAddress, String? ccAddress, String? bccAddress, String? replyToAddress, - List? listAttachment, }) { - return [ - pw.Container( - padding: const pw.EdgeInsets.symmetric(horizontal: 32), - child: pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - _createUserInformationRow( - context: context, - logoAppSvg: logoAppSvg, - appName: appName, - userName: userName - ), - _createPageDivider(), - if (title.isNotEmpty) - ...[ - _createTitleRow( - context: context, - title: title - ), - _createPageDivider(), - ], - pw.SizedBox(height: 12), - pw.Row( - children: [ - pw.Expanded( - child: _createSenderWidget( - context: context, - name: senderName, - emailAddress: senderEmailAddress - ) - ), - _createDateTimeWidget( - context: context, - dateTime: dateTime - ) - ] - ), - if (replyToAddress?.isNotEmpty == true) - _createRecipientRow( - prefix: replyToPrefix, - emailAddress: replyToAddress! - ), - if (toAddress?.isNotEmpty == true) - _createRecipientRow( - prefix: toPrefix, - emailAddress: toAddress! - ), - if (ccAddress?.isNotEmpty == true) - _createRecipientRow( - prefix: ccPrefix, - emailAddress: ccAddress! - ), - if (bccAddress?.isNotEmpty == true) - _createRecipientRow( - prefix: bccPrefix, - emailAddress: bccAddress! - ), - pw.Padding( - padding: const pw.EdgeInsets.symmetric( - horizontal: 12, - vertical: 24), - child: contentWidget - ), - if (listAttachment?.isNotEmpty == true) - ...[ - _createPageDivider(), - pw.SizedBox(height: 12), - _createAttachmentTitle( - context: context, - title: titleAttachment, - totalAttachments: listAttachment!.length - ), - pw.SizedBox(height: 4), - ...listAttachment.map((attachment) => _createAttachmentRow( - context: context, - attachment: attachment - )) - ] - ] - ) - ) - ]; + return Element.html(''' + + + ${replyToAddress?.isNotEmpty == true ? _createRecipientHtmlTag(replyToPrefix, replyToAddress!) : ''} + ${toAddress?.isNotEmpty == true ? _createRecipientHtmlTag(toPrefix, toAddress!) : ''} + ${ccAddress?.isNotEmpty == true ? _createRecipientHtmlTag(ccPrefix, ccAddress!) : ''} + ${bccAddress?.isNotEmpty == true ? _createRecipientHtmlTag(bccPrefix, bccAddress!) : ''} + + + '''); } - pw.Widget _createPageDivider() { - return pw.Padding( - padding: const pw.EdgeInsets.only(top: 12), - child: pw.Divider() - ); + Element _createEmailContentElement(String emailContent) { + return Element.html(''' + + + + + + + + +
$emailContent
+ + + '''); } - pw.Widget _createPageHeader({ - required pw.Context context, - required String appName, - required String title, - required String locale, + String _createTitleAttachmentHtmlTag({ + required int countAttachments, + required String titleAttachment }) { - final currentTime = DateFormat('MM/dd/yyyy, h:mm a', locale).format(DateTime.now()); - return pw.Padding( - padding: const pw.EdgeInsets.all(20), - child: pw.Row( - children: [ - pw.Text( - currentTime, - style: pw.Theme.of(context).defaultTextStyle.copyWith( - fontSize: 8, - color: pw.PdfColor.fromInt(AppColor.colorTextBody.value) - ) - ), - pw.SizedBox(width: 16), - pw.Expanded( - child: pw.Text( - '$appName - $title', - textAlign: pw.TextAlign.center, - maxLines: 1, - style: pw.Theme.of(context).defaultTextStyle.copyWith( - fontSize: 8, - color: pw.PdfColor.fromInt(AppColor.colorTextBody.value) - ) - ) - ), - ] - ) - ); + return '$countAttachments $titleAttachment'; } - pw.Widget _createUserInformationRow({ - required pw.Context context, - required String logoAppSvg, + String _createAttachmentHtmlTag(PrintAttachment printAttachment) { + return ''' + + + + + + + + + + +
+ + + + + ${printAttachment.name}
+ ${printAttachment.size} +
+ + + '''; + } + + Element _createAttachmentsElement({ + required String titleAttachment, + required List listAttachment + }) { + return Element.html(''' + + + ${_createTitleAttachmentHtmlTag(countAttachments: listAttachment.length, titleAttachment: titleAttachment)} + ${listAttachment.map((printAttachment) => _createAttachmentHtmlTag(printAttachment)).toList().join('')} + +
+ '''); + } + + Future printEmail({ required String appName, required String userName, - }) { - return pw.Row( - children: [ - pw.SvgImage( - svg: logoAppSvg, - width: 32, - height: 32 - ), - pw.SizedBox(width: 12), - pw.Text( - appName, - style: pw.Theme.of(context).header0 - ), - pw.Spacer(), - pw.SizedBox(width: 12), - pw.Text( - userName, - style: pw.Theme.of(context).header4 - ) - ] - ); - } - - pw.Widget _createTitleRow({ - required pw.Context context, - required String title, - }) { - return pw.Padding( - padding: const pw.EdgeInsets.only(top: 12), - child: pw.Text( - title, - style: pw.Theme.of(context).header3 - ) - ); - } - - pw.Widget _createSenderWidget({ - required pw.Context context, - required String name, - required String emailAddress, - }) { - return pw.Row( - children: [ - if (name.isNotEmpty) - pw.Padding( - padding: const pw.EdgeInsetsDirectional.only(end: 4), - child: pw.Text( - name, - style: pw.Theme.of(context).header4 - ) - ), - pw.Text('<$emailAddress>') - ] - ); - } - - pw.Widget _createDateTimeWidget({ - required pw.Context context, - required String dateTime, - }) { - return pw.Text( - dateTime, - style: pw.Theme.of(context).defaultTextStyle.copyWith( - fontSize: 10, - color: pw.PdfColor.fromInt(AppColor.colorTextBody.value) - ) - ); - } - - pw.Widget _createRecipientRow({ - required String prefix, - required String emailAddress, - }) { - return pw.Row( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Text('$prefix:'), - pw.SizedBox(width: 4), - pw.Expanded(child: pw.Text(emailAddress)) - ] - ); - } - - pw.Widget _createAttachmentTitle({ - required pw.Context context, - required String title, - required int totalAttachments, - }) { - return pw.Text( - '$totalAttachments $title', - style: pw.Theme.of(context).header4 - ); - } - - pw.Widget _createAttachmentRow({ - required pw.Context context, - required PrintAttachment attachment, - }) { - return pw.Padding( - padding: const pw.EdgeInsets.only(top: 8), - child: pw.Row( - children: [ - pw.SvgImage( - svg: attachment.iconSvg, - width: 24, - height: 24 - ), - pw.SizedBox(width: 8), - pw.Expanded( - child: pw.Column( - mainAxisSize: pw.MainAxisSize.min, - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Text( - attachment.name, - style: pw.Theme.of(context).header4 - ), - pw.Text(attachment.size) - ] - ) - ), - ] - ) - ); - } - - Future printEmailToPDF({ - required String appName, - required String userName, - required String title, + required String subject, required String emailContent, required String senderName, required String senderEmailAddress, @@ -331,69 +178,71 @@ class PrintUtils { String? replyToAddress, List? listAttachment, }) async { - return await Printing.layoutPdf(onLayout: (pw.PdfPageFormat format) async { - final googleInterRegularFont = await PdfGoogleFonts.interRegular(); - final googleInterBoldFont = await PdfGoogleFonts.interBold(); - final logoAppSvg = await rootBundle.loadString(_imagePaths.icTMailLogo); - final contentWidget = await _createEmailContentWidget(emailContent); + Document document = parse(HtmlUtils.createTemplateHtmlDocument(title: '$appName - $subject')); - final pdfDocument = pw.Document(); + Element bodyContainerElement = Element.html('
'); + Element mainContentElement = Element.html('
'); + Element messageElement = Element.html('
'); + Element messageBodyElement = Element.html(''); - pdfDocument.addPage( - pw.MultiPage( - pageFormat: pw.PdfPageFormat.standard, - orientation: pw.PageOrientation.portrait, - theme: pw.ThemeData( - defaultTextStyle: pw.TextStyle( - font: googleInterRegularFont, - fontSize: 12, - color: pw.PdfColors.black - ), - header3: pw.TextStyle( - font: googleInterBoldFont, - fontSize: 14, - fontWeight: pw.FontWeight.bold, - color: pw.PdfColors.black - ), - header4: pw.TextStyle( - font: googleInterBoldFont, - fontSize: 12, - fontWeight: pw.FontWeight.bold, - color: pw.PdfColors.black - ), - ), - margin: pw.EdgeInsets.zero, - build: (context) => _createBodyWidgets( - context: context, - contentWidget: contentWidget, - logoAppSvg: logoAppSvg, - appName: appName, - userName: userName, - title: title, - htmlDocument: emailContent, - senderName: senderName, - senderEmailAddress: senderEmailAddress, - dateTime: dateTime, - toPrefix: toPrefix, - ccPrefix: ccPrefix, - bccPrefix: toPrefix, - replyToPrefix: replyToPrefix, - toAddress: toAddress, - ccAddress: ccAddress, - bccAddress: bccAddress, - replyToAddress: replyToAddress, - titleAttachment: titleAttachment, - listAttachment: listAttachment - ), - header: (context) => _createPageHeader( - context: context, - appName: appName, - title: title, - locale: locale, - ), - ) - ); - return await pdfDocument.save(); - }); + Element userInfoElement = await _createUserInformationElement( + appName: appName, + userName: userName); + + Element subjectElement = _createSubjectElement(subject); + + Element senderElement = _createSenderElement( + senderName: senderName, + senderEmailAddress: senderEmailAddress, + dateTime: dateTime); + + Element recipientsElement = _createRecipientsElement( + toPrefix: toPrefix, + ccPrefix: ccPrefix, + bccPrefix: bccPrefix, + replyToPrefix: replyToPrefix, + toAddress: toAddress, + ccAddress: ccAddress, + bccAddress: bccAddress, + replyToAddress: replyToAddress, + ); + + Element emailContentElement = _createEmailContentElement(emailContent); + + bodyContainerElement.append(userInfoElement); + bodyContainerElement.append(dividerElement); + + mainContentElement.append(subjectElement); + mainContentElement.append(dividerElement); + + messageBodyElement.append(senderElement); + messageBodyElement.append(recipientsElement); + messageBodyElement.append(emailContentElement); + + messageElement.append(messageBodyElement); + + mainContentElement.append(messageElement); + + if (listAttachment?.isNotEmpty == true) { + Element attachmentsElement = _createAttachmentsElement( + titleAttachment: titleAttachment, + listAttachment: listAttachment!); + mainContentElement.append(dividerElement); + mainContentElement.append(attachmentsElement); + } + + bodyContainerElement.append(mainContentElement); + + document.body?.append(bodyContainerElement); + + Element scriptElement = Element.html(HtmlInteraction.scriptHandleInvokePrinterOnBrowser); + document.body?.append(scriptElement); + + Element styleElement = Element.html(HtmlTemplate.printDocumentCssStyle); + document.head?.append(styleElement); + + final htmlDocument = document.outerHtml; + + HtmlUtils.openNewTabHtmlDocument(htmlDocument); } } diff --git a/core/pubspec.lock b/core/pubspec.lock index 4bc72cb78..32f33c83d 100644 --- a/core/pubspec.lock +++ b/core/pubspec.lock @@ -1,14 +1,6 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" - url: "https://pub.dev" - source: hosted - version: "3.4.10" args: dependency: transitive description: @@ -25,22 +17,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" - barcode: - dependency: transitive - description: - name: barcode - sha256: "91b143666f7bb13636f716b6d4e412e372ab15ff7969799af8c9e30a382e9385" - url: "https://pub.dev" - source: hosted - version: "2.2.6" - bidi: - dependency: transitive - description: - name: bidi - sha256: "1a7d0c696324b2089f72e7671fd1f1f64fef44c980f3cebc84e803967c597b63" - url: "https://pub.dev" - source: hosted - version: "2.0.10" boolean_selector: dependency: transitive description: @@ -89,14 +65,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" cross_file: dependency: transitive description: @@ -105,14 +73,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.3+7" - crypto: - dependency: transitive - description: - name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab - url: "https://pub.dev" - source: hosted - version: "3.0.3" csslib: dependency: transitive description: @@ -368,14 +328,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.15.3" - htmltopdfwidgets: - dependency: "direct main" - description: - name: htmltopdfwidgets - sha256: "990e3002fbbfaf307555f1991bed61b6228d7053b7e1945815c7a68f56bbda81" - url: "https://pub.dev" - source: hosted - version: "1.0.3" http: dependency: "direct main" description: @@ -392,14 +344,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" - image: - dependency: transitive - description: - name: image - sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" - url: "https://pub.dev" - source: hosted - version: "4.1.7" intl: dependency: "direct main" description: @@ -520,22 +464,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" - 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" petitparser: dependency: transitive description: @@ -568,30 +496,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.1" - pointycastle: - dependency: transitive - description: - name: pointycastle - sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" - url: "https://pub.dev" - source: hosted - version: "3.7.4" - printing: - dependency: "direct main" - description: - name: printing - sha256: "1c99cab90ebcc1fff65831d264627d5b529359d563e53f33ab9b8117f2d280bc" - url: "https://pub.dev" - source: hosted - version: "5.12.0" - qr: - dependency: transitive - description: - name: qr - sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" - url: "https://pub.dev" - source: hosted - version: "3.0.1" sky_engine: dependency: transitive description: flutter diff --git a/core/pubspec.yaml b/core/pubspec.yaml index 35ea63279..10c480911 100644 --- a/core/pubspec.yaml +++ b/core/pubspec.yaml @@ -75,10 +75,6 @@ dependencies: linkify: 5.0.0 - htmltopdfwidgets: 1.0.3 - - printing: 5.12.0 - dev_dependencies: flutter_test: sdk: flutter diff --git a/lib/features/composer/presentation/composer_bindings.dart b/lib/features/composer/presentation/composer_bindings.dart index 515c9e0b3..f0fe3479d 100644 --- a/lib/features/composer/presentation/composer_bindings.dart +++ b/lib/features/composer/presentation/composer_bindings.dart @@ -106,6 +106,7 @@ class ComposerBindings extends BaseBindings { Get.lazyPut(() => PrintFileDataSourceImpl( Get.find(), Get.find(), + Get.find(), Get.find() )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( diff --git a/lib/features/email/data/datasource/print_file_datasource.dart b/lib/features/email/data/datasource/print_file_datasource.dart index ba97a2bfa..3da111efe 100644 --- a/lib/features/email/data/datasource/print_file_datasource.dart +++ b/lib/features/email/data/datasource/print_file_datasource.dart @@ -1,5 +1,5 @@ import 'package:tmail_ui_user/features/email/domain/model/email_print.dart'; abstract class PrintFileDataSource { - Future printEmailToPDF(EmailPrint emailPrint); + Future printEmail(EmailPrint emailPrint); } \ No newline at end of file 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 index f769a5d2f..af8f2a500 100644 --- a/lib/features/email/data/datasource_impl/print_file_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/print_file_datasource_impl.dart @@ -1,9 +1,8 @@ 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/file_utils.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'; @@ -15,16 +14,18 @@ class PrintFileDataSourceImpl extends PrintFileDataSource { final PrintUtils _printUtils; final ImagePaths _imagePaths; + final FileUtils _fileUtils; final ExceptionThrower _exceptionThrower; PrintFileDataSourceImpl( this._printUtils, this._imagePaths, + this._fileUtils, this._exceptionThrower ); @override - Future printEmailToPDF(EmailPrint emailPrint) { + Future printEmail(EmailPrint emailPrint) { return Future.sync(() async { final sender = emailPrint.emailInformation.from?.isNotEmpty == true ? emailPrint.emailInformation.from!.first @@ -37,9 +38,9 @@ class PrintFileDataSourceImpl extends PrintFileDataSource { if (emailPrint.attachments?.isNotEmpty == true) { await Future.forEach(emailPrint.attachments ?? [], (attachment) async { - final iconSvg = await rootBundle.loadString(attachment.getIcon(_imagePaths)); + final iconBase64Data = await _fileUtils.convertImageAssetToBase64(attachment.getIcon(_imagePaths)); final printAttachment = PrintAttachment( - iconSvg: iconSvg, + iconBase64Data: iconBase64Data, name: attachment.name ?? '', size: filesize(attachment.size?.value) ); @@ -47,11 +48,11 @@ class PrintFileDataSourceImpl extends PrintFileDataSource { }); } - final result = await _printUtils.printEmailToPDF( + return await _printUtils.printEmail( appName: emailPrint.appName, userName: emailPrint.userName, locale: emailPrint.locale, - title: emailPrint.emailInformation.subject ?? '', + subject: emailPrint.emailInformation.subject ?? '', emailContent: emailPrint.emailContent, senderName: sender?.name ?? '', senderEmailAddress: sender?.email ?? '', @@ -67,8 +68,6 @@ class PrintFileDataSourceImpl extends PrintFileDataSource { 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 2561e2dfe..014bca06b 100644 --- a/lib/features/email/data/repository/email_repository_impl.dart +++ b/lib/features/email/data/repository/email_repository_impl.dart @@ -235,6 +235,6 @@ class EmailRepositoryImpl extends EmailRepository { @override Future printEmail(EmailPrint emailPrint) { - return _printFileDataSource.printEmailToPDF(emailPrint); + return _printFileDataSource.printEmail(emailPrint); } } \ 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 index 93131846c..7fadbfbca 100644 --- a/lib/features/email/domain/usecases/print_email_interactor.dart +++ b/lib/features/email/domain/usecases/print_email_interactor.dart @@ -29,7 +29,6 @@ class PrintEmailInteractor { final htmlContentTransformed = await emailRepository.transformHtmlEmailContent( emailContent, TransformConfiguration.forPrintEmail()); - log('PrintEmailInteractor::_transformHtmlEmailContent: htmlContentTransformed: $htmlContentTransformed'); return htmlContentTransformed; } catch (e) { logError('PrintEmailInteractor::_transformHtmlEmailContent: Exception: $e'); diff --git a/lib/features/email/presentation/bindings/email_bindings.dart b/lib/features/email/presentation/bindings/email_bindings.dart index 1e1056ba7..19f0b8aeb 100644 --- a/lib/features/email/presentation/bindings/email_bindings.dart +++ b/lib/features/email/presentation/bindings/email_bindings.dart @@ -105,6 +105,7 @@ class EmailBindings extends BaseBindings { Get.lazyPut(() => PrintFileDataSourceImpl( Get.find(), Get.find(), + Get.find(), Get.find() )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( 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 46a3efda8..a535f3519 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -214,6 +214,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => PrintFileDataSourceImpl( Get.find(), Get.find(), + Get.find(), Get.find() )); Get.lazyPut(() => MailboxDataSourceImpl( 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 0565f17db..3de0a9931 100644 --- a/lib/features/offline_mode/bindings/sending_email_interactor_bindings.dart +++ b/lib/features/offline_mode/bindings/sending_email_interactor_bindings.dart @@ -70,6 +70,7 @@ class SendEmailInteractorBindings extends InteractorsBindings { Get.lazyPut(() => PrintFileDataSourceImpl( Get.find(), Get.find(), + Get.find(), Get.find(), )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( 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 891e0f170..45f6c3490 100644 --- a/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart +++ b/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart @@ -114,6 +114,7 @@ class FcmInteractorBindings extends InteractorsBindings { Get.lazyPut(() => PrintFileDataSourceImpl( Get.find(), Get.find(), + Get.find(), Get.find() )); Get.lazyPut(() => EmailHiveCacheDataSourceImpl( diff --git a/lib/main/bindings/core/core_bindings.dart b/lib/main/bindings/core/core_bindings.dart index 57615c17f..17890f940 100644 --- a/lib/main/bindings/core/core_bindings.dart +++ b/lib/main/bindings/core/core_bindings.dart @@ -10,7 +10,6 @@ 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'; @@ -62,8 +61,7 @@ class CoreBindings extends Bindings { Get.put(CompressFileUtils()); Get.put(AppConfigLoader()); Get.put(FileUtils()); - Get.put(HTMLToPdf()); - Get.put(PrintUtils(Get.find(), Get.find())); + Get.put(PrintUtils(Get.find(), Get.find())); } void _bindingIsolate() { diff --git a/pubspec.lock b/pubspec.lock index d350fc2cd..0a07e03f1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -57,14 +57,6 @@ 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: @@ -73,14 +65,6 @@ 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: @@ -1046,14 +1030,6 @@ 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: @@ -1358,22 +1334,6 @@ 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: @@ -1470,14 +1430,6 @@ 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: @@ -1502,14 +1454,6 @@ 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 fccf2c18f..7747da9d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -231,8 +231,6 @@ dependencies: mime: 1.0.4 - htmltopdfwidgets: 1.0.3 - dev_dependencies: flutter_test: sdk: flutter diff --git a/test/features/email/presentation/controller/single_email_controller_test.dart b/test/features/email/presentation/controller/single_email_controller_test.dart index 3c7d9de79..770bddce1 100644 --- a/test/features/email/presentation/controller/single_email_controller_test.dart +++ b/test/features/email/presentation/controller/single_email_controller_test.dart @@ -21,6 +21,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_i 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'; @@ -69,6 +70,7 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), + MockSpec(), ]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -99,6 +101,7 @@ void main() { final imagePaths = MockImagePaths(); final responsiveUtils = MockResponsiveUtils(); final uuid = MockUuid(); + final printEmailInteractor = MockPrintEmailInteractor(); late SingleEmailController singleEmailController = SingleEmailController( getEmailContentInteractor, @@ -112,6 +115,7 @@ void main() { getAllIdentitiesInteractor, storeOpenedEmailInteractor, viewAttachmentForWebInteractor, + printEmailInteractor, ); final testAccountId = AccountId(Id('123'));