Gestión de usuarios y avatares en la aplicación. Gestión de traducciones de las palabras.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../modelos/partida.dart';
|
||||
|
||||
class ResultadoPartidaGuardado {
|
||||
final String id;
|
||||
final DateTime fecha;
|
||||
final bool modoMultimovil;
|
||||
final int jugadores;
|
||||
final int impostores;
|
||||
final int rondas;
|
||||
final String ganador;
|
||||
final String palabra;
|
||||
final String categoria;
|
||||
|
||||
const ResultadoPartidaGuardado({
|
||||
required this.id,
|
||||
required this.fecha,
|
||||
required this.modoMultimovil,
|
||||
required this.jugadores,
|
||||
required this.impostores,
|
||||
required this.rondas,
|
||||
required this.ganador,
|
||||
required this.palabra,
|
||||
required this.categoria,
|
||||
});
|
||||
|
||||
factory ResultadoPartidaGuardado.desdePartida(Partida partida) {
|
||||
return ResultadoPartidaGuardado(
|
||||
id: DateTime.now().microsecondsSinceEpoch.toString(),
|
||||
fecha: DateTime.now(),
|
||||
modoMultimovil: partida.config.modoMultimovil,
|
||||
jugadores: partida.jugadores.length,
|
||||
impostores: partida.impostoresTotales,
|
||||
rondas: partida.rondaActual,
|
||||
ganador: partida.ganador ?? 'sin_resultado',
|
||||
palabra: partida.palabraSecreta,
|
||||
categoria: partida.categoriaReal,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'fecha': fecha.toIso8601String(),
|
||||
'modoMultimovil': modoMultimovil,
|
||||
'jugadores': jugadores,
|
||||
'impostores': impostores,
|
||||
'rondas': rondas,
|
||||
'ganador': ganador,
|
||||
'palabra': palabra,
|
||||
'categoria': categoria,
|
||||
};
|
||||
|
||||
factory ResultadoPartidaGuardado.fromJson(Map<String, dynamic> json) {
|
||||
return ResultadoPartidaGuardado(
|
||||
id: json['id'] as String,
|
||||
fecha: DateTime.parse(json['fecha'] as String),
|
||||
modoMultimovil: json['modoMultimovil'] as bool? ?? false,
|
||||
jugadores: json['jugadores'] as int? ?? 0,
|
||||
impostores: json['impostores'] as int? ?? 0,
|
||||
rondas: json['rondas'] as int? ?? 0,
|
||||
ganador: json['ganador'] as String? ?? 'sin_resultado',
|
||||
palabra: json['palabra'] as String? ?? '',
|
||||
categoria: json['categoria'] as String? ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ServicioHistorialPartidas extends ChangeNotifier {
|
||||
static const _clave = 'historial.partidas';
|
||||
final List<ResultadoPartidaGuardado> _partidas = [];
|
||||
bool _cargado = false;
|
||||
|
||||
List<ResultadoPartidaGuardado> get partidas => List.unmodifiable(_partidas);
|
||||
bool get cargado => _cargado;
|
||||
|
||||
Future<void> cargar() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final raw = prefs.getString(_clave);
|
||||
_partidas.clear();
|
||||
if (raw != null) {
|
||||
final lista = json.decode(raw) as List<dynamic>;
|
||||
_partidas.addAll(
|
||||
lista.map((e) => ResultadoPartidaGuardado.fromJson(e as Map<String, dynamic>)),
|
||||
);
|
||||
}
|
||||
_cargado = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> guardarPartida(Partida partida) async {
|
||||
if (partida.ganador == null) return;
|
||||
_partidas.insert(0, ResultadoPartidaGuardado.desdePartida(partida));
|
||||
if (_partidas.length > 100) _partidas.removeRange(100, _partidas.length);
|
||||
await _persistir();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> limpiar() async {
|
||||
_partidas.clear();
|
||||
await _persistir();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> _persistir() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(
|
||||
_clave,
|
||||
json.encode(_partidas.map((p) => p.toJson()).toList()),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -204,7 +204,12 @@ class ServicioNearby extends ChangeNotifier {
|
||||
|
||||
// ==================== HOST ====================
|
||||
|
||||
Future<bool> iniciarHost(String nombreSala, String miNombre) async {
|
||||
Future<bool> iniciarHost(
|
||||
String nombreSala,
|
||||
String miNombre, {
|
||||
String? miNick,
|
||||
String? miAvatar,
|
||||
}) async {
|
||||
_nombreSala = nombreSala;
|
||||
_miNombre = miNombre;
|
||||
_roomId = DateTime.now().microsecondsSinceEpoch.toString();
|
||||
@@ -222,6 +227,9 @@ class ServicioNearby extends ChangeNotifier {
|
||||
final usuarioHost = Usuario(
|
||||
id: 'u-${_roomId!}-host',
|
||||
nombre: miNombre,
|
||||
nick: miNick,
|
||||
avatar: miAvatar,
|
||||
foto: miAvatar,
|
||||
creadoPorClienteId: _hostClientId,
|
||||
clienteIdSeleccionado: _hostClientId,
|
||||
);
|
||||
@@ -654,13 +662,21 @@ class ServicioNearby extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> crearUsuarioSala(String nombre, {bool seleccionar = true}) async {
|
||||
Future<void> crearUsuarioSala(
|
||||
String nombre, {
|
||||
bool seleccionar = true,
|
||||
String? nick,
|
||||
String? avatar,
|
||||
}) async {
|
||||
final nombreLimpio = nombre.trim();
|
||||
if (nombreLimpio.isEmpty) return;
|
||||
final clientId = _miClientId;
|
||||
final usuario = Usuario(
|
||||
id: 'u-${DateTime.now().microsecondsSinceEpoch}',
|
||||
nombre: nombreLimpio,
|
||||
nick: nick,
|
||||
avatar: avatar,
|
||||
foto: avatar,
|
||||
creadoPorClienteId: clientId,
|
||||
);
|
||||
if (_esHost && _estadoSala != null && clientId != null) {
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class PerfilUsuario {
|
||||
final String nombre;
|
||||
final String nick;
|
||||
final String avatarAsset;
|
||||
|
||||
const PerfilUsuario({
|
||||
required this.nombre,
|
||||
required this.nick,
|
||||
required this.avatarAsset,
|
||||
});
|
||||
|
||||
PerfilUsuario copiar({String? nombre, String? nick, String? avatarAsset}) {
|
||||
return PerfilUsuario(
|
||||
nombre: nombre ?? this.nombre,
|
||||
nick: nick ?? this.nick,
|
||||
avatarAsset: avatarAsset ?? this.avatarAsset,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ServicioPerfilUsuario extends ChangeNotifier {
|
||||
static const _claveNombre = 'perfil.nombre';
|
||||
static const _claveNick = 'perfil.nick';
|
||||
static const _claveAvatar = 'perfil.avatar';
|
||||
|
||||
static const avatares = [
|
||||
'assets/avatars/avatar_01.png',
|
||||
'assets/avatars/avatar_02.png',
|
||||
'assets/avatars/avatar_03.png',
|
||||
'assets/avatars/avatar_04.png',
|
||||
'assets/avatars/avatar_05.png',
|
||||
'assets/avatars/avatar_06.png',
|
||||
'assets/avatars/avatar_07.png',
|
||||
'assets/avatars/avatar_08.png',
|
||||
'assets/avatars/avatar_09.png',
|
||||
'assets/avatars/avatar_10.png',
|
||||
'assets/avatars/avatar_11.png',
|
||||
'assets/avatars/avatar_12.png',
|
||||
'assets/avatars/avatar_13.png',
|
||||
'assets/avatars/avatar_14.png',
|
||||
'assets/avatars/avatar_15.png',
|
||||
'assets/avatars/avatar_16.png',
|
||||
'assets/avatars/avatar_17.png',
|
||||
'assets/avatars/avatar_18.png',
|
||||
'assets/avatars/avatar_19.png',
|
||||
'assets/avatars/avatar_20.png',
|
||||
'assets/avatars/avatar_21.png',
|
||||
'assets/avatars/avatar_22.png',
|
||||
'assets/avatars/avatar_23.png',
|
||||
'assets/avatars/avatar_24.png',
|
||||
'assets/avatars/avatar_25.png',
|
||||
'assets/avatars/avatar_26.png',
|
||||
'assets/avatars/avatar_27.png',
|
||||
'assets/avatars/avatar_28.png',
|
||||
'assets/avatars/avatar_29.png',
|
||||
'assets/avatars/avatar_30.png',
|
||||
];
|
||||
|
||||
PerfilUsuario _perfil = const PerfilUsuario(
|
||||
nombre: 'Jugador',
|
||||
nick: 'farolero',
|
||||
avatarAsset: 'assets/avatars/avatar_01.png',
|
||||
);
|
||||
bool _cargado = false;
|
||||
|
||||
PerfilUsuario get perfil => _perfil;
|
||||
bool get cargado => _cargado;
|
||||
|
||||
Future<void> cargar() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_perfil = PerfilUsuario(
|
||||
nombre: prefs.getString(_claveNombre) ?? _perfil.nombre,
|
||||
nick: prefs.getString(_claveNick) ?? _perfil.nick,
|
||||
avatarAsset: prefs.getString(_claveAvatar) ?? _perfil.avatarAsset,
|
||||
);
|
||||
_cargado = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> guardar({
|
||||
required String nombre,
|
||||
required String nick,
|
||||
required String avatarAsset,
|
||||
}) async {
|
||||
final nombreLimpio = nombre.trim().isEmpty ? 'Jugador' : nombre.trim();
|
||||
final nickLimpio = nick.trim().isEmpty ? 'farolero' : nick.trim();
|
||||
final avatarSeguro = avatares.contains(avatarAsset)
|
||||
? avatarAsset
|
||||
: avatares.first;
|
||||
_perfil = PerfilUsuario(
|
||||
nombre: nombreLimpio,
|
||||
nick: nickLimpio,
|
||||
avatarAsset: avatarSeguro,
|
||||
);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_claveNombre, _perfil.nombre);
|
||||
await prefs.setString(_claveNick, _perfil.nick);
|
||||
await prefs.setString(_claveAvatar, _perfil.avatarAsset);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user