import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../estado/estado_radio.dart'; import '../../l10n/gen/app_localizations.dart'; import '../../widgets/pluri_glass_surface.dart'; import '../../widgets/pluri_layout.dart'; import '../../widgets/pluri_push_scaffold.dart'; /// AUDIO group · "Temporizador de sueño" (design ADR-3). Body moved verbatim /// from the former `_SeccionTimerSueno` in `pantalla_ajustes.dart` — the /// panel header's icon and title were removed (the pushed screen's title /// now carries them), and the "Add" action moved into the screen's app bar /// via [PluriPushScaffold.actions] since it is a real capability, not /// decorative header chrome. class PantallaAjustesTimerSueno extends StatelessWidget { const PantallaAjustesTimerSueno({super.key}); @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); return PluriPushScaffold( title: l10n.timerSectionTitle, actions: [ IconButton( icon: const Icon(Icons.add_rounded), tooltip: l10n.timerSectionAdd, onPressed: () => _anadirPreset(context), ), ], body: ListView( padding: PluriLayout.pageContentPadding, children: const [_CuerpoTimerSueno()], ), ); } } Future _anadirPreset(BuildContext context) async { final l10n = AppLocalizations.of(context); final duracion = await showModalBottomSheet( context: context, isScrollControlled: true, showDragHandle: true, builder: (_) => const _FormularioDuracionTimer(), ); if (duracion == null || !context.mounted) return; await context.read().agregarTimerSuenoPreset(duracion); if (!context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '${l10n.saveQuickAccessButton}: ${_formatearDuracionTimer(l10n, duracion)}', ), ), ); } class _CuerpoTimerSueno extends StatelessWidget { const _CuerpoTimerSueno(); @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); // S4-R5: scoped select — rebuilds only when the presets list changes. final presets = context.select>( (e) => e.timerSuenoPresetsSegundos, ); return PluriGlassSurface( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n.timerSectionDescription, style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 12), Wrap( spacing: 8, runSpacing: 8, children: [ for (final segundos in presets) InputChip( label: Text( _formatearDuracionTimer(l10n, Duration(seconds: segundos)), ), onDeleted: presets.length <= 1 ? null : () => context .read() .eliminarTimerSuenoPreset(segundos), ), ], ), const SizedBox(height: 8), Align( alignment: Alignment.centerLeft, child: TextButton.icon( icon: const Icon(Icons.restore_rounded), label: Text(l10n.timerSectionRestoreRecommended), onPressed: () => context.read().restaurarTimerSuenoPresets(), ), ), ], ), ); } } class _FormularioDuracionTimer extends StatefulWidget { const _FormularioDuracionTimer(); @override State<_FormularioDuracionTimer> createState() => _FormularioDuracionTimerState(); } class _FormularioDuracionTimerState extends State<_FormularioDuracionTimer> { final _horasCtrl = TextEditingController(); final _minutosCtrl = TextEditingController(text: '15'); final _segundosCtrl = TextEditingController(); @override void dispose() { _horasCtrl.dispose(); _minutosCtrl.dispose(); _segundosCtrl.dispose(); super.dispose(); } int _leer(TextEditingController ctrl) => int.tryParse(ctrl.text.trim()) ?? 0; void _guardar() { final l10n = AppLocalizations.of(context); final duracion = Duration( hours: _leer(_horasCtrl), minutes: _leer(_minutosCtrl), seconds: _leer(_segundosCtrl), ); if (duracion <= Duration.zero) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.durationGreaterThanZero))); return; } Navigator.pop(context, duracion); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); final bottom = MediaQuery.viewInsetsOf(context).bottom; return SafeArea( child: Padding( padding: EdgeInsets.fromLTRB(18, 0, 18, 18 + bottom), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( l10n.newQuickAccessTitle, style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 12), Row( children: [ Expanded(child: _campo(_horasCtrl, l10n.hoursLabel)), const SizedBox(width: 8), Expanded(child: _campo(_minutosCtrl, l10n.minutesLabel)), const SizedBox(width: 8), Expanded(child: _campo(_segundosCtrl, l10n.secondsLabel)), ], ), const SizedBox(height: 16), FilledButton.icon( icon: const Icon(Icons.save_rounded), label: Text(l10n.saveQuickAccessButton), onPressed: _guardar, ), ], ), ), ); } Widget _campo(TextEditingController controller, String label) { return TextField( controller: controller, keyboardType: TextInputType.number, decoration: InputDecoration( labelText: label, border: const OutlineInputBorder(), ), ); } } String _formatearDuracionTimer(AppLocalizations l10n, Duration duracion) { final horas = duracion.inHours; final minutos = duracion.inMinutes.remainder(60); final segundos = duracion.inSeconds.remainder(60); if (horas > 0) { return l10n.durationHoursMinutesSeconds( horas, minutos.toString().padLeft(2, '0'), segundos.toString().padLeft(2, '0'), ); } if (minutos > 0) { return segundos == 0 ? l10n.durationMinutesOnly(minutos) : l10n.durationMinutesSeconds( minutos, segundos.toString().padLeft(2, '0'), ); } return l10n.durationSecondsOnly(segundos); }