From edacf7ad1a3ecff481c5e174fabbf1f21ba157d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=BCllner?= Date: Thu, 5 Mar 2026 14:45:00 +0100 Subject: [PATCH] perf(scanner): add adaptive cooldown backoff for repeated OCR misses --- lib/scanner_screen.dart | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/scanner_screen.dart b/lib/scanner_screen.dart index 00e9ad9..fe18aa3 100644 --- a/lib/scanner_screen.dart +++ b/lib/scanner_screen.dart @@ -37,6 +37,7 @@ class _ScannerScreenState extends State static const _scanCooldownSuccess = Duration(milliseconds: 1500); static const _scanCooldownNoMatch = Duration(milliseconds: 2200); static const _scanCooldownError = Duration(milliseconds: 2600); + static const _scanCooldownNoMatchMax = Duration(milliseconds: 5000); CameraController? _cameraController; late final TextRecognizer _textRecognizer; @@ -52,6 +53,7 @@ class _ScannerScreenState extends State DateTime _nextScanAllowedAt = DateTime.fromMillisecondsSinceEpoch(0); bool _isInitializingCamera = false; String? _cameraError; + int _consecutiveMisses = 0; @override void initState() { @@ -202,13 +204,23 @@ class _ScannerScreenState extends State if (!mounted) return; if (found != null) { + _consecutiveMisses = 0; _nextScanAllowedAt = DateTime.now().add(_scanCooldownSuccess); setState(() => _lastDetected = found); if (widget.onDetected != null) { await _submitDetected(found); } } else { - _nextScanAllowedAt = DateTime.now().add(_scanCooldownNoMatch); + _consecutiveMisses += 1; + final missBackoffMs = (_scanCooldownNoMatch.inMilliseconds + + (_consecutiveMisses * 300)) + .clamp( + _scanCooldownNoMatch.inMilliseconds, + _scanCooldownNoMatchMax.inMilliseconds, + ); + _nextScanAllowedAt = DateTime.now().add( + Duration(milliseconds: missBackoffMs), + ); setState(() { _scanAccepted = false; _scanNotFound = true; @@ -216,6 +228,7 @@ class _ScannerScreenState extends State }); } } catch (e) { + _consecutiveMisses += 1; _nextScanAllowedAt = DateTime.now().add(_scanCooldownError); if (!mounted) return; logError('scanner.capture', e);