traducciones
This commit is contained in:
+47
-45
@@ -1,47 +1,61 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:farolero/l10n/generated/app_localizations.dart';
|
||||
|
||||
/// Categorías disponibles en el banco de palabras
|
||||
/// Categorías disponibles en el banco de palabras.
|
||||
class BancoPalabras {
|
||||
final Map<String, List<String>> categorias;
|
||||
final Map<String, String> pistasPorCategoria;
|
||||
|
||||
BancoPalabras(this.categorias);
|
||||
BancoPalabras(this.categorias, {Map<String, String>? pistasPorCategoria})
|
||||
: pistasPorCategoria = pistasPorCategoria ?? {};
|
||||
|
||||
static final Map<String, BancoPalabras> _instancias = {};
|
||||
|
||||
static Future<BancoPalabras> cargar({String idioma = 'es'}) async {
|
||||
if (_instancias.containsKey(idioma)) return _instancias[idioma]!;
|
||||
|
||||
// Intentar cargar el banco del idioma solicitado, fallback a castellano
|
||||
String jsonStr;
|
||||
try {
|
||||
final archivo = idioma == 'es'
|
||||
? 'assets/palabras.json'
|
||||
: 'assets/palabras_$idioma.json';
|
||||
jsonStr = await rootBundle.loadString(archivo);
|
||||
jsonStr = await rootBundle.loadString(
|
||||
'assets/words/palabras_$idioma.json',
|
||||
);
|
||||
} catch (_) {
|
||||
// Fallback a castellano si no existe el banco para ese idioma
|
||||
if (idioma != 'es') {
|
||||
return cargar(idioma: 'es');
|
||||
try {
|
||||
final archivoLegacy = idioma == 'es'
|
||||
? 'assets/palabras.json'
|
||||
: 'assets/palabras_$idioma.json';
|
||||
jsonStr = await rootBundle.loadString(archivoLegacy);
|
||||
} catch (_) {
|
||||
if (idioma != 'es') return cargar(idioma: 'es');
|
||||
rethrow;
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
|
||||
final data = json.decode(jsonStr) as Map<String, dynamic>;
|
||||
final cats = data['categorias'] as Map<String, dynamic>;
|
||||
final mapa = <String, List<String>>{};
|
||||
final pistas = <String, String>{};
|
||||
|
||||
for (final entrada in cats.entries) {
|
||||
mapa[entrada.key] = List<String>.from(entrada.value);
|
||||
final valor = entrada.value;
|
||||
if (valor is Map<String, dynamic>) {
|
||||
mapa[entrada.key] = List<String>.from(valor['palabras'] as List);
|
||||
final pista = valor['pista'];
|
||||
if (pista is String && pista.isNotEmpty) pistas[entrada.key] = pista;
|
||||
} else {
|
||||
mapa[entrada.key] = List<String>.from(valor as List);
|
||||
}
|
||||
}
|
||||
_instancias[idioma] = BancoPalabras(mapa);
|
||||
|
||||
_instancias[idioma] = BancoPalabras(mapa, pistasPorCategoria: pistas);
|
||||
return _instancias[idioma]!;
|
||||
}
|
||||
|
||||
List<String> get nombresCategorias => categorias.keys.toList();
|
||||
|
||||
/// Obtiene una palabra aleatoria de la categoría dada (o de todas si es null)
|
||||
/// Obtiene una palabra aleatoria de la categoría dada (o de todas si es null).
|
||||
String palabraAleatoria(String? categoria) {
|
||||
final rng = Random();
|
||||
if (categoria == null || categoria == 'todas') {
|
||||
@@ -52,7 +66,7 @@ class BancoPalabras {
|
||||
return lista[rng.nextInt(lista.length)];
|
||||
}
|
||||
|
||||
/// Devuelve la categoría a la que pertenece una palabra
|
||||
/// Devuelve la categoría a la que pertenece una palabra.
|
||||
String? categoriaDepalabra(String palabra) {
|
||||
for (final entrada in categorias.entries) {
|
||||
if (entrada.value.contains(palabra)) return entrada.key;
|
||||
@@ -60,7 +74,10 @@ class BancoPalabras {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Devuelve el nombre localizado de la categoría usando AppLocalizations
|
||||
/// Devuelve la pista localizada de una categoría si el banco la trae.
|
||||
String? pistaDeCategoria(String categoria) => pistasPorCategoria[categoria];
|
||||
|
||||
/// Devuelve el nombre localizado de la categoría usando AppLocalizations.
|
||||
static String nombreBonitoCategoria(String clave, [AppLocalizations? l10n]) {
|
||||
if (l10n != null) {
|
||||
final nombres = {
|
||||
@@ -78,7 +95,6 @@ class BancoPalabras {
|
||||
};
|
||||
return nombres[clave] ?? clave;
|
||||
}
|
||||
// Fallback a castellano si no hay l10n
|
||||
const nombres = {
|
||||
'todas': 'Todas',
|
||||
'animales': 'Animales',
|
||||
@@ -98,12 +114,9 @@ class BancoPalabras {
|
||||
|
||||
class EntradaPalabraTraducida {
|
||||
final String palabra;
|
||||
final Map<String, String> traducciones;
|
||||
final String pista;
|
||||
|
||||
const EntradaPalabraTraducida({
|
||||
required this.palabra,
|
||||
required this.traducciones,
|
||||
});
|
||||
const EntradaPalabraTraducida({required this.palabra, required this.pista});
|
||||
}
|
||||
|
||||
class BancoPalabrasTraducidas {
|
||||
@@ -111,32 +124,21 @@ class BancoPalabrasTraducidas {
|
||||
|
||||
const BancoPalabrasTraducidas(this.categorias);
|
||||
|
||||
static BancoPalabrasTraducidas? _instancia;
|
||||
static final Map<String, BancoPalabrasTraducidas> _instancias = {};
|
||||
|
||||
static Future<BancoPalabrasTraducidas> cargar() async {
|
||||
if (_instancia != null) return _instancia!;
|
||||
static Future<BancoPalabrasTraducidas> cargar({String idioma = 'es'}) async {
|
||||
if (_instancias.containsKey(idioma)) return _instancias[idioma]!;
|
||||
|
||||
final jsonStr = await rootBundle.loadString('assets/palabras_i18n.json');
|
||||
final data = json.decode(jsonStr) as Map<String, dynamic>;
|
||||
final cats = data['categorias'] as Map<String, dynamic>;
|
||||
final banco = await BancoPalabras.cargar(idioma: idioma);
|
||||
final mapa = <String, List<EntradaPalabraTraducida>>{};
|
||||
|
||||
for (final categoria in cats.entries) {
|
||||
final entradas = categoria.value as List<dynamic>;
|
||||
mapa[categoria.key] = entradas.map((entradaRaw) {
|
||||
final entrada = entradaRaw as Map<String, dynamic>;
|
||||
final traduccionesRaw =
|
||||
entrada['traducciones'] as Map<String, dynamic>? ?? {};
|
||||
return EntradaPalabraTraducida(
|
||||
palabra: entrada['es'] as String,
|
||||
traducciones: traduccionesRaw.map(
|
||||
(idioma, valor) => MapEntry(idioma, valor?.toString() ?? ''),
|
||||
)..removeWhere((_, valor) => valor.isEmpty),
|
||||
);
|
||||
}).toList();
|
||||
for (final categoria in banco.categorias.entries) {
|
||||
final pista = banco.pistaDeCategoria(categoria.key) ?? categoria.key;
|
||||
mapa[categoria.key] = categoria.value
|
||||
.map((palabra) => EntradaPalabraTraducida(palabra: palabra, pista: pista))
|
||||
.toList();
|
||||
}
|
||||
|
||||
_instancia = BancoPalabrasTraducidas(mapa);
|
||||
return _instancia!;
|
||||
_instancias[idioma] = BancoPalabrasTraducidas(mapa);
|
||||
return _instancias[idioma]!;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user