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.
This commit is contained in:
@@ -794,6 +794,7 @@ class ServicioNearby extends ChangeNotifier {
|
||||
'esImpostor': esImpostor,
|
||||
'categoria': categoria,
|
||||
'numJugadores': _jugadores.length + 1,
|
||||
'roomId': _roomId,
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -819,6 +820,7 @@ class ServicioNearby extends ChangeNotifier {
|
||||
if (endpointId == null) continue;
|
||||
final datos = payload.toJson();
|
||||
datos['jugadoresTodos'] = jugadoresTodos;
|
||||
datos['roomId'] = _roomId;
|
||||
await enviarMensaje(
|
||||
endpointId,
|
||||
MensajeP2P(tipo: TipoMensaje.partidaInicio, datos: datos),
|
||||
|
||||
@@ -1,42 +1,94 @@
|
||||
import 'dart:convert';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// Servicio para persistir las notas de los jugadores localmente
|
||||
/// 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
|
||||
/// 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();
|
||||
final datos = {
|
||||
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,
|
||||
};
|
||||
await prefs.setString('$_clavePrefix$jugadorId', json.encode(datos));
|
||||
}
|
||||
|
||||
/// Carga las notas de un jugador
|
||||
static Future<Map<String, dynamic>> cargarNotas(String jugadorId) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final str = prefs.getString('$_clavePrefix$jugadorId');
|
||||
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'] ?? '',
|
||||
'notaLibre': datos['notaLibre'] as String? ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
/// Limpia todas las notas (al iniciar nueva partida)
|
||||
/// 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));
|
||||
final claves = prefs
|
||||
.getKeys()
|
||||
.where((k) => k.startsWith(_clavePrefix))
|
||||
.toList();
|
||||
for (final clave in claves) {
|
||||
await prefs.remove(clave);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user