v0.2.0: i18n 18 idiomas + pantalla ajustes + bancos multiidioma

Internacionalización completa:
- 18 ficheros .arb: es, en, fr, pt, de, it, ru, ja, ko, zh, zh_TW, ar, hi, tr, pl, nl, ca, eu
- Todos los strings extraídos de todas las pantallas
- Detección automática de idioma del sistema
- Selector manual en pantalla de ajustes

Pantalla de ajustes nueva:
- Selector de idioma con banderas emoji
- Vibración ON/OFF
- Acerca de (versión, desarrollador)

Bancos de palabras multiidioma:
- palabras.json (castellano, 1000 palabras)
- palabras_en.json (inglés, 1000 palabras)
- palabras_fr.json (francés, 1000 palabras)
- Fallback a castellano si no hay banco del idioma

13138 líneas Dart, 39 ficheros, 0 issues en flutter analyze
This commit is contained in:
ShanaiaBot
2026-04-04 01:18:09 +02:00
parent de2c8ffa18
commit 1bca50af1d
56 changed files with 14389 additions and 201 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:el_impostor/l10n/generated/app_localizations.dart';
import 'package:provider/provider.dart';
import '../estado/estado_juego.dart';
import '../modelos/partida.dart';
@@ -52,12 +53,13 @@ class _PantallaResultadoState extends State<PantallaResultado>
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final estado = context.read<EstadoJuego>();
final partida = estado.partida;
return Scaffold(
appBar: AppBar(
title: const Text('Resultado'),
title: Text(l10n.result),
automaticallyImplyLeading: false,
),
body: Center(
@@ -71,7 +73,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
const Text('🥁', style: TextStyle(fontSize: 64)),
const SizedBox(height: 16),
Text(
'Revelando...',
l10n.revealing,
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 24),
@@ -113,8 +115,8 @@ class _PantallaResultadoState extends State<PantallaResultado>
),
child: Text(
widget.resultado.eraImpostor
? '¡Era IMPOSTOR! 🎉'
: 'Era INOCENTE 😱',
? l10n.wasImpostor
: l10n.wasInnocent,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
@@ -133,7 +135,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Votos de esta ronda',
Text(l10n.votesThisRound,
style: Theme.of(context)
.textTheme
.titleMedium),
@@ -177,6 +179,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
}
Widget _construirBotones(BuildContext context, EstadoJuego estado) {
final l10n = AppLocalizations.of(context)!;
final partida = estado.partida;
if (partida == null) return const SizedBox.shrink();
@@ -195,7 +198,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
);
},
icon: const Icon(Icons.emoji_events),
label: const Text('Ver resultado final'),
label: Text(l10n.seeEndResult),
),
);
}
@@ -217,7 +220,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
);
},
icon: const Text('🎯', style: TextStyle(fontSize: 18)),
label: const Text('¿El impostor adivina la palabra?'),
label: Text(l10n.impostorGuessWord),
),
),
const SizedBox(height: 12),
@@ -227,7 +230,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
child: ElevatedButton.icon(
onPressed: () => _siguienteRonda(context, estado),
icon: const Icon(Icons.skip_next),
label: const Text('Siguiente ronda'),
label: Text(l10n.nextRound),
),
),
],
@@ -240,7 +243,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
child: ElevatedButton.icon(
onPressed: () => _siguienteRonda(context, estado),
icon: const Icon(Icons.skip_next),
label: const Text('Siguiente ronda'),
label: Text(l10n.nextRound),
),
);
}