mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-16 09:05:16 +00:00
feat(queue): add track(s) for playing next (#460)
This commit is contained in:
parent
441b43bef6
commit
cac8ea6388
@ -75,4 +75,5 @@ abstract class SpotubeIcons {
|
|||||||
static const hoverOn = Icons.back_hand_rounded;
|
static const hoverOn = Icons.back_hand_rounded;
|
||||||
static const hoverOff = Icons.back_hand_outlined;
|
static const hoverOff = Icons.back_hand_outlined;
|
||||||
static const dragHandle = Icons.drag_indicator;
|
static const dragHandle = Icons.drag_indicator;
|
||||||
|
static const lightning = Icons.flash_on_rounded;
|
||||||
}
|
}
|
||||||
|
@ -310,27 +310,46 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
tooltip: "More options",
|
tooltip: "More options",
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
if (!playlistQueueNotifier.isTrackOnQueue(track.value))
|
if (!playlistQueueNotifier.isTrackOnQueue(track.value)) ...[
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
playlistQueueNotifier.add([track.value]);
|
playlistQueueNotifier.add([track.value]);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content:
|
content: Text(
|
||||||
Text("Added ${track.value.name} to queue"),
|
"Added ${track.value.name} to queue",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: const ListTile(
|
child: const ListTile(
|
||||||
leading: Icon(SpotubeIcons.queueAdd),
|
leading: Icon(SpotubeIcons.queueAdd),
|
||||||
title: Text("Add to queue"),
|
title: Text("Add to Queue"),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
|
||||||
else
|
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
playlistQueueNotifier.playNext([track.value]);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content:
|
||||||
|
Text("${track.value.name} will play next"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const ListTile(
|
||||||
|
leading: Icon(SpotubeIcons.lightning),
|
||||||
|
title: Text("Play next"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
] else
|
||||||
|
PopupMenuItem(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
onTap: playlist?.activeTrack.id == track.value.id
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
playlistQueueNotifier.remove([track.value]);
|
playlistQueueNotifier.remove([track.value]);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
@ -339,6 +358,7 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
enabled: playlist?.activeTrack.id != track.value.id,
|
||||||
child: const ListTile(
|
child: const ListTile(
|
||||||
leading: Icon(SpotubeIcons.queueRemove),
|
leading: Icon(SpotubeIcons.queueRemove),
|
||||||
title: Text("Remove from queue"),
|
title: Text("Remove from queue"),
|
||||||
|
@ -41,6 +41,7 @@ class TracksTableView extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(context, ref) {
|
Widget build(context, ref) {
|
||||||
final playlist = ref.watch(PlaylistQueueNotifier.provider);
|
final playlist = ref.watch(PlaylistQueueNotifier.provider);
|
||||||
|
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
|
||||||
final downloader = ref.watch(downloaderProvider);
|
final downloader = ref.watch(downloaderProvider);
|
||||||
TextStyle tableHeadStyle =
|
TextStyle tableHeadStyle =
|
||||||
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
||||||
@ -162,6 +163,32 @@ class TracksTableView extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
enabled: selectedTracks.isNotEmpty,
|
||||||
|
value: "add-to-queue",
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(SpotubeIcons.queueAdd),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(
|
||||||
|
"Add (${selectedTracks.length}) to Queue",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
enabled: selectedTracks.isNotEmpty,
|
||||||
|
value: "play-next",
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(SpotubeIcons.lightning),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(
|
||||||
|
"Play (${selectedTracks.length}) Next",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
onSelected: (action) async {
|
onSelected: (action) async {
|
||||||
@ -194,6 +221,20 @@ class TracksTableView extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "play-next":
|
||||||
|
{
|
||||||
|
playlistNotifier.playNext(selectedTracks.toList());
|
||||||
|
selected.value = [];
|
||||||
|
showCheck.value = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "add-to-queue":
|
||||||
|
{
|
||||||
|
playlistNotifier.add(selectedTracks.toList());
|
||||||
|
selected.value = [];
|
||||||
|
showCheck.value = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -266,6 +266,18 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void playNext(List<Track> tracks) {
|
||||||
|
if (!isLoaded) {
|
||||||
|
loadAndPlay(tracks);
|
||||||
|
} else {
|
||||||
|
final stateTracks = state!.tracks.toList();
|
||||||
|
|
||||||
|
stateTracks.insertAll(state!.active + 1, tracks);
|
||||||
|
|
||||||
|
state = state?.copyWith(tracks: Set.from(stateTracks));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void remove(List<Track> tracks) {
|
void remove(List<Track> tracks) {
|
||||||
if (!isLoaded) return;
|
if (!isLoaded) return;
|
||||||
final trackIds = tracks.map((e) => e.id!).toSet();
|
final trackIds = tracks.map((e) => e.id!).toSet();
|
||||||
|
Loading…
Reference in New Issue
Block a user