Add document scanner
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

This commit is contained in:
2025-07-08 23:19:28 +02:00
parent 52bbcf708f
commit a4b630c66e
7 changed files with 78 additions and 17 deletions

View File

@ -9,6 +9,7 @@ import 'package:moneymgr_mobile/services/storage/prefs.dart';
import 'package:moneymgr_mobile/services/storage/secure_storage.dart'; import 'package:moneymgr_mobile/services/storage/secure_storage.dart';
import 'package:moneymgr_mobile/utils/provider_observer.dart'; import 'package:moneymgr_mobile/utils/provider_observer.dart';
import 'package:moneymgr_mobile/utils/theme_utils.dart'; import 'package:moneymgr_mobile/utils/theme_utils.dart';
import 'package:scanbot_sdk/scanbot_sdk.dart';
// Inspired from https://github.com/dhafinrayhan/dummymart // Inspired from https://github.com/dhafinrayhan/dummymart
@ -27,6 +28,14 @@ Future<void> main() async {
print('${record.level.name}: ${record.time}: ${record.message}'), print('${record.level.name}: ${record.time}: ${record.message}'),
); );
// Initialize scanbot sdk
var config = ScanbotSdkConfig(
loggingEnabled: true,
allowGpuAcceleration: true,
allowXnnpackAcceleration: true,
);
ScanbotSdk.initScanbotSdk(config);
runApp( runApp(
ProviderScope( ProviderScope(
observers: [AppProviderObserver()], observers: [AppProviderObserver()],

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:scanbot_sdk/scanbot_sdk_ui_v2.dart';
part 'scan_screen.g.dart';
@riverpod
Future<String> _scanDocument(Ref ref) async {
var configuration = DocumentScanningFlow(
appearance: DocumentFlowAppearanceConfiguration(
statusBarMode: StatusBarMode.DARK,
),
cleanScanningSession: true,
outputSettings: DocumentScannerOutputSettings(pagesScanLimit: 1),
screens: DocumentScannerScreens(
review: ReviewScreenConfiguration(enabled: false),
),
);
var documentResult = await ScanbotSdkUiV2.startDocumentScanner(configuration);
print("@@@");
print(documentResult);
print("####");
return "changeme";
}
class ScanScreen extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final boredSuggestion = ref.watch(_scanDocumentProvider);
// Perform a switch-case on the result to handle loading/error states
return switch (boredSuggestion) {
AsyncData(:final value) => Text('data: $value'),
AsyncError(:final error) => Text('error: $error'),
_ => const Center(child: CircularProgressIndicator()),
};
}
}

View File

@ -6,6 +6,7 @@ import 'package:moneymgr_mobile/routes/login/login_screen.dart';
import 'package:moneymgr_mobile/routes/login/manual_auth_screen.dart'; import 'package:moneymgr_mobile/routes/login/manual_auth_screen.dart';
import 'package:moneymgr_mobile/routes/login/qr_auth_screen.dart'; import 'package:moneymgr_mobile/routes/login/qr_auth_screen.dart';
import 'package:moneymgr_mobile/routes/profile/profile_screen.dart'; import 'package:moneymgr_mobile/routes/profile/profile_screen.dart';
import 'package:moneymgr_mobile/routes/scan/scan_screen.dart';
import 'package:moneymgr_mobile/routes/settings/settings_screen.dart'; import 'package:moneymgr_mobile/routes/settings/settings_screen.dart';
import 'package:moneymgr_mobile/services/router/routes_list.dart'; import 'package:moneymgr_mobile/services/router/routes_list.dart';
import 'package:moneymgr_mobile/widgets/load_startup_data.dart'; import 'package:moneymgr_mobile/widgets/load_startup_data.dart';
@ -34,20 +35,11 @@ GoRouter router(Ref ref) {
// see [AuthState] enum. // see [AuthState] enum.
final navigationItems = [ final navigationItems = [
NavigationItem( NavigationItem(
path: '/products', path: scanPage,
body: (_) => const Text("product screen"), body: (_) => ScanScreen(),
icon: Icons.widgets_outlined, icon: Icons.camera_alt_outlined,
selectedIcon: Icons.widgets, selectedIcon: Icons.camera_alt,
label: 'Products', label: "Scan",
routes: [
GoRoute(
path: ':id',
builder: (_, state) {
final id = int.parse(state.pathParameters['id']!);
return Text("product screen $id");
},
),
],
), ),
NavigationItem( NavigationItem(
path: profilePage, path: profilePage,

View File

@ -13,5 +13,8 @@ const manualAuthPage = "/login/manual";
/// Settings path /// Settings path
const settingsPage = "/settings"; const settingsPage = "/settings";
// Profile path /// Scan URL path
const scanPage = "/scan";
/// Profile path
const profilePage = "/profile"; const profilePage = "/profile";

View File

@ -32,8 +32,13 @@ class LoadStartupData extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final serverConfig = ref.watch(_loadStartupElementsProvider); final serverConfig = ref.watch(_loadStartupElementsProvider);
tryAgain() { tryAgain() async {
ref.refresh(_loadStartupElementsProvider); try {
final val = ref.refresh(_loadStartupElementsProvider);
Logger.root.info("Load again startup result: $val");
} catch (e, s) {
Logger.root.shout("Failed to try again startup loading! $e $s");
}
} }
handleSignOut() { handleSignOut() {

View File

@ -816,6 +816,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.5" version: "2.6.5"
scanbot_sdk:
dependency: "direct main"
description:
name: scanbot_sdk
sha256: adbd24643e9d7ade1050a0ed4310ace76088cec258970488a7dbe08c3dc5a872
url: "https://pub.dev"
source: hosted
version: "7.0.0"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -80,6 +80,11 @@ dependencies:
confirm_dialog: ^1.0.4 confirm_dialog: ^1.0.4
alert_dialog: ^1.0.2 alert_dialog: ^1.0.2
# Document scanner
# flutter_doc_scanner: ^0.0.16 # no bundled support yet
# https://developers.google.com/ml-kit/tips/installation-paths
scanbot_sdk: ^7.0.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter