feat(ui): implement award mockup redesign
Build & Deploy Pluriwave / Análisis de código (push) Successful in 10s
Build & Deploy Pluriwave / Build APK + AAB release (push) Successful in 1m19s

This commit is contained in:
2026-05-20 21:29:36 +02:00
parent eb0ef37c76
commit d8acf74771
14 changed files with 621 additions and 211 deletions
+88 -69
View File
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import '../estado/estado_radio.dart';
import '../widgets/pluri_glass_surface.dart';
import '../widgets/pluri_icon.dart';
import '../widgets/pluri_premium_widgets.dart';
import 'package:pluriwave/widgets/tarjeta_emisora.dart';
class PantallaFavoritos extends StatelessWidget {
@@ -13,84 +14,102 @@ class PantallaFavoritos extends StatelessWidget {
Widget build(BuildContext context) {
final estado = context.watch<EstadoRadio>();
final favoritos = estado.listaFavoritos;
final theme = Theme.of(context);
if (favoritos.isEmpty) {
return Center(
child: PluriGlassSurface(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const PluriIcon(
glyph: PluriIconGlyph.favorites,
variant: PluriIconVariant.activeGlow,
size: 52,
),
const SizedBox(height: 16),
Text('Sin favoritos aún', style: theme.textTheme.titleMedium),
const SizedBox(height: 8),
Text(
'Tocá ♥ en cualquier emisora para guardarla',
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
],
return const Column(
children: [
PluriScreenHeader(
title: 'Favoritos',
subtitle: 'Tu cabina personal para volver a las senales que mas escuchas.',
glyph: PluriIconGlyph.favorites,
trailing: PluriStatusPill(
icon: Icons.favorite_rounded,
label: 'Coleccion',
),
),
),
Expanded(
child: PluriEmptyState(
glyph: PluriIconGlyph.favorites,
title: 'Sin favoritos aun',
subtitle: 'Toca el corazon en cualquier emisora para guardarla en tu coleccion.',
),
),
],
);
}
return ReorderableListView.builder(
padding: const EdgeInsets.all(12),
onReorder: (oldIndex, newIndex) async {
if (newIndex > oldIndex) newIndex--;
final emisora = favoritos[oldIndex];
await estado.favoritos.reordenar(emisora.uuid, newIndex);
await estado.cargarFavoritos();
},
itemCount: favoritos.length,
itemBuilder: (context, i) {
final emisora = favoritos[i];
return Padding(
key: ValueKey('favorito-pad-${emisora.uuid}'),
padding: const EdgeInsets.symmetric(vertical: 4),
child: PluriGlassSurface(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
child: Row(
children: [
const Icon(Icons.drag_indicator_rounded),
const SizedBox(width: 6),
Expanded(
child: TarjetaEmisora(
key: Key(emisora.uuid),
emisora: emisora,
esCompacta: true,
onTap: () => estado.reproducir(emisora),
return Column(
children: [
PluriScreenHeader(
title: 'Favoritos',
subtitle: 'Reordena tu coleccion y deja arriba las radios que mas importan.',
glyph: PluriIconGlyph.favorites,
trailing: PluriStatusPill(
icon: Icons.library_music_rounded,
label: '${favoritos.length} guardadas',
),
),
Expanded(
child: ReorderableListView.builder(
padding: const EdgeInsets.fromLTRB(12, 4, 12, 122),
proxyDecorator: (child, index, animation) => ScaleTransition(
scale: Tween<double>(begin: 1, end: 1.03).animate(animation),
child: child,
),
onReorder: (oldIndex, newIndex) async {
if (newIndex > oldIndex) newIndex--;
final emisora = favoritos[oldIndex];
await estado.favoritos.reordenar(emisora.uuid, newIndex);
await estado.cargarFavoritos();
},
itemCount: favoritos.length,
itemBuilder: (context, i) {
final emisora = favoritos[i];
return Padding(
key: ValueKey('favorito-pad-${emisora.uuid}'),
padding: const EdgeInsets.symmetric(vertical: 5),
child: PluriGlassSurface(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 7),
child: Row(
children: [
ReorderableDragStartListener(
index: i,
child: const Padding(
padding: EdgeInsets.all(8),
child: Icon(Icons.drag_indicator_rounded),
),
),
Expanded(
child: TarjetaEmisora(
key: Key(emisora.uuid),
emisora: emisora,
esCompacta: true,
onTap: () => estado.reproducir(emisora),
),
),
IconButton.filledTonal(
tooltip: 'Eliminar de favoritos',
icon: const Icon(Icons.delete_outline_rounded),
onPressed: () async {
await estado.favoritos.eliminar(emisora.uuid);
await estado.cargarFavoritos();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('${emisora.nombre} eliminada de favoritos'),
),
);
}
},
),
],
),
),
IconButton(
tooltip: 'Eliminar de favoritos',
icon: const Icon(Icons.delete_outline_rounded),
onPressed: () async {
await estado.favoritos.eliminar(emisora.uuid);
await estado.cargarFavoritos();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'${emisora.nombre} eliminada de favoritos',
),
),
);
}
},
),
],
),
);
},
),
);
},
),
],
);
}
}