v2.48.4 — Als Nächstes abspielen (Play Next)

## SongTile
- Long-Press auf Song-Tile öffnet Kontextmenü (Bottom-Sheet):
  ▶ Als Nächstes abspielen + ⏭ Am Ende hinzufügen

## ViewModel
- spieleAlsNaechstes(Song) / amEndeHinzufuegen(Song) → PlayerService

## HomeScreen
- SongTile-Callbacks verdrahtet, SnackBar-Bestätigung bei beiden Aktionen

Keine neuen Packages, flutter analyze 0 Issues, Tests 4/4
This commit is contained in:
Dustin
2026-08-04 16:25:53 +02:00
parent 34ac791fa6
commit 82003c55d6
3 changed files with 63 additions and 0 deletions
+12
View File
@@ -388,6 +388,18 @@ class _MeloHomeState extends State<MeloHome> {
onPlay: _vm.spieleSong,
onMetadataChanged: _vm.ladeSongs,
onAddToPlaylist: _zeigeAddToPlaylist,
onSpieleAlsNaechstes: (song) {
_vm.spieleAlsNaechstes(song);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('▶ Als Nächstes: ${song.titel}')),
);
},
onAmEndeHinzufuegen: (song) {
_vm.amEndeHinzufuegen(song);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('→ Am Ende hinzugefügt: ${song.titel}')),
);
},
),
),
),
+6
View File
@@ -266,6 +266,12 @@ class MeloHomeViewModel extends ChangeNotifier {
player.spiele(song);
}
/// Fügt den Song direkt nach dem aktuellen in die Warteschlange ein
void spieleAlsNaechstes(Song song) => player.spieleAlsNaechstes(song);
/// Hängt den Song ans Ende der Warteschlange an
void amEndeHinzufuegen(Song song) => player.amEndeHinzufuegen(song);
@override
void dispose() {
_positionsSub?.cancel();
+45
View File
@@ -13,6 +13,8 @@ class SongTile extends StatelessWidget {
final VoidCallback onMetadataChanged;
final ValueChanged<Song>? onAddToPlaylist;
final ValueChanged<Song>? onErneutHerunterladen;
final ValueChanged<Song>? onSpieleAlsNaechstes;
final ValueChanged<Song>? onAmEndeHinzufuegen;
const SongTile({
super.key,
@@ -23,6 +25,8 @@ class SongTile extends StatelessWidget {
required this.onMetadataChanged,
this.onAddToPlaylist,
this.onErneutHerunterladen,
this.onSpieleAlsNaechstes,
this.onAmEndeHinzufuegen,
});
@override
@@ -130,6 +134,47 @@ class SongTile extends StatelessWidget {
],
),
onTap: hatDatei ? () => onPlay(song) : null,
onLongPress: (hatDatei && (onSpieleAlsNaechstes != null || onAmEndeHinzufuegen != null))
? () => _zeigeKontextMenu(context)
: null,
);
}
/// Kontextmenü per Long-Press: "Als Nächstes abspielen" + "Am Ende hinzufügen"
void _zeigeKontextMenu(BuildContext context) {
showModalBottomSheet(
context: context,
backgroundColor: MeloTheme.dunkel1,
builder: (ctx) => SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
leading: const Icon(Icons.playlist_play, color: MeloTheme.rot, size: 20),
title: const Text(
'Als Nächstes abspielen',
style: TextStyle(color: Colors.white, fontSize: 14),
),
onTap: () {
Navigator.pop(ctx);
onSpieleAlsNaechstes?.call(song);
},
),
if (onAmEndeHinzufuegen != null)
ListTile(
leading: const Icon(Icons.playlist_add, color: MeloTheme.rot, size: 20),
title: const Text(
'Am Ende hinzufügen',
style: TextStyle(color: Colors.white, fontSize: 14),
),
onTap: () {
Navigator.pop(ctx);
onAmEndeHinzufuegen!(song);
},
),
],
),
),
);
}
}