Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to add to queue #471

Merged
merged 8 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ cargo bundle --release
- Reorder tracks
- Rename playlist
- Playlist folders
- [ ] Playback queue
- [x] Playback queue
- [ ] React to audio output device events
- Pause after disconnecting headphones
- Transfer playback after connecting headphones
Expand Down
6 changes: 5 additions & 1 deletion psst-core/src/player/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl Player {
PlayerCommand::Seek { position } => self.seek(position),
PlayerCommand::Configure { config } => self.configure(config),
PlayerCommand::SetQueueBehavior { behavior } => self.queue.set_behaviour(behavior),
PlayerCommand::AddToQueue { item } => self.queue.add(item),
PlayerCommand::SetVolume { volume } => self.set_volume(volume),
}
}
Expand Down Expand Up @@ -282,7 +283,7 @@ impl Player {
loading_handle,
};
}

SO9010 marked this conversation as resolved.
Show resolved Hide resolved
fn set_volume(&mut self, volume: f64) {
self.audio_output_sink.set_volume(volume as f32);
}
Expand Down Expand Up @@ -422,6 +423,9 @@ pub enum PlayerCommand {
SetQueueBehavior {
behavior: QueueBehavior,
},
AddToQueue{
item: PlaybackItem,
},
/// Change playback volume to a value in 0.0..=1.0 range.
SetVolume {
volume: f64,
Expand Down
33 changes: 31 additions & 2 deletions psst-core/src/player/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ impl Default for QueueBehavior {

pub struct Queue {
items: Vec<PlaybackItem>,
added_items: Vec<PlaybackItem>,
SO9010 marked this conversation as resolved.
Show resolved Hide resolved
position: usize,
added_items_position: usize,
positions: Vec<usize>,
behavior: QueueBehavior,
}
Expand All @@ -27,7 +29,9 @@ impl Queue {
pub fn new() -> Self {
Self {
items: Vec::new(),
added_items: Vec::new(),
position: 0,
added_items_position: 0,
positions: Vec::new(),
behavior: QueueBehavior::default(),
}
Expand All @@ -46,6 +50,23 @@ impl Queue {
self.compute_positions();
}

pub fn add(&mut self, item: PlaybackItem) {
self.added_items.push(item);
}

fn handle_added_queue(&mut self){
if self.added_items.len() > self.added_items_position {
self.items.insert(self.positions.len(), self.added_items[self.added_items_position]);
self.positions.insert(self.position + 1, self.positions.len());
self.added_items_position += 1;

if self.added_items_position > 2 {
self.added_items.remove(0);
self.added_items_position -= 1;
}
}
}
SO9010 marked this conversation as resolved.
Show resolved Hide resolved

pub fn set_behaviour(&mut self, behavior: QueueBehavior) {
self.behavior = behavior;
self.compute_positions();
Expand Down Expand Up @@ -81,10 +102,12 @@ impl Queue {
}

pub fn skip_to_next(&mut self) {
self.handle_added_queue();
self.position = self.next_position();
}

pub fn skip_to_following(&mut self) {
self.handle_added_queue();
self.position = self.following_position();
}

Expand All @@ -94,8 +117,14 @@ impl Queue {
}

pub fn get_following(&self) -> Option<&PlaybackItem> {
let position = self.positions.get(self.following_position()).copied()?;
self.items.get(position)
if let Some(position) = self.positions.get(self.position).copied() {
if let Some(item) = self.items.get(position) {
return Some(item);
}
} else {
return self.added_items.get(0);
}
None
}

fn previous_position(&self) -> usize {
Expand Down
5 changes: 3 additions & 2 deletions psst-gui/src/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::time::Duration;

use druid::{Selector, WidgetId};
use psst_core::item_id::ItemId;
use psst_core::{item_id::ItemId, player::item::PlaybackItem};

use crate::{
data::{Nav, PlaybackPayload, QueueBehavior},
data::{Nav, PlaybackPayload, QueueBehavior, QueueEntry},
ui::find::Find,
};

Expand Down Expand Up @@ -56,6 +56,7 @@ pub const PLAY_PAUSE: Selector = Selector::new("app.play-pause");
pub const PLAY_RESUME: Selector = Selector::new("app.play-resume");
pub const PLAY_NEXT: Selector = Selector::new("app.play-next");
pub const PLAY_STOP: Selector = Selector::new("app.play-stop");
pub const ADD_TO_QUEUE: Selector<(QueueEntry, PlaybackItem)> = Selector::new("app.add-to-queue");
pub const PLAY_QUEUE_BEHAVIOR: Selector<QueueBehavior> = Selector::new("app.play-queue-behavior");
pub const PLAY_SEEK: Selector<f64> = Selector::new("app.play-seek");

Expand Down
19 changes: 17 additions & 2 deletions psst-gui/src/controller/playback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,12 @@ impl PlaybackController {
self.send(PlayerEvent::Command(PlayerCommand::SetVolume { volume }));
}

fn add_to_queue(&mut self, item: &PlaybackItem) {
self.send(PlayerEvent::Command(PlayerCommand::AddToQueue {
item: item.clone(),
}));
}

fn set_queue_behavior(&mut self, behavior: QueueBehavior) {
self.send(PlayerEvent::Command(PlayerCommand::SetQueueBehavior {
behavior: match behavior {
Expand All @@ -310,7 +316,7 @@ impl<W> Controller<AppState, W> for PlaybackController
where
W: Widget<AppState>,
{
fn event(
fn event(
&mut self,
child: &mut W,
ctx: &mut EventCtx,
Expand Down Expand Up @@ -342,7 +348,8 @@ where
data.start_playback(queued.item, queued.origin, progress.to_owned());
self.update_media_control_playback(&data.playback);
self.update_media_control_metadata(&data.playback);
} else {
}
SO9010 marked this conversation as resolved.
Show resolved Hide resolved
else {
log::warn!("played item not found in playback queue");
}
ctx.set_handled();
Expand Down Expand Up @@ -406,6 +413,14 @@ where
self.stop();
ctx.set_handled();
}
Event::Command(cmd) if cmd.is(cmd::ADD_TO_QUEUE) => {
log::info!("adding to queue");
let (entry, item) = cmd.get_unchecked(cmd::ADD_TO_QUEUE);

self.add_to_queue(&item.to_owned());
data.add_queued_entry(entry.clone());
ctx.set_handled();
}
Event::Command(cmd) if cmd.is(cmd::PLAY_QUEUE_BEHAVIOR) => {
let behavior = cmd.get_unchecked(cmd::PLAY_QUEUE_BEHAVIOR);
data.set_queue_behavior(behavior.to_owned());
Expand Down
20 changes: 15 additions & 5 deletions psst-gui/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub struct AppState {
pub personalized: Personalized,
pub alerts: Vector<Alert>,
pub finder: Finder,
pub added_queue: Vector<QueueEntry>,
}

impl AppState {
Expand Down Expand Up @@ -118,6 +119,7 @@ impl AppState {
cache_size: Promise::Empty,
},
playback,
added_queue: Vector::new(),
search: Search {
input: "".into(),
results: Promise::Empty,
Expand Down Expand Up @@ -180,11 +182,19 @@ impl AppState {

impl AppState {
pub fn queued_entry(&self, item_id: ItemId) -> Option<QueueEntry> {
self.playback
.queue
.iter()
.find(|queued| queued.item.id() == item_id)
.cloned()
if let Some(queued) = self.playback.queue.iter().find(|queued| queued.item.id() == item_id).cloned() {
return Some(queued);
} else if let Some(queued) = self.added_queue.iter().find(|queued| queued.item.id() == item_id).cloned() {
return Some(queued);
} else {
None
}
}
SO9010 marked this conversation as resolved.
Show resolved Hide resolved

pub fn add_queued_entry(&mut self, queue_entry: QueueEntry) {
// it still gets updated and wiped when playlsit changes
self.added_queue.push_back(queue_entry);

}

pub fn loading_playback(&mut self, item: Playable, origin: PlaybackOrigin) {
Expand Down
15 changes: 13 additions & 2 deletions psst-gui/src/ui/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use druid::{
widget::{CrossAxisAlignment, Either, Flex, Label, ViewSwitcher},
LensExt, LocalizedString, Menu, MenuItem, Size, TextAlignment, Widget, WidgetExt,
};
use psst_core::{audio::normalize::NormalizationLevel, item_id::{ItemId, ItemIdType}, player::item::PlaybackItem};

use crate::{
cmd,
data::{
AppState, Library, Nav, PlaybackOrigin, PlaylistAddTrack, PlaylistRemoveTrack,
RecommendationsRequest, Track,
AppState, Library, Nav, PlaybackOrigin, PlaylistAddTrack, PlaylistRemoveTrack, QueueEntry, RecommendationsRequest, Track
},
ui::playlist,
widget::{icons, Empty, MyWidgetExt, RemoteImage},
Expand Down Expand Up @@ -323,6 +323,17 @@ pub fn track_menu(
}
}

menu = menu.entry(
MenuItem::new(
LocalizedString::new("menu-item-add-to-queue").with_placeholder("Add Track To Queue"),
)
//PlayerCommand
.command(cmd::ADD_TO_QUEUE.with((QueueEntry {item: crate::ui::Playable::Track(track.clone()), origin: origin.clone()}, PlaybackItem{
item_id: ItemId::from_base62(&String::from(track.id), ItemIdType::Track).unwrap(),
norm_level: NormalizationLevel::Track,
}))),
);

let mut playlist_menu = Menu::new(
LocalizedString::new("menu-item-add-to-playlist").with_placeholder("Add to Playlist"),
);
Expand Down