diff --git a/assets/fonts/Roboto-Bold.ttf b/assets/fonts/Roboto-Bold.ttf new file mode 100644 index 00000000..aaf374d2 Binary files /dev/null and b/assets/fonts/Roboto-Bold.ttf differ diff --git a/assets/fonts/Roboto-Regular.ttf b/assets/fonts/Roboto-Regular.ttf new file mode 100644 index 00000000..3e6e2e76 Binary files /dev/null and b/assets/fonts/Roboto-Regular.ttf differ diff --git a/lib/main.dart b/lib/main.dart index 4945c274..abf65cba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:pdfrx/pdfrx.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -36,6 +37,8 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { Future main() async { WidgetsFlutterBinding.ensureInitialized(); + // The flag optionally hides annoying WASM warnings in your Chrome dev console + pdfrxFlutterInitialize(dismissPdfiumWasmWarnings: true); // initialize Firebase before anything that uses messaging await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); @@ -192,7 +195,10 @@ class NotificationSoundObserver extends ProviderObserver { controller.registerFcmToken(token); } }) - .catchError((e) => debugPrint('getToken error: $e')); + .catchError((e) { + debugPrint('getToken error: $e'); + return null; + }); _tokenSub = FirebaseMessaging.instance.onTokenRefresh.listen((token) { debugPrint('token refreshed: $token'); controller.registerFcmToken(token); @@ -210,7 +216,10 @@ class NotificationSoundObserver extends ProviderObserver { controller.unregisterFcmToken(token); } }) - .catchError((e) => debugPrint('getToken error: $e')); + .catchError((e) { + debugPrint('getToken error: $e'); + return null; + }); } } } diff --git a/lib/screens/tasks/task_pdf.dart b/lib/screens/tasks/task_pdf.dart index 7a7c6b49..0b9a0ba1 100644 --- a/lib/screens/tasks/task_pdf.dart +++ b/lib/screens/tasks/task_pdf.dart @@ -7,6 +7,7 @@ import 'package:flutter_quill/flutter_quill.dart' as quill; import 'package:pdf/widgets.dart' as pw; import 'package:pdf/pdf.dart' as pdf; import 'package:printing/printing.dart'; +import 'package:pdfrx/pdfrx.dart'; import '../../models/task.dart'; import '../../models/ticket.dart'; @@ -27,6 +28,14 @@ Future buildTaskPdfBytes( ) async { final logoData = await rootBundle.load('assets/crmc_logo.png'); final logoImage = pw.MemoryImage(logoData.buffer.asUint8List()); + + final regularFontData = await rootBundle.load( + 'assets/fonts/Roboto-Regular.ttf', + ); + final boldFontData = await rootBundle.load('assets/fonts/Roboto-Bold.ttf'); + final regularFont = pw.Font.ttf(regularFontData); + final boldFont = pw.Font.ttf(boldFontData); + final doc = pw.Document(); final created = AppTime.formatDate(task.createdAt); @@ -85,321 +94,325 @@ Future buildTaskPdfBytes( final profileById = {for (final p in profiles) p.id: p}; final assignedForTask = assignments.where((a) => a.taskId == task.id).toList() ..sort((a, b) => a.createdAt.compareTo(b.createdAt)); - // Collect all unique assigned user IDs for this task and map to profile names final assignedUserIds = {for (final a in assignedForTask) a.userId}; final performedBy = assignedUserIds.isEmpty ? '' : assignedUserIds.map((id) => profileById[id]?.fullName ?? id).join(', '); + // Use MultiPage to avoid overflow on long content and apply embedded fonts via ThemeData doc.addPage( - pw.Page( + pw.MultiPage( pageFormat: format ?? pdf.PdfPageFormat.a4, margin: pw.EdgeInsets.all(28), - build: (pw.Context ctx) { - return pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Center( - child: pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.center, + theme: pw.ThemeData.withFont(base: regularFont, bold: boldFont), + footer: (pw.Context ctx) => pw.Container( + alignment: pw.Alignment.centerRight, + child: pw.Text( + 'MC-IHO-F-05 Rev. 2', + style: pw.TextStyle(fontSize: 9, color: pdf.PdfColors.grey), + ), + ), + build: (pw.Context ctx) => [ + pw.Center( + child: pw.Row( + mainAxisAlignment: pw.MainAxisAlignment.center, + crossAxisAlignment: pw.CrossAxisAlignment.center, + children: [ + pw.Container(width: 80, height: 80, child: pw.Image(logoImage)), + pw.SizedBox(width: 16), + pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.center, children: [ - pw.Container( - width: 80, - height: 80, - child: pw.Image(logoImage), + pw.Text( + 'Republic of the Philippines', + textAlign: pw.TextAlign.center, ), - pw.SizedBox(width: 16), - pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.center, + pw.Text( + 'Department of Health', + textAlign: pw.TextAlign.center, + ), + pw.Text( + 'Regional and Medical Center', + textAlign: pw.TextAlign.center, + ), + pw.SizedBox(height: 6), + pw.Text( + 'Cotabato Regional and Medical Center', + textAlign: pw.TextAlign.center, + style: pw.TextStyle(fontWeight: pw.FontWeight.bold), + ), + pw.Text( + 'Integrated Hospital Operations and Management Program', + textAlign: pw.TextAlign.center, + ), + pw.Text('(IHOMP)', textAlign: pw.TextAlign.center), + ], + ), + ], + ), + ), + pw.SizedBox(height: 12), + pw.Center( + child: pw.Text( + 'IT Job / Maintenance Request Form', + style: pw.TextStyle(fontSize: 16, fontWeight: pw.FontWeight.bold), + ), + ), + pw.SizedBox(height: 12), + pw.Row( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + pw.Expanded( + child: pw.Column( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + pw.Row( children: [ - pw.Text( - 'Republic of the Philippines', - textAlign: pw.TextAlign.center, + pw.Text('Task Number: '), + pw.Container( + padding: pw.EdgeInsets.only(bottom: 2), + decoration: pw.BoxDecoration( + border: pw.Border( + bottom: pw.BorderSide( + width: 0.8, + color: pdf.PdfColors.black, + ), + ), + ), + child: pw.Text(task.taskNumber ?? task.id), ), - pw.Text( - 'Department of Health', - textAlign: pw.TextAlign.center, + ], + ), + pw.SizedBox(height: 8), + pw.Row( + children: [ + pw.Text('Service: '), + pw.Container( + padding: pw.EdgeInsets.only(bottom: 2), + decoration: pw.BoxDecoration( + border: pw.Border( + bottom: pw.BorderSide( + width: 0.8, + color: pdf.PdfColors.black, + ), + ), + ), + child: pw.Text(serviceName), ), - pw.Text( - 'Regional and Medical Center', - textAlign: pw.TextAlign.center, + ], + ), + pw.SizedBox(height: 8), + pw.Row( + children: [ + pw.Text('Type: '), + pw.Container( + padding: pw.EdgeInsets.only(bottom: 2), + decoration: pw.BoxDecoration( + border: pw.Border( + bottom: pw.BorderSide( + width: 0.8, + color: pdf.PdfColors.black, + ), + ), + ), + child: pw.Text(task.requestType ?? ''), ), - pw.SizedBox(height: 6), - pw.Text( - 'Cotabato Regional and Medical Center', - textAlign: pw.TextAlign.center, - style: pw.TextStyle(fontWeight: pw.FontWeight.bold), - ), - pw.Text( - 'Integrated Hospital Operations and Management Program', - textAlign: pw.TextAlign.center, - ), - pw.Text('(IHOMP)', textAlign: pw.TextAlign.center), ], ), ], ), ), - pw.SizedBox(height: 12), - pw.Center( - child: pw.Text( - 'IT Job / Maintenance Request Form', - style: pw.TextStyle( - fontSize: 16, - fontWeight: pw.FontWeight.bold, + pw.SizedBox(width: 12), + pw.Container( + width: 180, + child: pw.Column( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + pw.Row( + children: [ + pw.Text('Filed At: '), + pw.Container( + padding: pw.EdgeInsets.only(bottom: 2), + decoration: pw.BoxDecoration( + border: pw.Border( + bottom: pw.BorderSide( + width: 0.8, + color: pdf.PdfColors.black, + ), + ), + ), + child: pw.Text(created), + ), + ], + ), + pw.SizedBox(height: 8), + pw.Row( + children: [ + pw.Text('Office: '), + pw.Container( + padding: pw.EdgeInsets.only(bottom: 2), + decoration: pw.BoxDecoration( + border: pw.Border( + bottom: pw.BorderSide( + width: 0.8, + color: pdf.PdfColors.black, + ), + ), + ), + child: pw.Text(officeName), + ), + ], + ), + pw.SizedBox(height: 8), + pw.Row( + children: [ + pw.Text('Category: '), + pw.Container( + padding: pw.EdgeInsets.only(bottom: 2), + decoration: pw.BoxDecoration( + border: pw.Border( + bottom: pw.BorderSide( + width: 0.8, + color: pdf.PdfColors.black, + ), + ), + ), + child: pw.Text(task.requestCategory ?? ''), + ), + ], + ), + ], + ), + ), + ], + ), + pw.SizedBox(height: 12), + pw.Divider(thickness: 0.8, color: pdf.PdfColors.grey), + pw.SizedBox(height: 6), + pw.Center( + child: pw.Text( + task.title, + textAlign: pw.TextAlign.center, + style: pw.TextStyle(fontWeight: pw.FontWeight.bold), + ), + ), + pw.SizedBox(height: 6), + pw.Divider(thickness: 0.8, color: pdf.PdfColors.grey), + pw.SizedBox(height: 6), + pw.Text('Description:'), + pw.SizedBox(height: 6), + pw.Container( + padding: pw.EdgeInsets.all(6), + child: pw.Text(descriptionText), + ), + pw.SizedBox(height: 12), + // Requested/Noted signature lines (bottom-aligned to match Performed/Received) + pw.Row( + crossAxisAlignment: pw.CrossAxisAlignment.end, + children: [ + pw.Expanded( + child: pw.Container( + height: 56, + child: pw.Column( + mainAxisAlignment: pw.MainAxisAlignment.end, + children: [ + pw.Container(height: 1, color: pdf.PdfColors.black), + pw.SizedBox(height: 6), + pw.Text( + requestedBy, + style: pw.TextStyle(fontWeight: pw.FontWeight.bold), + ), + pw.Text('Requested By'), + ], ), ), ), - pw.SizedBox(height: 12), - pw.Row( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Expanded( - child: pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Row( - children: [ - pw.Text('Task Number: '), - pw.Container( - padding: pw.EdgeInsets.only(bottom: 2), - decoration: pw.BoxDecoration( - border: pw.Border( - bottom: pw.BorderSide( - width: 0.8, - color: pdf.PdfColors.black, - ), - ), - ), - child: pw.Text(task.taskNumber ?? task.id), - ), - ], - ), - pw.SizedBox(height: 8), - pw.Row( - children: [ - pw.Text('Service: '), - pw.Container( - padding: pw.EdgeInsets.only(bottom: 2), - decoration: pw.BoxDecoration( - border: pw.Border( - bottom: pw.BorderSide( - width: 0.8, - color: pdf.PdfColors.black, - ), - ), - ), - child: pw.Text(serviceName), - ), - ], - ), - pw.SizedBox(height: 8), - pw.Row( - children: [ - pw.Text('Type: '), - pw.Container( - padding: pw.EdgeInsets.only(bottom: 2), - decoration: pw.BoxDecoration( - border: pw.Border( - bottom: pw.BorderSide( - width: 0.8, - color: pdf.PdfColors.black, - ), - ), - ), - child: pw.Text(task.requestType ?? ''), - ), - ], - ), - ], - ), + pw.SizedBox(width: 12), + pw.Expanded( + child: pw.Container( + height: 56, + child: pw.Column( + mainAxisAlignment: pw.MainAxisAlignment.end, + children: [ + pw.Container(height: 1, color: pdf.PdfColors.black), + pw.SizedBox(height: 6), + pw.Text( + notedBy, + style: pw.TextStyle(fontWeight: pw.FontWeight.bold), + ), + pw.Text('Noted by Supervisor/Senior'), + ], ), - pw.SizedBox(width: 12), - pw.Container( - width: 180, - child: pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Row( - children: [ - pw.Text('Filed At: '), - pw.Container( - padding: pw.EdgeInsets.only(bottom: 2), - decoration: pw.BoxDecoration( - border: pw.Border( - bottom: pw.BorderSide( - width: 0.8, - color: pdf.PdfColors.black, - ), - ), - ), - child: pw.Text(created), - ), - ], - ), - pw.SizedBox(height: 8), - pw.Row( - children: [ - pw.Text('Office: '), - pw.Container( - padding: pw.EdgeInsets.only(bottom: 2), - decoration: pw.BoxDecoration( - border: pw.Border( - bottom: pw.BorderSide( - width: 0.8, - color: pdf.PdfColors.black, - ), - ), - ), - child: pw.Text(officeName), - ), - ], - ), - pw.SizedBox(height: 8), - pw.Row( - children: [ - pw.Text('Category: '), - pw.Container( - padding: pw.EdgeInsets.only(bottom: 2), - decoration: pw.BoxDecoration( - border: pw.Border( - bottom: pw.BorderSide( - width: 0.8, - color: pdf.PdfColors.black, - ), - ), - ), - child: pw.Text(task.requestCategory ?? ''), - ), - ], - ), - ], - ), - ), - ], - ), - pw.SizedBox(height: 12), - pw.Divider(thickness: 0.8, color: pdf.PdfColors.grey), - pw.SizedBox(height: 6), - pw.Center( - child: pw.Text( - task.title, - textAlign: pw.TextAlign.center, - style: pw.TextStyle(fontWeight: pw.FontWeight.bold), ), ), - pw.SizedBox(height: 6), - pw.Divider(thickness: 0.8, color: pdf.PdfColors.grey), - pw.SizedBox(height: 6), - pw.Text('Description:'), - pw.SizedBox(height: 6), - pw.Container( - padding: pw.EdgeInsets.all(6), - child: pw.Text(descriptionText), + ], + ), + pw.SizedBox(height: 12), + pw.Text('Action Taken:'), + pw.SizedBox(height: 6), + pw.Container( + padding: pw.EdgeInsets.all(6), + child: pw.Text(actionTakenText), + ), + pw.SizedBox(height: 6), + pw.Divider(thickness: 0.8, color: pdf.PdfColors.grey), + pw.SizedBox(height: 12), + // Historical timestamps side-by-side: Created / Started / Closed + pw.Row( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + pw.Expanded( + child: pw.Column( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + pw.Text('Created At:'), + pw.SizedBox(height: 4), + pw.Text( + '${AppTime.formatDate(task.createdAt)} ${AppTime.formatTime(task.createdAt)}', + ), + ], + ), ), - pw.SizedBox(height: 12), - // Requested/Noted signature lines (bottom-aligned to match Performed/Received) - pw.Row( - crossAxisAlignment: pw.CrossAxisAlignment.end, - children: [ - pw.Expanded( - child: pw.Container( - height: 56, - child: pw.Column( - mainAxisAlignment: pw.MainAxisAlignment.end, - children: [ - pw.Container(height: 1, color: pdf.PdfColors.black), - pw.SizedBox(height: 6), - pw.Text( - requestedBy, - style: pw.TextStyle(fontWeight: pw.FontWeight.bold), - ), - pw.Text('Requested By'), - ], - ), + pw.SizedBox(width: 12), + pw.Expanded( + child: pw.Column( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + pw.Text('Started At:'), + pw.SizedBox(height: 4), + pw.Text( + task.startedAt == null + ? '' + : '${AppTime.formatDate(task.startedAt!)} ${AppTime.formatTime(task.startedAt!)}', ), - ), - pw.SizedBox(width: 12), - pw.Expanded( - child: pw.Container( - height: 56, - child: pw.Column( - mainAxisAlignment: pw.MainAxisAlignment.end, - children: [ - pw.Container(height: 1, color: pdf.PdfColors.black), - pw.SizedBox(height: 6), - pw.Text( - notedBy, - style: pw.TextStyle(fontWeight: pw.FontWeight.bold), - ), - pw.Text('Noted by Supervisor/Senior'), - ], - ), - ), - ), - ], + ], + ), ), - pw.SizedBox(height: 12), - pw.Text('Action Taken:'), - pw.SizedBox(height: 6), - pw.Container( - padding: pw.EdgeInsets.all(6), - child: pw.Text(actionTakenText), + pw.SizedBox(width: 12), + pw.Expanded( + child: pw.Column( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + pw.Text('Closed At:'), + pw.SizedBox(height: 4), + pw.Text( + task.completedAt == null + ? '' + : '${AppTime.formatDate(task.completedAt!)} ${AppTime.formatTime(task.completedAt!)}', + ), + ], + ), ), - pw.SizedBox(height: 6), - pw.Divider(thickness: 0.8, color: pdf.PdfColors.grey), - pw.SizedBox(height: 12), - // Historical timestamps side-by-side: Created / Started / Closed - pw.Row( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Expanded( - child: pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Text('Created At:'), - pw.SizedBox(height: 4), - pw.Text( - '${AppTime.formatDate(task.createdAt)} ${AppTime.formatTime(task.createdAt)}', - ), - ], - ), - ), - pw.SizedBox(width: 12), - pw.Expanded( - child: pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Text('Started At:'), - pw.SizedBox(height: 4), - pw.Text( - task.startedAt == null - ? '' - : '${AppTime.formatDate(task.startedAt!)} ${AppTime.formatTime(task.startedAt!)}', - ), - ], - ), - ), - pw.SizedBox(width: 12), - pw.Expanded( - child: pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - pw.Text('Closed At:'), - pw.SizedBox(height: 4), - pw.Text( - task.completedAt == null - ? '' - : '${AppTime.formatDate(task.completedAt!)} ${AppTime.formatTime(task.completedAt!)}', - ), - ], - ), - ), - ], - ), - pw.SizedBox(height: 36), - // Signature lines row (fixed) — stays aligned regardless of name length + ], + ), + pw.SizedBox(height: 36), + + // Wrap signature block to prevent awkward page breaks + pw.Wrap( + spacing: 6, + runSpacing: 6, + children: [ + // Signature lines row (fixed) pw.Row( children: [ pw.Expanded( @@ -419,8 +432,7 @@ Future buildTaskPdfBytes( ), ], ), - pw.SizedBox(height: 6), - // Names row: performedBy can be long but won't move the signature line; center names under lines + // Names row pw.Row( children: [ pw.Expanded( @@ -448,8 +460,7 @@ Future buildTaskPdfBytes( ), ], ), - pw.SizedBox(height: 6), - // Labels row (centered) + // Labels row pw.Row( children: [ pw.Expanded( @@ -464,18 +475,10 @@ Future buildTaskPdfBytes( ), ], ), - pw.SizedBox(height: 12), - pw.Spacer(), - pw.Align( - alignment: pw.Alignment.centerRight, - child: pw.Text( - 'MC-IHO-F-05 Rev. 2', - style: pw.TextStyle(fontSize: 9, color: pdf.PdfColors.grey), - ), - ), ], - ); - }, + ), + pw.SizedBox(height: 12), + ], ), ); @@ -494,32 +497,137 @@ Future showTaskPdfPreview( ) async { await showDialog( context: context, - builder: (ctx) => AlertDialog( - contentPadding: const EdgeInsets.all(8), - content: SizedBox( - width: 700, - height: 900, - child: PdfPreview( - build: (format) => buildTaskPdfBytes( - task, - ticket, - officeName, - serviceName, - logs, - assignments, - profiles, - format, - ), - allowPrinting: true, - allowSharing: true, - ), - ), - actions: [ - TextButton( - onPressed: () => Navigator.of(ctx).pop(), - child: const Text('Close'), - ), - ], + builder: (ctx) => TaskPdfDialog( + task: task, + ticket: ticket, + officeName: officeName, + serviceName: serviceName, + logs: logs, + assignments: assignments, + profiles: profiles, ), ); } + +class TaskPdfDialog extends StatefulWidget { + final Task task; + final Ticket? ticket; + final String officeName; + final String serviceName; + final List logs; + final List assignments; + final List profiles; + + const TaskPdfDialog({ + super.key, + required this.task, + this.ticket, + required this.officeName, + required this.serviceName, + required this.logs, + required this.assignments, + required this.profiles, + }); + + @override + State createState() => _TaskPdfDialogState(); +} + +class _TaskPdfDialogState extends State { + Future? _pdfFuture; + + @override + void initState() { + super.initState(); + // Initialize once + _pdfFuture = buildTaskPdfBytes( + widget.task, + widget.ticket, + widget.officeName, + widget.serviceName, + widget.logs, + widget.assignments, + widget.profiles, + null, + ); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: SizedBox( + width: 800, + height: 900, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + child: Row( + children: [ + const Expanded( + child: Text( + 'IT Job Preview', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + tooltip: 'Print', + icon: const Icon(Icons.print), + onPressed: () async { + final bytes = await _pdfFuture; + if (bytes == null) return; + await Printing.layoutPdf( + onLayout: (_) async => bytes, + name: + 'Task - ${widget.task.taskNumber ?? widget.task.id}.pdf', + ); + }, + ), + IconButton( + tooltip: 'Download', + icon: const Icon(Icons.download), + onPressed: () async { + final bytes = await _pdfFuture; + if (bytes == null) return; + await Printing.sharePdf( + bytes: bytes, + filename: + 'Task - ${widget.task.taskNumber ?? widget.task.id}.pdf', + ); + }, + ), + IconButton( + tooltip: 'Close', + icon: const Icon(Icons.close), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ), + ), + const Divider(height: 1), + Expanded( + child: FutureBuilder( + future: _pdfFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + if (snapshot.hasError) { + return Center(child: Text(snapshot.error.toString())); + } + final data = snapshot.data; + if (data == null) return const SizedBox.shrink(); + return PdfViewer.data(data, sourceName: 'task.pdf'); + }, + ), + ), + ], + ), + ), + ); + } +} diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 6d13abb6..7bbfe238 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + pdfium_flutter ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/pubspec.lock b/pubspec.lock index 64730683..7b2cf56d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -325,10 +325,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.1" file_picker: dependency: "direct main" description: @@ -981,6 +981,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + pdfium_dart: + dependency: transitive + description: + name: pdfium_dart + sha256: f1683b9070ddc5c9189c6ee008c285791da66328ce1b882c7162d3393f3a4a74 + url: "https://pub.dev" + source: hosted + version: "0.1.3" + pdfium_flutter: + dependency: transitive + description: + name: pdfium_flutter + sha256: "0c8b7d5d11d20a1486eade599648e907067568955bd14a1b06de076a968b60a1" + url: "https://pub.dev" + source: hosted + version: "0.1.9" + pdfrx: + dependency: "direct main" + description: + name: pdfrx + sha256: e32e0c786528eec2b3c56b43f59ef1debce3a27c7accd862b95413f949afcfa9 + url: "https://pub.dev" + source: hosted + version: "2.2.24" + pdfrx_engine: + dependency: transitive + description: + name: pdfrx_engine + sha256: a8914433d1f6188b903c53d36b9d7dc908bfa89131591a9db22f1a22470d3a48 + url: "https://pub.dev" + source: hosted + version: "0.3.9" permission_handler: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 61968c0d..c7ee6492 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,6 +24,7 @@ dependencies: flutter_quill: ^11.5.0 file_picker: ^10.3.10 pdf: ^3.11.3 + pdfrx: ^2.2.24 printing: ^5.14.2 flutter_keyboard_visibility: ^5.4.1 awesome_snackbar_content: ^0.1.8 @@ -43,6 +44,7 @@ flutter: assets: - .env - assets/ + - assets/fonts/ flutter_launcher_icons: android: true diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 209df603..d1a7b3e5 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -15,6 +15,7 @@ list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST flutter_local_notifications_windows + pdfium_flutter ) set(PLUGIN_BUNDLED_LIBRARIES)