TF-2520 Handle print email to pdf
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -43,6 +43,8 @@ export 'utils/config/errors.dart';
|
|||||||
export 'data/utils/compress_file_utils.dart';
|
export 'data/utils/compress_file_utils.dart';
|
||||||
export 'utils/platform_info.dart';
|
export 'utils/platform_info.dart';
|
||||||
export 'utils/option_param_mixin.dart';
|
export 'utils/option_param_mixin.dart';
|
||||||
|
export 'utils/file_utils.dart';
|
||||||
|
export 'utils/print_utils.dart';
|
||||||
|
|
||||||
// Views
|
// Views
|
||||||
export 'presentation/views/text/slogan_builder.dart';
|
export 'presentation/views/text/slogan_builder.dart';
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
class PrintAttachment with EquatableMixin {
|
||||||
|
final String iconSvg;
|
||||||
|
final String name;
|
||||||
|
final String size;
|
||||||
|
|
||||||
|
PrintAttachment({
|
||||||
|
required this.iconSvg,
|
||||||
|
required this.name,
|
||||||
|
required this.size
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
iconSvg,
|
||||||
|
name,
|
||||||
|
size
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
|
||||||
|
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';
|
||||||
|
|
||||||
|
class PrintUtils {
|
||||||
|
final pw.HTMLToPdf _htmlToPdf;
|
||||||
|
final ImagePaths _imagePaths;
|
||||||
|
|
||||||
|
PrintUtils(this._htmlToPdf, this._imagePaths);
|
||||||
|
|
||||||
|
Future<pw.Widget> _createEmailContentWidget(String htmlDocument) async {
|
||||||
|
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 userName,
|
||||||
|
required String title,
|
||||||
|
required String htmlDocument,
|
||||||
|
required String senderName,
|
||||||
|
required String senderEmailAddress,
|
||||||
|
required String dateTime,
|
||||||
|
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<PrintAttachment>? 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
|
||||||
|
))
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.Widget _createPageDivider() {
|
||||||
|
return pw.Padding(
|
||||||
|
padding: const pw.EdgeInsets.only(top: 12),
|
||||||
|
child: pw.Divider()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.Widget _createPageHeader({
|
||||||
|
required pw.Context context,
|
||||||
|
required String appName,
|
||||||
|
required String title,
|
||||||
|
required String locale,
|
||||||
|
}) {
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.Widget _createUserInformationRow({
|
||||||
|
required pw.Context context,
|
||||||
|
required String logoAppSvg,
|
||||||
|
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<bool> printEmailToPDF({
|
||||||
|
required String appName,
|
||||||
|
required String userName,
|
||||||
|
required String title,
|
||||||
|
required String emailContent,
|
||||||
|
required String senderName,
|
||||||
|
required String senderEmailAddress,
|
||||||
|
required String locale,
|
||||||
|
required String dateTime,
|
||||||
|
required String toPrefix,
|
||||||
|
required String ccPrefix,
|
||||||
|
required String bccPrefix,
|
||||||
|
required String replyToPrefix,
|
||||||
|
required String titleAttachment,
|
||||||
|
String? toAddress,
|
||||||
|
String? ccAddress,
|
||||||
|
String? bccAddress,
|
||||||
|
String? replyToAddress,
|
||||||
|
List<PrintAttachment>? 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);
|
||||||
|
|
||||||
|
final pdfDocument = pw.Document();
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,14 @@
|
|||||||
# 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:
|
||||||
@@ -17,6 +25,22 @@ 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:
|
||||||
@@ -65,6 +89,14 @@ 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:
|
||||||
@@ -73,6 +105,14 @@ 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:
|
||||||
@@ -328,6 +368,14 @@ 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:
|
||||||
@@ -344,6 +392,14 @@ 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:
|
||||||
@@ -464,6 +520,22 @@ 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:
|
||||||
@@ -496,6 +568,30 @@ 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,6 +75,10 @@ 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
|
||||||
|
|||||||
Reference in New Issue
Block a user