refactor(ajustes): split remaining Settings sections into pushed screens
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../l10n/gen/app_localizations.dart';
|
||||
import '../../servicios/musica_local_auto.dart';
|
||||
import '../../widgets/pluri_glass_surface.dart';
|
||||
import '../../widgets/pluri_layout.dart';
|
||||
import '../../widgets/pluri_push_scaffold.dart';
|
||||
|
||||
/// GRABACIONES Y MÚSICA group · "Música local" (design ADR-3). Body moved
|
||||
/// verbatim from the former `_SeccionMusicaLocal` in `pantalla_ajustes.dart`
|
||||
/// — only the panel header's icon and title were removed (the pushed
|
||||
/// screen's title now carries them). Deliberately does NOT use
|
||||
/// `FilePicker.platform` (see tasks.md "Grounding corrections") —
|
||||
/// [FuenteMusicaLocalAutoImpl.elegirCarpeta] calls the native
|
||||
/// `pickMusicFolder` channel method directly, since it needs a
|
||||
/// persistable-grant SAF tree URI, not a plain filesystem path.
|
||||
class PantallaAjustesMusicaLocal extends StatelessWidget {
|
||||
const PantallaAjustesMusicaLocal({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
return PluriPushScaffold(
|
||||
title: l10n.localMusicSectionTitle,
|
||||
body: ListView(
|
||||
padding: PluriLayout.pageContentPadding,
|
||||
children: const [_CuerpoMusicaLocal()],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CuerpoMusicaLocal extends StatefulWidget {
|
||||
const _CuerpoMusicaLocal();
|
||||
|
||||
@override
|
||||
State<_CuerpoMusicaLocal> createState() => _CuerpoMusicaLocalState();
|
||||
}
|
||||
|
||||
class _CuerpoMusicaLocalState extends State<_CuerpoMusicaLocal> {
|
||||
final _fuente = FuenteMusicaLocalAutoImpl();
|
||||
late Future<String?> _carpetaActual;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_carpetaActual = _fuente.carpetaActual();
|
||||
}
|
||||
|
||||
Future<void> _elegirCarpeta(BuildContext context) async {
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final l10n = AppLocalizations.of(context);
|
||||
try {
|
||||
final uri = await _fuente.elegirCarpeta();
|
||||
if (uri == null) return; // Cancelled — no snackbar, matches the SAF
|
||||
// picker's own "nothing changed" affordance.
|
||||
if (!context.mounted) return;
|
||||
setState(() {
|
||||
_carpetaActual = Future.value(uri);
|
||||
});
|
||||
messenger.showSnackBar(
|
||||
SnackBar(content: Text(l10n.localMusicFolderUpdated)),
|
||||
);
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
messenger.showSnackBar(
|
||||
SnackBar(content: Text(l10n.localMusicFolderSaveError(e.toString()))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
|
||||
return PluriGlassSurface(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
l10n.localMusicSectionDescription,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
FutureBuilder<String?>(
|
||||
future: _carpetaActual,
|
||||
builder: (ctx, snap) {
|
||||
final carpeta = snap.data;
|
||||
return ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.folder_outlined),
|
||||
title: Text(l10n.localMusicFolderTitle),
|
||||
subtitle: Text(
|
||||
(carpeta == null || carpeta.isEmpty)
|
||||
? l10n.localMusicFolderNotConfigured
|
||||
: nombreCarpetaDesdeUri(
|
||||
carpeta,
|
||||
nombreGenerico: l10n.localMusicFolderGenericName,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
FutureBuilder<String?>(
|
||||
future: _carpetaActual,
|
||||
builder: (ctx, snap) {
|
||||
final configurada = (snap.data ?? '').isNotEmpty;
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: OutlinedButton.icon(
|
||||
icon: const Icon(Icons.folder_open_rounded),
|
||||
label: Text(
|
||||
configurada
|
||||
? l10n.localMusicChangePath
|
||||
: l10n.localMusicChoosePath,
|
||||
),
|
||||
onPressed: () => _elegirCarpeta(context),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user