TF-2520 Convert email object to html to perform print on browser
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -2,4 +2,5 @@ class Constant {
|
|||||||
static const acceptHeaderDefault = 'application/json';
|
static const acceptHeaderDefault = 'application/json';
|
||||||
static const contentTypeHeaderDefault = 'application/json';
|
static const contentTypeHeaderDefault = 'application/json';
|
||||||
static const pdfMimeType = 'application/pdf';
|
static const pdfMimeType = 'application/pdf';
|
||||||
|
static const textHtmlMimeType = 'text/html';
|
||||||
}
|
}
|
||||||
@@ -2,19 +2,19 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
class PrintAttachment with EquatableMixin {
|
class PrintAttachment with EquatableMixin {
|
||||||
final String iconSvg;
|
final String iconBase64Data;
|
||||||
final String name;
|
final String name;
|
||||||
final String size;
|
final String size;
|
||||||
|
|
||||||
PrintAttachment({
|
PrintAttachment({
|
||||||
required this.iconSvg,
|
required this.iconBase64Data,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.size
|
required this.size
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [
|
List<Object?> get props => [
|
||||||
iconSvg,
|
iconBase64Data,
|
||||||
name,
|
name,
|
||||||
size
|
size
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:core/domain/exceptions/download_file_exception.dart';
|
import 'package:core/domain/exceptions/download_file_exception.dart';
|
||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
class FileUtils {
|
class FileUtils {
|
||||||
@@ -111,4 +114,11 @@ class FileUtils {
|
|||||||
logError('FileUtils::removeFolder():EXCEPTION: $e');
|
logError('FileUtils::removeFolder():EXCEPTION: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> convertImageAssetToBase64(String assetImage) async {
|
||||||
|
ByteData bytes = await rootBundle.load(assetImage);
|
||||||
|
final buffer = bytes.buffer;
|
||||||
|
final base64Data = base64Encode(Uint8List.view(buffer));
|
||||||
|
return base64Data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -91,4 +91,13 @@ class HtmlInteraction {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
''';
|
''';
|
||||||
|
|
||||||
|
static const String scriptHandleInvokePrinterOnBrowser = '''
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.body.onload= function() {
|
||||||
|
document.body.offsetHeight;
|
||||||
|
window.print();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
''';
|
||||||
}
|
}
|
||||||
@@ -21,14 +21,47 @@ class HtmlTemplate {
|
|||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
|
|
||||||
static const String sampleHtmlDocument = '''
|
static const String printDocumentCssStyle = '''
|
||||||
<!DOCTYPE html>
|
<style>
|
||||||
<html>
|
body,td,div,p,a,input {
|
||||||
<head>
|
font-family: arial, sans-serif;
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
}
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
</head>
|
body, td {
|
||||||
<body</body>
|
font-size: 13px;
|
||||||
</html>
|
}
|
||||||
|
|
||||||
|
a:link, a:active {
|
||||||
|
color: #1155CC;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited{
|
||||||
|
color: #6611CC;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0px
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
white-space: pre;
|
||||||
|
white-space: -moz-pre-wrap;
|
||||||
|
white-space: -o-pre-wrap;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
max-width: 800px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
''';
|
''';
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
|
import 'package:core/data/constants/constant.dart';
|
||||||
import 'package:core/presentation/extensions/html_extension.dart';
|
import 'package:core/presentation/extensions/html_extension.dart';
|
||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
|
||||||
class HtmlUtils {
|
class HtmlUtils {
|
||||||
static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) {
|
static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) {
|
||||||
@@ -94,4 +96,31 @@ class HtmlUtils {
|
|||||||
</html>
|
</html>
|
||||||
''';
|
''';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String createTemplateHtmlDocument({String? title}) {
|
||||||
|
return '''
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
${title != null ? '<title>$title</title>' : ''}
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+195
-346
@@ -2,319 +2,166 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:core/data/model/print_attachment.dart';
|
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/presentation/resources/image_paths.dart';
|
||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/file_utils.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:core/utils/html/html_interaction.dart';
|
||||||
import 'package:htmltopdfwidgets/htmltopdfwidgets.dart' as pw;
|
import 'package:core/utils/html/html_template.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:core/utils/html/html_utils.dart';
|
||||||
import 'package:printing/printing.dart';
|
import 'package:html/dom.dart';
|
||||||
|
import 'package:html/parser.dart';
|
||||||
|
|
||||||
class PrintUtils {
|
class PrintUtils {
|
||||||
final pw.HTMLToPdf _htmlToPdf;
|
|
||||||
final ImagePaths _imagePaths;
|
final ImagePaths _imagePaths;
|
||||||
|
final FileUtils _fileUtils;
|
||||||
|
|
||||||
PrintUtils(this._htmlToPdf, this._imagePaths);
|
PrintUtils(this._imagePaths, this._fileUtils);
|
||||||
|
|
||||||
Future<pw.Widget> _createEmailContentWidget(String htmlDocument) async {
|
Future<Element> _createUserInformationElement({
|
||||||
try {
|
|
||||||
final List<pw.Widget> 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<pw.Widget> _createBodyWidgets({
|
|
||||||
required pw.Context context,
|
|
||||||
required String logoAppSvg,
|
|
||||||
required String appName,
|
required String appName,
|
||||||
required String userName,
|
required String userName,
|
||||||
required String title,
|
}) async {
|
||||||
required String htmlDocument,
|
final logoBase64Data = await _fileUtils.convertImageAssetToBase64(_imagePaths.icTMailLogo);
|
||||||
|
|
||||||
|
return Element.html('''
|
||||||
|
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr height="14px">
|
||||||
|
<td width="40"><img src="${HtmlUtils.generateSVGImageData(logoBase64Data)}" width="40" height="40" class="logo" /></td>
|
||||||
|
<td style="padding-left: 10px;font-size: 20px;color: #000;"><b>$appName</b></td>
|
||||||
|
<td align="right" style="color: #777;">
|
||||||
|
<b>$userName</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
|
||||||
|
Element get dividerElement => Element.html('<hr />');
|
||||||
|
|
||||||
|
Element _createSubjectElement(String subject) {
|
||||||
|
return Element.html('''
|
||||||
|
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<font size="+1"><b>$subject</b></font><br />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
|
||||||
|
Element _createSenderElement({
|
||||||
required String senderName,
|
required String senderName,
|
||||||
required String senderEmailAddress,
|
required String senderEmailAddress,
|
||||||
required String dateTime,
|
required String dateTime,
|
||||||
|
}) {
|
||||||
|
return Element.html('''
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<font size="-1"><b>$senderName </b><$senderEmailAddress></font>
|
||||||
|
</td>
|
||||||
|
<td align="right"><font size="-1">$dateTime</font></td>
|
||||||
|
</tr>
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
|
||||||
|
String _createRecipientHtmlTag(String prefix, String emailAddress) {
|
||||||
|
Element element = Element.html('<div class="${prefix.toLowerCase()}"></div>');
|
||||||
|
element.text = '$prefix: $emailAddress';
|
||||||
|
return element.outerHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
Element _createRecipientsElement({
|
||||||
required String toPrefix,
|
required String toPrefix,
|
||||||
required String ccPrefix,
|
required String ccPrefix,
|
||||||
required String bccPrefix,
|
required String bccPrefix,
|
||||||
required String replyToPrefix,
|
required String replyToPrefix,
|
||||||
required String titleAttachment,
|
|
||||||
required pw.Widget contentWidget,
|
|
||||||
String? toAddress,
|
String? toAddress,
|
||||||
String? ccAddress,
|
String? ccAddress,
|
||||||
String? bccAddress,
|
String? bccAddress,
|
||||||
String? replyToAddress,
|
String? replyToAddress,
|
||||||
List<PrintAttachment>? listAttachment,
|
|
||||||
}) {
|
}) {
|
||||||
return [
|
return Element.html('''
|
||||||
pw.Container(
|
<tr>
|
||||||
padding: const pw.EdgeInsets.symmetric(horizontal: 32),
|
<td colspan="2" style="padding-bottom: 4px;" class="recipient">
|
||||||
child: pw.Column(
|
${replyToAddress?.isNotEmpty == true ? _createRecipientHtmlTag(replyToPrefix, replyToAddress!) : ''}
|
||||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
${toAddress?.isNotEmpty == true ? _createRecipientHtmlTag(toPrefix, toAddress!) : ''}
|
||||||
children: [
|
${ccAddress?.isNotEmpty == true ? _createRecipientHtmlTag(ccPrefix, ccAddress!) : ''}
|
||||||
_createUserInformationRow(
|
${bccAddress?.isNotEmpty == true ? _createRecipientHtmlTag(bccPrefix, bccAddress!) : ''}
|
||||||
context: context,
|
</td>
|
||||||
logoAppSvg: logoAppSvg,
|
</tr>
|
||||||
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
|
|
||||||
))
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.Widget _createPageDivider() {
|
Element _createEmailContentElement(String emailContent) {
|
||||||
return pw.Padding(
|
return Element.html('''
|
||||||
padding: const pw.EdgeInsets.only(top: 12),
|
<tr>
|
||||||
child: pw.Divider()
|
<td colspan="2">
|
||||||
);
|
<table width="100%" cellpadding="12" cellspacing="0" border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>$emailContent</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
''');
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.Widget _createPageHeader({
|
String _createTitleAttachmentHtmlTag({
|
||||||
required pw.Context context,
|
required int countAttachments,
|
||||||
required String appName,
|
required String titleAttachment
|
||||||
required String title,
|
|
||||||
required String locale,
|
|
||||||
}) {
|
}) {
|
||||||
final currentTime = DateFormat('MM/dd/yyyy, h:mm a', locale).format(DateTime.now());
|
return '<tr><td colspan="2"><b style="padding-left:3">$countAttachments $titleAttachment</b></td></tr>';
|
||||||
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)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.Widget _createUserInformationRow({
|
String _createAttachmentHtmlTag(PrintAttachment printAttachment) {
|
||||||
required pw.Context context,
|
return '''
|
||||||
required String logoAppSvg,
|
<tr>
|
||||||
|
<td>
|
||||||
|
<table cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a target="_blank" href="">
|
||||||
|
<img width="16" height="16" src="${HtmlUtils.generateSVGImageData(printAttachment.iconBase64Data)}" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td width="7"></td>
|
||||||
|
<td>
|
||||||
|
<b>${printAttachment.name}</b><br />
|
||||||
|
${printAttachment.size}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
|
||||||
|
Element _createAttachmentsElement({
|
||||||
|
required String titleAttachment,
|
||||||
|
required List<PrintAttachment> listAttachment
|
||||||
|
}) {
|
||||||
|
return Element.html('''
|
||||||
|
<table class="attachments" cellspacing="0" cellpadding="5" border="0">
|
||||||
|
<tbody>
|
||||||
|
${_createTitleAttachmentHtmlTag(countAttachments: listAttachment.length, titleAttachment: titleAttachment)}
|
||||||
|
${listAttachment.map((printAttachment) => _createAttachmentHtmlTag(printAttachment)).toList().join('')}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> printEmail({
|
||||||
required String appName,
|
required String appName,
|
||||||
required String userName,
|
required String userName,
|
||||||
}) {
|
required String subject,
|
||||||
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<bool> printEmailToPDF({
|
|
||||||
required String appName,
|
|
||||||
required String userName,
|
|
||||||
required String title,
|
|
||||||
required String emailContent,
|
required String emailContent,
|
||||||
required String senderName,
|
required String senderName,
|
||||||
required String senderEmailAddress,
|
required String senderEmailAddress,
|
||||||
@@ -331,69 +178,71 @@ class PrintUtils {
|
|||||||
String? replyToAddress,
|
String? replyToAddress,
|
||||||
List<PrintAttachment>? listAttachment,
|
List<PrintAttachment>? listAttachment,
|
||||||
}) async {
|
}) async {
|
||||||
return await Printing.layoutPdf(onLayout: (pw.PdfPageFormat format) async {
|
Document document = parse(HtmlUtils.createTemplateHtmlDocument(title: '$appName - $subject'));
|
||||||
final googleInterRegularFont = await PdfGoogleFonts.interRegular();
|
|
||||||
final googleInterBoldFont = await PdfGoogleFonts.interBold();
|
|
||||||
final logoAppSvg = await rootBundle.loadString(_imagePaths.icTMailLogo);
|
|
||||||
final contentWidget = await _createEmailContentWidget(emailContent);
|
|
||||||
|
|
||||||
final pdfDocument = pw.Document();
|
Element bodyContainerElement = Element.html('<div class="body-container"></div>');
|
||||||
|
Element mainContentElement = Element.html('<div class="main-content"></div>');
|
||||||
|
Element messageElement = Element.html('<table width="100%" cellpadding="0" cellspacing="0" border="0" class="message"></table>');
|
||||||
|
Element messageBodyElement = Element.html('<tbody></tbody>');
|
||||||
|
|
||||||
pdfDocument.addPage(
|
Element userInfoElement = await _createUserInformationElement(
|
||||||
pw.MultiPage(
|
appName: appName,
|
||||||
pageFormat: pw.PdfPageFormat.standard,
|
userName: userName);
|
||||||
orientation: pw.PageOrientation.portrait,
|
|
||||||
theme: pw.ThemeData(
|
Element subjectElement = _createSubjectElement(subject);
|
||||||
defaultTextStyle: pw.TextStyle(
|
|
||||||
font: googleInterRegularFont,
|
Element senderElement = _createSenderElement(
|
||||||
fontSize: 12,
|
senderName: senderName,
|
||||||
color: pw.PdfColors.black
|
senderEmailAddress: senderEmailAddress,
|
||||||
),
|
dateTime: dateTime);
|
||||||
header3: pw.TextStyle(
|
|
||||||
font: googleInterBoldFont,
|
Element recipientsElement = _createRecipientsElement(
|
||||||
fontSize: 14,
|
toPrefix: toPrefix,
|
||||||
fontWeight: pw.FontWeight.bold,
|
ccPrefix: ccPrefix,
|
||||||
color: pw.PdfColors.black
|
bccPrefix: bccPrefix,
|
||||||
),
|
replyToPrefix: replyToPrefix,
|
||||||
header4: pw.TextStyle(
|
toAddress: toAddress,
|
||||||
font: googleInterBoldFont,
|
ccAddress: ccAddress,
|
||||||
fontSize: 12,
|
bccAddress: bccAddress,
|
||||||
fontWeight: pw.FontWeight.bold,
|
replyToAddress: replyToAddress,
|
||||||
color: pw.PdfColors.black
|
);
|
||||||
),
|
|
||||||
),
|
Element emailContentElement = _createEmailContentElement(emailContent);
|
||||||
margin: pw.EdgeInsets.zero,
|
|
||||||
build: (context) => _createBodyWidgets(
|
bodyContainerElement.append(userInfoElement);
|
||||||
context: context,
|
bodyContainerElement.append(dividerElement);
|
||||||
contentWidget: contentWidget,
|
|
||||||
logoAppSvg: logoAppSvg,
|
mainContentElement.append(subjectElement);
|
||||||
appName: appName,
|
mainContentElement.append(dividerElement);
|
||||||
userName: userName,
|
|
||||||
title: title,
|
messageBodyElement.append(senderElement);
|
||||||
htmlDocument: emailContent,
|
messageBodyElement.append(recipientsElement);
|
||||||
senderName: senderName,
|
messageBodyElement.append(emailContentElement);
|
||||||
senderEmailAddress: senderEmailAddress,
|
|
||||||
dateTime: dateTime,
|
messageElement.append(messageBodyElement);
|
||||||
toPrefix: toPrefix,
|
|
||||||
ccPrefix: ccPrefix,
|
mainContentElement.append(messageElement);
|
||||||
bccPrefix: toPrefix,
|
|
||||||
replyToPrefix: replyToPrefix,
|
if (listAttachment?.isNotEmpty == true) {
|
||||||
toAddress: toAddress,
|
Element attachmentsElement = _createAttachmentsElement(
|
||||||
ccAddress: ccAddress,
|
titleAttachment: titleAttachment,
|
||||||
bccAddress: bccAddress,
|
listAttachment: listAttachment!);
|
||||||
replyToAddress: replyToAddress,
|
mainContentElement.append(dividerElement);
|
||||||
titleAttachment: titleAttachment,
|
mainContentElement.append(attachmentsElement);
|
||||||
listAttachment: listAttachment
|
}
|
||||||
),
|
|
||||||
header: (context) => _createPageHeader(
|
bodyContainerElement.append(mainContentElement);
|
||||||
context: context,
|
|
||||||
appName: appName,
|
document.body?.append(bodyContainerElement);
|
||||||
title: title,
|
|
||||||
locale: locale,
|
Element scriptElement = Element.html(HtmlInteraction.scriptHandleInvokePrinterOnBrowser);
|
||||||
),
|
document.body?.append(scriptElement);
|
||||||
)
|
|
||||||
);
|
Element styleElement = Element.html(HtmlTemplate.printDocumentCssStyle);
|
||||||
return await pdfDocument.save();
|
document.head?.append(styleElement);
|
||||||
});
|
|
||||||
|
final htmlDocument = document.outerHtml;
|
||||||
|
|
||||||
|
HtmlUtils.openNewTabHtmlDocument(htmlDocument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
archive:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: archive
|
|
||||||
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.4.10"
|
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -25,22 +17,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.11.0"
|
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:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -89,14 +65,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.18.0"
|
version: "1.18.0"
|
||||||
convert:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: convert
|
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.1"
|
|
||||||
cross_file:
|
cross_file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -105,14 +73,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.3+7"
|
version: "0.3.3+7"
|
||||||
crypto:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: crypto
|
|
||||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.3"
|
|
||||||
csslib:
|
csslib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -368,14 +328,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.3"
|
version: "0.15.3"
|
||||||
htmltopdfwidgets:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: htmltopdfwidgets
|
|
||||||
sha256: "990e3002fbbfaf307555f1991bed61b6228d7053b7e1945815c7a68f56bbda81"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.3"
|
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -392,14 +344,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.0.2"
|
||||||
image:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: image
|
|
||||||
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.1.7"
|
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -520,22 +464,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
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:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -568,30 +496,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.1"
|
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:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|||||||
@@ -75,10 +75,6 @@ dependencies:
|
|||||||
|
|
||||||
linkify: 5.0.0
|
linkify: 5.0.0
|
||||||
|
|
||||||
htmltopdfwidgets: 1.0.3
|
|
||||||
|
|
||||||
printing: 5.12.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ class ComposerBindings extends BaseBindings {
|
|||||||
Get.lazyPut(() => PrintFileDataSourceImpl(
|
Get.lazyPut(() => PrintFileDataSourceImpl(
|
||||||
Get.find<PrintUtils>(),
|
Get.find<PrintUtils>(),
|
||||||
Get.find<ImagePaths>(),
|
Get.find<ImagePaths>(),
|
||||||
|
Get.find<FileUtils>(),
|
||||||
Get.find<CacheExceptionThrower>()
|
Get.find<CacheExceptionThrower>()
|
||||||
));
|
));
|
||||||
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:tmail_ui_user/features/email/domain/model/email_print.dart';
|
import 'package:tmail_ui_user/features/email/domain/model/email_print.dart';
|
||||||
|
|
||||||
abstract class PrintFileDataSource {
|
abstract class PrintFileDataSource {
|
||||||
Future<void> printEmailToPDF(EmailPrint emailPrint);
|
Future<void> printEmail(EmailPrint emailPrint);
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import 'package:core/data/model/print_attachment.dart';
|
import 'package:core/data/model/print_attachment.dart';
|
||||||
import 'package:core/presentation/resources/image_paths.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:core/utils/print_utils.dart';
|
||||||
import 'package:filesize/filesize.dart';
|
import 'package:filesize/filesize.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:model/email/attachment.dart';
|
import 'package:model/email/attachment.dart';
|
||||||
import 'package:model/extensions/utc_date_extension.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/data/datasource/print_file_datasource.dart';
|
||||||
@@ -15,16 +14,18 @@ class PrintFileDataSourceImpl extends PrintFileDataSource {
|
|||||||
|
|
||||||
final PrintUtils _printUtils;
|
final PrintUtils _printUtils;
|
||||||
final ImagePaths _imagePaths;
|
final ImagePaths _imagePaths;
|
||||||
|
final FileUtils _fileUtils;
|
||||||
final ExceptionThrower _exceptionThrower;
|
final ExceptionThrower _exceptionThrower;
|
||||||
|
|
||||||
PrintFileDataSourceImpl(
|
PrintFileDataSourceImpl(
|
||||||
this._printUtils,
|
this._printUtils,
|
||||||
this._imagePaths,
|
this._imagePaths,
|
||||||
|
this._fileUtils,
|
||||||
this._exceptionThrower
|
this._exceptionThrower
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> printEmailToPDF(EmailPrint emailPrint) {
|
Future<void> printEmail(EmailPrint emailPrint) {
|
||||||
return Future.sync(() async {
|
return Future.sync(() async {
|
||||||
final sender = emailPrint.emailInformation.from?.isNotEmpty == true
|
final sender = emailPrint.emailInformation.from?.isNotEmpty == true
|
||||||
? emailPrint.emailInformation.from!.first
|
? emailPrint.emailInformation.from!.first
|
||||||
@@ -37,9 +38,9 @@ class PrintFileDataSourceImpl extends PrintFileDataSource {
|
|||||||
|
|
||||||
if (emailPrint.attachments?.isNotEmpty == true) {
|
if (emailPrint.attachments?.isNotEmpty == true) {
|
||||||
await Future.forEach<Attachment>(emailPrint.attachments ?? [], (attachment) async {
|
await Future.forEach<Attachment>(emailPrint.attachments ?? [], (attachment) async {
|
||||||
final iconSvg = await rootBundle.loadString(attachment.getIcon(_imagePaths));
|
final iconBase64Data = await _fileUtils.convertImageAssetToBase64(attachment.getIcon(_imagePaths));
|
||||||
final printAttachment = PrintAttachment(
|
final printAttachment = PrintAttachment(
|
||||||
iconSvg: iconSvg,
|
iconBase64Data: iconBase64Data,
|
||||||
name: attachment.name ?? '',
|
name: attachment.name ?? '',
|
||||||
size: filesize(attachment.size?.value)
|
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,
|
appName: emailPrint.appName,
|
||||||
userName: emailPrint.userName,
|
userName: emailPrint.userName,
|
||||||
locale: emailPrint.locale,
|
locale: emailPrint.locale,
|
||||||
title: emailPrint.emailInformation.subject ?? '',
|
subject: emailPrint.emailInformation.subject ?? '',
|
||||||
emailContent: emailPrint.emailContent,
|
emailContent: emailPrint.emailContent,
|
||||||
senderName: sender?.name ?? '',
|
senderName: sender?.name ?? '',
|
||||||
senderEmailAddress: sender?.email ?? '',
|
senderEmailAddress: sender?.email ?? '',
|
||||||
@@ -67,8 +68,6 @@ class PrintFileDataSourceImpl extends PrintFileDataSource {
|
|||||||
titleAttachment: emailPrint.titleAttachment,
|
titleAttachment: emailPrint.titleAttachment,
|
||||||
listAttachment: listPrintAttachment
|
listAttachment: listPrintAttachment
|
||||||
);
|
);
|
||||||
log('PrintFileDataSourceImpl::printEmailToPDF: RESULT = $result');
|
|
||||||
return result;
|
|
||||||
}).catchError(_exceptionThrower.throwException);
|
}).catchError(_exceptionThrower.throwException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,6 +235,6 @@ class EmailRepositoryImpl extends EmailRepository {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> printEmail(EmailPrint emailPrint) {
|
Future<void> printEmail(EmailPrint emailPrint) {
|
||||||
return _printFileDataSource.printEmailToPDF(emailPrint);
|
return _printFileDataSource.printEmail(emailPrint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,6 @@ class PrintEmailInteractor {
|
|||||||
final htmlContentTransformed = await emailRepository.transformHtmlEmailContent(
|
final htmlContentTransformed = await emailRepository.transformHtmlEmailContent(
|
||||||
emailContent,
|
emailContent,
|
||||||
TransformConfiguration.forPrintEmail());
|
TransformConfiguration.forPrintEmail());
|
||||||
log('PrintEmailInteractor::_transformHtmlEmailContent: htmlContentTransformed: $htmlContentTransformed');
|
|
||||||
return htmlContentTransformed;
|
return htmlContentTransformed;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('PrintEmailInteractor::_transformHtmlEmailContent: Exception: $e');
|
logError('PrintEmailInteractor::_transformHtmlEmailContent: Exception: $e');
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ class EmailBindings extends BaseBindings {
|
|||||||
Get.lazyPut(() => PrintFileDataSourceImpl(
|
Get.lazyPut(() => PrintFileDataSourceImpl(
|
||||||
Get.find<PrintUtils>(),
|
Get.find<PrintUtils>(),
|
||||||
Get.find<ImagePaths>(),
|
Get.find<ImagePaths>(),
|
||||||
|
Get.find<FileUtils>(),
|
||||||
Get.find<CacheExceptionThrower>()
|
Get.find<CacheExceptionThrower>()
|
||||||
));
|
));
|
||||||
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ class MailboxDashBoardBindings extends BaseBindings {
|
|||||||
Get.lazyPut(() => PrintFileDataSourceImpl(
|
Get.lazyPut(() => PrintFileDataSourceImpl(
|
||||||
Get.find<PrintUtils>(),
|
Get.find<PrintUtils>(),
|
||||||
Get.find<ImagePaths>(),
|
Get.find<ImagePaths>(),
|
||||||
|
Get.find<FileUtils>(),
|
||||||
Get.find<CacheExceptionThrower>()
|
Get.find<CacheExceptionThrower>()
|
||||||
));
|
));
|
||||||
Get.lazyPut(() => MailboxDataSourceImpl(
|
Get.lazyPut(() => MailboxDataSourceImpl(
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ class SendEmailInteractorBindings extends InteractorsBindings {
|
|||||||
Get.lazyPut(() => PrintFileDataSourceImpl(
|
Get.lazyPut(() => PrintFileDataSourceImpl(
|
||||||
Get.find<PrintUtils>(),
|
Get.find<PrintUtils>(),
|
||||||
Get.find<ImagePaths>(),
|
Get.find<ImagePaths>(),
|
||||||
|
Get.find<FileUtils>(),
|
||||||
Get.find<CacheExceptionThrower>(),
|
Get.find<CacheExceptionThrower>(),
|
||||||
));
|
));
|
||||||
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ class FcmInteractorBindings extends InteractorsBindings {
|
|||||||
Get.lazyPut(() => PrintFileDataSourceImpl(
|
Get.lazyPut(() => PrintFileDataSourceImpl(
|
||||||
Get.find<PrintUtils>(),
|
Get.find<PrintUtils>(),
|
||||||
Get.find<ImagePaths>(),
|
Get.find<ImagePaths>(),
|
||||||
|
Get.find<FileUtils>(),
|
||||||
Get.find<CacheExceptionThrower>()
|
Get.find<CacheExceptionThrower>()
|
||||||
));
|
));
|
||||||
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import 'package:core/utils/print_utils.dart';
|
|||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:htmltopdfwidgets/htmltopdfwidgets.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.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/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart';
|
||||||
import 'package:tmail_ui_user/main/utils/app_config.dart';
|
import 'package:tmail_ui_user/main/utils/app_config.dart';
|
||||||
@@ -62,8 +61,7 @@ class CoreBindings extends Bindings {
|
|||||||
Get.put(CompressFileUtils());
|
Get.put(CompressFileUtils());
|
||||||
Get.put(AppConfigLoader());
|
Get.put(AppConfigLoader());
|
||||||
Get.put(FileUtils());
|
Get.put(FileUtils());
|
||||||
Get.put(HTMLToPdf());
|
Get.put(PrintUtils(Get.find<ImagePaths>(), Get.find<FileUtils>()));
|
||||||
Get.put(PrintUtils(Get.find<HTMLToPdf>(), Get.find<ImagePaths>()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _bindingIsolate() {
|
void _bindingIsolate() {
|
||||||
|
|||||||
@@ -57,14 +57,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
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:
|
better_open_file:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -73,14 +65,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.6.4"
|
version: "3.6.4"
|
||||||
bidi:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: bidi
|
|
||||||
sha256: "1a7d0c696324b2089f72e7671fd1f1f64fef44c980f3cebc84e803967c597b63"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.10"
|
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1046,14 +1030,6 @@ packages:
|
|||||||
url: "https://github.com/linagora/html-editor-enhanced.git"
|
url: "https://github.com/linagora/html-editor-enhanced.git"
|
||||||
source: git
|
source: git
|
||||||
version: "2.5.1"
|
version: "2.5.1"
|
||||||
htmltopdfwidgets:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: htmltopdfwidgets
|
|
||||||
sha256: "990e3002fbbfaf307555f1991bed61b6228d7053b7e1945815c7a68f56bbda81"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.3"
|
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1358,22 +1334,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
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:
|
percent_indicator:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -1470,14 +1430,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
printing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: printing
|
|
||||||
sha256: "1c99cab90ebcc1fff65831d264627d5b529359d563e53f33ab9b8117f2d280bc"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "5.12.0"
|
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1502,14 +1454,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.3"
|
version: "1.2.3"
|
||||||
qr:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: qr
|
|
||||||
sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -231,8 +231,6 @@ dependencies:
|
|||||||
|
|
||||||
mime: 1.0.4
|
mime: 1.0.4
|
||||||
|
|
||||||
htmltopdfwidgets: 1.0.3
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
@@ -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_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/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/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/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/domain/usecases/view_attachment_for_web_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart';
|
import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart';
|
||||||
@@ -69,6 +70,7 @@ const fallbackGenerators = {
|
|||||||
MockSpec<ImagePaths>(),
|
MockSpec<ImagePaths>(),
|
||||||
MockSpec<ResponsiveUtils>(),
|
MockSpec<ResponsiveUtils>(),
|
||||||
MockSpec<Uuid>(),
|
MockSpec<Uuid>(),
|
||||||
|
MockSpec<PrintEmailInteractor>(),
|
||||||
])
|
])
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
@@ -99,6 +101,7 @@ void main() {
|
|||||||
final imagePaths = MockImagePaths();
|
final imagePaths = MockImagePaths();
|
||||||
final responsiveUtils = MockResponsiveUtils();
|
final responsiveUtils = MockResponsiveUtils();
|
||||||
final uuid = MockUuid();
|
final uuid = MockUuid();
|
||||||
|
final printEmailInteractor = MockPrintEmailInteractor();
|
||||||
|
|
||||||
late SingleEmailController singleEmailController = SingleEmailController(
|
late SingleEmailController singleEmailController = SingleEmailController(
|
||||||
getEmailContentInteractor,
|
getEmailContentInteractor,
|
||||||
@@ -112,6 +115,7 @@ void main() {
|
|||||||
getAllIdentitiesInteractor,
|
getAllIdentitiesInteractor,
|
||||||
storeOpenedEmailInteractor,
|
storeOpenedEmailInteractor,
|
||||||
viewAttachmentForWebInteractor,
|
viewAttachmentForWebInteractor,
|
||||||
|
printEmailInteractor,
|
||||||
);
|
);
|
||||||
|
|
||||||
final testAccountId = AccountId(Id('123'));
|
final testAccountId = AccountId(Id('123'));
|
||||||
|
|||||||
Reference in New Issue
Block a user