feat(ui): add premium PluriWave redesign
Build & Deploy Pluriwave / Análisis de código (push) Failing after 21s
Build & Deploy Pluriwave / Build APK + AAB release (push) Has been skipped

This commit is contained in:
2026-05-20 18:42:22 +02:00
parent f95a8290ae
commit c707fc9911
30 changed files with 2218 additions and 954 deletions
+52 -39
View File
@@ -1,9 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../estado/estado_radio.dart';
import '../tema/pluriwave_theme.dart';
import '../widgets/pluri_glass_surface.dart';
import '../widgets/pluri_icon.dart';
import '../widgets/tarjeta_emisora.dart';
/// Pantalla de emisoras favoritas con reordenado y swipe-to-delete.
class PantallaFavoritos extends StatelessWidget {
const PantallaFavoritos({super.key});
@@ -15,26 +18,26 @@ class PantallaFavoritos extends StatelessWidget {
if (favoritos.isEmpty) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.favorite_border, size: 72, color: theme.colorScheme.outlineVariant),
const SizedBox(height: 16),
Text('Sin favoritos aún', style: theme.textTheme.titleMedium),
const SizedBox(height: 8),
Text(
'Toca ♥ en cualquier emisora para guardarla',
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
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 ReorderableListView.builder(
padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(12),
onReorder: (oldIndex, newIndex) async {
if (newIndex > oldIndex) newIndex--;
final emisora = favoritos[oldIndex];
@@ -44,29 +47,39 @@ class PantallaFavoritos extends StatelessWidget {
itemCount: favoritos.length,
itemBuilder: (context, i) {
final emisora = favoritos[i];
return Dismissible(
key: Key(emisora.uuid),
direction: DismissDirection.endToStart,
background: Container(
color: theme.colorScheme.error,
alignment: Alignment.centerRight,
padding: const EdgeInsets.only(right: 16),
child: Icon(Icons.delete, color: theme.colorScheme.onError),
),
onDismissed: (_) 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')),
);
}
},
child: TarjetaEmisora(
key: Key(emisora.uuid),
emisora: emisora,
esCompacta: true,
onTap: () => estado.reproducir(emisora),
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),
),
),
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')),
);
}
},
),
],
),
),
),
);
},