feat(player): add radio recording and real waveform
This commit is contained in:
@@ -25,7 +25,8 @@ class PantallaAjustes extends StatelessWidget {
|
||||
children: const [
|
||||
PluriScreenHeader(
|
||||
title: 'Ajustes',
|
||||
subtitle: 'Control fino de sonido, copias de seguridad y emisoras personalizadas.',
|
||||
subtitle:
|
||||
'Control fino de sonido, copias de seguridad y emisoras personalizadas.',
|
||||
glyph: PluriIconGlyph.settings,
|
||||
trailing: PluriStatusPill(
|
||||
icon: Icons.security_rounded,
|
||||
@@ -50,6 +51,8 @@ class _AjustesContent extends StatelessWidget {
|
||||
children: const [
|
||||
_SeccionEcualizador(),
|
||||
SizedBox(height: 12),
|
||||
_SeccionGrabaciones(),
|
||||
SizedBox(height: 12),
|
||||
_SeccionEmisoras(),
|
||||
SizedBox(height: 12),
|
||||
_SeccionBackup(),
|
||||
@@ -60,6 +63,97 @@ class _AjustesContent extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _SeccionGrabaciones extends StatelessWidget {
|
||||
const _SeccionGrabaciones();
|
||||
|
||||
Future<void> _seleccionarRuta(BuildContext context) async {
|
||||
final estado = context.read<EstadoRadio>();
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final ruta = await FilePicker.platform.getDirectoryPath(
|
||||
dialogTitle: 'Selecciona la carpeta de grabaciones',
|
||||
);
|
||||
if (ruta == null) return;
|
||||
try {
|
||||
await estado.cambiarDirectorioGrabacion(ruta);
|
||||
messenger.showSnackBar(
|
||||
const SnackBar(content: Text('Ruta de grabación actualizada')),
|
||||
);
|
||||
} catch (e) {
|
||||
messenger.showSnackBar(
|
||||
SnackBar(content: Text('No se pudo guardar la ruta: $e')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _restaurarRuta(BuildContext context) async {
|
||||
final estado = context.read<EstadoRadio>();
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
await estado.restaurarDirectorioGrabacion();
|
||||
messenger.showSnackBar(
|
||||
const SnackBar(content: Text('Se usará la carpeta interna por defecto')),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final estado = context.watch<EstadoRadio>();
|
||||
|
||||
return PluriGlassSurface(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.radio_button_checked),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'Grabaciones',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
FutureBuilder<String>(
|
||||
future: estado.directorioGrabacionEfectivo(),
|
||||
builder:
|
||||
(ctx, snap) => ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.folder_outlined),
|
||||
title: const Text('Carpeta de grabación'),
|
||||
subtitle: Text(
|
||||
snap.data ?? 'Calculando ruta...',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
onTap: () => _seleccionarRuta(context),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton.icon(
|
||||
icon: const Icon(Icons.folder_open_rounded),
|
||||
label: const Text('Cambiar ruta'),
|
||||
onPressed: () => _seleccionarRuta(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
IconButton.filledTonal(
|
||||
tooltip: 'Usar ruta por defecto',
|
||||
icon: const Icon(Icons.restore_rounded),
|
||||
onPressed: () => _restaurarRuta(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'La radio se guarda desde el stream original, sin recomprimir.',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SeccionEcualizador extends StatelessWidget {
|
||||
const _SeccionEcualizador();
|
||||
|
||||
Reference in New Issue
Block a user