Add shuffle and repeat
This commit is contained in:
147
src/queue.rs
147
src/queue.rs
@@ -1,11 +1,22 @@
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use rand::prelude::*;
|
||||
|
||||
use spotify::Spotify;
|
||||
use track::Track;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum RepeatSetting {
|
||||
None,
|
||||
RepeatPlaylist,
|
||||
RepeatTrack,
|
||||
}
|
||||
|
||||
pub struct Queue {
|
||||
pub queue: Arc<RwLock<Vec<Track>>>,
|
||||
random_order: RwLock<Option<Vec<usize>>>,
|
||||
current_track: RwLock<Option<usize>>,
|
||||
repeat: RwLock<RepeatSetting>,
|
||||
spotify: Arc<Spotify>,
|
||||
}
|
||||
|
||||
@@ -14,15 +25,26 @@ impl Queue {
|
||||
Queue {
|
||||
queue: Arc::new(RwLock::new(Vec::new())),
|
||||
current_track: RwLock::new(None),
|
||||
repeat: RwLock::new(RepeatSetting::None),
|
||||
random_order: RwLock::new(None),
|
||||
spotify: spotify,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_index(&self) -> Option<usize> {
|
||||
match *self.current_track.read().unwrap() {
|
||||
Some(index) => {
|
||||
let next_index = index + 1;
|
||||
Some(mut index) => {
|
||||
let random_order = self.random_order.read().unwrap();
|
||||
if let Some(order) = random_order.as_ref() {
|
||||
index = order.iter().position(|&i| i == index).unwrap();
|
||||
}
|
||||
|
||||
let mut next_index = index + 1;
|
||||
if next_index < self.queue.read().unwrap().len() {
|
||||
if let Some(order) = random_order.as_ref() {
|
||||
next_index = order[next_index];
|
||||
}
|
||||
|
||||
Some(next_index)
|
||||
} else {
|
||||
None
|
||||
@@ -34,9 +56,19 @@ impl Queue {
|
||||
|
||||
pub fn previous_index(&self) -> Option<usize> {
|
||||
match *self.current_track.read().unwrap() {
|
||||
Some(index) => {
|
||||
Some(mut index) => {
|
||||
let random_order = self.random_order.read().unwrap();
|
||||
if let Some(order) = random_order.as_ref() {
|
||||
index = order.iter().position(|&i| i == index).unwrap();
|
||||
}
|
||||
|
||||
if index > 0 {
|
||||
Some(index - 1)
|
||||
let mut next_index = index - 1;
|
||||
if let Some(order) = random_order.as_ref() {
|
||||
next_index = order[next_index];
|
||||
}
|
||||
|
||||
Some(next_index)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -53,21 +85,38 @@ impl Queue {
|
||||
}
|
||||
|
||||
pub fn append(&self, track: &Track) {
|
||||
let mut random_order = self.random_order.write().unwrap();
|
||||
if let Some(order) = random_order.as_mut() {
|
||||
let index = order.len() - 1;
|
||||
order.push(index);
|
||||
}
|
||||
|
||||
let mut q = self.queue.write().unwrap();
|
||||
q.push(track.clone());
|
||||
}
|
||||
|
||||
pub fn append_next(&self, track: &Track) -> usize {
|
||||
let next = self.next_index();
|
||||
pub fn append_next(&self, tracks: Vec<&Track>) -> usize {
|
||||
let mut q = self.queue.write().unwrap();
|
||||
|
||||
if let Some(next_index) = next {
|
||||
q.insert(next_index, track.clone());
|
||||
next_index
|
||||
} else {
|
||||
q.push(track.clone());
|
||||
q.len() - 1
|
||||
{
|
||||
let mut random_order = self.random_order.write().unwrap();
|
||||
if let Some(order) = random_order.as_mut() {
|
||||
order.extend((q.len() - 1)..(q.len() + tracks.len()));
|
||||
}
|
||||
}
|
||||
|
||||
let first = match *self.current_track.read().unwrap() {
|
||||
Some(index) => index + 1,
|
||||
None => q.len()
|
||||
};
|
||||
|
||||
let mut i = first;
|
||||
for track in tracks {
|
||||
q.insert(i, track.clone());
|
||||
i += 1;
|
||||
}
|
||||
|
||||
first
|
||||
}
|
||||
|
||||
pub fn remove(&self, index: usize) {
|
||||
@@ -90,12 +139,14 @@ impl Queue {
|
||||
let current = *self.current_track.read().unwrap();
|
||||
if let Some(current_track) = current {
|
||||
if index == current_track {
|
||||
self.play(index);
|
||||
self.play(index, false);
|
||||
} else if index < current_track {
|
||||
let mut current = self.current_track.write().unwrap();
|
||||
current.replace(current_track - 1);
|
||||
}
|
||||
}
|
||||
|
||||
self.generate_random_order();
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
@@ -103,9 +154,12 @@ impl Queue {
|
||||
|
||||
let mut q = self.queue.write().unwrap();
|
||||
q.clear();
|
||||
|
||||
let mut random_order = self.random_order.write().unwrap();
|
||||
random_order.as_mut().map(|o| o.clear());
|
||||
}
|
||||
|
||||
pub fn play(&self, index: usize) {
|
||||
pub fn play(&self, index: usize, reshuffle: bool) {
|
||||
if let Some(track) = &self.queue.read().unwrap().get(index) {
|
||||
self.spotify.load(&track);
|
||||
let mut current = self.current_track.write().unwrap();
|
||||
@@ -113,6 +167,10 @@ impl Queue {
|
||||
self.spotify.play();
|
||||
self.spotify.update_track();
|
||||
}
|
||||
|
||||
if reshuffle {
|
||||
self.generate_random_order()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggleplayback(&self) {
|
||||
@@ -125,9 +183,20 @@ impl Queue {
|
||||
self.spotify.stop();
|
||||
}
|
||||
|
||||
pub fn next(&self) {
|
||||
if let Some(index) = self.next_index() {
|
||||
self.play(index);
|
||||
pub fn next(&self, manual: bool) {
|
||||
let q = self.queue.read().unwrap();
|
||||
let current = *self.current_track.read().unwrap();
|
||||
let repeat = *self.repeat.read().unwrap();
|
||||
|
||||
if repeat == RepeatSetting::RepeatTrack && !manual {
|
||||
if let Some(index) = current {
|
||||
self.play(index, false);
|
||||
}
|
||||
} else if let Some(index) = self.next_index() {
|
||||
self.play(index, false);
|
||||
} else if repeat == RepeatSetting::RepeatPlaylist && q.len() > 0 {
|
||||
let random_order = self.random_order.read().unwrap();
|
||||
self.play(random_order.as_ref().map(|o| o[0]).unwrap_or(0), false);
|
||||
} else {
|
||||
self.spotify.stop();
|
||||
}
|
||||
@@ -135,9 +204,51 @@ impl Queue {
|
||||
|
||||
pub fn previous(&self) {
|
||||
if let Some(index) = self.previous_index() {
|
||||
self.play(index);
|
||||
self.play(index, false);
|
||||
} else {
|
||||
self.spotify.stop();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_repeat(&self) -> RepeatSetting {
|
||||
let repeat = self.repeat.read().unwrap();
|
||||
*repeat
|
||||
}
|
||||
|
||||
pub fn set_repeat(&self, new: RepeatSetting) {
|
||||
let mut repeat = self.repeat.write().unwrap();
|
||||
*repeat = new;
|
||||
}
|
||||
|
||||
pub fn get_shuffle(&self) -> bool {
|
||||
let random_order = self.random_order.read().unwrap();
|
||||
random_order.is_some()
|
||||
}
|
||||
|
||||
fn generate_random_order(&self) {
|
||||
let q = self.queue.read().unwrap();
|
||||
let mut order: Vec<usize> = Vec::with_capacity(q.len());
|
||||
let mut random: Vec<usize> = (0..q.len()).collect();
|
||||
|
||||
if let Some(current) = *self.current_track.read().unwrap() {
|
||||
order.push(current);
|
||||
random.remove(current);
|
||||
}
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
random.shuffle(&mut rng);
|
||||
order.extend(random);
|
||||
|
||||
let mut random_order = self.random_order.write().unwrap();
|
||||
*random_order = Some(order);
|
||||
}
|
||||
|
||||
pub fn set_shuffle(&self, new: bool) {
|
||||
if new {
|
||||
self.generate_random_order();
|
||||
} else {
|
||||
let mut random_order = self.random_order.write().unwrap();
|
||||
*random_order = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user