Gamificación
This commit is contained in:
@@ -2,10 +2,13 @@ import 'package:flutter/material.dart';
|
||||
import 'package:farolero/l10n/generated/app_localizations.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../modelos/inicio_partida_multijugador.dart';
|
||||
import '../modelos/gamificacion_usuario.dart';
|
||||
import '../modelos/palabra.dart';
|
||||
import '../modelos/snapshot_partida_online.dart';
|
||||
import '../servicios/servicio_historial_partidas.dart';
|
||||
import '../servicios/servicio_nearby.dart';
|
||||
import '../servicios/servicio_perfil_usuario.dart';
|
||||
import '../tema/componentes_farolero.dart';
|
||||
import '../tema/tema_app.dart';
|
||||
import 'pantalla_notas_online.dart';
|
||||
import 'pantalla_principal.dart';
|
||||
@@ -30,6 +33,7 @@ class PantallaFinPartidaOnline extends StatefulWidget {
|
||||
|
||||
class _PantallaFinPartidaOnlineState extends State<PantallaFinPartidaOnline> {
|
||||
bool _guardada = false;
|
||||
ProgresoGamificacionUsuario? _progreso;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -41,11 +45,18 @@ class _PantallaFinPartidaOnlineState extends State<PantallaFinPartidaOnline> {
|
||||
|
||||
if (!_guardada && snapshot.ganador != null) {
|
||||
_guardada = true;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
if (mounted) {
|
||||
context
|
||||
.read<ServicioHistorialPartidas>()
|
||||
.guardarSnapshotOnline(snapshot);
|
||||
final historial = context.read<ServicioHistorialPartidas>();
|
||||
final perfil = context.read<ServicioPerfilUsuario>();
|
||||
await historial.guardarSnapshotOnline(snapshot);
|
||||
final progreso = await perfil.registrarPartidaCompletada(
|
||||
victoria: _perfilLocalGano(snapshot, jugadoresControlados),
|
||||
comoImpostor: jugadoresControlados.any((j) => j.esImpostor),
|
||||
victoriaComoImpostor: snapshot.ganador == 'impostores' &&
|
||||
jugadoresControlados.any((j) => j.esImpostor),
|
||||
);
|
||||
if (mounted) setState(() => _progreso = progreso);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -132,6 +143,10 @@ class _PantallaFinPartidaOnlineState extends State<PantallaFinPartidaOnline> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
if (_progreso != null) ...[
|
||||
_TarjetaProgresoGamificacion(progreso: _progreso!),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
@@ -254,4 +269,71 @@ class _PantallaFinPartidaOnlineState extends State<PantallaFinPartidaOnline> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool _perfilLocalGano(
|
||||
SnapshotPartidaOnline snapshot,
|
||||
List<JugadorInicioPartida> jugadoresControlados,
|
||||
) {
|
||||
if (jugadoresControlados.isEmpty) return snapshot.ganador == 'jugadores';
|
||||
final ganaronImpostores = snapshot.ganador == 'impostores';
|
||||
return jugadoresControlados.any(
|
||||
(jugador) => jugador.esImpostor ? ganaronImpostores : !ganaronImpostores,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TarjetaProgresoGamificacion extends StatelessWidget {
|
||||
final ProgresoGamificacionUsuario progreso;
|
||||
|
||||
const _TarjetaProgresoGamificacion({required this.progreso});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final nuevas = progreso.nuevasMedallas;
|
||||
return Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Tu progreso', style: Theme.of(context).textTheme.titleMedium),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
const Text('🔥', style: TextStyle(fontSize: 24)),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
child: LinearProgressIndicator(
|
||||
value: progreso.despues.fuego / 100,
|
||||
minHeight: 8,
|
||||
color: TemaApp.colorNaranja,
|
||||
backgroundColor: Colors.black.withValues(alpha: 0.35),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text('${progreso.despues.fuego}%'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
progreso.incrementoFuego >= 0
|
||||
? '+${progreso.incrementoFuego}% de fuego'
|
||||
: '${progreso.incrementoFuego}% de fuego',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
if (nuevas.isNotEmpty) ...[
|
||||
const SizedBox(height: 12),
|
||||
Text('Nuevas medallas',
|
||||
style: Theme.of(context).textTheme.bodyMedium),
|
||||
const SizedBox(height: 6),
|
||||
MedallasCompactasFarolero(ids: nuevas, max: nuevas.length),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user