/// Album Track Tile - Track item for album details library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../domain/entities/track.dart'; import '../../../../core/theme/colors.dart'; import '../../providers/music_provider.dart'; import '../common/cached_network_image_with_fallback.dart'; class AlbumTrackTile extends ConsumerWidget { final Track track; final int index; final VoidCallback? onTap; final VoidCallback? onMenuTap; const AlbumTrackTile({ required this.track, required this.index, this.onTap, this.onMenuTap, super.key, }); @override Widget build(BuildContext context, WidgetRef ref) { final playerState = ref.watch(playerProvider); final isCurrentlyPlaying = playerState.currentTrack?.id == track.id && playerState.isPlaying; return Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), decoration: BoxDecoration( color: AppColors.surface.withOpacity(isCurrentlyPlaying ? 0.8 : 0.4), borderRadius: BorderRadius.circular(12), border: Border.all( color: isCurrentlyPlaying ? AppColors.cyan.withOpacity(0.5) : AppColors.cyan.withOpacity(0.1), width: isCurrentlyPlaying ? 2 : 1, ), boxShadow: isCurrentlyPlaying ? AppColors.cyanGlow : null, ), child: Material( color: Colors.transparent, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(12), child: Row( children: [ // Track number or playing indicator _buildTrackIndicator(isCurrentlyPlaying), const SizedBox(width: 16), // Track info Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( track.title, style: TextStyle( color: isCurrentlyPlaying ? AppColors.cyan : AppColors.onBackground, fontWeight: isCurrentlyPlaying ? FontWeight.w700 : FontWeight.w600, fontSize: 15, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), if (track.artist != null) ...[ const SizedBox(height: 4), Text( track.artist!.name, style: const TextStyle( color: AppColors.onSurfaceVariant, fontSize: 13, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ], ), ), // Duration Text( track.formattedDuration, style: const TextStyle( color: AppColors.muted, fontSize: 13, fontWeight: FontWeight.w500, ), ), const SizedBox(width: 12), // Menu button _buildMenuButton(ref), ], ), ), ), ), ); } Widget _buildTrackIndicator(bool isPlaying) { return SizedBox( width: 24, child: isPlaying ? _buildPlayingIndicator() : Text( '${index + 1}', style: const TextStyle( color: AppColors.muted, fontSize: 14, fontWeight: FontWeight.w500, ), textAlign: TextAlign.center, ), ); } Widget _buildPlayingIndicator() { return SizedBox( width: 24, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ _buildBar(0.6), const SizedBox(height: 2), _buildBar(1.0), const SizedBox(height: 2), _buildBar(0.4), ], ), ); } Widget _buildBar(double height) { return AnimatedContainer( duration: const Duration(milliseconds: 300), width: 3, height: 8 * height, decoration: BoxDecoration( color: AppColors.cyan, borderRadius: BorderRadius.circular(2), ), ); } Widget _buildMenuButton(WidgetRef ref) { return PopupMenuButton( icon: const Icon( Icons.more_vert, color: AppColors.muted, size: 20, ), color: AppColors.surface, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: BorderSide( color: AppColors.cyan.withOpacity(0.3), ), ), onSelected: (choice) { switch (choice) { case 'queue': ref.read(playerProvider.notifier).addToQueue(track); ScaffoldMessenger.of(ref.context).showSnackBar( SnackBar( content: Text('${track.title} added to queue'), duration: const Duration(seconds: 2), backgroundColor: AppColors.surface, behavior: SnackBarBehavior.floating, ), ); break; case 'playlist': // TODO: Implement add to playlist ScaffoldMessenger.of(ref.context).showSnackBar( SnackBar( content: Text('Add to playlist coming soon'), duration: const Duration(seconds: 2), backgroundColor: AppColors.surface, behavior: SnackBarBehavior.floating, ), ); break; } }, itemBuilder: (context) => [ PopupMenuItem( value: 'queue', child: Row( children: const [ Icon(Icons.playlist_add, color: AppColors.cyan, size: 20), SizedBox(width: 12), Text( 'Add to queue', style: TextStyle(color: AppColors.onBackground), ), ], ), ), PopupMenuItem( value: 'playlist', child: Row( children: const [ Icon(Icons.playlist_play, color: AppColors.violet, size: 20), SizedBox(width: 12), Text( 'Add to playlist', style: TextStyle(color: AppColors.onBackground), ), ], ), ), ], ); } }