feat: barcode scan visual feedback + EAN checksum validation

- Add scan-status-bar overlay inside scanner viewport showing:
  - Active scan method (Native API / Quagga / Native + Quagga)
  - Scanning state: ready, scanning, partial read, invalid, confirmed
- Validate EAN-8/EAN-13/UPC checksums in Quagga path before confirming
  (native BarcodeDetector validates internally; Quagga can return false positives)
- Show 'invalid barcode, retrying' message with invalid code highlighted
- Reset invalid barcode confidence counter on invalid read so scanner retries
- Spawn parallel Quagga scan with 'combined scan active' status message
- Add 6 translation keys (scan.status_*) in all 5 language files
This commit is contained in:
dadaloop82
2026-05-27 05:26:47 +00:00
parent b83db76a8d
commit bc39361246
8 changed files with 117 additions and 8 deletions
+7 -1
View File
@@ -214,7 +214,13 @@
"scan_barcode": "🔖 Barcode scannen",
"create_named": "{name} erstellen",
"new_without_barcode": "Neues Produkt ohne Barcode",
"stock_in_pantry": "Bereits im Vorrat:"
"stock_in_pantry": "Bereits im Vorrat:",
"status_ready": "Kamera auf Barcode richten",
"status_scanning": "Scanne...",
"status_partial": "Erkannt: {code} — prüfe...",
"status_invalid": "Ungültig: {code} — versuche erneut",
"status_confirmed": "Bestätigt!",
"status_parallel": "Kombinierter Scan aktiv..."
},
"action": {
"title": "Was möchtest du tun?",
+7 -1
View File
@@ -214,7 +214,13 @@
"scan_barcode": "🔖 Scan Barcode",
"create_named": "Create {name}",
"new_without_barcode": "New product without barcode",
"stock_in_pantry": "Already in pantry:"
"stock_in_pantry": "Already in pantry:",
"status_ready": "Point camera at barcode",
"status_scanning": "Scanning...",
"status_partial": "Detected: {code} — verifying...",
"status_invalid": "Invalid: {code} — retrying",
"status_confirmed": "Confirmed!",
"status_parallel": "Using combined scan methods..."
},
"action": {
"title": "What do you want to do?",
+7 -1
View File
@@ -211,7 +211,13 @@
"barcode_acquired": "🔖 Código de barras escaneado: {code}",
"scan_barcode": "🔖 Escanear código de barras",
"create_named": "Crear {name}",
"new_without_barcode": "Nuevo producto sin código de barras"
"new_without_barcode": "Nuevo producto sin código de barras",
"status_ready": "Apunta la cámara al código de barras",
"status_scanning": "Escaneando...",
"status_partial": "Detectado: {code} — verificando...",
"status_invalid": "Inválido: {code} — reintentando",
"status_confirmed": "Confirmado!",
"status_parallel": "Escaneo combinado activo..."
},
"action": {
"title": "¿Qué quieres hacer?",
+7 -1
View File
@@ -211,7 +211,13 @@
"barcode_acquired": "🔖 Code-barres scanné : {code}",
"scan_barcode": "🔖 Scanner le code-barres",
"create_named": "Créer {name}",
"new_without_barcode": "Nouveau produit sans code-barres"
"new_without_barcode": "Nouveau produit sans code-barres",
"status_ready": "Pointez la caméra sur le code-barres",
"status_scanning": "Scan en cours...",
"status_partial": "Lu : {code} — vérification...",
"status_invalid": "Invalide : {code} — nouvel essai",
"status_confirmed": "Confirmé !",
"status_parallel": "Scan combiné actif..."
},
"action": {
"title": "Que voulez-vous faire ?",
+7 -1
View File
@@ -214,7 +214,13 @@
"scan_barcode": "🔖 Scansiona Barcode",
"create_named": "Crea {name}",
"new_without_barcode": "Nuovo prodotto senza barcode",
"stock_in_pantry": "Hai gia in dispensa:"
"stock_in_pantry": "Hai gia in dispensa:",
"status_ready": "Inquadra il codice a barre",
"status_scanning": "Scansione in corso...",
"status_partial": "Letto: {code} — verifico...",
"status_invalid": "Non valido: {code} — riprovo",
"status_confirmed": "Confermato!",
"status_parallel": "Doppia scansione attiva..."
},
"action": {
"title": "Cosa vuoi fare?",