fix(alarm): improve firing and preferred station
Build & Deploy Pluriwave / Análisis de código (push) Successful in 15s
Build & Deploy Pluriwave / Build APK + AAB release (push) Successful in 4m15s

This commit is contained in:
2026-05-22 01:05:50 +02:00
parent 28067e392d
commit eeadcc1cc6
11 changed files with 344 additions and 18 deletions
+8 -1
View File
@@ -64,7 +64,12 @@ class EstadoAlarmas extends ChangeNotifier {
Future<void> guardarAlarma(AlarmaMusical alarma) async {
final config = await servicio.guardarAlarma(alarma);
_aplicar(config);
await android.programar(_alarmas.firstWhere((a) => a.id == alarma.id));
try {
await android.programar(_alarmas.firstWhere((a) => a.id == alarma.id));
} catch (e) {
_error =
'Alarma guardada, pero Android no pudo programarla todavía: $e';
}
notifyListeners();
}
@@ -111,10 +116,12 @@ class EstadoAlarmas extends ChangeNotifier {
Future<void> posponerAlarma(AlarmaMusical alarma, int minutos) async {
final proxima = DateTime.now().add(Duration(minutes: minutos));
await android.ocultarNotificacionAlarma(alarma.id);
await android.programar(alarma.copyWith(proximaEjecucion: proxima));
}
Future<void> finalizarEjecucion(String alarmaId) async {
await android.ocultarNotificacionAlarma(alarmaId);
await refrescarProgramacion();
}
+82
View File
@@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../modelos/emisora.dart';
import '../modelos/preset_ecualizador.dart';
@@ -53,6 +54,7 @@ class EstadoRadio extends ChangeNotifier {
Future<void>? _initFuture;
int _revisionReproduccion = 0;
Emisora? _emisoraSeleccionada;
String? _emisoraPreferidaUuid;
// Errores de reproducción → SnackBar.
final _errorController = StreamController<String>.broadcast();
@@ -84,6 +86,7 @@ class EstadoRadio extends ChangeNotifier {
String? _ultimoIdiomaBusqueda;
String? _ultimoTagBusqueda;
String? _errorCarga;
static const _keyEmisoraPreferida = 'emisora_preferida_uuid_v1';
List<Emisora> get populares => _populares;
List<Emisora> get tendencias => _tendencias;
@@ -100,6 +103,8 @@ class EstadoRadio extends ChangeNotifier {
String? get errorCercanas => _errorCercanas;
String? get error => _errorCarga;
Emisora? get emisoraActual => _emisoraSeleccionada ?? audio.emisoraActual;
Emisora? get emisoraPreferida => _resolverEmisoraPreferida();
String? get emisoraPreferidaUuid => emisoraPreferida?.uuid;
Stream<EstadoReproduccion> get estadoStream => audio.estadoStream;
PresetEcualizador get presetEcualizador => _presetActual;
PresetEcualizador get presetPrincipalEcualizador => _presetPrincipal;
@@ -134,6 +139,29 @@ class EstadoRadio extends ChangeNotifier {
return mapa.values.toList();
}
List<Emisora> get emisorasDisponiblesPreferencia {
final mapa = <String, Emisora>{};
for (final emisora in _listaFavoritos) {
mapa[emisora.uuid] = emisora;
}
for (final emisora in _emisorasCustom) {
mapa.putIfAbsent(emisora.uuid, () => emisora);
}
for (final emisora in _populares) {
mapa.putIfAbsent(emisora.uuid, () => emisora);
}
for (final emisora in _tendencias) {
mapa.putIfAbsent(emisora.uuid, () => emisora);
}
for (final emisora in _resultadosBusqueda) {
mapa.putIfAbsent(emisora.uuid, () => emisora);
}
for (final emisora in _emisorasCercanas) {
mapa.putIfAbsent(emisora.uuid, () => emisora);
}
return mapa.values.toList();
}
Future<void> inicializar() {
_initFuture ??= _init();
return _initFuture!;
@@ -142,11 +170,13 @@ class EstadoRadio extends ChangeNotifier {
Future<void> _init() async {
await grabacion.inicializar();
await _cargarEcualizadorPersistido();
await _cargarEmisoraPreferida();
await Future.wait([
cargarPopulares(),
cargarFavoritos(),
_cargarEmisorasCustom(),
]);
await _normalizarEmisoraPreferida();
}
/// Escucha el stream de estado del audio y gestiona errores de reproducción.
@@ -209,9 +239,61 @@ class EstadoRadio extends ChangeNotifier {
Future<void> cargarFavoritos() async {
_listaFavoritos = await favoritos.obtenerTodos();
await _normalizarEmisoraPreferida();
notifyListeners();
}
Future<void> cambiarEmisoraPreferida(Emisora? emisora) async {
_emisoraPreferidaUuid = emisora?.uuid;
final prefs = await SharedPreferences.getInstance();
if (_emisoraPreferidaUuid == null) {
await prefs.remove(_keyEmisoraPreferida);
} else {
await prefs.setString(_keyEmisoraPreferida, _emisoraPreferidaUuid!);
}
notifyListeners();
}
Future<void> reproducirEmisoraPreferida() async {
final preferida = emisoraPreferida;
if (preferida == null) return;
await reproducir(preferida);
}
Future<void> _cargarEmisoraPreferida() async {
final prefs = await SharedPreferences.getInstance();
_emisoraPreferidaUuid = prefs.getString(_keyEmisoraPreferida);
}
Future<void> _normalizarEmisoraPreferida() async {
final preferida = _resolverEmisoraPreferida();
if (preferida?.uuid == _emisoraPreferidaUuid) return;
_emisoraPreferidaUuid = preferida?.uuid;
final prefs = await SharedPreferences.getInstance();
if (_emisoraPreferidaUuid == null) {
await prefs.remove(_keyEmisoraPreferida);
} else {
await prefs.setString(_keyEmisoraPreferida, _emisoraPreferidaUuid!);
}
}
Emisora? _resolverEmisoraPreferida() {
final uuid = _emisoraPreferidaUuid;
if (uuid != null) {
for (final emisora in _listaFavoritos) {
if (emisora.uuid == uuid) return emisora;
}
}
if (_listaFavoritos.isNotEmpty) return _listaFavoritos.first;
if (uuid != null) {
for (final emisora in emisorasDisponiblesPreferencia) {
if (emisora.uuid == uuid) return emisora;
}
}
final disponibles = emisorasDisponiblesPreferencia;
return disponibles.isEmpty ? null : disponibles.first;
}
static const int _tamanoPaginaBusqueda = 30;
static const int _maxResultadosBusquedaEnMemoria = 180;