literales y unificación de resultados en los dos modos de juego

This commit is contained in:
2026-05-11 21:57:46 +02:00
parent 8ecd1ead32
commit 3c5d98d6dd
42 changed files with 1815 additions and 786 deletions
+13 -117
View File
@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:farolero/l10n/generated/app_localizations.dart';
import '../modelos/inicio_partida_multijugador.dart';
import '../modelos/partida.dart';
import '../modelos/snapshot_partida_online.dart';
import '../servicios/servicio_nearby.dart';
import '../tema/componentes_farolero.dart';
import '../tema/componentes_resultado_farolero.dart';
import '../tema/tema_app.dart';
import 'pantalla_debate_cliente.dart';
import 'pantalla_fin_partida_online.dart';
@@ -171,11 +171,18 @@ class _PantallaResultadoOnlineState extends State<PantallaResultadoOnline> {
),
body: FondoFarolero(
intenso: true,
child: Padding(
padding: const EdgeInsets.all(24),
child: resultado == null
? _buildEsperaAdivinanza(context, l10n)
: _buildResultado(context, l10n, resultado),
child: SafeArea(
top: false,
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: resultado == null
? _buildEsperaAdivinanza(context, l10n)
: ResultadoRondaFarolero(
resultado: resultado,
jugadores: _snapshot.jugadores,
mensaje: _snapshot.mensaje,
),
),
),
),
);
@@ -242,116 +249,5 @@ class _PantallaResultadoOnlineState extends State<PantallaResultadoOnline> {
);
}
Widget _buildResultado(
BuildContext context,
AppLocalizations l10n,
ResultadoVotacion resultado,
) {
final conteo = <String, int>{};
for (final votadoId in resultado.votos.values) {
conteo[votadoId] = (conteo[votadoId] ?? 0) + 1;
}
final maxVotos = conteo.values.isEmpty
? 1
: conteo.values.reduce((a, b) => a > b ? a : b);
final ranking = conteo.entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
final jugadores = {for (final jugador in _snapshot.jugadores) jugador.id: jugador};
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ArteGameplayFarolero.resultado(height: 132),
const SizedBox(height: 12),
Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: TemaApp.decoracionPanel(
color: resultado.eraImpostor
? TemaApp.colorVerde.withValues(alpha: 0.18)
: TemaApp.colorAcento.withValues(alpha: 0.18),
borderColor:
resultado.eraImpostor ? TemaApp.colorVerde : TemaApp.colorAcento,
),
child: Column(
children: [
Text(
resultado.eliminadoNombre,
style: Theme.of(context).textTheme.headlineMedium,
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
resultado.eraImpostor ? l10n.wasImpostor : l10n.wasInnocent,
style: TextStyle(
color: resultado.eraImpostor
? TemaApp.colorVerde
: TemaApp.colorAcento,
fontWeight: FontWeight.bold,
),
),
if (_snapshot.mensaje != null) ...[
const SizedBox(height: 12),
Text(_snapshot.mensaje!, textAlign: TextAlign.center),
],
],
),
),
const SizedBox(height: 20),
Text(l10n.votesThisRound, style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 12),
Expanded(
child: ListView(
children: [
...ranking.map((entry) {
final jugador = jugadores[entry.key];
final destacado = entry.key == resultado.eliminadoId;
final color = destacado ? TemaApp.colorAcento : TemaApp.colorNaranja;
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(child: Text(jugador?.nombre ?? '?')),
Text(
'${entry.value}',
style: TextStyle(
color: color,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 6),
ClipRRect(
borderRadius: BorderRadius.circular(999),
child: LinearProgressIndicator(
value: (entry.value / maxVotos).clamp(0.0, 1.0).toDouble(),
minHeight: 10,
backgroundColor: TemaApp.colorSuperficie,
valueColor: AlwaysStoppedAnimation(color),
),
),
],
),
);
}),
const Divider(height: 24),
...resultado.votos.entries.map((entry) {
final votante = jugadores[entry.key]?.nombre ?? '?';
final votado = jugadores[entry.value]?.nombre ?? '?';
return ListTile(
dense: true,
leading: const Icon(Icons.how_to_vote),
title: Text('$votante$votado'),
);
}),
],
),
),
],
);
}
}