Cambio de icono y traducciones
This commit is contained in:
@@ -94,6 +94,7 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
void _avanzarAFase(FaseJuego fase) {
|
||||
final estado = context.read<EstadoJuego>();
|
||||
final nearby = context.read<ServicioNearby>();
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
|
||||
switch (fase) {
|
||||
case FaseJuego.debate:
|
||||
@@ -122,7 +123,7 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
_snapshot(
|
||||
fase: 'resultado',
|
||||
resultadoActual: resultado,
|
||||
mensaje: _mensajeSiguienteAccion(estado, resultado),
|
||||
mensaje: _mensajeSiguienteAccion(estado, resultado, l10n),
|
||||
).toJson(),
|
||||
);
|
||||
}
|
||||
@@ -142,7 +143,10 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
if (partida == null) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(l10n.hostGame)),
|
||||
body: const Center(child: Text('Error: Sin partida')),
|
||||
body: FondoFarolero(
|
||||
intenso: true,
|
||||
child: Center(child: Text(l10n.errorNoGame)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -259,7 +263,7 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Hay jugadores con el dispositivo desconectado.',
|
||||
AppLocalizations.of(context)!.disconnectedPlayersWarning,
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
),
|
||||
),
|
||||
@@ -276,7 +280,7 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
child: OutlinedButton.icon(
|
||||
onPressed: () => nearby.asumirUsuariosDesconectados(),
|
||||
icon: const Icon(Icons.person_add_alt_1),
|
||||
label: const Text('Asumir en este móvil'),
|
||||
label: Text(AppLocalizations.of(context)!.assumeOnThisPhone),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -347,7 +351,7 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
case FaseJuego.finPartida:
|
||||
return _buildFaseFinOnline(context, l10n);
|
||||
default:
|
||||
return const Center(child: Text('Fin de la partida'));
|
||||
return Center(child: Text(l10n.gameOver));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,15 +378,16 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
String _mensajeSiguienteAccion(
|
||||
EstadoJuego estado,
|
||||
ResultadoVotacion resultado,
|
||||
AppLocalizations l10n,
|
||||
) {
|
||||
final partida = estado.partida;
|
||||
if (partida != null && _hayFinTrasVotacion(partida)) {
|
||||
return 'La partida ha terminado.';
|
||||
return l10n.gameOver;
|
||||
}
|
||||
if (resultado.eraImpostor) {
|
||||
return 'El impostor eliminado puede intentar adivinar la palabra.';
|
||||
return l10n.impostorCanGuess.replaceAll('\n', ' ');
|
||||
}
|
||||
return 'La partida continúa en la siguiente ronda.';
|
||||
return l10n.gameContinues;
|
||||
}
|
||||
|
||||
bool _hayFinTrasVotacion(Partida partida) {
|
||||
@@ -750,7 +755,7 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
|
||||
? partida!.historialVotaciones.last
|
||||
: null;
|
||||
if (partida == null || resultado == null) {
|
||||
return const Center(child: Text('Sin resultado'));
|
||||
return Center(child: Text(l10n.noResult));
|
||||
}
|
||||
|
||||
final conteo = <String, int>{};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:farolero/l10n/generated/app_localizations.dart';
|
||||
|
||||
import '../servicios/servicio_historial_partidas.dart';
|
||||
import '../tema/componentes_farolero.dart';
|
||||
@@ -10,52 +11,98 @@ class PantallaHistorial extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final historial = context.watch<ServicioHistorialPartidas>();
|
||||
final partidas = historial.partidas;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Historial')),
|
||||
appBar: AppBar(title: Text(l10n.history)),
|
||||
body: FondoFarolero(
|
||||
intenso: true,
|
||||
child: partidas.isEmpty
|
||||
? const Center(child: Text('Todavía no hay partidas guardadas.'))
|
||||
: ListView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: partidas.length,
|
||||
itemBuilder: (context, index) {
|
||||
final partida = partidas[index];
|
||||
final ganaronJugadores = partida.ganador == 'jugadores';
|
||||
final dia =
|
||||
partida.fecha.day.toString().padLeft(2, '0');
|
||||
final mes =
|
||||
partida.fecha.month.toString().padLeft(2, '0');
|
||||
return Card(
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: ganaronJugadores
|
||||
? TemaApp.colorVerde
|
||||
: TemaApp.colorAcento,
|
||||
child: Icon(
|
||||
ganaronJugadores ? Icons.groups : Icons.theater_comedy,
|
||||
color: Colors.white,
|
||||
),
|
||||
? Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: EstadoVacioFarolero(
|
||||
icono: Icons.history_rounded,
|
||||
titulo: l10n.history,
|
||||
subtitulo: l10n.noSavedGames,
|
||||
),
|
||||
),
|
||||
)
|
||||
: SafeArea(
|
||||
top: false,
|
||||
child: ListView.separated(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 24),
|
||||
itemCount: partidas.length,
|
||||
separatorBuilder: (_, __) => const SizedBox(height: 12),
|
||||
itemBuilder: (context, index) {
|
||||
final partida = partidas[index];
|
||||
final ganaronJugadores = partida.ganador == 'jugadores';
|
||||
final color = ganaronJugadores
|
||||
? TemaApp.colorVerde
|
||||
: TemaApp.colorAcento;
|
||||
final dia = partida.fecha.day.toString().padLeft(2, '0');
|
||||
final mes = partida.fecha.month.toString().padLeft(2, '0');
|
||||
return PanelFarolero(
|
||||
padding: const EdgeInsets.all(14),
|
||||
borderColor: color.withValues(alpha: 0.48),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 52,
|
||||
height: 52,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: color.withValues(alpha: 0.18),
|
||||
border: Border.all(color: color),
|
||||
),
|
||||
child: Icon(
|
||||
ganaronJugadores
|
||||
? Icons.groups_rounded
|
||||
: Icons.theater_comedy_rounded,
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
ganaronJugadores
|
||||
? l10n.playersWin
|
||||
: l10n.impostorsWin,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
l10n.historyGameSummary(
|
||||
partida.jugadores,
|
||||
partida.impostores,
|
||||
partida.rondas,
|
||||
partida.palabra,
|
||||
partida.categoria,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'$dia/$mes',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
title: Text(
|
||||
ganaronJugadores
|
||||
? 'Ganaron los jugadores'
|
||||
: 'Ganaron los impostores',
|
||||
),
|
||||
subtitle: Text(
|
||||
'${partida.jugadores} jugadores · ${partida.impostores} impostor(es) · ${partida.rondas} ronda(s)\n${partida.palabra} · ${partida.categoria}',
|
||||
),
|
||||
isThreeLine: true,
|
||||
trailing: Text(
|
||||
'$dia/$mes',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -14,82 +14,54 @@ class PantallaReglas extends StatelessWidget {
|
||||
appBar: AppBar(title: Text(l10n.rulesTitle)),
|
||||
body: FondoFarolero(
|
||||
intenso: true,
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_seccion(
|
||||
context,
|
||||
1,
|
||||
Icons.person_search,
|
||||
l10n.rulesWhatIsTitle,
|
||||
l10n.rulesWhatIsBody,
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 28),
|
||||
child: Center(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 620),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
EncabezadoFarolero(
|
||||
icono: Icons.menu_book_rounded,
|
||||
titulo: l10n.rulesTitle,
|
||||
subtitulo: l10n.rulesWhatIsBody,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_seccion(context, 1, Icons.person_search, l10n.rulesWhatIsTitle, l10n.rulesWhatIsBody),
|
||||
_seccion(context, 2, Icons.chat_bubble, l10n.rulesHowToPlayTitle, l10n.rulesHowToPlayBody),
|
||||
_seccion(context, 3, Icons.how_to_vote, l10n.rulesWhoWinsTitle, l10n.rulesWhoWinsBody),
|
||||
_seccion(context, 4, Icons.lightbulb, l10n.rulesTipsPlayersTitle, l10n.rulesTipsPlayersBody),
|
||||
_seccion(context, 5, Icons.theater_comedy, l10n.rulesTipsImpostorTitle, l10n.rulesTipsImpostorBody),
|
||||
_seccion(context, 6, Icons.devices, l10n.rulesModesTitle, l10n.rulesModesBody),
|
||||
_ejemplo(context, l10n.rulesExampleTitle, l10n.rulesExampleBody),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
_seccion(
|
||||
context,
|
||||
2,
|
||||
Icons.chat_bubble,
|
||||
l10n.rulesHowToPlayTitle,
|
||||
l10n.rulesHowToPlayBody,
|
||||
),
|
||||
_seccion(
|
||||
context,
|
||||
3,
|
||||
Icons.how_to_vote,
|
||||
l10n.rulesWhoWinsTitle,
|
||||
l10n.rulesWhoWinsBody,
|
||||
),
|
||||
_seccion(
|
||||
context,
|
||||
4,
|
||||
Icons.lightbulb,
|
||||
l10n.rulesTipsPlayersTitle,
|
||||
l10n.rulesTipsPlayersBody,
|
||||
),
|
||||
_seccion(
|
||||
context,
|
||||
5,
|
||||
Icons.theater_comedy,
|
||||
l10n.rulesTipsImpostorTitle,
|
||||
l10n.rulesTipsImpostorBody,
|
||||
),
|
||||
_seccion(
|
||||
context,
|
||||
6,
|
||||
Icons.devices,
|
||||
l10n.rulesModesTitle,
|
||||
l10n.rulesModesBody,
|
||||
),
|
||||
_ejemplo(context, l10n.rulesExampleTitle, l10n.rulesExampleBody),
|
||||
const SizedBox(height: 32),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _seccion(
|
||||
BuildContext context,
|
||||
int numero,
|
||||
IconData icono,
|
||||
String titulo,
|
||||
String contenido,
|
||||
) {
|
||||
Widget _seccion(BuildContext context, int numero, IconData icono, String titulo, String contenido) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
padding: const EdgeInsets.only(bottom: 14),
|
||||
child: PanelFarolero(
|
||||
padding: const EdgeInsets.all(12),
|
||||
padding: const EdgeInsets.fromLTRB(14, 14, 14, 16),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 54,
|
||||
height: 54,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: TemaApp.colorNaranja.withValues(alpha: 0.16),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: TemaApp.colorNaranja),
|
||||
),
|
||||
child: Icon(icono, color: TemaApp.colorNaranja, size: 30),
|
||||
@@ -97,23 +69,25 @@ class PantallaReglas extends StatelessWidget {
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'$numero. ${titulo.toUpperCase()}',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(contenido,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
height: 1.5,
|
||||
)),
|
||||
],
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
contenido,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(height: 1.45),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -123,19 +97,20 @@ class PantallaReglas extends StatelessWidget {
|
||||
child: PanelFarolero(
|
||||
color: TemaApp.colorNaranja.withValues(alpha: 0.15),
|
||||
borderColor: TemaApp.colorNaranja,
|
||||
padding: const EdgeInsets.fromLTRB(18, 18, 18, 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(titulo,
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: TemaApp.colorNaranja,
|
||||
)),
|
||||
const SizedBox(height: 8),
|
||||
Text(contenido,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
height: 1.5,
|
||||
)),
|
||||
],
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
titulo,
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(color: TemaApp.colorNaranja),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
contenido,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(height: 1.45),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -213,7 +213,7 @@ class _PantallaVotacionClienteState extends State<PantallaVotacionCliente> {
|
||||
return Scaffold(
|
||||
backgroundColor: TemaApp.colorFondo,
|
||||
appBar: AppBar(
|
||||
title: const Text('Resultado'),
|
||||
title: Text(l10n.result),
|
||||
automaticallyImplyLeading: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
|
||||
Reference in New Issue
Block a user