feat: barcode scanning for shelf add + scan screen barcode option
- Add ShelfBarcodeScanScreen: scans barcode via mobile_scanner, looks up
product via GET /products/barcode/{barcode} (Open Food Facts fallback),
returns CatalogProduct to caller; loading overlay while looking up;
"Add manually" fallback in AppBar for unknown products
- Extract AddToShelfSheet to add_to_shelf_sheet.dart (was private in
product_search_screen.dart) so both search and scan screens can reuse it
- Add barcode icon button to ProductSearchScreen AppBar → opens scanner
- Add "Scan barcode" card (📷) to ScanScreen alongside receipt and photo modes
- Rename ScanScreen title: addFromReceiptOrPhoto → scanScreenTitle
("Сканировать" / "Scan & Recognize") to reflect all three modes
- Add 2 L10n keys (scanScreenTitle, barcodeScanSubtitle) across all 12 locales
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -100,6 +100,8 @@
|
||||
"navProducts": "المنتجات",
|
||||
"navRecipes": "الوصفات",
|
||||
"addFromReceiptOrPhoto": "إضافة من الإيصال أو الصورة",
|
||||
"scanScreenTitle": "المسح والتعرف",
|
||||
"barcodeScanSubtitle": "ابحث عن منتج بالباركود",
|
||||
"chooseMethod": "اختر الطريقة",
|
||||
"photoReceipt": "تصوير الإيصال",
|
||||
"photoReceiptSubtitle": "التعرف على جميع المنتجات من الإيصال",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "Produkte",
|
||||
"navRecipes": "Rezepte",
|
||||
"addFromReceiptOrPhoto": "Aus Kassenbon oder Foto hinzufügen",
|
||||
"scanScreenTitle": "Scannen & Erkennen",
|
||||
"barcodeScanSubtitle": "Produkt per Barcode finden",
|
||||
"chooseMethod": "Methode wählen",
|
||||
"photoReceipt": "Kassenbon fotografieren",
|
||||
"photoReceiptSubtitle": "Alle Produkte vom Kassenbon erkennen",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "Products",
|
||||
"navRecipes": "Recipes",
|
||||
"addFromReceiptOrPhoto": "Add from receipt or photo",
|
||||
"scanScreenTitle": "Scan & Recognize",
|
||||
"barcodeScanSubtitle": "Find a product by its barcode",
|
||||
"chooseMethod": "Choose method",
|
||||
"photoReceipt": "Photo of receipt",
|
||||
"photoReceiptSubtitle": "Recognize all items from a receipt",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "Productos",
|
||||
"navRecipes": "Recetas",
|
||||
"addFromReceiptOrPhoto": "Añadir desde recibo o foto",
|
||||
"scanScreenTitle": "Escanear y Reconocer",
|
||||
"barcodeScanSubtitle": "Encontrar un producto por su código de barras",
|
||||
"chooseMethod": "Elegir método",
|
||||
"photoReceipt": "Fotografiar recibo",
|
||||
"photoReceiptSubtitle": "Reconocemos todos los productos del recibo",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "Produits",
|
||||
"navRecipes": "Recettes",
|
||||
"addFromReceiptOrPhoto": "Ajouter depuis ticket ou photo",
|
||||
"scanScreenTitle": "Scanner & Reconnaître",
|
||||
"barcodeScanSubtitle": "Trouver un produit par son code-barres",
|
||||
"chooseMethod": "Choisir la méthode",
|
||||
"photoReceipt": "Photographier le ticket",
|
||||
"photoReceiptSubtitle": "Reconnaissance de tous les produits du ticket",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "उत्पाद",
|
||||
"navRecipes": "रेसिपी",
|
||||
"addFromReceiptOrPhoto": "रसीद या फ़ोटो से जोड़ें",
|
||||
"scanScreenTitle": "स्कैन और पहचानें",
|
||||
"barcodeScanSubtitle": "बारकोड से उत्पाद खोजें",
|
||||
"chooseMethod": "तरीका चुनें",
|
||||
"photoReceipt": "रसीद की फ़ोटो",
|
||||
"photoReceiptSubtitle": "रसीद से सभी उत्पाद पहचानें",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "Prodotti",
|
||||
"navRecipes": "Ricette",
|
||||
"addFromReceiptOrPhoto": "Aggiungi da scontrino o foto",
|
||||
"scanScreenTitle": "Scansiona & Riconosci",
|
||||
"barcodeScanSubtitle": "Trova un prodotto tramite il codice a barre",
|
||||
"chooseMethod": "Scegli il metodo",
|
||||
"photoReceipt": "Fotografa scontrino",
|
||||
"photoReceiptSubtitle": "Riconosciamo tutti i prodotti dallo scontrino",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "食品",
|
||||
"navRecipes": "レシピ",
|
||||
"addFromReceiptOrPhoto": "レシートや写真から追加",
|
||||
"scanScreenTitle": "スキャン&認識",
|
||||
"barcodeScanSubtitle": "バーコードで商品を探す",
|
||||
"chooseMethod": "方法を選択",
|
||||
"photoReceipt": "レシートを撮影",
|
||||
"photoReceiptSubtitle": "レシートから全商品を認識",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "식품",
|
||||
"navRecipes": "레시피",
|
||||
"addFromReceiptOrPhoto": "영수증 또는 사진으로 추가",
|
||||
"scanScreenTitle": "스캔 및 인식",
|
||||
"barcodeScanSubtitle": "바코드로 제품 찾기",
|
||||
"chooseMethod": "방법 선택",
|
||||
"photoReceipt": "영수증 촬영",
|
||||
"photoReceiptSubtitle": "영수증의 모든 상품 인식",
|
||||
|
||||
@@ -676,6 +676,18 @@ abstract class AppLocalizations {
|
||||
/// **'Add from receipt or photo'**
|
||||
String get addFromReceiptOrPhoto;
|
||||
|
||||
/// No description provided for @scanScreenTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Scan & Recognize'**
|
||||
String get scanScreenTitle;
|
||||
|
||||
/// No description provided for @barcodeScanSubtitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Find a product by its barcode'**
|
||||
String get barcodeScanSubtitle;
|
||||
|
||||
/// No description provided for @chooseMethod.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -290,6 +290,12 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'إضافة من الإيصال أو الصورة';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'المسح والتعرف';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'ابحث عن منتج بالباركود';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'اختر الطريقة';
|
||||
|
||||
|
||||
@@ -291,6 +291,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'Aus Kassenbon oder Foto hinzufügen';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'Scannen & Erkennen';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'Produkt per Barcode finden';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'Methode wählen';
|
||||
|
||||
|
||||
@@ -290,6 +290,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'Add from receipt or photo';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'Scan & Recognize';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'Find a product by its barcode';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'Choose method';
|
||||
|
||||
|
||||
@@ -291,6 +291,13 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'Añadir desde recibo o foto';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'Escanear y Reconocer';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle =>
|
||||
'Encontrar un producto por su código de barras';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'Elegir método';
|
||||
|
||||
|
||||
@@ -291,6 +291,12 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'Ajouter depuis ticket ou photo';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'Scanner & Reconnaître';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'Trouver un produit par son code-barres';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'Choisir la méthode';
|
||||
|
||||
|
||||
@@ -291,6 +291,12 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'रसीद या फ़ोटो से जोड़ें';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'स्कैन और पहचानें';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'बारकोड से उत्पाद खोजें';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'तरीका चुनें';
|
||||
|
||||
|
||||
@@ -291,6 +291,13 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'Aggiungi da scontrino o foto';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'Scansiona & Riconosci';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle =>
|
||||
'Trova un prodotto tramite il codice a barre';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'Scegli il metodo';
|
||||
|
||||
|
||||
@@ -289,6 +289,12 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'レシートや写真から追加';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'スキャン&認識';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'バーコードで商品を探す';
|
||||
|
||||
@override
|
||||
String get chooseMethod => '方法を選択';
|
||||
|
||||
|
||||
@@ -289,6 +289,12 @@ class AppLocalizationsKo extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => '영수증 또는 사진으로 추가';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => '스캔 및 인식';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => '바코드로 제품 찾기';
|
||||
|
||||
@override
|
||||
String get chooseMethod => '방법 선택';
|
||||
|
||||
|
||||
@@ -291,6 +291,12 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'Adicionar de recibo ou foto';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'Escanear & Reconhecer';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'Encontrar produto pelo código de barras';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'Escolher método';
|
||||
|
||||
|
||||
@@ -290,6 +290,12 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => 'Добавить из чека или фото';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => 'Сканировать';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => 'Найти продукт по штрихкоду';
|
||||
|
||||
@override
|
||||
String get chooseMethod => 'Выберите способ';
|
||||
|
||||
|
||||
@@ -289,6 +289,12 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
@override
|
||||
String get addFromReceiptOrPhoto => '从收据或照片添加';
|
||||
|
||||
@override
|
||||
String get scanScreenTitle => '扫描与识别';
|
||||
|
||||
@override
|
||||
String get barcodeScanSubtitle => '通过条形码查找产品';
|
||||
|
||||
@override
|
||||
String get chooseMethod => '选择方式';
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "Produtos",
|
||||
"navRecipes": "Receitas",
|
||||
"addFromReceiptOrPhoto": "Adicionar de recibo ou foto",
|
||||
"scanScreenTitle": "Escanear & Reconhecer",
|
||||
"barcodeScanSubtitle": "Encontrar produto pelo código de barras",
|
||||
"chooseMethod": "Escolher método",
|
||||
"photoReceipt": "Fotografar recibo",
|
||||
"photoReceiptSubtitle": "Reconhecemos todos os produtos do recibo",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "Продукты",
|
||||
"navRecipes": "Рецепты",
|
||||
"addFromReceiptOrPhoto": "Добавить из чека или фото",
|
||||
"scanScreenTitle": "Сканировать",
|
||||
"barcodeScanSubtitle": "Найти продукт по штрихкоду",
|
||||
"chooseMethod": "Выберите способ",
|
||||
"photoReceipt": "Сфотографировать чек",
|
||||
"photoReceiptSubtitle": "Распознаем все продукты из чека",
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
"navProducts": "食品",
|
||||
"navRecipes": "食谱",
|
||||
"addFromReceiptOrPhoto": "从收据或照片添加",
|
||||
"scanScreenTitle": "扫描与识别",
|
||||
"barcodeScanSubtitle": "通过条形码查找产品",
|
||||
"chooseMethod": "选择方式",
|
||||
"photoReceipt": "拍摄收据",
|
||||
"photoReceiptSubtitle": "识别收据中的所有商品",
|
||||
|
||||
Reference in New Issue
Block a user