Refactor DocumentIntelligenceService and related classes to comment out code for future reference; update AuthenticationRepository to remove splash screen on app start.

This commit is contained in:
vergiLgood1 2025-05-22 16:51:13 +07:00
parent 6a85f75e3c
commit 1908318769
4 changed files with 1318 additions and 794 deletions

View File

@ -1,19 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
import 'package:sigap/app.dart'; import 'package:sigap/app.dart';
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
Future<void> main() async { Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
// Make sure status bar is properly set // Make sure status bar is properly set
SystemChrome.setSystemUIOverlayStyle( SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(statusBarColor: Colors.transparent), const SystemUiOverlayStyle(statusBarColor: Colors.transparent),
); );
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
// Load environment variables from the .env file // Load environment variables from the .env file
await dotenv.load(fileName: ".env"); await dotenv.load(fileName: ".env");

File diff suppressed because it is too large Load Diff

View File

@ -1,286 +1,286 @@
import 'dart:convert'; // import 'dart:convert';
import 'dart:io'; // import 'dart:io';
import 'package:http/http.dart' as http; // import 'package:http/http.dart' as http;
class DocumentIntelligenceService { // class DocumentIntelligenceService {
final String endpoint; // final String endpoint;
final String key; // final String key;
final http.Client _client = http.Client(); // final http.Client _client = http.Client();
DocumentIntelligenceService({ // DocumentIntelligenceService({
required this.endpoint, // required this.endpoint,
required this.key, // required this.key,
}); // });
// Generator function equivalent for getting text of spans // // Generator function equivalent for getting text of spans
List<String> getTextOfSpans(String content, List<Map<String, dynamic>> spans) { // List<String> getTextOfSpans(String content, List<Map<String, dynamic>> spans) {
List<String> textList = []; // List<String> textList = [];
for (var span in spans) { // for (var span in spans) {
int offset = span['offset']; // int offset = span['offset'];
int length = span['length']; // int length = span['length'];
textList.add(content.substring(offset, offset + length)); // textList.add(content.substring(offset, offset + length));
} // }
return textList; // return textList;
} // }
Future<Map<String, dynamic>> analyzeDocument(String documentUrl) async { // Future<Map<String, dynamic>> analyzeDocument(String documentUrl) async {
try { // try {
// Initial request to start document analysis // // Initial request to start document analysis
final initialResponse = await _client.post( // final initialResponse = await _client.post(
Uri.parse('$endpoint/documentModels/prebuilt-read:analyze'), // Uri.parse('$endpoint/documentModels/prebuilt-read:analyze'),
headers: { // headers: {
'Content-Type': 'application/json', // 'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': key, // 'Ocp-Apim-Subscription-Key': key,
}, // },
body: jsonEncode({ // body: jsonEncode({
'urlSource': documentUrl, // 'urlSource': documentUrl,
}), // }),
); // );
if (initialResponse.statusCode != 202) { // if (initialResponse.statusCode != 202) {
throw Exception('Failed to start analysis: ${initialResponse.body}'); // throw Exception('Failed to start analysis: ${initialResponse.body}');
} // }
// Get operation location from response headers // // Get operation location from response headers
String? operationLocation = initialResponse.headers['operation-location']; // String? operationLocation = initialResponse.headers['operation-location'];
if (operationLocation == null) { // if (operationLocation == null) {
throw Exception('Operation location not found in response headers'); // throw Exception('Operation location not found in response headers');
} // }
// Poll for results // // Poll for results
return await _pollForResults(operationLocation); // return await _pollForResults(operationLocation);
} catch (e) { // } catch (e) {
throw Exception('Error analyzing document: $e'); // throw Exception('Error analyzing document: $e');
} // }
} // }
Future<Map<String, dynamic>> _pollForResults(String operationLocation) async { // Future<Map<String, dynamic>> _pollForResults(String operationLocation) async {
const int maxAttempts = 60; // Maximum polling attempts // const int maxAttempts = 60; // Maximum polling attempts
const Duration pollInterval = Duration(seconds: 2); // const Duration pollInterval = Duration(seconds: 2);
for (int attempt = 0; attempt < maxAttempts; attempt++) { // for (int attempt = 0; attempt < maxAttempts; attempt++) {
final response = await _client.get( // final response = await _client.get(
Uri.parse(operationLocation), // Uri.parse(operationLocation),
headers: { // headers: {
'Ocp-Apim-Subscription-Key': key, // 'Ocp-Apim-Subscription-Key': key,
}, // },
); // );
if (response.statusCode != 200) { // if (response.statusCode != 200) {
throw Exception('Failed to get operation status: ${response.body}'); // throw Exception('Failed to get operation status: ${response.body}');
} // }
final responseData = jsonDecode(response.body); // final responseData = jsonDecode(response.body);
final String status = responseData['status']; // final String status = responseData['status'];
if (status == 'succeeded') { // if (status == 'succeeded') {
return responseData['analyzeResult']; // return responseData['analyzeResult'];
} else if (status == 'failed') { // } else if (status == 'failed') {
throw Exception('Document analysis failed: ${responseData['error']}'); // throw Exception('Document analysis failed: ${responseData['error']}');
} // }
// Wait before next poll // // Wait before next poll
await Future.delayed(pollInterval); // await Future.delayed(pollInterval);
} // }
throw Exception('Operation timed out after $maxAttempts attempts'); // throw Exception('Operation timed out after $maxAttempts attempts');
} // }
Future<void> processDocument(String documentUrl) async { // Future<void> processDocument(String documentUrl) async {
try { // try {
final analyzeResult = await analyzeDocument(documentUrl); // final analyzeResult = await analyzeDocument(documentUrl);
final String? content = analyzeResult['content']; // final String? content = analyzeResult['content'];
final List<dynamic>? pages = analyzeResult['pages']; // final List<dynamic>? pages = analyzeResult['pages'];
final List<dynamic>? languages = analyzeResult['languages']; // final List<dynamic>? languages = analyzeResult['languages'];
final List<dynamic>? styles = analyzeResult['styles']; // final List<dynamic>? styles = analyzeResult['styles'];
// Process pages // // Process pages
if (pages == null || pages.isEmpty) { // if (pages == null || pages.isEmpty) {
print('No pages were extracted from the document.'); // print('No pages were extracted from the document.');
} else { // } else {
print('Pages:'); // print('Pages:');
for (var page in pages) { // for (var page in pages) {
print('- Page ${page['pageNumber']} (unit: ${page['unit']})'); // print('- Page ${page['pageNumber']} (unit: ${page['unit']})');
print(' ${page['width']}x${page['height']}, angle: ${page['angle']}'); // print(' ${page['width']}x${page['height']}, angle: ${page['angle']}');
final List<dynamic> lines = page['lines'] ?? []; // final List<dynamic> lines = page['lines'] ?? [];
final List<dynamic> words = page['words'] ?? []; // final List<dynamic> words = page['words'] ?? [];
print(' ${lines.length} lines, ${words.length} words'); // print(' ${lines.length} lines, ${words.length} words');
if (lines.isNotEmpty) { // if (lines.isNotEmpty) {
print(' Lines:'); // print(' Lines:');
for (var line in lines) { // for (var line in lines) {
print(' - "${line['content']}"'); // print(' - "${line['content']}"');
} // }
} // }
if (words.isNotEmpty) { // if (words.isNotEmpty) {
print(' Words:'); // print(' Words:');
for (var word in words) { // for (var word in words) {
print(' - "${word['content']}"'); // print(' - "${word['content']}"');
} // }
} // }
} // }
} // }
// Process languages // // Process languages
if (languages == null || languages.isEmpty) { // if (languages == null || languages.isEmpty) {
print('No language spans were extracted from the document.'); // print('No language spans were extracted from the document.');
} else { // } else {
print('Languages:'); // print('Languages:');
for (var languageEntry in languages) { // for (var languageEntry in languages) {
print('- Found language: ${languageEntry['locale']} ' // print('- Found language: ${languageEntry['locale']} '
'(confidence: ${languageEntry['confidence']})'); // '(confidence: ${languageEntry['confidence']})');
if (content != null && languageEntry['spans'] != null) { // if (content != null && languageEntry['spans'] != null) {
final spans = List<Map<String, dynamic>>.from(languageEntry['spans']); // final spans = List<Map<String, dynamic>>.from(languageEntry['spans']);
final textList = getTextOfSpans(content, spans); // final textList = getTextOfSpans(content, spans);
for (var text in textList) { // for (var text in textList) {
final escapedText = text // final escapedText = text
.replaceAll(RegExp(r'\r?\n'), '\\n') // .replaceAll(RegExp(r'\r?\n'), '\\n')
.replaceAll('"', '\\"'); // .replaceAll('"', '\\"');
print(' - "$escapedText"'); // print(' - "$escapedText"');
} // }
} // }
} // }
} // }
// Process styles // // Process styles
if (styles == null || styles.isEmpty) { // if (styles == null || styles.isEmpty) {
print('No text styles were extracted from the document.'); // print('No text styles were extracted from the document.');
} else { // } else {
print('Styles:'); // print('Styles:');
for (var style in styles) { // for (var style in styles) {
final bool isHandwritten = style['isHandwritten'] ?? false; // final bool isHandwritten = style['isHandwritten'] ?? false;
final double confidence = style['confidence'] ?? 0.0; // final double confidence = style['confidence'] ?? 0.0;
print('- Handwritten: ${isHandwritten ? "yes" : "no"} ' // print('- Handwritten: ${isHandwritten ? "yes" : "no"} '
'(confidence=$confidence)'); // '(confidence=$confidence)');
if (content != null && style['spans'] != null) { // if (content != null && style['spans'] != null) {
final spans = List<Map<String, dynamic>>.from(style['spans']); // final spans = List<Map<String, dynamic>>.from(style['spans']);
final textList = getTextOfSpans(content, spans); // final textList = getTextOfSpans(content, spans);
for (var text in textList) { // for (var text in textList) {
print(' - "$text"'); // print(' - "$text"');
} // }
} // }
} // }
} // }
} catch (e) { // } catch (e) {
print('An error occurred: $e'); // print('An error occurred: $e');
} // }
} // }
void dispose() { // void dispose() {
_client.close(); // _client.close();
} // }
} // }
// Example usage in a Flutter app // // Example usage in a Flutter app
class DocumentAnalyzerApp { // class DocumentAnalyzerApp {
static const String endpoint = "YOUR_FORM_RECOGNIZER_ENDPOINT"; // static const String endpoint = "YOUR_FORM_RECOGNIZER_ENDPOINT";
static const String key = "YOUR_FORM_RECOGNIZER_KEY"; // static const String key = "YOUR_FORM_RECOGNIZER_KEY";
static const String formUrl = // static const String formUrl =
"https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png"; // "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png";
static Future<void> main() async { // static Future<void> main() async {
final service = DocumentIntelligenceService( // final service = DocumentIntelligenceService(
endpoint: endpoint, // endpoint: endpoint,
key: key, // key: key,
); // );
try { // try {
await service.processDocument(formUrl); // await service.processDocument(formUrl);
} finally { // } finally {
service.dispose(); // service.dispose();
} // }
} // }
} // }
// Flutter Widget Example // // Flutter Widget Example
import 'package:flutter/material.dart'; // import 'package:flutter/material.dart';
class DocumentAnalyzerWidget extends StatefulWidget { // class DocumentAnalyzerWidget extends StatefulWidget {
const DocumentAnalyzerWidget({super.key}); // const DocumentAnalyzerWidget({super.key});
@override // @override
_DocumentAnalyzerWidgetState createState() => _DocumentAnalyzerWidgetState(); // _DocumentAnalyzerWidgetState createState() => _DocumentAnalyzerWidgetState();
} // }
class _DocumentAnalyzerWidgetState extends State<DocumentAnalyzerWidget> { // class _DocumentAnalyzerWidgetState extends State<DocumentAnalyzerWidget> {
final DocumentIntelligenceService _service = DocumentIntelligenceService( // final DocumentIntelligenceService _service = DocumentIntelligenceService(
endpoint: "YOUR_FORM_RECOGNIZER_ENDPOINT", // endpoint: "YOUR_FORM_RECOGNIZER_ENDPOINT",
key: "YOUR_FORM_RECOGNIZER_KEY", // key: "YOUR_FORM_RECOGNIZER_KEY",
); // );
bool _isLoading = false; // bool _isLoading = false;
String _result = ''; // String _result = '';
Future<void> _analyzeDocument() async { // Future<void> _analyzeDocument() async {
setState(() { // setState(() {
_isLoading = true; // _isLoading = true;
_result = ''; // _result = '';
}); // });
try { // try {
const String documentUrl = // const String documentUrl =
"https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png"; // "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png";
await _service.processDocument(documentUrl); // await _service.processDocument(documentUrl);
setState(() { // setState(() {
_result = 'Document analysis completed successfully!'; // _result = 'Document analysis completed successfully!';
}); // });
} catch (e) { // } catch (e) {
setState(() { // setState(() {
_result = 'Error: $e'; // _result = 'Error: $e';
}); // });
} finally { // } finally {
setState(() { // setState(() {
_isLoading = false; // _isLoading = false;
}); // });
} // }
} // }
@override // @override
void dispose() { // void dispose() {
_service.dispose(); // _service.dispose();
super.dispose(); // super.dispose();
} // }
@override // @override
Widget build(BuildContext context) { // Widget build(BuildContext context) {
return Scaffold( // return Scaffold(
appBar: AppBar( // appBar: AppBar(
title: Text('Document Intelligence'), // title: Text('Document Intelligence'),
), // ),
body: Padding( // body: Padding(
padding: EdgeInsets.all(16.0), // padding: EdgeInsets.all(16.0),
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ // children: [
ElevatedButton( // ElevatedButton(
onPressed: _isLoading ? null : _analyzeDocument, // onPressed: _isLoading ? null : _analyzeDocument,
child: _isLoading // child: _isLoading
? CircularProgressIndicator(color: Colors.white) // ? CircularProgressIndicator(color: Colors.white)
: Text('Analyze Document'), // : Text('Analyze Document'),
), // ),
SizedBox(height: 20), // SizedBox(height: 20),
if (_result.isNotEmpty) // if (_result.isNotEmpty)
Expanded( // Expanded(
child: SingleChildScrollView( // child: SingleChildScrollView(
child: Text( // child: Text(
_result, // _result,
style: TextStyle(fontSize: 14), // style: TextStyle(fontSize: 14),
), // ),
), // ),
), // ),
], // ],
), // ),
), // ),
); // );
} // }
} // }

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
@ -36,10 +37,8 @@ class AuthenticationRepository extends GetxController {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@override @override
void onReady() { void onReady() {
// Delay the redirect to avoid issues during build FlutterNativeSplash.remove();
Future.delayed(Duration.zero, () { screenRedirect();
screenRedirect();
});
} }
// Check for biometric login on app start // Check for biometric login on app start