fix(radio): persist the last-played station across restarts
EstadoRadio.emisoraActual only ever reflected in-memory state (_emisoraSeleccionada or the live audio service), so stopping playback and reopening the app left the Escuchar hero empty even though the user had a station selected right before closing it. Persist the station whenever it changes (reproducir(), and the Android-Auto out-of-band reconciliation path) and restore it as _emisoraSeleccionada on the next cold start, only when nothing is already selected. This never touches the audio service directly: no playback starts and estadoStream/estaSonando stay at their stopped default, matching how every consumer already gates "is it playing" on the playback-status stream rather than on emisoraActual itself.
This commit is contained in:
@@ -173,6 +173,10 @@ class EstadoRadio extends ChangeNotifier {
|
||||
static const _keyEmisoraPreferida = 'emisora_preferida_uuid_v1';
|
||||
static const _keyOrdenListas = 'orden_listas_emisoras_v1';
|
||||
static const _keyTimerSuenoPresets = 'timer_sueno_presets_segundos_v1';
|
||||
// Issue 4 (feedback-pruebas): last-played station, so the Escuchar hero
|
||||
// keeps showing "what I was listening to" (stopped, not playing) after a
|
||||
// full app restart instead of going empty.
|
||||
static const _keyUltimaEmisora = 'ultima_emisora_v1';
|
||||
static const _timerSuenoPresetsDefecto = <int>[
|
||||
180,
|
||||
300,
|
||||
@@ -300,6 +304,50 @@ class EstadoRadio extends ChangeNotifier {
|
||||
_cargarEmisorasCustom(),
|
||||
]);
|
||||
await _normalizarEmisoraPreferida();
|
||||
await _restaurarUltimaEmisora();
|
||||
}
|
||||
|
||||
/// Issue 4 (feedback-pruebas): restores the last-played station as a
|
||||
/// STOPPED `emisoraActual` on a cold start. Only fills the gap — if
|
||||
/// something is ALREADY selected (a real play already ran concurrently),
|
||||
/// this is a no-op. Never touches `audio`: no playback starts, no network
|
||||
/// request is made, `estadoStream`/`estaSonando` stay at their fresh
|
||||
/// "detenido" default, exactly like every other consumer of
|
||||
/// `emisoraActual` already expects (they gate "is it playing" on the
|
||||
/// separate playback-status stream, never on `emisoraActual != null`).
|
||||
Future<void> _restaurarUltimaEmisora() async {
|
||||
if (_emisoraSeleccionada != null || audio.emisoraActual != null) return;
|
||||
try {
|
||||
final prefs = await _resolverPrefs();
|
||||
final raw = prefs.getString(_keyUltimaEmisora);
|
||||
if (raw == null) return;
|
||||
final mapa = jsonDecode(raw) as Map<String, dynamic>;
|
||||
_emisoraSeleccionada = Emisora.fromMap(mapa);
|
||||
} catch (e) {
|
||||
registrarSaltoPersistencia(
|
||||
subsistema: 'ultima_emisora',
|
||||
detalle: 'restaurar',
|
||||
razon: e.toString(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Best-effort remembers [emisora] as the last used station (issue 4) so
|
||||
/// [_restaurarUltimaEmisora] can bring it back after a restart. Fire-and-
|
||||
/// forget, same treatment [reproducir] already gives other non-critical
|
||||
/// side effects (e.g. `radio.registrarClick`) — a failed write here must
|
||||
/// never block or fail actual playback.
|
||||
Future<void> _persistirUltimaEmisora(Emisora emisora) async {
|
||||
try {
|
||||
final prefs = await _resolverPrefs();
|
||||
await prefs.setString(_keyUltimaEmisora, jsonEncode(emisora.toMap()));
|
||||
} catch (e) {
|
||||
registrarSaltoPersistencia(
|
||||
subsistema: 'ultima_emisora',
|
||||
detalle: 'persistir ${emisora.uuid}',
|
||||
razon: e.toString(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Escucha el stream de estado del audio y gestiona errores de reproducción.
|
||||
@@ -321,6 +369,9 @@ class EstadoRadio extends ChangeNotifier {
|
||||
final actual = audio.emisoraActual;
|
||||
if (actual != null && actual.uuid != _emisoraSeleccionada?.uuid) {
|
||||
_emisoraSeleccionada = actual;
|
||||
// Issue 4: an Android-Auto-initiated selection is a real station
|
||||
// change too — remember it the same way `reproducir` does.
|
||||
unawaited(_persistirUltimaEmisora(actual));
|
||||
}
|
||||
notifyListeners();
|
||||
});
|
||||
@@ -508,6 +559,10 @@ class EstadoRadio extends ChangeNotifier {
|
||||
}
|
||||
_emisoraSeleccionada = emisora;
|
||||
notifyListeners();
|
||||
// Issue 4: remembers the station the user just picked so it survives a
|
||||
// restart — fire-and-forget, same treatment as `radio.registrarClick`
|
||||
// below (a persistence failure here must never block playback).
|
||||
unawaited(_persistirUltimaEmisora(emisora));
|
||||
try {
|
||||
await audio.reproducir(emisora);
|
||||
if (revision != _revisionReproduccion) return;
|
||||
|
||||
Reference in New Issue
Block a user