import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; import '../modelos/emisora.dart'; /// Tarjeta compacta para mostrar una emisora en listas y grids. class TarjetaEmisora extends StatelessWidget { final Emisora emisora; final VoidCallback? onTap; final bool esCompacta; const TarjetaEmisora({ super.key, required this.emisora, this.onTap, this.esCompacta = false, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Card( clipBehavior: Clip.antiAlias, child: InkWell( onTap: onTap, child: esCompacta ? _buildCompacta(theme) : _buildCompleta(theme), ), ); } Widget _buildCompleta(ThemeData theme) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AspectRatio( aspectRatio: 1, child: _logo(theme, 60), ), Padding( padding: const EdgeInsets.all(8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( emisora.nombre, style: theme.textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.bold), maxLines: 2, overflow: TextOverflow.ellipsis, ), if (emisora.pais != null) Text( emisora.pais!, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), ], ); } Widget _buildCompacta(ThemeData theme) { return ListTile( leading: SizedBox(width: 48, height: 48, child: _logo(theme, 24)), title: Text( emisora.nombre, maxLines: 1, overflow: TextOverflow.ellipsis, ), subtitle: Text( [emisora.pais, emisora.idioma].where((s) => s != null).join(' ยท '), maxLines: 1, overflow: TextOverflow.ellipsis, ), ); } Widget _logo(ThemeData theme, double iconSize) { if (emisora.favicon != null && emisora.favicon!.isNotEmpty) { return CachedNetworkImage( imageUrl: emisora.favicon!, fit: BoxFit.cover, placeholder: (_, __) => _shimmer(theme), errorWidget: (_, __, ___) => _iconoFallback(theme, iconSize), ); } return _iconoFallback(theme, iconSize); } Widget _shimmer(ThemeData theme) { return Shimmer.fromColors( baseColor: theme.colorScheme.surfaceContainerHighest, highlightColor: theme.colorScheme.surface, child: Container(color: theme.colorScheme.surfaceContainerHighest), ); } Widget _iconoFallback(ThemeData theme, double size) { return Container( color: theme.colorScheme.primaryContainer, child: Icon(Icons.radio, size: size, color: theme.colorScheme.onPrimaryContainer), ); } } /// Placeholder shimmer para listas en carga. class TarjetaEmisoraShimmer extends StatelessWidget { const TarjetaEmisoraShimmer({super.key}); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Shimmer.fromColors( baseColor: theme.colorScheme.surfaceContainerHighest, highlightColor: theme.colorScheme.surface, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AspectRatio( aspectRatio: 1, child: Container(color: theme.colorScheme.surfaceContainerHighest), ), const SizedBox(height: 8), Container(height: 14, color: theme.colorScheme.surfaceContainerHighest), const SizedBox(height: 4), Container(height: 12, width: 60, color: theme.colorScheme.surfaceContainerHighest), ], ), ); } }