import 'package:flutter/material.dart'; import 'album_controller.dart'; import 'album_actions.dart'; import 'package:aves/widgets/common/thumbnail/aves_thumbnail_widget.dart'; /// Tile principale usato nella griglia "Tutti gli album" /// Basato su AlbumRow (derivato da FolderStats) class AlbumTile extends StatelessWidget { final AlbumRow album; final VoidCallback onTap; final VoidCallback onLongPress; const AlbumTile({ super.key, required this.album, required this.onTap, required this.onLongPress, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, onLongPress: onLongPress, child: ClipRRect( borderRadius: BorderRadius.circular(12), child: Stack( children: [ // COVER Positioned.fill( child: Hero( tag: 'album:${album.path}', child: AlbumTileThumbnail(album: album), ), ), // GRADIENT OVERLAY Positioned.fill( child: DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.bottomCenter, end: Alignment.center, colors: [ Colors.black.withOpacity(0.7), Colors.black.withOpacity(0.2), Colors.transparent, ], stops: const [0.0, 0.4, 1.0], ), ), ), ), // BADGES (remoto, vault, hybrid, pinned, hidden) Positioned( top: 6, right: 6, child: Row( children: [ if (album.isRemote) const _Badge(icon: Icons.cloud_outlined), if (album.isVault) const _Badge(icon: Icons.lock_outline), if (album.hybridType != 0) const _Badge(icon: Icons.all_inclusive), if (album.priority > 0) const _Badge(icon: Icons.push_pin_outlined), if (album.hidden) const _Badge(icon: Icons.visibility_off_outlined), ], ), ), // TESTO (nome + count + size) Positioned( left: 8, right: 8, bottom: 8, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( album.displayName, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w600, fontSize: 15, ), ), const SizedBox(height: 2), Text( '${album.fileCount} file', style: const TextStyle( color: Colors.white70, fontSize: 12, ), ), Text( _formatSize(album.totalSize), style: const TextStyle( color: Colors.white60, fontSize: 11, ), ), ], ), ), // MENU RAPIDO (3 dots) Positioned( top: 0, right: 0, child: IconButton( icon: const Icon(Icons.more_vert, color: Colors.white), onPressed: () { AlbumActions.showMenu(context, album); }, ), ), ], ), ), ); } String _formatSize(int bytes) { if (bytes < 1024) return '$bytes B'; if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB'; if (bytes < 1024 * 1024 * 1024) return '${(bytes / 1024 / 1024).toStringAsFixed(1)} MB'; return '${(bytes / 1024 / 1024 / 1024).toStringAsFixed(1)} GB'; } } /// Thumbnail con fallback class AlbumTileThumbnail extends StatelessWidget { final AlbumRow album; final double radius; const AlbumTileThumbnail({ super.key, required this.album, this.radius = 12, }); @override Widget build(BuildContext context) { final entry = album.thumbEntry; if (entry == null) { return Container( decoration: BoxDecoration( color: Colors.grey.shade900, borderRadius: BorderRadius.circular(radius), ), child: const Icon(Icons.folder, size: 48, color: Colors.white54), ); } return ClipRRect( borderRadius: BorderRadius.circular(radius), child: AvesThumbnailWidget( entry: entry, heroTag: 'album:${album.path}', fit: BoxFit.cover, ), ); } } /// Badge icona piccolo class _Badge extends StatelessWidget { final IconData icon; const _Badge({required this.icon}); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(left: 4), padding: const EdgeInsets.all(5), decoration: BoxDecoration( color: Colors.black.withOpacity(0.55), borderRadius: BorderRadius.circular(6), ), child: Icon(icon, color: Colors.white, size: 16), ); } }