feat(i18n): add Asturian (asturianu) as a language

Adds Asturianu, translated in full (345 strings), plus the wiring to
make a minority language work end to end — the OS language picker is an
unreliable way to reach it, so the in-app choice must be explicit and
remembered.

- Model Asturian as the real `ast` locale (honest, international-by-design),
  not a fake `es-AST` region — slang rejects a 3-letter region anyway.
- Flutter ships no Material/Cupertino/intl localizations for `ast`, so map
  the framework chrome to Spanish (`materialLocaleFor`); the app's own text
  stays Asturian via slang. Fixes an "Invalid locale ast" crash when the
  auto-backup date was formatted with intl.
- Persist the picked language in the keystore (LocaleStore) and restore it
  at startup so it survives restarts and wins over the device locale.
- Settings: add the Asturianu tile; compare the full AppLocale so `es` and
  `ast` aren't both marked selected.

Tests: LocaleStore round-trip, locale switch + Spanish-chrome fallback,
and a regression for the intl date crash under Asturian.
This commit is contained in:
vjrj 2026-07-10 15:43:33 +02:00
parent beb29915d8
commit 9bf5c5cfbc
10 changed files with 695 additions and 15 deletions

View file

@ -0,0 +1,410 @@
{
"app": {
"title": "Tanemaki"
},
"common": {
"save": "Guardar",
"cancel": "Encaboxar",
"delete": "Desaniciar",
"edit": "Editar",
"type": "Triba",
"comingSoon": "Aína"
},
"home": {
"tagline": "Comparte y cultiva simiente llocal",
"openMarket": "Mercáu",
"openMarketSubtitle": "Descubri y comparte simiente cerca",
"yourInventory": "El to inventariu",
"yourInventorySubtitle": "Remana la to simiente"
},
"photo": {
"camera": "Facer una semeya",
"gallery": "Escoyer de la galería",
"setAsCover": "Poner de portada",
"isCover": "Semeya de portada",
"deleteConfirm": "¿Desaniciar esta semeya?"
},
"menu": {
"tagline": "el to bancu de simiente",
"inventory": "Inventariu",
"market": "Mercáu",
"profile": "El to perfil",
"chat": "Charra",
"wishlist": "Llista de deseos",
"following": "Siguiendo",
"settings": "Axustes"
},
"settings": {
"language": "Llingua",
"systemLanguage": "Llingua del sistema",
"langEs": "Español",
"langEn": "English",
"langPt": "Português",
"langAst": "Asturianu",
"about": "Tocante a",
"aboutText": "Inventariu llocal y cifráu pa simiente tradicional. AGPL-3.0.",
"aboutOpen": "Tocante a Tanemaki"
},
"backup": {
"title": "Copia de seguranza",
"autoBackupTitle": "Copies automátiques",
"autoBackupLast": "Cabera copia guardada'l {date}",
"autoBackupNone": "Guárdase una copia automáticamente en segundu planu",
"exportJson": "Guardar una copia de seguranza",
"exportJsonSubtitle": "Una copia completa pa guardar a salvo, restaurar dempués o pasar a otru preséu",
"importJson": "Restaurar una copia",
"importJsonSubtitle": "Recupera una copia guardada — nun se dobla nada",
"exportCsv": "Esportar a una fueya de cálculu",
"exportCsvSubtitle": "Una llista cenciella pa Excel o LibreOffice — ensin semeyes",
"importCsv": "Importar una llista",
"importCsvSubtitle": "Amiesta entraes dende una fueya de cálculu",
"importConfirmTitle": "¿Restaurar una copia?",
"importConfirmBody": "Les entraes fusiónense col to inventariu; si una entrada esiste en dambos llaos, gana la versión más nueva. Nun se dobla nada.",
"importCsvConfirmTitle": "¿Importar una llista?",
"importCsvConfirmBody": "Cada filera amiéstase como una entrada nueva. Nun fusiona nin troca, asina qu'importar el mesmu ficheru dos veces amiéstalu dos veces.",
"importAction": "Importar",
"exportSaved": "Copia guardada",
"cancelled": "Encaboxáu",
"importDone": "Importáu: {added} nueves, {updated} anovaes",
"importCsvDone": "Amestaes {count} entraes",
"importFailed": "Esti ficheru nun se pudo lleer como una copia de Tanemaki",
"failed": "Daqué salió mal",
"recoveryTitle": "El to códigu de recuperación",
"recoverySubtitle": "Imprémelu y guárdalu bien: abre les tos copies n'otru preséu",
"recoveryIntro": "Esti códigu abre les tos copies guardaes y recupera'l to bancu en cualquier preséu. Guarda dos copies en papel en sitios seguros, como la to meyor simiente. Quien lu tenga pue lleer les tos copies, asina que nun lu compartas con naide.",
"recoveryCopy": "Copiar",
"recoverySave": "Guardar la fueya",
"recoverySheetTitle": "Tanemaki — la to fueya de recuperación",
"recoveryPromptTitle": "Escribi'l to códigu de recuperación",
"recoveryPromptBody": "Esta copia guardóse con otru códigu. Escribi'l códigu de la to fueya de recuperación p'abrilla.",
"recoveryWrongCode": "Esi códigu nun abre esta copia"
},
"about": {
"title": "Tocante a",
"kanji": "種まき",
"tagline": "Una app local-first y descentralizada pa remanar y compartir simiente y plantones tradicionales.",
"intro": "Tanemaki (種まき, «semar / esparder simiente» en xaponés; nome curtiu Tane, 種 «grana») ayuda a persones y coleutivos a llevar un inventariu amable del so bancu de simiente, decidir qué ufierten y compartilo llocalmente — ensin un intermediariu central que pueda controlalo, censuralo o ser multáu por ello. L'oxetivu ye a la vez práuticu y políticu: sofitar les variedaes tradicionales de simiente y plantar cara al monopoliu simienteru.",
"heritage": "El nome honra les vieyes tradiciones xaponeses d'ayuda mutua alredor del arroz — yui (trabayu comunitariu compartíu) y tanomoshi (fondos de reciprocidá) — qu'inspiraron el papel Plantare, la «moneda comunitaria pal intercambiu de simiente» (BAH-Semilleru, 2009, CC-BY-SA). Tanemaki ye'l Plantare dixital.",
"version": "Versión",
"license": "Llicencia",
"licenseValue": "AGPL-3.0",
"website": "Sitiu web",
"openSourceLicenses": "Llicencies de códigu abiertu",
"openSourceLicensesSubtitle": "Biblioteques de terceros y les sos llicencies",
"copyright": "© {years} Asociación Comunes, baxo AGPLv3"
},
"intro": {
"skip": "Saltar",
"next": "Siguiente",
"start": "Entamar",
"menuEntry": "Cómo furrula Tanemaki",
"slides": {
"welcome": {
"title": "La grana que te traxo hasta equí",
"body": "Cada simiente tradicional ye una carta escrita por miles de xeneraciones, que pasó de mano en mano. Somos lo que somos gracies a esi intercambiu."
},
"inventory": {
"title": "El to bancu de simiente, nel bolsu",
"body": "Apunta qué tienes, de qué añu, cuánto y d'ónde vieno, col nome que tu uses. Una semeya y un nome abasten pa entamar."
},
"privacy": {
"title": "Tuyo y namás tuyo",
"body": "Ensin cuenta, ensin internet, ensin rastrexadores. Los tos datos viven cifraos nel to preséu y namás se comparte lo que tu decidas."
},
"share": {
"title": "Compartir, como siempres se fizo",
"body": "Ufierta lo que te sobra —regalu, truecu o venta— y qu'alguien cerca lo atope. Namás s'amuesa la distancia averada, enxamás la to direición; el tratu ciérraslu en persona."
},
"plantare": {
"title": "Semar ye multiplicar",
"body": "Col Plantare, quien recibe promete devolver simiente más alantre. Y como pa devolvela hai que cultivala, cada préstamu multiplica'l común."
}
}
},
"inventory": {
"title": "Inventariu",
"searchHint": "Guetar simiente",
"empty": "Entá nun hai simiente. Toca + p'amestar la primera.",
"noMatches": "Nenguna simiente concasa colos filtros.",
"clearFilters": "Quitar filtros",
"uncategorized": "Ensin categoría",
"needsReproductionFilter": "Por reproducir"
},
"draft": {
"capture": "Capturar semeyes",
"captured": "{n} capturaes por catalogar",
"triageTitle": "Por catalogar",
"triageCount": "{n} por catalogar",
"untitled": "Ensin nome",
"nameField": "Ponle nome a esta simiente",
"nameHint": "¿Qué ye?",
"suggestFromPhoto": "Suxerir nome de la semeya",
"discard": "Descartar"
},
"quickAdd": {
"title": "Amestar una simiente",
"labelField": "Nome",
"labelRequired": "Ponle un nome",
"addPhoto": "Amestar semeya",
"quantity": "¿Cuánta?",
"more": "Amestar más…",
"save": "Guardar",
"saveAndAddAnother": "Guardar y amestar otra",
"addedCount": "{n} amestaes",
"cancel": "Encaboxar"
},
"detail": {
"notFound": "Esta simiente yá nun ta equí.",
"lots": "Llotes",
"noLots": "Entá nun hai llotes.",
"names": "Conocida tamién como",
"addName": "Amestar nome",
"links": "Enllaces",
"addLink": "Amestar enllaz",
"linkUrl": "URL",
"linkTitle": "Títulu (opcional)",
"reference": "Saber más",
"refGbif": "GBIF",
"refWikipedia": "Wikipedia",
"refWikispecies": "Wikispecies",
"notes": "Notes",
"addLot": "Amestar llote",
"editLot": "Editar llote",
"deleteConfirm": "¿Desaniciar esta simiente?",
"year": "Añu {year}",
"noYear": "Añu desconocíu"
},
"germination": {
"title": "Germinación",
"add": "Amestar prueba",
"sampleSize": "Amuesa",
"germinated": "Germinaes",
"none": "Entá nun hai pruebes de germinación.",
"result": "{percent}%"
},
"viability": {
"expiringSoon": "Úsala o multiplícala esta temporada",
"expiringSoonYears": "Úsala o multiplícala esta temporada · dura ~{years} años",
"expired": "Pasa la so viabilidá típica — a multiplicar",
"expiredYears": "Pasa la so viabilidá típica (~{years} años) — a multiplicar"
},
"editVariety": {
"title": "Editar simiente",
"name": "Nome",
"category": "Categoría",
"notes": "Notes",
"species": "Especie (del catálogu)",
"speciesHint": "Guetar una especie…",
"speciesSuggested": "Suxerida pol nome",
"organic": "Ecolóxica",
"organicHint": "Cultivada de mou ecolóxicu (eco)"
},
"addLot": {
"title": "Amestar llote",
"year": "Data de coyecha",
"quantity": "¿Cuánta?",
"amount": "Cantidá"
},
"harvest": {
"pickTitle": "Escoyer mes / añu",
"anyMonth": "Cualquier mes",
"noDate": "Indicar data de coyecha",
"monthNames": [
"xineru", "febreru", "marzu", "abril", "mayu", "xunu",
"xunetu", "agostu", "setiembre", "ochobre", "payares", "avientu"
]
},
"lotType": {
"seed": "Simiente",
"plant": "Planta",
"seedling": "Planton",
"tree": "Árbol / matu",
"bulb": "Bulbu / tubérculu",
"cutting": "Esqueje"
},
"presentation": {
"title": "Envase",
"none": "Ensin especificar",
"pot": "Tiestu",
"tray": "Bandexa",
"plug": "Alvéolu",
"bareRoot": "Raíz esnuda",
"rootBall": "Cepellón"
},
"provenance": {
"section": "D'ónde vien",
"seedsFrom": "Simiente de",
"seedsFromHint": "Quién la cultivó o la dio",
"place": "Llugar",
"placeHint": "D'ónde vien (con provincia)",
"addSeedsFrom": "Simiente de",
"addPlace": "Llugar"
},
"abundance": {
"add": "Cuánta tengo",
"title": "Cuánta tengo",
"none": "Ensin indicar",
"plentyToShare": "A esgaya pa compartir",
"enoughToShare": "Abondo, pa compartir con mesura",
"enoughForMe": "Abondo pa min",
"runningLow": "Queda poca"
},
"share": {
"add": "¿Compártesla?",
"title": "¿Compártesla?",
"nudge": "Tienes a esgaya: podríes compartir un poco.",
"private": "Namás pa min",
"gift": "Pa regalar",
"exchange": "Pa trocar",
"sell": "En venta",
"filterChip": "Comparto",
"printCatalog": "Imprentar lo que comparto",
"catalogTitle": "Lo que comparto",
"catalogSaved": "Catálogu guardáu",
"cancelled": "Encaboxáu"
},
"cropCalendar": {
"add": "Calendariu de cultivu",
"title": "Calendariu de cultivu",
"sow": "Sema",
"transplant": "Tresplante",
"flowering": "Floriamientu",
"fruiting": "Fructificación",
"seedHarvest": "Coyecha de simiente",
"unset": "—"
},
"needsReproduction": {
"label": "Reproducir esta temporada",
"hint": "Cultívala enantes de que s'acabe la simiente",
"badge": "Por reproducir"
},
"preservation": {
"add": "Cómo se caltién",
"title": "Cómo se caltién",
"none": "Ensin especificar",
"jarWithDesiccant": "Bote con desecante",
"glassJar": "Bote de cristal",
"paperEnvelope": "Sobre de papel",
"paperBag": "Bolsa de papel",
"plasticBag": "Bolsa de plásticu"
},
"conditionCheck": {
"advanced": "Caltenimientu y detalles del bancu",
"title": "Revisiones de caltenimientu",
"add": "Amestar revisión",
"containers": "Botes / recipientes",
"desiccant": "Desecante",
"none": "Entá nun hai revisiones.",
"summary": "{count} bote(s) · {state}"
},
"desiccant": {
"none": "Nun tien",
"add": "Pónse",
"replace": "Cámbiase",
"dry": "Azul — secu",
"fresh": "Recién puestu"
},
"unit": {
"aFew": "delles poques",
"some": "dalgunes",
"plenty": "munches",
"pinch": "una migaya",
"handful": { "singular": "puñáu", "plural": "puñaos" },
"teaspoon": { "singular": "cuyaradina", "plural": "cuyaradines" },
"spoon": { "singular": "cuyar", "plural": "cuyares" },
"cup": { "singular": "taza", "plural": "tazes" },
"jar": { "singular": "bote", "plural": "botes" },
"sack": { "singular": "sacu", "plural": "sacos" },
"packet": { "singular": "sobre", "plural": "sobres" },
"cob": { "singular": "panoya", "plural": "panoyes" },
"pod": { "singular": "vaina", "plural": "vaines" },
"ear": { "singular": "espiga", "plural": "espigues" },
"head": { "singular": "cabezuela", "plural": "cabezueles" },
"fruit": { "singular": "frutu", "plural": "frutos" },
"bulb": { "singular": "bulbu", "plural": "bulbos" },
"tuber": { "singular": "tubérculu", "plural": "tubérculos" },
"seedHead": { "singular": "cabeza de simiente", "plural": "cabeces de simiente" },
"bunch": { "singular": "manoyu", "plural": "manoyos" },
"plant": { "singular": "planta", "plural": "plantes" },
"pot": { "singular": "tiestu", "plural": "tiestos" },
"tray": { "singular": "bandexa", "plural": "bandexes" },
"seedling": { "singular": "plántula", "plural": "plántules" },
"tree": { "singular": "árbol", "plural": "árboles" },
"cutting": { "singular": "esqueje", "plural": "esquejes" },
"grams": { "singular": "gramu", "plural": "gramos" },
"count": { "singular": "grana", "plural": "granes" }
},
"market": {
"title": "Simiente cerca de ti",
"subtitle": "Lo qu'otres persones comparten cerca",
"notSetUp": "Entá nun configurasti'l compartir",
"notSetUpBody": "Activa'l compartir pa ver y dar simiente a xente cercano. Caltiénse averao — la to zona, enxamás la to direición esacta.",
"setUp": "Configurar el compartir",
"cantReach": "Nun se pue coneutar colos servidores agora mesmo",
"cantReachBody": "Inténtalo otra vez, o revisa los servidores na configuración avanzada.",
"retry": "Retentar",
"setArea": "Indica la to zona",
"setAreaBody": "Dile al mercáu la to zona averada pa ver simiente cerca.",
"searching": "Guetando pela to zona…",
"empty": "Entá nun hai simiente compartida cerca de ti",
"near": "Cerca de ti",
"contact": "Mensaxe",
"mine": "Tu",
"configTitle": "Configuración de compartir",
"setupIntro": "Compartir con xente cercano ye opcional. Namás indica la to zona averada — yá tas coneutáu a servidores comunitarios compartíos pa qu'otres persones atopen lo qu'ufiertes, ensin nenguna empresa en mediu.",
"areaLabel": "La to zona",
"areaHelp": "Caltiénse averao a costafecha — la to zona, enxamás un puntu esactu.",
"areaSet": "La to zona ta puesta — averada, enxamás el to puntu esactu",
"areaNotSet": "Zona ensin definir — usa'l to allugamientu, o amiesta un códigu n'Avanzáu",
"advanced": "Avanzáu",
"areaCodeLabel": "Códigu de zona",
"areaCodeHint": "Un códigu curtiu como sp3e9 — non un nome de llugar",
"serversLabel": "Servidores de la comunidá",
"serversHelp": "Una direición per llinia (wss://…). Déxalo asina si nun sabes.",
"serversAdvanced": "Amestar otru servidor",
"save": "Guardar",
"saved": "Guardáu",
"wanted": "Gueto",
"shareMine": "Compartir la mio simiente",
"sharedCount": "Compartíes {n} simientes",
"nothingToShare": "Marca primero dalguna simiente pa regalar, trocar o vender",
"useLocation": "Usar el mio allugamientu averáu",
"locationFailed": "Nun se pudo consiguir el to allugamientu — comprueba que l'allugamientu ta activáu y el permisu concedíu",
"queued": "Guardáu — compartirémosles cuando tengas conexón"
},
"profile": {
"title": "El to perfil",
"name": "Nome",
"nameHint": "Cómo te ven los demás",
"about": "Sobre ti",
"aboutHint": "Una llinia — qué cultives, ónde",
"g1": "Direición Ğ1 (opcional)",
"g1Hint": "Pa que te paguen en Ğ1 — aparte de la to clave",
"yourId": "La to identidá",
"idHelp": "Compártela pa que te reconozan",
"copy": "Copiar",
"copied": "Copiao",
"save": "Guardar",
"saved": "Perfil guardáu"
},
"chatList": {
"title": "Mensaxes",
"empty": "Entá nun hai charres. Escríbi-y a alguien dende'l mercáu."
},
"chat": {
"title": "Charra",
"hint": "Escribi un mensaxe…",
"send": "Unviar",
"empty": "Entá nun hai mensaxes — saluda",
"offline": "Configura'l compartir pa unviar mensaxes",
"payG1": "Pagar en Ğ1",
"g1Copied": "Direición Ğ1 copiada — apégala na to cartera"
},
"trust": {
"none": "Naide los avala entá",
"count": "Avalada por {n}",
"vouch": "Conozo a esta persona",
"vouched": "Avales a esta persona",
"circle": "Nel to círculu"
}
}