Skip to content

Commit

Permalink
Add ability to add to queue (#471)
Browse files Browse the repository at this point in the history
* Add ability to add to queue

* add ability to take queued song to other playlists, TODO: make it so it passes the song so it can be displayed in the corner

* Add to queue rework - Now queues are held

* Fix if switching contexts e.g: playing a different song from a different album, retains added queue.

* Change added_items to user_added_items, Lint using clippy.

* Linting done with format

* Var name to user_items

* Remove redundant comment

---------

Co-authored-by: SO9010 <SO9010sami@gmail.com>
  • Loading branch information
SO9010 and SO9010 authored Jun 17, 2024
1 parent fc74902 commit f9a54a6
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 7 deletions.
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
4 changes: 4 additions & 0 deletions 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 @@ -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
32 changes: 30 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>,
user_items: Vec<PlaybackItem>,
position: usize,
user_items_position: usize,
positions: Vec<usize>,
behavior: QueueBehavior,
}
Expand All @@ -27,7 +29,9 @@ impl Queue {
pub fn new() -> Self {
Self {
items: Vec::new(),
user_items: Vec::new(),
position: 0,
user_items_position: 0,
positions: Vec::new(),
behavior: QueueBehavior::default(),
}
Expand All @@ -46,6 +50,22 @@ impl Queue {
self.compute_positions();
}

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

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

pub fn set_behaviour(&mut self, behavior: QueueBehavior) {
self.behavior = behavior;
self.compute_positions();
Expand Down Expand Up @@ -81,10 +101,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 +116,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.user_items.first();
}
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
14 changes: 14 additions & 0 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,
}));
}

fn set_queue_behavior(&mut self, behavior: QueueBehavior) {
self.send(PlayerEvent::Command(PlayerCommand::SetQueueBehavior {
behavior: match behavior {
Expand Down Expand Up @@ -406,6 +412,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);
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
21 changes: 20 additions & 1 deletion 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,28 @@ impl AppState {

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

pub fn add_queued_entry(&mut self, queue_entry: QueueEntry) {
self.added_queue.push_back(queue_entry);
}

pub fn loading_playback(&mut self, item: Playable, origin: PlaybackOrigin) {
Expand Down
24 changes: 23 additions & 1 deletion psst-gui/src/ui/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ 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,
AppState, Library, Nav, PlaybackOrigin, PlaylistAddTrack, PlaylistRemoveTrack, QueueEntry,
RecommendationsRequest, Track,
},
ui::playlist,
Expand Down Expand Up @@ -323,6 +328,23 @@ 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

0 comments on commit f9a54a6

Please sign in to comment.