feat: update backend OCR parser, web app, mobile app camera/preview UI, tests, and documentation with sample images
This commit is contained in:
1 parent
aa3233e411
commit
bdb3a49742
71 files changed
+3360
-764
No files matched your search
@@ -2,7 +2,6 @@ import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:image/image.dart' as img;
|
||||
import '../../config/app_config.dart';
|
||||
import '../documents/pending_documents_provider.dart';
|
||||
import 'blur_detector.dart';
|
||||
@@ -162,51 +161,7 @@ class _ImagePreviewScreenState extends ConsumerState<ImagePreviewScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _rotateImage() async {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => const Center(
|
||||
child: CircularProgressIndicator(color: AppConfig.primaryColor),
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
final bytes = await File(_currentImagePath).readAsBytes();
|
||||
final decoded = img.decodeImage(bytes);
|
||||
if (decoded != null) {
|
||||
// Rotate 90 degrees clockwise
|
||||
final rotated = img.copyRotate(decoded, angle: 90);
|
||||
final encoded = img.encodeJpg(rotated);
|
||||
|
||||
final dir = Directory(_currentImagePath).parent.path;
|
||||
final name = _currentImagePath.split('/').last.split('\\').last;
|
||||
final newPath = '$dir/rotated_${DateTime.now().millisecondsSinceEpoch}_$name';
|
||||
|
||||
await File(newPath).writeAsBytes(encoded);
|
||||
|
||||
// Delete old rotated files to prevent memory leaks/leftovers
|
||||
if (_currentImagePath.contains('rotated_')) {
|
||||
try {
|
||||
await File(_currentImagePath).delete();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_currentImagePath = newPath;
|
||||
_analyzing = true;
|
||||
});
|
||||
Navigator.pop(context); // Close loading dialog
|
||||
_detectBlur(); // Re-run blur analysis
|
||||
}
|
||||
} else {
|
||||
if (mounted) Navigator.pop(context);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -214,13 +169,6 @@ class _ImagePreviewScreenState extends ConsumerState<ImagePreviewScreen> {
|
||||
backgroundColor: AppConfig.backgroundColor,
|
||||
appBar: AppBar(
|
||||
title: const Text('Konfirmasi Foto'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.rotate_right),
|
||||
onPressed: _rotateImage,
|
||||
tooltip: 'Putar 90°',
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
@@ -259,17 +207,6 @@ class _ImagePreviewScreenState extends ConsumerState<ImagePreviewScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 24,
|
||||
right: 24,
|
||||
child: FloatingActionButton.small(
|
||||
heroTag: 'rotate_button',
|
||||
backgroundColor: Colors.white.withOpacity(0.9),
|
||||
foregroundColor: AppConfig.primaryColor,
|
||||
onPressed: _rotateImage,
|
||||
child: const Icon(Icons.rotate_right),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -346,7 +283,7 @@ class _ImagePreviewScreenState extends ConsumerState<ImagePreviewScreen> {
|
||||
// Confirm & Sync Button
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: (!_analyzing && _blurResult != null && !_blurResult!.isBlur) ? () {
|
||||
onPressed: !_analyzing ? () {
|
||||
ref.read(pendingDocumentsProvider.notifier).addDocument(
|
||||
_currentImagePath,
|
||||
latitude: widget.latitude,
|
||||
|
||||
Reference in new issue
Block a user