|
@@ -1,57 +1,94 @@
|
|
|
use super::song::Song;
|
|
|
use rand::seq::SliceRandom;
|
|
|
+use serenity::model::id::UserId;
|
|
|
+use std::collections::HashMap;
|
|
|
use std::{cmp::min, collections::VecDeque};
|
|
|
|
|
|
+#[derive(Clone)]
|
|
|
pub struct SongQueue {
|
|
|
- queue: VecDeque<Song>,
|
|
|
+ queues: HashMap<UserId, VecDeque<Song>>,
|
|
|
+ users: VecDeque<UserId>,
|
|
|
}
|
|
|
|
|
|
impl SongQueue {
|
|
|
pub fn new() -> SongQueue {
|
|
|
SongQueue {
|
|
|
- queue: VecDeque::new(),
|
|
|
+ queues: HashMap::new(),
|
|
|
+ users: VecDeque::new(),
|
|
|
}
|
|
|
}
|
|
|
- pub async fn push(&mut self, songs: Vec<Song>) {
|
|
|
- for item in songs.into_iter() {
|
|
|
- self.queue.push_back(item);
|
|
|
+ fn new_user_queue(&mut self, user: UserId) {
|
|
|
+ if self.queues.get(&user).is_none() {
|
|
|
+ self.queues.insert(user, VecDeque::new());
|
|
|
+ }
|
|
|
+ if !self.users.contains(&user) {
|
|
|
+ self.users.push_back(user);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pub fn push(&mut self, songs: Vec<Song>) {
|
|
|
+ for song in songs.into_iter() {
|
|
|
+ self.new_user_queue(song.queuer.id);
|
|
|
+ let deque = self.queues.get_mut(&song.queuer.id).unwrap();
|
|
|
+ deque.push_back(song);
|
|
|
}
|
|
|
}
|
|
|
- pub async fn pop(&mut self) -> Option<Song> {
|
|
|
- self.queue.pop_front()
|
|
|
+ pub fn pop(&mut self) -> Option<Song> {
|
|
|
+ let user = match self.users.pop_front() {
|
|
|
+ Some(user) => user,
|
|
|
+ None => return None,
|
|
|
+ };
|
|
|
+ let deque = self.queues.get_mut(&user).unwrap();
|
|
|
+ let song = deque.pop_front();
|
|
|
+ if deque.len() > 0 {
|
|
|
+ self.users.push_back(user);
|
|
|
+ }
|
|
|
+ song
|
|
|
}
|
|
|
- pub async fn shuffle(&mut self) -> Result<(), String> {
|
|
|
- if self.queue.len() == 0 {
|
|
|
+ pub fn shuffle(&mut self) -> Result<(), String> {
|
|
|
+ if self.users.len() == 0 {
|
|
|
return Err("queue is empty".to_string());
|
|
|
}
|
|
|
- self.queue
|
|
|
- .make_contiguous()
|
|
|
- .shuffle(&mut rand::thread_rng());
|
|
|
+ for deque in self.queues.values_mut() {
|
|
|
+ deque.make_contiguous().shuffle(&mut rand::thread_rng());
|
|
|
+ }
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
- pub async fn clear(&mut self) -> Result<(), String> {
|
|
|
- if self.queue.len() == 0 {
|
|
|
+ pub fn clear(&mut self) -> Result<(), String> {
|
|
|
+ if self.users.len() == 0 {
|
|
|
return Err("queue is empty".to_string());
|
|
|
};
|
|
|
- self.queue.clear();
|
|
|
+ self.queues.clear();
|
|
|
+ self.users.clear();
|
|
|
Ok(())
|
|
|
}
|
|
|
- pub async fn get_string(&self) -> String {
|
|
|
- if self.queue.len() == 0 {
|
|
|
+ pub fn get_string(&self) -> String {
|
|
|
+ if self.users.len() == 0 {
|
|
|
return "*empty*".to_string();
|
|
|
};
|
|
|
let mut s = String::new();
|
|
|
+ let queue = self.as_vec();
|
|
|
s.push_str(&format!(
|
|
|
"*Showing {} of {} songs*\n",
|
|
|
- min(20, self.queue.len()),
|
|
|
- self.queue.len()
|
|
|
+ min(20, queue.len()),
|
|
|
+ queue.len()
|
|
|
));
|
|
|
- for (i, song) in self.queue.iter().take(20).enumerate() {
|
|
|
- s += &format!("{}: ", i);
|
|
|
- s += &song.get_string().await;
|
|
|
- s += "\n";
|
|
|
+ for (i, song) in queue.iter().take(20).enumerate() {
|
|
|
+ s += &format!(
|
|
|
+ "{}: {} (queued by {})\n",
|
|
|
+ i + 1,
|
|
|
+ &song.get_string(),
|
|
|
+ song.queuer.name
|
|
|
+ );
|
|
|
}
|
|
|
s
|
|
|
}
|
|
|
+ fn as_vec(&self) -> Vec<Song> {
|
|
|
+ let mut clone = self.clone();
|
|
|
+ let mut queue = vec![];
|
|
|
+ while let Some(song) = clone.pop() {
|
|
|
+ queue.push(song);
|
|
|
+ }
|
|
|
+ queue
|
|
|
+ }
|
|
|
}
|