import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:provider/provider.dart'; import 'estado/estado_radio.dart'; import 'pantallas/pantalla_inicio.dart'; import 'pantallas/pantalla_buscar.dart'; import 'pantallas/pantalla_favoritos.dart'; import 'pantallas/pantalla_ajustes.dart'; import 'widgets/mini_reproductor.dart'; class PluriWaveApp extends StatelessWidget { const PluriWaveApp({super.key}); @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (_) => EstadoRadio(), child: MaterialApp( title: 'PluriWave', debugShowCheckedModeBanner: false, theme: _buildTheme(Brightness.dark), darkTheme: _buildTheme(Brightness.dark), themeMode: ThemeMode.dark, home: const _PaginaPrincipal(), ), ); } ThemeData _buildTheme(Brightness brightness) { final colorScheme = ColorScheme.fromSeed( seedColor: const Color(0xFF6750A4), brightness: brightness, ); return ThemeData( useMaterial3: true, colorScheme: colorScheme, textTheme: GoogleFonts.interTextTheme( ThemeData(brightness: brightness).textTheme, ), cardTheme: CardThemeData( elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), color: colorScheme.surfaceContainerLow, ), snackBarTheme: SnackBarThemeData( behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), ); } } class _PaginaPrincipal extends StatefulWidget { const _PaginaPrincipal(); @override State<_PaginaPrincipal> createState() => _PaginaPrincipalState(); } class _PaginaPrincipalState extends State<_PaginaPrincipal> { int _indice = 0; static const _paginas = [ PantallaInicio(), PantallaBuscar(), PantallaFavoritos(), PantallaAjustes(), ]; static const _destinos = [ NavigationDestination( icon: Icon(Icons.home_outlined), selectedIcon: Icon(Icons.home), label: 'Inicio', ), NavigationDestination( icon: Icon(Icons.search_outlined), selectedIcon: Icon(Icons.search), label: 'Buscar', ), NavigationDestination( icon: Icon(Icons.favorite_outline), selectedIcon: Icon(Icons.favorite), label: 'Favoritos', ), NavigationDestination( icon: Icon(Icons.settings_outlined), selectedIcon: Icon(Icons.settings), label: 'Ajustes', ), ]; @override void didChangeDependencies() { super.didChangeDependencies(); context.read().errorStream.listen((msg) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(msg), duration: const Duration(seconds: 3), action: SnackBarAction(label: 'OK', onPressed: () {}), ), ); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: _indice == 3 ? null // PantallaAjustes tiene su propio AppBar : AppBar( title: const Text('PluriWave'), actions: [ IconButton( icon: const Icon(Icons.bedtime_outlined), tooltip: 'Timer de sueño', onPressed: () => _mostrarTimerDialog(context), ), ], ), body: _paginas[_indice], bottomNavigationBar: Column( mainAxisSize: MainAxisSize.min, children: [ const MiniReproductor(), NavigationBar( selectedIndex: _indice, onDestinationSelected: (i) => setState(() => _indice = i), destinations: _destinos, ), ], ), ); } void _mostrarTimerDialog(BuildContext context) { final estado = context.read(); showModalBottomSheet( context: context, builder: (ctx) => SafeArea( child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Timer de sueño', style: Theme.of(ctx).textTheme.titleLarge), const SizedBox(height: 16), if (estado.timer.activo) StreamBuilder( stream: estado.timer.tiempoRestanteStream, builder: (ctx, snap) { final t = snap.data ?? Duration.zero; final h = t.inHours; final m = t.inMinutes.remainder(60).toString().padLeft(2, '0'); final s = t.inSeconds.remainder(60).toString().padLeft(2, '0'); return Column( children: [ Text( '${h > 0 ? "${h}h " : ""}${m}m ${s}s', style: Theme.of(ctx).textTheme.headlineMedium, ), const SizedBox(height: 8), FilledButton.tonal( onPressed: () { estado.cancelarTimer(); Navigator.pop(ctx); }, child: const Text('Cancelar timer'), ), ], ); }, ) else Wrap( spacing: 8, children: [3, 5, 10, 15, 30, 60, 90, 120, 180] .map((min) => ActionChip( label: Text('$min min'), onPressed: () { estado.iniciarTimer(min); Navigator.pop(ctx); }, )) .toList(), ), ], ), ), ), ); } }