perf: reduce scanner OCR workload
This commit is contained in:
parent
abf1b9d788
commit
07b1df3369
1 changed files with 13 additions and 2 deletions
|
|
@ -31,6 +31,11 @@ class ScannerScreen extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _ScannerScreenState extends State<ScannerScreen> {
|
||||
static const _autoScanTickInterval = Duration(milliseconds: 700);
|
||||
static const _scanCooldownSuccess = Duration(milliseconds: 1500);
|
||||
static const _scanCooldownNoMatch = Duration(milliseconds: 2200);
|
||||
static const _scanCooldownError = Duration(milliseconds: 2600);
|
||||
|
||||
CameraController? _cameraController;
|
||||
late final TextRecognizer _textRecognizer;
|
||||
bool _isBusy = false;
|
||||
|
|
@ -42,6 +47,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
|||
String? _activeCollectionId;
|
||||
bool _autoScanEnabled = false;
|
||||
Timer? _autoScanTimer;
|
||||
DateTime _nextScanAllowedAt = DateTime.fromMillisecondsSinceEpoch(0);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -76,7 +82,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
|||
|
||||
_cameraController = CameraController(
|
||||
backCamera,
|
||||
ResolutionPreset.high,
|
||||
ResolutionPreset.medium,
|
||||
enableAudio: false,
|
||||
);
|
||||
|
||||
|
|
@ -88,8 +94,9 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
|||
|
||||
void _startAutoScanLoop() {
|
||||
_autoScanTimer?.cancel();
|
||||
_autoScanTimer = Timer.periodic(const Duration(milliseconds: 1400), (_) {
|
||||
_autoScanTimer = Timer.periodic(_autoScanTickInterval, (_) {
|
||||
if (!_autoScanEnabled || _isBusy || !_cameraReady || !mounted) return;
|
||||
if (DateTime.now().isBefore(_nextScanAllowedAt)) return;
|
||||
_captureAndScan();
|
||||
});
|
||||
}
|
||||
|
|
@ -105,6 +112,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
|||
/// Capture a photo, run OCR, and look for a Hot Wheels ID.
|
||||
Future<void> _captureAndScan() async {
|
||||
if (_isBusy || _cameraController == null || !_cameraController!.value.isInitialized) return;
|
||||
if (_cameraController!.value.isTakingPicture) return;
|
||||
|
||||
setState(() {
|
||||
_isBusy = true;
|
||||
|
|
@ -131,11 +139,13 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
|||
if (!mounted) return;
|
||||
|
||||
if (found != null) {
|
||||
_nextScanAllowedAt = DateTime.now().add(_scanCooldownSuccess);
|
||||
setState(() => _lastDetected = found);
|
||||
if (widget.onDetected != null) {
|
||||
await _submitDetected(found);
|
||||
}
|
||||
} else {
|
||||
_nextScanAllowedAt = DateTime.now().add(_scanCooldownNoMatch);
|
||||
setState(() {
|
||||
_scanAccepted = false;
|
||||
_scanNotFound = true;
|
||||
|
|
@ -143,6 +153,7 @@ class _ScannerScreenState extends State<ScannerScreen> {
|
|||
});
|
||||
}
|
||||
} catch (e) {
|
||||
_nextScanAllowedAt = DateTime.now().add(_scanCooldownError);
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Scan error: $e'), backgroundColor: Colors.red),
|
||||
|
|
|
|||
Loading…
Reference in a new issue