import 'dart:io'; import 'package:flutter/material.dart'; import '../models/song.dart'; import '../utils/farb_theme.dart'; import 'metadaten_dialog.dart'; import 'tag_auswahl_dialog.dart'; class SongTile extends StatelessWidget { final Song song; final bool istFavorit; final ValueChanged onFavoriteToggle; final ValueChanged onPlay; final VoidCallback onMetadataChanged; final ValueChanged? onAddToPlaylist; final ValueChanged? onDelete; const SongTile({ super.key, required this.song, required this.istFavorit, required this.onFavoriteToggle, required this.onPlay, required this.onMetadataChanged, this.onAddToPlaylist, this.onDelete, }); @override Widget build(BuildContext context) { final hatDatei = song.dateiPfad.isNotEmpty; final hatCover = song.coverPfad != null && File(song.coverPfad!).existsSync(); return ListTile( contentPadding: const EdgeInsets.symmetric(vertical: 2), leading: ClipRRect( borderRadius: BorderRadius.circular(10), child: Container( width: 44, height: 44, decoration: const BoxDecoration( gradient: LinearGradient(colors: [Color(0xFF1A0000), Color(0xFF660000)]), ), child: hatCover ? Image.file(File(song.coverPfad!), fit: BoxFit.cover) : const Center(child: Text('♪', style: TextStyle(fontSize: 18, color: Colors.white54))), ), ), title: Text(song.titel, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white)), subtitle: Text(song.kuenstler, style: const TextStyle(fontSize: 12, color: MeloTheme.textSekundaer)), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ InkWell( borderRadius: BorderRadius.circular(50), onTap: () async { final geaendert = await showDialog( context: context, builder: (_) => MetadatenDialog(song: song), ); if (geaendert == true) onMetadataChanged(); }, child: Padding( padding: const EdgeInsets.all(6), child: Icon(Icons.edit, size: 14, color: MeloTheme.textSekundaer), ), ), InkWell( borderRadius: BorderRadius.circular(50), onTap: () { // Guard gegen null-ID (defensive) final id = song.id; if (id == null) return; showDialog( context: context, builder: (_) => TagAuswahlDialog( songId: id, songTitel: song.titel, onChanged: onMetadataChanged, ), ); }, child: Padding( padding: const EdgeInsets.all(6), child: const Icon(Icons.label_outline, size: 14, color: MeloTheme.textSekundaer), ), ), if (onAddToPlaylist != null) InkWell( borderRadius: BorderRadius.circular(50), onTap: () => onAddToPlaylist!(song), child: Padding( padding: const EdgeInsets.all(6), child: const Icon(Icons.playlist_add, size: 14, color: MeloTheme.textSekundaer), ), ), InkWell( borderRadius: BorderRadius.circular(50), onTap: () => onFavoriteToggle(song), child: Padding( padding: const EdgeInsets.all(6), child: Icon( istFavorit ? Icons.favorite : Icons.favorite_border, size: 16, color: MeloTheme.rot, ), ), ), Text(song.dauerFormatiert, style: const TextStyle(fontSize: 12, color: MeloTheme.textSekundaer)), ], ), onTap: hatDatei ? () => onPlay(song) : null, onLongPress: onDelete != null ? () { showModalBottomSheet( context: context, backgroundColor: MeloTheme.dunkel1, builder: (ctx) => SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: const Icon(Icons.edit, color: Colors.white), title: const Text('Bearbeiten', style: TextStyle(color: Colors.white)), onTap: () async { Navigator.pop(ctx); final geaendert = await showDialog( context: context, builder: (_) => MetadatenDialog(song: song), ); if (geaendert == true) onMetadataChanged(); }, ), ListTile( leading: const Icon(Icons.delete, color: Colors.red), title: const Text('Löschen', style: TextStyle(color: Colors.red)), onTap: () { Navigator.pop(ctx); onDelete!(song); }, ), ], ), ), ); } : null, ); } }