Files
farolero/lib/servicios/servicio_notas.dart
freetlab 6e5e423ab4 Implementado:
No se puede marcar “vista” sin revelar la palabra antes.
Se puede volver a ver la palabra durante debate/votación/resultado.
Notas online privadas por partida y jugador.
Tests añadidos para notas scoped.
Ajusté roomId en el payload de inicio para que las notas no se mezclen entre partidas.
2026-05-05 21:49:40 +02:00

97 lines
3.0 KiB
Dart

import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
/// Servicio para persistir las notas de los jugadores localmente.
class ServicioNotas {
static const _clavePrefix = 'notas_';
static const _clavePartidaPrefix = 'notas_partida_';
/// Guarda las notas de un jugador para una partida local/legacy.
static Future<void> guardarNotas(
String jugadorId,
Map<String, String> notas,
String notaLibre,
) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(
'$_clavePrefix$jugadorId',
json.encode(_serializar(notas, notaLibre)),
);
}
/// Carga las notas de un jugador en modo local/legacy.
static Future<Map<String, dynamic>> cargarNotas(String jugadorId) async {
final prefs = await SharedPreferences.getInstance();
return _decodificar(prefs.getString('$_clavePrefix$jugadorId'));
}
/// Guarda notas privadas scoped por partida y jugador autor.
///
/// Esto evita que una partida online contamine otra aunque se reutilicen
/// nombres o ids visibles de jugador.
static Future<void> guardarNotasPartida({
required String partidaId,
required String autorJugadorId,
required Map<String, String> notasPorJugador,
required String notaLibre,
}) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(
_claveNotasPartida(partidaId, autorJugadorId),
json.encode(_serializar(notasPorJugador, notaLibre)),
);
}
/// Carga notas privadas scoped por partida y jugador autor.
static Future<Map<String, dynamic>> cargarNotasPartida({
required String partidaId,
required String autorJugadorId,
}) async {
final prefs = await SharedPreferences.getInstance();
return _decodificar(
prefs.getString(_claveNotasPartida(partidaId, autorJugadorId)),
);
}
static String _claveNotasPartida(String partidaId, String autorJugadorId) {
return '$_clavePartidaPrefix${_normalizarClave(partidaId)}_${_normalizarClave(autorJugadorId)}';
}
static String _normalizarClave(String valor) {
return base64Url.encode(utf8.encode(valor));
}
static Map<String, Object> _serializar(
Map<String, String> notas,
String notaLibre,
) {
return {
'notas': notas,
'notaLibre': notaLibre,
};
}
static Map<String, dynamic> _decodificar(String? str) {
if (str == null) {
return {'notas': <String, String>{}, 'notaLibre': ''};
}
final datos = json.decode(str) as Map<String, dynamic>;
return {
'notas': Map<String, String>.from(datos['notas'] ?? {}),
'notaLibre': datos['notaLibre'] as String? ?? '',
};
}
/// Limpia todas las notas (al iniciar nueva partida local o reset manual).
static Future<void> limpiarNotas() async {
final prefs = await SharedPreferences.getInstance();
final claves = prefs
.getKeys()
.where((k) => k.startsWith(_clavePrefix))
.toList();
for (final clave in claves) {
await prefs.remove(clave);
}
}
}