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
+72 -15
View File
@@ -294,6 +294,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
late bool _sonarEnVacaciones;
late SonidoInternoAlarma _sonidoInterno;
Emisora? _emisora;
bool _favoritosSolicitados = false;
@override
void initState() {
@@ -311,7 +312,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
_volumen = alarma?.volumen ?? 0.85;
_sonarEnVacaciones = alarma?.sonarEnVacaciones ?? true;
_sonidoInterno = alarma?.sonidoInterno ?? SonidoInternoAlarma.amanecer;
_emisora = alarma?.emisora;
_emisora = alarma?.emisora ?? context.read<EstadoRadio>().emisoraPreferida;
}
@override
@@ -324,6 +325,20 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
Widget build(BuildContext context) {
final radio = context.watch<EstadoRadio>();
final bottom = MediaQuery.of(context).viewInsets.bottom;
if (!_favoritosSolicitados) {
_favoritosSolicitados = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) context.read<EstadoRadio>().cargarFavoritos();
});
}
if (_emisora == null && widget.alarma == null && radio.emisoraPreferida != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted && _emisora == null) {
setState(() => _emisora = radio.emisoraPreferida);
}
});
}
final favoritas = _favoritasConSeleccion(radio.listaFavoritos);
return Padding(
padding: EdgeInsets.fromLTRB(12, 12, 12, bottom + 12),
child: PluriGlassSurface(
@@ -437,22 +452,52 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
onChanged: (value) => setState(() => _sonidoInterno = value ?? _sonidoInterno),
),
const SizedBox(height: 8),
ListTile(
contentPadding: EdgeInsets.zero,
leading: const Icon(Icons.radio_rounded),
title: Text(_emisora?.nombre ?? 'Sin emisora principal'),
subtitle: Text(
radio.emisoraActual == null
? 'Se usará el sonido interno si la radio falla.'
: 'Podés usar la emisora que está seleccionada ahora.',
),
trailing: FilledButton.tonal(
onPressed: radio.emisoraActual == null
? null
: () => setState(() => _emisora = radio.emisoraActual),
child: const Text('Usar actual'),
DropdownButtonFormField<String>(
key: ValueKey(_emisora?.uuid ?? 'sin-emisora'),
initialValue: _emisora?.uuid,
decoration: const InputDecoration(
labelText: 'Emisora favorita',
prefixIcon: Icon(Icons.radio_rounded),
),
items: [
const DropdownMenuItem<String>(
value: '',
child: Text('Sin emisora: usar sonido interno'),
),
for (final emisora in favoritas)
DropdownMenuItem<String>(
value: emisora.uuid,
child: Text(
emisora.nombre,
overflow: TextOverflow.ellipsis,
),
),
],
onChanged: (uuid) => setState(() {
if (uuid == null || uuid.isEmpty) {
_emisora = null;
return;
}
_emisora = favoritas.firstWhere((e) => e.uuid == uuid);
}),
),
if (favoritas.isEmpty) ...[
const SizedBox(height: 6),
const Text(
'Guardá emisoras en Favoritos para usarlas como alarma musical.',
),
],
if (radio.emisoraActual != null) ...[
const SizedBox(height: 8),
Align(
alignment: Alignment.centerLeft,
child: FilledButton.tonalIcon(
onPressed: () => setState(() => _emisora = radio.emisoraActual),
icon: const Icon(Icons.add_task_rounded),
label: const Text('Usar emisora actual'),
),
),
],
const SizedBox(height: 8),
SwitchListTile.adaptive(
contentPadding: EdgeInsets.zero,
@@ -531,6 +576,18 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
await estado.guardarAlarma(alarma);
if (mounted) Navigator.pop(context);
}
List<Emisora> _favoritasConSeleccion(List<Emisora> favoritas) {
final mapa = <String, Emisora>{};
for (final emisora in favoritas) {
mapa[emisora.uuid] = emisora;
}
final seleccionada = _emisora;
if (seleccionada != null) {
mapa[seleccionada.uuid] = seleccionada;
}
return mapa.values.toList();
}
}
class _AccesoDiagnostico extends StatelessWidget {