- Rewrite receipt OCR prompt: completes truncated names, preserves fat% and flavour attributes, extracts weight/volume from line, infers typical package sizes for solid goods with quantity_confidence field - Add quantity_confidence to RecognizedItem, EnrichedItem, and ProductJobResultItem; propagate through item enricher and worker - Replace per-item create loop with single POST /user-products/batch call from RecognitionConfirmScreen - Rebuild RecognitionConfirmScreen: amber qty border for low quantity_confidence, tappable product name → catalog picker, sort items by confidence, full L10n (no hardcoded strings) - Add timestamps (HH:mm / d MMM HH:mm) to recent scan chips - Show close-app hint on ProductJobWatchScreen (queued + processing) - Refresh recentProductJobsProvider on watch screen init so new job appears without a manual pull-to-refresh - App-level WidgetsBindingObserver refreshes product and dish job lists on resume, fixing stale lists after background/foreground transitions - Add 9 new L10n keys across all 12 locales Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
236 lines
8.1 KiB
Plaintext
236 lines
8.1 KiB
Plaintext
{
|
|
"@@locale": "es",
|
|
"appTitle": "FoodAI",
|
|
"greetingMorning": "Buenos días",
|
|
"greetingAfternoon": "Buenas tardes",
|
|
"greetingEvening": "Buenas noches",
|
|
"caloriesUnit": "kcal",
|
|
"gramsUnit": "g",
|
|
"goalLabel": "meta:",
|
|
"consumed": "Consumido",
|
|
"remaining": "Restante",
|
|
"exceeded": "Excedido",
|
|
"proteinLabel": "Proteínas",
|
|
"fatLabel": "Grasas",
|
|
"carbsLabel": "Carbohidratos",
|
|
"today": "Hoy",
|
|
"yesterday": "Ayer",
|
|
"mealsSection": "Comidas",
|
|
"addDish": "Añadir plato",
|
|
"scanDish": "Escanear",
|
|
"menu": "Menú",
|
|
"dishHistory": "Historial de platos",
|
|
"recommendCook": "Recomendamos cocinar",
|
|
"camera": "Cámara",
|
|
"gallery": "Galería",
|
|
"analyzingPhoto": "Analizando foto...",
|
|
"inQueue": "Estás en la cola",
|
|
"queuePosition": "Posición {position}",
|
|
"@queuePosition": {
|
|
"placeholders": {
|
|
"position": {
|
|
"type": "int"
|
|
}
|
|
}
|
|
},
|
|
"processing": "Procesando...",
|
|
"upgradePrompt": "¿Saltar la cola? Actualiza →",
|
|
"recognitionFailed": "Reconocimiento fallido. Inténtalo de nuevo.",
|
|
"dishRecognition": "Reconocimiento de platos",
|
|
"all": "Todos",
|
|
"dishRecognized": "Plato reconocido",
|
|
"recognizing": "Reconociendo…",
|
|
"recognitionError": "Error de reconocimiento",
|
|
"dishResultTitle": "Plato reconocido",
|
|
"selectDish": "Selecciona un plato",
|
|
"dishNotRecognized": "Plato no reconocido",
|
|
"tryAgain": "Intentar de nuevo",
|
|
"nutritionApproximate": "Los valores nutricionales son aproximados — estimados a partir de la foto.",
|
|
"portion": "Porción",
|
|
"mealType": "Tipo de comida",
|
|
"dateLabel": "Fecha",
|
|
"addToJournal": "Añadir al diario",
|
|
"addFailed": "Error al añadir. Inténtalo de nuevo.",
|
|
"historyTitle": "Historial de reconocimientos",
|
|
"historyLoadError": "Error al cargar el historial",
|
|
"retry": "Reintentar",
|
|
"noHistory": "Sin reconocimientos aún",
|
|
"profileTitle": "Perfil",
|
|
"edit": "Editar",
|
|
"bodyParams": "PARÁMETROS CORPORALES",
|
|
"goalActivity": "OBJETIVO Y ACTIVIDAD",
|
|
"nutrition": "NUTRICIÓN",
|
|
"settings": "AJUSTES",
|
|
"height": "Altura",
|
|
"weight": "Peso",
|
|
"age": "Edad",
|
|
"gender": "Género",
|
|
"genderMale": "Masculino",
|
|
"genderFemale": "Femenino",
|
|
"goalLoss": "Pérdida de peso",
|
|
"goalMaintain": "Mantenimiento",
|
|
"goalGain": "Ganancia muscular",
|
|
"activityLow": "Baja",
|
|
"activityMedium": "Media",
|
|
"activityHigh": "Alta",
|
|
"calorieGoal": "Objetivo calórico",
|
|
"mealTypes": "Tipos de comida",
|
|
"formulaNote": "Calculado con la fórmula de Mifflin-St Jeor",
|
|
"language": "Idioma",
|
|
"notSet": "No establecido",
|
|
"calorieHint": "Introduce los parámetros corporales para calcular el objetivo calórico",
|
|
"logout": "Cerrar sesión",
|
|
"editProfile": "Editar perfil",
|
|
"cancel": "Cancelar",
|
|
"save": "Guardar",
|
|
"nameLabel": "Nombre",
|
|
"heightCm": "Altura (cm)",
|
|
"weightKg": "Peso (kg)",
|
|
"birthDate": "Fecha de nacimiento",
|
|
"nameRequired": "Introduce el nombre",
|
|
"profileUpdated": "Perfil actualizado",
|
|
"profileSaveFailed": "Error al guardar",
|
|
"mealTypeBreakfast": "Desayuno",
|
|
"mealTypeSecondBreakfast": "Segundo desayuno",
|
|
"mealTypeLunch": "Almuerzo",
|
|
"mealTypeAfternoonSnack": "Merienda",
|
|
"mealTypeDinner": "Cena",
|
|
"mealTypeSnack": "Aperitivo",
|
|
"navHome": "Inicio",
|
|
"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",
|
|
"photoProducts": "Fotografiar productos",
|
|
"photoProductsSubtitle": "Nevera, mesa, estante — hasta 3 fotos",
|
|
"addPackagedFood": "Agregar alimento envasado",
|
|
"scanBarcode": "Escanear código de barras",
|
|
"portionWeightG": "Peso de la porción (g)",
|
|
"productNotFound": "Producto no encontrado",
|
|
"enterManually": "Ingresar manualmente",
|
|
"perHundredG": "por 100 g",
|
|
"searchFoodHint": "Buscar productos y platos...",
|
|
"recentlyUsedLabel": "Usados recientemente",
|
|
"productsSection": "Productos",
|
|
"dishesSection": "Platos",
|
|
"noResultsForQuery": "Nada encontrado para \"{query}\"",
|
|
"@noResultsForQuery": {
|
|
"placeholders": {
|
|
"query": {
|
|
"type": "String"
|
|
}
|
|
}
|
|
},
|
|
"servingsLabel": "Porciones",
|
|
"addToDiary": "Añadir al diario",
|
|
"scanDishPhoto": "Escanear foto",
|
|
"planningForDate": "",
|
|
"@planningForDate": {
|
|
"placeholders": {
|
|
"date": {
|
|
"type": "String"
|
|
}
|
|
}
|
|
},
|
|
"markAsEaten": "Marcar como comido",
|
|
"plannedMealLabel": "Planificado",
|
|
"generateWeekLabel": "Planificar la semana",
|
|
"generateWeekSubtitle": "La IA creará un menú con desayuno, comida y cena para toda la semana",
|
|
"generatingMenu": "Generando menú...",
|
|
"dayPlannedLabel": "Día planificado",
|
|
"planMenuButton": "Planificar comidas",
|
|
"planMenuTitle": "¿Qué planificar?",
|
|
"planOptionSingleMeal": "Una comida",
|
|
"planOptionSingleMealDesc": "Elegir día y tipo de comida",
|
|
"planOptionDay": "Un día",
|
|
"planOptionDayDesc": "Todas las comidas de un día",
|
|
"planOptionDays": "Varios días",
|
|
"planOptionDaysDesc": "Personalizar período",
|
|
"planOptionWeek": "Una semana",
|
|
"planOptionWeekDesc": "7 días de una vez",
|
|
"planSelectDate": "Seleccionar fecha",
|
|
"planSelectMealType": "Tipo de comida",
|
|
"planSelectRange": "Seleccionar período",
|
|
"planGenerateButton": "Planificar",
|
|
"planGenerating": "Generando plan…",
|
|
"planSuccess": "¡Menú planificado!",
|
|
"planProductsTitle": "Productos para el menú",
|
|
"planProductsSubtitle": "La IA tendrá en cuenta los productos seleccionados al generar recetas",
|
|
"planProductsEmpty": "No hay productos añadidos",
|
|
"planProductsEmptyMessage": "Añade productos que tengas en casa — la IA sugerirá recetas con lo que ya tienes",
|
|
"planProductsAddProducts": "Añadir productos",
|
|
"planProductsContinue": "Continuar",
|
|
"planProductsSkip": "Omitir selección de productos",
|
|
"planProductsSkipNoProducts": "Planificar sin productos",
|
|
"planProductsSelectAll": "Seleccionar todo",
|
|
"planProductsDeselectAll": "Deseleccionar todo",
|
|
"recentScans": "Escaneos recientes",
|
|
"seeAllScans": "Ver todos",
|
|
"productJobHistoryTitle": "Historial de escaneos",
|
|
"jobTypeReceipt": "Ticket",
|
|
"jobTypeProducts": "Productos",
|
|
"scanSubmitting": "Enviando...",
|
|
"processingProducts": "Procesando...",
|
|
"clearAllProducts": "Borrar todo",
|
|
"clearAllConfirmTitle": "¿Borrar todos los productos?",
|
|
"clearAllConfirmMessage": "Todos los productos serán eliminados permanentemente.",
|
|
"addManually": "Manual",
|
|
"scan": "Escanear",
|
|
"addProduct": "Agregar",
|
|
"searchProducts": "Buscar productos",
|
|
"searchProductsHint": "Escribe el nombre del producto o agrega manualmente",
|
|
"noSearchResults": "Sin resultados para \"{query}\"",
|
|
"@noSearchResults": {
|
|
"placeholders": {
|
|
"query": {
|
|
"type": "String"
|
|
}
|
|
}
|
|
},
|
|
"quantity": "Cantidad",
|
|
"storageDays": "Días de almacenamiento",
|
|
"addToShelf": "Agregar a despensa",
|
|
"errorGeneric": "Algo salió mal",
|
|
"nutritionOptional": "Nutrición por 100g (opcional)",
|
|
"calories": "Calorías",
|
|
"protein": "Proteína",
|
|
"fat": "Grasas",
|
|
"carbs": "Carbohidratos",
|
|
"fiber": "Fibra",
|
|
"productAddedToShelf": "Agregado a la despensa",
|
|
"recognitionFoundProducts": "Se encontraron {count} productos",
|
|
"@recognitionFoundProducts": {
|
|
"placeholders": {
|
|
"count": {
|
|
"type": "int"
|
|
}
|
|
}
|
|
},
|
|
"recognitionAddAll": "Agregar todo",
|
|
"recognitionAddToStock": "Agregar al almacén",
|
|
"recognitionAdded": "Se agregaron {count} productos",
|
|
"@recognitionAdded": {
|
|
"placeholders": {
|
|
"count": {
|
|
"type": "int"
|
|
}
|
|
}
|
|
},
|
|
"recognitionProductsFailed": "Error al agregar productos",
|
|
"recognitionEmpty": "No se encontraron productos",
|
|
"recognitionConfidence": "{percent}% de confianza",
|
|
"@recognitionConfidence": {
|
|
"placeholders": {
|
|
"percent": {
|
|
"type": "int"
|
|
}
|
|
}
|
|
},
|
|
"recognitionReplaceProduct": "Reemplazar producto",
|
|
"scanJobCloseHint": "Puedes cerrar la app — este escaneo aparecerá en Escaneos recientes en la pantalla de Productos"
|
|
}
|