diff --git a/moneymgr_mobile/lib/routes/scan/scan_screen.dart b/moneymgr_mobile/lib/routes/scan/scan_screen.dart index 9f96b04..756351c 100644 --- a/moneymgr_mobile/lib/routes/scan/scan_screen.dart +++ b/moneymgr_mobile/lib/routes/scan/scan_screen.dart @@ -1,8 +1,14 @@ +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:alert_dialog/alert_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_pdfview/flutter_pdfview.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:logging/logging.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:scanbot_sdk/scanbot_sdk.dart'; import 'package:scanbot_sdk/scanbot_sdk_ui_v2.dart'; import '../../services/storage/expenses.dart'; @@ -10,7 +16,8 @@ import '../../services/storage/expenses.dart'; part 'scan_screen.g.dart'; @riverpod -Future _scanDocument(Ref ref) async { +Future _scanDocument(Ref ref) async { + DocumentDataExtractionResult d; var configuration = DocumentScanningFlow( appearance: DocumentFlowAppearanceConfiguration( statusBarMode: StatusBarMode.DARK, @@ -23,7 +30,19 @@ Future _scanDocument(Ref ref) async { ); var documentResult = await ScanbotSdkUiV2.startDocumentScanner(configuration); - return documentResult.data?.pdfURI; + if (documentResult.status != OperationStatus.OK) { + throw Exception("Scanner failed with status ${documentResult.status}"); + } + + // Convert result to PDF + var result = await ScanbotSdk.document.createPDFForDocument( + PDFFromDocumentParams( + documentID: documentResult.data!.uuid, + pdfConfiguration: PdfConfiguration(), + ), + ); + final pdfPath = result.pdfFileUri.replaceFirst("file://", ""); + return File(pdfPath).readAsBytes(); } class ScanScreen extends HookConsumerWidget { @@ -43,7 +62,7 @@ class ScanScreen extends HookConsumerWidget { // Perform a switch-case on the result to handle loading/error states return switch (boredSuggestion) { AsyncData(:final value) when value != null => ExpenseEditor( - filePath: value, + file: value, onFinished: (e) {}, ), @@ -97,18 +116,31 @@ class ScanErrorScreen extends StatelessWidget { } class ExpenseEditor extends HookWidget { - final String filePath; + final Uint8List file; final Function(Expense) onFinished; const ExpenseEditor({ super.key, - required this.filePath, + required this.file, required this.onFinished, }); @override Widget build(BuildContext context) { - // TODO: implement build - throw UnimplementedError(); + return ListView( + children: [ + SizedBox( + height: 200, + child: PDFView( + pdfData: file, + onError: (e) { + Logger.root.warning("Failed to render PDF $e"); + alert(context, content: Text("Failed to render PDF $e")); + }, + fitPolicy: FitPolicy.BOTH, + ), + ), + ], + ); } } diff --git a/moneymgr_mobile/pubspec.lock b/moneymgr_mobile/pubspec.lock index 5d19604..e519b9e 100644 --- a/moneymgr_mobile/pubspec.lock +++ b/moneymgr_mobile/pubspec.lock @@ -382,6 +382,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.6" + flutter_pdfview: + dependency: "direct main" + description: + name: flutter_pdfview + sha256: c402ad1f51ba8ea73b9fb04c003ca0a9286118ba5ac9787ee2aa58956b3fcf8a + url: "https://pub.dev" + source: hosted + version: "1.4.1+1" flutter_riverpod: dependency: transitive description: diff --git a/moneymgr_mobile/pubspec.yaml b/moneymgr_mobile/pubspec.yaml index 6ddd402..4052832 100644 --- a/moneymgr_mobile/pubspec.yaml +++ b/moneymgr_mobile/pubspec.yaml @@ -88,6 +88,9 @@ dependencies: # Get documents path path_provider: ^2.1.5 + # PDF viewer + flutter_pdfview: ^1.4.1+1 + dev_dependencies: flutter_test: sdk: flutter