feat(favorites): manage favorite groups in ui
This commit is contained in:
@@ -13,6 +13,7 @@ import '../estado/estado_idioma.dart';
|
||||
import '../estado/estado_radio.dart';
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../modelos/emisora.dart';
|
||||
import '../modelos/grupo_favoritos.dart';
|
||||
import '../widgets/ecualizador_widget.dart';
|
||||
import '../widgets/pluri_glass_surface.dart';
|
||||
import '../widgets/pluri_icon.dart';
|
||||
@@ -64,6 +65,8 @@ class _AjustesContent extends StatelessWidget {
|
||||
SizedBox(height: 12),
|
||||
_SeccionOrdenListas(),
|
||||
SizedBox(height: 12),
|
||||
_SeccionGruposFavoritos(),
|
||||
SizedBox(height: 12),
|
||||
_SeccionEmisoraPreferida(),
|
||||
SizedBox(height: 12),
|
||||
_SeccionEmisoras(),
|
||||
@@ -693,6 +696,141 @@ class _SeccionOrdenListas extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _SeccionGruposFavoritos extends StatelessWidget {
|
||||
const _SeccionGruposFavoritos();
|
||||
|
||||
Future<void> _editarGrupo(BuildContext context, [GrupoFavoritos? grupo]) async {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final controller = TextEditingController(text: grupo?.nombre ?? '');
|
||||
final nombre = await showModalBottomSheet<String>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
showDragHandle: true,
|
||||
builder: (ctx) {
|
||||
final bottom = MediaQuery.viewInsetsOf(ctx).bottom;
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, 0, 20, bottom + 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
grupo == null ? l10n.favoriteGroupsAdd : l10n.favoriteGroupsEdit,
|
||||
style: Theme.of(ctx).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
maxLength: 28,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.favoriteGroupsNameLabel,
|
||||
helperText: l10n.favoriteGroupsNameTooLong,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
FilledButton.icon(
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
label: Text(AppLocalizations.of(ctx).saveQuickAccessButton),
|
||||
onPressed: () {
|
||||
final value = controller.text.trim();
|
||||
if (value.isEmpty || value.length > 28) return;
|
||||
Navigator.pop(ctx, value);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
controller.dispose();
|
||||
if (nombre == null || !context.mounted) return;
|
||||
final estado = context.read<EstadoRadio>();
|
||||
if (grupo == null) {
|
||||
await estado.crearGrupoFavoritos(nombre);
|
||||
} else {
|
||||
await estado.renombrarGrupoFavoritos(grupo.id, nombre);
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(grupo == null ? l10n.favoriteGroupsCreated : l10n.favoriteGroupsUpdated)),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _eliminarGrupo(BuildContext context, GrupoFavoritos grupo) async {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
await context.read<EstadoRadio>().eliminarGrupoFavoritos(grupo.id);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l10n.favoriteGroupsDeleted)),
|
||||
);
|
||||
}
|
||||
|
||||
String _nombreVisible(AppLocalizations l10n, GrupoFavoritos grupo) =>
|
||||
grupo.esSinAsignar ? l10n.favoriteGroupsUnassigned : grupo.nombre;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final estado = context.watch<EstadoRadio>();
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final grupos = estado.gruposFavoritos;
|
||||
return PluriGlassSurface(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.playlist_add_check_circle_rounded),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
l10n.favoriteGroupsTitle,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
),
|
||||
TextButton.icon(
|
||||
icon: const Icon(Icons.add_rounded),
|
||||
label: Text(l10n.favoriteGroupsAdd),
|
||||
onPressed: () => _editarGrupo(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(l10n.favoriteGroupsDescription),
|
||||
const SizedBox(height: 8),
|
||||
for (final grupo in grupos)
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: Icon(
|
||||
grupo.esSinAsignar ? Icons.lock_rounded : Icons.folder_rounded,
|
||||
),
|
||||
title: Text(_nombreVisible(l10n, grupo)),
|
||||
subtitle: grupo.esSinAsignar ? Text(l10n.favoriteGroupsProtectedHint) : null,
|
||||
trailing: grupo.esSinAsignar
|
||||
? null
|
||||
: Wrap(
|
||||
spacing: 4,
|
||||
children: [
|
||||
IconButton(
|
||||
tooltip: l10n.favoriteGroupsEdit,
|
||||
icon: const Icon(Icons.edit_rounded),
|
||||
onPressed: () => _editarGrupo(context, grupo),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: l10n.favoriteGroupsDelete,
|
||||
icon: const Icon(Icons.delete_outline_rounded),
|
||||
onPressed: () => _eliminarGrupo(context, grupo),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SeccionEmisoraPreferida extends StatelessWidget {
|
||||
const _SeccionEmisoraPreferida();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user