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,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:el_impostor/l10n/generated/app_localizations.dart';
import 'package:provider/provider.dart';
import 'estado/estado_juego.dart';
import 'servicios/servicio_idioma.dart';
import 'tema/tema_app.dart';
import 'pantallas/pantalla_principal.dart';
@@ -23,13 +26,32 @@ class ElImpostorApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => EstadoJuego()..cargarBanco(),
child: MaterialApp(
title: 'El Impostor',
theme: TemaApp.obtenerTema(),
debugShowCheckedModeBanner: false,
home: const PantallaCarga(),
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => EstadoJuego()..cargarBanco(),
),
ChangeNotifierProvider(
create: (_) => ServicioIdioma()..cargar(),
),
],
child: Consumer<ServicioIdioma>(
builder: (context, servicioIdioma, _) {
return MaterialApp(
title: 'El Impostor',
theme: TemaApp.obtenerTema(),
debugShowCheckedModeBanner: false,
locale: servicioIdioma.locale,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: ServicioIdioma.localesSoportados,
home: const PantallaCarga(),
);
},
),
);
}
@@ -41,6 +63,7 @@ class PantallaCarga extends StatelessWidget {
@override
Widget build(BuildContext context) {
final estado = context.watch<EstadoJuego>();
final l10n = AppLocalizations.of(context);
if (estado.cargando || estado.banco == null) {
return Scaffold(
@@ -51,14 +74,14 @@ class PantallaCarga extends StatelessWidget {
const Text('🎭', style: TextStyle(fontSize: 72)),
const SizedBox(height: 24),
Text(
'El Impostor',
l10n?.appTitle ?? 'El Impostor',
style: Theme.of(context).textTheme.headlineLarge,
),
const SizedBox(height: 16),
const CircularProgressIndicator(color: TemaApp.colorAcento),
const SizedBox(height: 12),
Text(
'Cargando palabras...',
l10n?.loadingWords ?? 'Cargando palabras...',
style: Theme.of(context).textTheme.bodyMedium,
),
],