diff --git a/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmReceiver.kt b/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmReceiver.kt index 59ddcc5..fbab194 100644 --- a/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmReceiver.kt +++ b/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmReceiver.kt @@ -117,7 +117,7 @@ class PluriWaveAlarmReceiver : BroadcastReceiver() { .setAutoCancel(false) .setContentIntent(fullScreenIntent) .setFullScreenIntent(fullScreenIntent, true) - .addAction(0, "Posponer $snoozeMinutes min", snoozePendingIntent(context, alarmId, snoozeMinutes)) + .addAction(0, "Posponer", snoozePendingIntent(context, alarmId, snoozeMinutes)) .addAction(0, "Detener", stopPendingIntent(context, alarmId)) .build() @@ -188,7 +188,7 @@ class PluriWaveAlarmReceiver : BroadcastReceiver() { .setSilent(true) .setAutoCancel(true) .setContentIntent(openAppIntent) - .addAction(0, "Posponer $snoozeMinutes min", postponeNextIntent) + .addAction(0, "Posponer", postponeNextIntent) .addAction(0, "Omitir esta vez", skipNextIntent) .build() diff --git a/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmService.kt b/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmService.kt index e28a53f..feb434c 100644 --- a/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmService.kt +++ b/android/app/src/main/kotlin/es/freetimelab/pluriwave/PluriWaveAlarmService.kt @@ -266,7 +266,7 @@ class PluriWaveAlarmService : Service() { .setAutoCancel(false) .setFullScreenIntent(openAlarmPendingIntent(alarmId, title, snoozeMinutes), true) .setContentIntent(openAlarmPendingIntent(alarmId, title, snoozeMinutes)) - .addAction(0, "Posponer $snoozeMinutes min", snoozePendingIntent(alarmId, snoozeMinutes)) + .addAction(0, "Posponer", snoozePendingIntent(alarmId, snoozeMinutes)) .addAction(0, "Detener", stopPendingIntent(alarmId)) .build() diff --git a/lib/app.dart b/lib/app.dart index 428bcfd..0e522c5 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -257,7 +257,7 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - 'Alarma pospuesta ${evento.snoozeMinutes} min para esta ejecución.', + 'Alarma pospuesta para esta ejecución.', ), ), ); diff --git a/lib/main.dart b/lib/main.dart index 090a9fb..0c64ac5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,10 +1,17 @@ +import 'dart:async'; +import 'dart:ui' as ui; + import 'package:audio_service/audio_service.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'app.dart'; import 'servicios/servicio_audio.dart'; +const _anchoMinimoLandscape = 600.0; + Future main() async { WidgetsFlutterBinding.ensureInitialized(); + await _aplicarPoliticaOrientacion(); final handler = await AudioService.init( builder: () => PluriWaveAudioHandler(), @@ -18,5 +25,67 @@ Future main() async { ); registrarHandler(handler); - runApp(const PluriWaveApp()); + runApp(const _OrientacionResponsiveApp(child: PluriWaveApp())); +} + +Future _aplicarPoliticaOrientacion([ui.Display? display]) async { + final vista = + WidgetsBinding.instance.platformDispatcher.views.isNotEmpty + ? WidgetsBinding.instance.platformDispatcher.views.first + : null; + final displayActivo = display ?? vista?.display; + if (displayActivo == null) return; + + final anchoLogico = + displayActivo.size.width / displayActivo.devicePixelRatio; + if (anchoLogico < _anchoMinimoLandscape) { + await SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + ]); + return; + } + + await SystemChrome.setPreferredOrientations(DeviceOrientation.values); +} + +class _OrientacionResponsiveApp extends StatefulWidget { + const _OrientacionResponsiveApp({required this.child}); + + final Widget child; + + @override + State<_OrientacionResponsiveApp> createState() => + _OrientacionResponsiveAppState(); +} + +class _OrientacionResponsiveAppState extends State<_OrientacionResponsiveApp> + with WidgetsBindingObserver { + ui.Display? _display; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _display = View.maybeOf(context)?.display; + unawaited(_aplicarPoliticaOrientacion(_display)); + } + + @override + void didChangeMetrics() { + unawaited(_aplicarPoliticaOrientacion(_display)); + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + + @override + Widget build(BuildContext context) => widget.child; } diff --git a/lib/pantallas/pantalla_alarma_sonando.dart b/lib/pantallas/pantalla_alarma_sonando.dart index a8f54f5..febe057 100644 --- a/lib/pantallas/pantalla_alarma_sonando.dart +++ b/lib/pantallas/pantalla_alarma_sonando.dart @@ -140,19 +140,6 @@ class _PantallaAlarmaSonandoState extends State { if (mounted) navigator.pop(); } - Future _posponer(int minutos) async { - final radio = context.read(); - final alarmas = context.read(); - final navigator = Navigator.of(context); - _fallbackTimer?.cancel(); - _fadeInTimer?.cancel(); - await _estadoSub?.cancel(); - await _fallbackPlayer.stop(); - await radio.audio.pausar(); - await alarmas.posponerAlarma(widget.alarma, minutos); - if (mounted) navigator.pop(); - } - @override void dispose() { _fallbackTimer?.cancel(); @@ -212,18 +199,6 @@ class _PantallaAlarmaSonandoState extends State { icon: const Icon(Icons.stop_rounded), label: const Text('Detener alarma'), ), - const SizedBox(height: 12), - Wrap( - spacing: 8, - children: [ - for (final min in const [3, 5, 10]) - ActionChip( - avatar: const Icon(Icons.snooze_rounded, size: 18), - label: Text('Posponer $min min'), - onPressed: () => _posponer(min), - ), - ], - ), ], ), ), diff --git a/lib/pantallas/pantalla_alarmas.dart b/lib/pantallas/pantalla_alarmas.dart index 31da28b..0636b95 100644 --- a/lib/pantallas/pantalla_alarmas.dart +++ b/lib/pantallas/pantalla_alarmas.dart @@ -176,10 +176,6 @@ class _TarjetaAlarma extends StatelessWidget { icon: Icons.repeat_rounded, label: _programacion(alarma), ), - _InfoChip( - icon: Icons.snooze_rounded, - label: '${alarma.snoozeMinutos} min', - ), _InfoChip( icon: Icons.beach_access_rounded, label: @@ -323,7 +319,6 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> { late DateTime _fecha; late TipoProgramacionAlarma _tipo; late Set _diasSemana; - late int _snooze; late double _volumen; late int _fadeInSegundos; late bool _sonarEnVacaciones; @@ -346,7 +341,6 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> { _fecha = alarma?.fechaUnica ?? ahora; _tipo = alarma?.tipoProgramacion ?? TipoProgramacionAlarma.unica; _diasSemana = {...alarma?.diasSemana ?? const []}; - _snooze = alarma?.snoozeMinutos ?? 5; _volumen = alarma?.volumen ?? 0.85; _fadeInSegundos = ((alarma?.fadeInSegundos ?? 0).clamp(0, 60)) as int; _sonarEnVacaciones = alarma?.sonarEnVacaciones ?? true; @@ -481,21 +475,6 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> { ), ], const SizedBox(height: 14), - _SectionLabel( - icon: 'assets/icons/alarmas/snooze_wave.png', - text: 'Postponer', - ), - SegmentedButton( - segments: const [ - ButtonSegment(value: 3, label: Text('3 min')), - ButtonSegment(value: 5, label: Text('5 min')), - ButtonSegment(value: 10, label: Text('10 min')), - ], - selected: {_snooze}, - onSelectionChanged: - (value) => setState(() => _snooze = value.first), - ), - const SizedBox(height: 14), _SectionLabel( icon: 'assets/icons/alarmas/fallback_sound.png', text: 'Sonido y volumen', @@ -679,7 +658,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> { limpiarFechaUnica: _tipo != TipoProgramacionAlarma.unica, emisora: _emisora, sonarEnVacaciones: _sonarEnVacaciones, - snoozeMinutos: _snooze, + snoozeMinutos: existente?.snoozeMinutos ?? 5, volumen: _volumen, fadeInSegundos: _fadeInSegundos.clamp(0, 60), sonidoInterno: _sonidoInterno,