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 '../tema/tema_app.dart';
@@ -48,12 +49,13 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
return _construirTodosVotaron(context, estado);
}
final l10n = AppLocalizations.of(context)!;
final votanteActual = sinVotar.isNotEmpty ? sinVotar[0] : activos[0];
final puedenRecibir = activos.where((j) => j.id != votanteActual.id).toList();
return Scaffold(
appBar: AppBar(
title: const Text('🗳️ Votación'),
title: Text(l10n.voting),
automaticallyImplyLeading: false,
),
body: Padding(
@@ -71,7 +73,7 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
child: Column(
children: [
Text(
'Turno de votar:',
l10n.turnToVote,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 4),
@@ -83,7 +85,7 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
),
const SizedBox(height: 8),
Text(
'Votos: ${estado.votos.length}/${activos.length}',
l10n.votesProgress(estado.votos.length, activos.length),
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 4),
@@ -102,7 +104,7 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
const SizedBox(height: 16),
Text(
'¿Quién crees que es el impostor?',
l10n.whoIsImpostor,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 12),
@@ -155,7 +157,7 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
}
: null,
icon: const Icon(Icons.how_to_vote),
label: const Text('Confirmar voto'),
label: Text(l10n.confirmVote),
),
),
],
@@ -165,9 +167,11 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
}
Widget _construirTodosVotaron(BuildContext context, EstadoJuego estado) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(
title: const Text('🗳️ Votación completa'),
title: Text(l10n.votingComplete),
automaticallyImplyLeading: false,
),
body: Center(
@@ -179,12 +183,12 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
const Text('🗳️', style: TextStyle(fontSize: 64)),
const SizedBox(height: 24),
Text(
'¡Todos han votado!',
l10n.allVoted,
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 16),
Text(
'Pulsa para revelar el resultado',
l10n.tapToReveal,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 32),
@@ -205,7 +209,7 @@ class _PantallaVotacionState extends State<PantallaVotacion> {
}
},
icon: const Icon(Icons.visibility),
label: const Text('Revelar resultado'),
label: Text(l10n.revealResult),
),
),
],