fix(alarms): harden native playback and pre-notice actions
This commit is contained in:
@@ -30,6 +30,7 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
Timer? _fallbackTimer;
|
||||
bool _fallbackActivo = false;
|
||||
bool _radioIntentada = false;
|
||||
bool _audioFlutterConfirmado = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -57,6 +58,7 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
_estadoSub = radio.estadoStream.listen((estado) {
|
||||
if (estado == EstadoReproduccion.reproduciendo && mounted) {
|
||||
_fallbackTimer?.cancel();
|
||||
_confirmarAudioFlutterListo();
|
||||
}
|
||||
if (estado == EstadoReproduccion.error && mounted) {
|
||||
_iniciarFallback();
|
||||
@@ -76,9 +78,18 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
_fallbackActivo = true;
|
||||
await _fallbackPlayer.setAsset(_assetFallback(widget.alarma.sonidoInterno));
|
||||
await _fallbackPlayer.play();
|
||||
await _confirmarAudioFlutterListo();
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
Future<void> _confirmarAudioFlutterListo() async {
|
||||
if (_audioFlutterConfirmado) return;
|
||||
_audioFlutterConfirmado = true;
|
||||
await context.read<EstadoAlarmas>().android.confirmarAudioFlutter(
|
||||
widget.alarma.id,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _detener() async {
|
||||
final radio = context.read<EstadoRadio>();
|
||||
final alarmas = context.read<EstadoAlarmas>();
|
||||
|
||||
@@ -82,8 +82,9 @@ class _PanelProximaAlarma extends StatelessWidget {
|
||||
final proxima = estado.proximaAlarma;
|
||||
final activasSinProxima =
|
||||
estado.alarmas
|
||||
.where((a) => a.activa && a.proximaEjecucion == null)
|
||||
.where((a) => a.activa && a.proximaProgramable == null)
|
||||
.length;
|
||||
final proximaProgramable = proxima?.proximaProgramable;
|
||||
return PluriGlassSurface(
|
||||
glowColor: const Color(0xFFFFB86B).withValues(alpha: 0.28),
|
||||
child: Row(
|
||||
@@ -110,7 +111,7 @@ class _PanelProximaAlarma extends StatelessWidget {
|
||||
? activasSinProxima > 0
|
||||
? 'Hay $activasSinProxima alarma(s) activas, pero ahora mismo no tienen una fecha futura válida. Revisá fecha, días y vacaciones.'
|
||||
: 'Creá una alarma y PluriWave calculará la siguiente ejecución automáticamente.'
|
||||
: '${proxima.nombre} · ${_fechaHora(proxima.proximaEjecucion!)}',
|
||||
: '${proxima.nombre} · ${_fechaHora(proximaProgramable!)}',
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -193,11 +194,11 @@ class _TarjetaAlarma extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (alarma.proximaEjecucion != null)
|
||||
if (alarma.proximaProgramable != null)
|
||||
_NoticeLine(
|
||||
icon: Icons.event_available_rounded,
|
||||
text:
|
||||
'Siguiente ejecución: ${_fechaHora(alarma.proximaEjecucion!)}',
|
||||
'Siguiente ejecución: ${_fechaHora(alarma.proximaProgramable!)}',
|
||||
)
|
||||
else
|
||||
const _NoticeLine(
|
||||
@@ -231,7 +232,7 @@ class _TarjetaAlarma extends StatelessWidget {
|
||||
icon: const Icon(Icons.skip_next_rounded),
|
||||
label: const Text('Omitir siguiente'),
|
||||
onPressed:
|
||||
alarma.proximaEjecucion == null
|
||||
alarma.proximaProgramable == null
|
||||
? null
|
||||
: () async {
|
||||
await estado.saltarProxima(alarma.id);
|
||||
@@ -248,9 +249,9 @@ class _TarjetaAlarma extends StatelessWidget {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
actualizada?.proximaEjecucion == null
|
||||
actualizada?.proximaProgramable == null
|
||||
? 'Alarma omitida. No queda próxima ejecución.'
|
||||
: 'Alarma omitida. Volverá el ${_fechaHora(actualizada!.proximaEjecucion!)}.',
|
||||
: 'Alarma omitida. Volverá el ${_fechaHora(actualizada!.proximaProgramable!)}.',
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -281,13 +282,13 @@ class _TarjetaAlarma extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
if (actual != null) {
|
||||
if (alarma.proximaEjecucion == null) {
|
||||
if (alarma.proximaProgramable == null) {
|
||||
return 'Está pausada por vacaciones (${actual.nombre}) y sin próxima ejecución.';
|
||||
}
|
||||
return 'Está pausada por vacaciones (${actual.nombre}) y vuelve el ${_fechaHora(alarma.proximaEjecucion!)}.';
|
||||
return 'Está pausada por vacaciones (${actual.nombre}) y vuelve el ${_fechaHora(alarma.proximaProgramable!)}.';
|
||||
}
|
||||
if (alarma.proximaEjecucion != null) {
|
||||
return 'Con vacaciones activas, volverá a sonar el ${_fechaHora(alarma.proximaEjecucion!)}.';
|
||||
if (alarma.proximaProgramable != null) {
|
||||
return 'Con vacaciones activas, volverá a sonar el ${_fechaHora(alarma.proximaProgramable!)}.';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -690,12 +691,18 @@ class _AccesoDiagnostico extends StatelessWidget {
|
||||
label: Text(
|
||||
diag == null
|
||||
? 'Revisar fiabilidad Android'
|
||||
: 'Fiabilidad: exactas ${diag.puedeProgramarExactas ? 'OK' : 'pendiente'} · notificaciones ${diag.notificacionesPermitidas ? 'OK' : 'pendiente'}',
|
||||
: 'Fiabilidad: exactas ${diag.puedeProgramarExactas ? 'OK' : 'pendiente'} ? notificaciones ${diag.notificacionesPermitidas ? 'OK' : 'pendiente'} ? pantalla ${diag.puedeUsarPantallaCompleta ? 'OK' : 'pendiente'}',
|
||||
),
|
||||
onPressed: () async {
|
||||
if (diag != null && !diag.puedeProgramarExactas) {
|
||||
await estado.android.solicitarPermisoAlarmasExactas();
|
||||
}
|
||||
if (diag != null && !diag.notificacionesPermitidas) {
|
||||
await estado.android.solicitarPermisoNotificaciones();
|
||||
}
|
||||
if (diag != null && !diag.puedeUsarPantallaCompleta) {
|
||||
await estado.android.solicitarPermisoPantallaCompleta();
|
||||
}
|
||||
await estado.cargarDiagnostico();
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user