Skip to content

Commit

Permalink
feat(queue): add track(s) for playing next (#460)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingkor Roy Tirtho committed Apr 28, 2023
1 parent 441b43b commit cac8ea6
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 9 deletions.
1 change: 1 addition & 0 deletions lib/collections/spotube_icons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,5 @@ abstract class SpotubeIcons {
static const hoverOn = Icons.back_hand_rounded;
static const hoverOff = Icons.back_hand_outlined;
static const dragHandle = Icons.drag_indicator;
static const lightning = Icons.flash_on_rounded;
}
38 changes: 29 additions & 9 deletions lib/components/shared/track_table/track_tile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -310,35 +310,55 @@ class TrackTile extends HookConsumerWidget {
tooltip: "More options",
itemBuilder: (context) {
return [
if (!playlistQueueNotifier.isTrackOnQueue(track.value))
if (!playlistQueueNotifier.isTrackOnQueue(track.value)) ...[
PopupMenuItem(
padding: EdgeInsets.zero,
onTap: () {
playlistQueueNotifier.add([track.value]);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text("Added ${track.value.name} to queue"),
content: Text(
"Added ${track.value.name} to queue",
),
),
);
},
child: const ListTile(
leading: Icon(SpotubeIcons.queueAdd),
title: Text("Add to queue"),
title: Text("Add to Queue"),
),
)
else
),
PopupMenuItem(
padding: EdgeInsets.zero,
onTap: () {
playlistQueueNotifier.remove([track.value]);
playlistQueueNotifier.playNext([track.value]);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Removed ${track.value.name} from queue"),
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]);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Removed ${track.value.name} from queue"),
),
);
},
enabled: playlist?.activeTrack.id != track.value.id,
child: const ListTile(
leading: Icon(SpotubeIcons.queueRemove),
title: Text("Remove from queue"),
Expand Down
41 changes: 41 additions & 0 deletions lib/components/shared/track_table/tracks_table_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class TracksTableView extends HookConsumerWidget {
@override
Widget build(context, ref) {
final playlist = ref.watch(PlaylistQueueNotifier.provider);
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
final downloader = ref.watch(downloaderProvider);
TextStyle tableHeadStyle =
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -194,6 +221,20 @@ class TracksTableView extends HookConsumerWidget {
);
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:
}
},
Expand Down
12 changes: 12 additions & 0 deletions lib/provider/playlist_queue_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
if (!isLoaded) return;
final trackIds = tracks.map((e) => e.id!).toSet();
Expand Down

0 comments on commit cac8ea6

Please sign in to comment.