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

Feature: randomize queue #1270

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
11 changes: 6 additions & 5 deletions doc/users.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,12 @@ When pressing <kbd>O</kbd>:
| <kbd>Shift</kbd>+<kbd>X</kbd> | Copy the URL to the **currently playing track** to the system clipboard. |

### Queue
| Key | Command |
|------------------------------|--------------------------------------|
| <kbd>C</kbd> | Clear the entire queue. |
| <kbd>D</kbd> | Delete the currently selected track. |
| <kbd>Ctrl</kbd>+<kbd>S</kbd> | Save the current queue. |
| Key | Command |
|------------------------------|-----------------------------------------------------|
| <kbd>C</kbd> | Clear the entire queue. |
| <kbd>D</kbd> | Delete the currently selected track. |
| <kbd>Ctrl</kbd>+<kbd>S</kbd> | Save the current queue. |
| <kbd>Z</kbd> | Randomize the queue tracks (put into random order). |

### Library
| Key | Command |
Expand Down
4 changes: 4 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ pub enum Command {
VolumeDown(u16),
Repeat(Option<RepeatSetting>),
Shuffle(Option<bool>),
Randomize,
#[cfg(feature = "share_clipboard")]
Share(TargetMode),
Back,
Expand Down Expand Up @@ -220,6 +221,7 @@ impl fmt::Display for Command {
| Command::SaveQueue
| Command::Add
| Command::AddCurrent
| Command::Randomize
| Command::Delete
| Command::Back
| Command::Help
Expand Down Expand Up @@ -259,6 +261,7 @@ impl Command {
Command::VolumeDown(_) => "voldown",
Command::Repeat(_) => "repeat",
Command::Shuffle(_) => "shuffle",
Command::Randomize => "randomize",
#[cfg(feature = "share_clipboard")]
Command::Share(_) => "share",
Command::Back => "back",
Expand Down Expand Up @@ -547,6 +550,7 @@ pub fn parse(input: &str) -> Result<Vec<Command>, CommandParseError> {
}?;
Command::Shuffle(switch)
}
"randomize" => Command::Randomize,
#[cfg(feature = "share_clipboard")]
"share" => {
let &target_mode_raw = args.first().ok_or(InsufficientArgs {
Expand Down
5 changes: 5 additions & 0 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ impl CommandManager {
self.queue.set_shuffle(mode);
Ok(None)
}
Command::Randomize => {
self.queue.randomize();
Ok(None)
}
Command::Repeat(mode) => {
let mode = mode.unwrap_or_else(|| match self.queue.get_repeat() {
RepeatSetting::None => RepeatSetting::RepeatPlaylist,
Expand Down Expand Up @@ -452,6 +456,7 @@ impl CommandManager {

kb.insert("r".into(), vec![Command::Repeat(None)]);
kb.insert("z".into(), vec![Command::Shuffle(None)]);
kb.insert("Ctrl+z".into(), vec![Command::Randomize]);

#[cfg(feature = "share_clipboard")]
{
Expand Down
6 changes: 6 additions & 0 deletions src/mpris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ impl MprisPlayer {
self.event.trigger();
}

/*#[dbus_interface(property)]
fn randomize(&self, _b: bool) {
self.queue.randomize();
self.event.trigger();
}*/

#[dbus_interface(property)]
fn volume(&self) -> f64 {
self.spotify.volume() as f64 / 65535_f64
Expand Down
29 changes: 29 additions & 0 deletions src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,35 @@ impl Queue {
}
}

/// Randomize the queue ("shuffle" all the entries of the underlying Vec). Different from the `Shuffle`
/// option in that this actually changes the track positions in the queue (that gets displayed to the user),
/// but leaves the play order running from top to bottom. Useful If you want to shuffle a playlist,
/// but still want to add songs to be played next.
///
/// This deactivates `Shuffle`.
pub fn randomize(&self) {
// stop playlist, because we completely invalidate any playing order
let previous_playback_state = self.cfg.state().playback_state.clone();
self.stop();

// deactivate `Shuffle` feature, because it usually wouldn't make sense to use both
if self.get_shuffle() == true {
self.set_shuffle(false);
}

// permutate the queue Vec
let mut queue = self.queue.write().unwrap();
queue.shuffle(&mut thread_rng());

// resetting playing position to start of queue doesn't seem necessary
// my guess is that stop() does that

// resume playback if we were playing before
if previous_playback_state == PlaybackState::Playing {
self.toggleplayback();
}
}

/// Handle events that are specific to the queue.
pub fn handle_event(&self, event: QueueEvent) {
match event {
Expand Down