mirror of
				https://github.com/Dummi26/musicdb.git
				synced 2025-11-04 05:16:17 +01:00 
			
		
		
		
	fix shuffle not shuffling away first element
and fix dragging selected song not dragging all selected elements but rather only those that pass current filter/search, which was not intended.
This commit is contained in:
		
							parent
							
								
									7f33d2daf8
								
							
						
					
					
						commit
						8a9ee5c9cf
					
				@ -1106,6 +1106,8 @@ impl Gui {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            GuiAction::SendToServer(cmd) => {
 | 
			
		||||
                #[cfg(debug_assertions)]
 | 
			
		||||
                eprintln!("[DEBUG] Sending command to server: {cmd:?}");
 | 
			
		||||
                if let Err(e) = cmd.to_bytes(&mut self.connection) {
 | 
			
		||||
                    eprintln!("Error sending command to server: {e}");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -2157,7 +2157,7 @@ mod selected {
 | 
			
		||||
            let lock = self.0.lock().unwrap();
 | 
			
		||||
            let (sel_artists, sel_albums, sel_songs) = &*lock;
 | 
			
		||||
            let mut out = vec![];
 | 
			
		||||
            for (artist, singles, albums, _) in &lb.library_filtered {
 | 
			
		||||
            for (artist, singles, albums) in &lb.library_sorted {
 | 
			
		||||
                let artist_selected = sel_artists.contains(artist);
 | 
			
		||||
                let mut local_artist_owned = vec![];
 | 
			
		||||
                let mut local_artist = if artist_selected {
 | 
			
		||||
@ -2165,13 +2165,13 @@ mod selected {
 | 
			
		||||
                } else {
 | 
			
		||||
                    &mut out
 | 
			
		||||
                };
 | 
			
		||||
                for (song, _) in singles {
 | 
			
		||||
                for song in singles {
 | 
			
		||||
                    let song_selected = sel_songs.contains(song);
 | 
			
		||||
                    if song_selected {
 | 
			
		||||
                        local_artist.push(QueueContent::Song(*song).into());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                for (album, songs, _) in albums {
 | 
			
		||||
                for (album, songs) in albums {
 | 
			
		||||
                    let album_selected = sel_albums.contains(album);
 | 
			
		||||
                    let mut local_album_owned = vec![];
 | 
			
		||||
                    let local_album = if album_selected {
 | 
			
		||||
@ -2179,7 +2179,7 @@ mod selected {
 | 
			
		||||
                    } else {
 | 
			
		||||
                        &mut local_artist
 | 
			
		||||
                    };
 | 
			
		||||
                    for (song, _) in songs {
 | 
			
		||||
                    for song in songs {
 | 
			
		||||
                        let song_selected = sel_songs.contains(song);
 | 
			
		||||
                        if song_selected {
 | 
			
		||||
                            local_album.push(QueueContent::Song(*song).into());
 | 
			
		||||
 | 
			
		||||
@ -408,7 +408,7 @@ impl GuiElem for QueueEmptySpaceDragHandler {
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
    fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
 | 
			
		||||
        dragged_add_to_queue(dragged, |q, _| Command::QueueAdd(vec![], q))
 | 
			
		||||
        dragged_add_to_queue(dragged, |q| Command::QueueAdd(vec![], q))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -623,9 +623,9 @@ impl GuiElem for QueueSong {
 | 
			
		||||
        if !self.always_copy {
 | 
			
		||||
            let mut p = self.path.clone();
 | 
			
		||||
            let insert_below = self.insert_below;
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q, i| {
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q| {
 | 
			
		||||
                if let Some(j) = p.pop() {
 | 
			
		||||
                    Command::QueueInsert(p.clone(), if insert_below { j + 1 } else { j } + i, q)
 | 
			
		||||
                    Command::QueueInsert(p.clone(), if insert_below { j + 1 } else { j }, q)
 | 
			
		||||
                } else {
 | 
			
		||||
                    Command::QueueAdd(p.clone(), q)
 | 
			
		||||
                }
 | 
			
		||||
@ -782,13 +782,11 @@ impl GuiElem for QueueFolder {
 | 
			
		||||
        if !self.always_copy {
 | 
			
		||||
            if self.insert_into {
 | 
			
		||||
                let p = self.path.clone();
 | 
			
		||||
                dragged_add_to_queue(dragged, move |q, _| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
                dragged_add_to_queue(dragged, move |q| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
            } else {
 | 
			
		||||
                let mut p = self.path.clone();
 | 
			
		||||
                let j = p.pop().unwrap_or(0);
 | 
			
		||||
                dragged_add_to_queue(dragged, move |q, i| {
 | 
			
		||||
                    Command::QueueInsert(p.clone(), j + i, q)
 | 
			
		||||
                })
 | 
			
		||||
                dragged_add_to_queue(dragged, move |q| Command::QueueInsert(p.clone(), j, q))
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            vec![]
 | 
			
		||||
@ -850,9 +848,7 @@ impl GuiElem for QueueIndentEnd {
 | 
			
		||||
    }
 | 
			
		||||
    fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
 | 
			
		||||
        let (p, j) = self.path_insert.clone();
 | 
			
		||||
        dragged_add_to_queue(dragged, move |q, i| {
 | 
			
		||||
            Command::QueueInsert(p.clone(), j + i, q)
 | 
			
		||||
        })
 | 
			
		||||
        dragged_add_to_queue(dragged, move |q| Command::QueueInsert(p.clone(), j, q))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1004,7 +1000,7 @@ impl GuiElem for QueueLoop {
 | 
			
		||||
        if !self.always_copy {
 | 
			
		||||
            let mut p = self.path.clone();
 | 
			
		||||
            p.push(0);
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q, _| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
        } else {
 | 
			
		||||
            vec![]
 | 
			
		||||
        }
 | 
			
		||||
@ -1130,7 +1126,7 @@ impl GuiElem for QueueRandom {
 | 
			
		||||
    fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
 | 
			
		||||
        if !self.always_copy {
 | 
			
		||||
            let p = self.path.clone();
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q, _| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
        } else {
 | 
			
		||||
            vec![]
 | 
			
		||||
        }
 | 
			
		||||
@ -1257,22 +1253,22 @@ impl GuiElem for QueueShuffle {
 | 
			
		||||
        if !self.always_copy {
 | 
			
		||||
            let mut p = self.path.clone();
 | 
			
		||||
            p.push(0);
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q, _| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
            dragged_add_to_queue(dragged, move |q| Command::QueueAdd(p.clone(), q))
 | 
			
		||||
        } else {
 | 
			
		||||
            vec![]
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn dragged_add_to_queue<F: FnMut(Queue, usize) -> Command + 'static>(
 | 
			
		||||
fn dragged_add_to_queue<F: FnOnce(Vec<Queue>) -> Command + 'static>(
 | 
			
		||||
    dragged: Dragging,
 | 
			
		||||
    mut f: F,
 | 
			
		||||
    f: F,
 | 
			
		||||
) -> Vec<GuiAction> {
 | 
			
		||||
    match dragged {
 | 
			
		||||
        Dragging::Artist(id) => {
 | 
			
		||||
            vec![GuiAction::Build(Box::new(move |db| {
 | 
			
		||||
                if let Some(q) = add_to_queue_artist_by_id(id, db) {
 | 
			
		||||
                    vec![GuiAction::SendToServer(f(q, 0))]
 | 
			
		||||
                    vec![GuiAction::SendToServer(f(vec![q]))]
 | 
			
		||||
                } else {
 | 
			
		||||
                    vec![]
 | 
			
		||||
                }
 | 
			
		||||
@ -1281,7 +1277,7 @@ fn dragged_add_to_queue<F: FnMut(Queue, usize) -> Command + 'static>(
 | 
			
		||||
        Dragging::Album(id) => {
 | 
			
		||||
            vec![GuiAction::Build(Box::new(move |db| {
 | 
			
		||||
                if let Some(q) = add_to_queue_album_by_id(id, db) {
 | 
			
		||||
                    vec![GuiAction::SendToServer(f(q, 0))]
 | 
			
		||||
                    vec![GuiAction::SendToServer(f(vec![q]))]
 | 
			
		||||
                } else {
 | 
			
		||||
                    vec![]
 | 
			
		||||
                }
 | 
			
		||||
@ -1289,16 +1285,12 @@ fn dragged_add_to_queue<F: FnMut(Queue, usize) -> Command + 'static>(
 | 
			
		||||
        }
 | 
			
		||||
        Dragging::Song(id) => {
 | 
			
		||||
            let q = QueueContent::Song(id).into();
 | 
			
		||||
            vec![GuiAction::SendToServer(f(q, 0))]
 | 
			
		||||
            vec![GuiAction::SendToServer(f(vec![q]))]
 | 
			
		||||
        }
 | 
			
		||||
        Dragging::Queue(q) => {
 | 
			
		||||
            vec![GuiAction::SendToServer(f(q, 0))]
 | 
			
		||||
            vec![GuiAction::SendToServer(f(vec![q]))]
 | 
			
		||||
        }
 | 
			
		||||
        Dragging::Queues(q) => q
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .enumerate()
 | 
			
		||||
            .map(|(i, q)| GuiAction::SendToServer(f(q, i)))
 | 
			
		||||
            .collect(),
 | 
			
		||||
        Dragging::Queues(q) => vec![GuiAction::SendToServer(f(q))],
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ edition = "2021"
 | 
			
		||||
[dependencies]
 | 
			
		||||
awedio = { version = "0.2.0", optional = true }
 | 
			
		||||
base64 = "0.21.2"
 | 
			
		||||
colorize = "0.1.0"
 | 
			
		||||
rand = "0.8.5"
 | 
			
		||||
rc-u8-reader = "2.0.16"
 | 
			
		||||
tokio = { version = "1.29.1", features = ["sync"] }
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,8 @@ use std::{
 | 
			
		||||
    time::{Duration, Instant},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use colorize::AnsiColor;
 | 
			
		||||
 | 
			
		||||
use crate::{load::ToFromBytes, server::Command};
 | 
			
		||||
 | 
			
		||||
use super::{
 | 
			
		||||
@ -263,7 +265,7 @@ impl Database {
 | 
			
		||||
            }
 | 
			
		||||
            Command::Save => {
 | 
			
		||||
                if let Err(e) = self.save_database(None) {
 | 
			
		||||
                    eprintln!("Couldn't save: {e}");
 | 
			
		||||
                    eprintln!("[{}] Couldn't save: {e}", "ERR!".red());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Command::SyncDatabase(a, b, c) => self.sync(a, b, c),
 | 
			
		||||
@ -274,28 +276,17 @@ impl Database {
 | 
			
		||||
                }
 | 
			
		||||
                Queue::handle_actions(self, actions);
 | 
			
		||||
            }
 | 
			
		||||
            Command::QueueAdd(mut index, new_data) => {
 | 
			
		||||
            Command::QueueAdd(index, new_data) => {
 | 
			
		||||
                let mut actions = vec![];
 | 
			
		||||
                if let Some(v) = self.queue.get_item_at_index_mut(&index, 0, &mut actions) {
 | 
			
		||||
                    if let Some(i) = v.add_to_end(new_data) {
 | 
			
		||||
                        index.push(i);
 | 
			
		||||
                        if let Some(q) = self.queue.get_item_at_index_mut(&index, 0, &mut actions) {
 | 
			
		||||
                            let mut actions = Vec::new();
 | 
			
		||||
                            q.init(index, &mut actions);
 | 
			
		||||
                            Queue::handle_actions(self, actions);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    v.add_to_end(new_data, index, &mut actions);
 | 
			
		||||
                }
 | 
			
		||||
                Queue::handle_actions(self, actions);
 | 
			
		||||
            }
 | 
			
		||||
            Command::QueueInsert(mut index, pos, mut new_data) => {
 | 
			
		||||
            Command::QueueInsert(index, pos, new_data) => {
 | 
			
		||||
                let mut actions = vec![];
 | 
			
		||||
                if let Some(v) = self.queue.get_item_at_index_mut(&index, 0, &mut actions) {
 | 
			
		||||
                    index.push(pos);
 | 
			
		||||
                    let mut actions = Vec::new();
 | 
			
		||||
                    new_data.init(index, &mut actions);
 | 
			
		||||
                    v.insert(new_data, pos);
 | 
			
		||||
                    Queue::handle_actions(self, actions);
 | 
			
		||||
                    v.insert(new_data, pos, index, &mut actions);
 | 
			
		||||
                }
 | 
			
		||||
                Queue::handle_actions(self, actions);
 | 
			
		||||
            }
 | 
			
		||||
@ -316,7 +307,7 @@ impl Database {
 | 
			
		||||
                                if let Some(a) = o.get_mut(i).and_then(Option::take) {
 | 
			
		||||
                                    v.push(a);
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    eprintln!("[warn] Can't properly apply requested order to Queue/Shuffle: no element at index {i}. Index may be out of bounds or used twice. Len: {}, Order: {order:?}.", v.len());
 | 
			
		||||
                                    eprintln!("[{}] Can't properly apply requested order to Queue/Shuffle: no element at index {i}. Index may be out of bounds or used twice. Len: {}, Order: {order:?}.", "WARN".yellow(), v.len());
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
@ -327,7 +318,10 @@ impl Database {
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    eprintln!("[warn] can't QueueSetShuffle - no element at path {path:?}");
 | 
			
		||||
                    eprintln!(
 | 
			
		||||
                        "[{}] can't QueueSetShuffle - no element at path {path:?}",
 | 
			
		||||
                        "WARN".yellow()
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                Queue::handle_actions(self, actions);
 | 
			
		||||
            }
 | 
			
		||||
@ -365,42 +359,42 @@ impl Database {
 | 
			
		||||
                        v.general.tags.push(tag);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            }
 | 
			
		||||
            Command::TagSongFlagUnset(id, tag) => {
 | 
			
		||||
                if let Some(v) = self.get_song_mut(&id) {
 | 
			
		||||
                    if let Some(i) = v.general.tags.iter().position(|v| v == &tag) {
 | 
			
		||||
                        v.general.tags.remove(i);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            }
 | 
			
		||||
            Command::TagAlbumFlagSet(id, tag) => {
 | 
			
		||||
                if let Some(v) = self.albums.get_mut(&id) {
 | 
			
		||||
                    if !v.general.tags.contains(&tag) {
 | 
			
		||||
                        v.general.tags.push(tag);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            }
 | 
			
		||||
            Command::TagAlbumFlagUnset(id, tag) => {
 | 
			
		||||
                if let Some(v) = self.albums.get_mut(&id) {
 | 
			
		||||
                    if let Some(i) = v.general.tags.iter().position(|v| v == &tag) {
 | 
			
		||||
                        v.general.tags.remove(i);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            }
 | 
			
		||||
            Command::TagArtistFlagSet(id, tag) => {
 | 
			
		||||
                if let Some(v) = self.artists.get_mut(&id) {
 | 
			
		||||
                    if !v.general.tags.contains(&tag) {
 | 
			
		||||
                        v.general.tags.push(tag);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            }
 | 
			
		||||
            Command::TagArtistFlagUnset(id, tag) => {
 | 
			
		||||
                if let Some(v) = self.artists.get_mut(&id) {
 | 
			
		||||
                    if let Some(i) = v.general.tags.iter().position(|v| v == &tag) {
 | 
			
		||||
                        v.general.tags.remove(i);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            }
 | 
			
		||||
            Command::TagSongPropertySet(id, key, val) => {
 | 
			
		||||
                if let Some(v) = self.get_song_mut(&id) {
 | 
			
		||||
                    let new = format!("{key}{val}");
 | 
			
		||||
@ -507,8 +501,8 @@ impl Database {
 | 
			
		||||
    }
 | 
			
		||||
    pub fn load_database(path: PathBuf, lib_directory: PathBuf) -> Result<Self, std::io::Error> {
 | 
			
		||||
        let mut file = BufReader::new(File::open(&path)?);
 | 
			
		||||
        eprintln!("[info] loading library from {file:?}");
 | 
			
		||||
        Ok(Self {
 | 
			
		||||
        eprintln!("[{}] loading library from {file:?}", "INFO".cyan());
 | 
			
		||||
        let s = Self {
 | 
			
		||||
            db_file: path,
 | 
			
		||||
            lib_directory,
 | 
			
		||||
            artists: ToFromBytes::from_bytes(&mut file)?,
 | 
			
		||||
@ -524,7 +518,9 @@ impl Database {
 | 
			
		||||
            command_sender: None,
 | 
			
		||||
            remote_server_as_song_file_source: None,
 | 
			
		||||
            client_is_init: false,
 | 
			
		||||
        })
 | 
			
		||||
        };
 | 
			
		||||
        eprintln!("[{}] loaded library", "INFO".green());
 | 
			
		||||
        Ok(s)
 | 
			
		||||
    }
 | 
			
		||||
    /// saves the database's contents. save path can be overridden
 | 
			
		||||
    pub fn save_database(&self, path: Option<PathBuf>) -> Result<PathBuf, std::io::Error> {
 | 
			
		||||
@ -537,7 +533,7 @@ impl Database {
 | 
			
		||||
        if path.as_os_str().is_empty() {
 | 
			
		||||
            return Ok(path);
 | 
			
		||||
        }
 | 
			
		||||
        eprintln!("[info] saving db to {path:?}.");
 | 
			
		||||
        eprintln!("[{}] saving db to {path:?}", "INFO".cyan());
 | 
			
		||||
        let mut file = fs::OpenOptions::new()
 | 
			
		||||
            .write(true)
 | 
			
		||||
            .truncate(true)
 | 
			
		||||
@ -547,6 +543,7 @@ impl Database {
 | 
			
		||||
        self.albums.to_bytes(&mut file)?;
 | 
			
		||||
        self.songs.to_bytes(&mut file)?;
 | 
			
		||||
        self.covers.to_bytes(&mut file)?;
 | 
			
		||||
        eprintln!("[{}] saved db", "INFO".green());
 | 
			
		||||
        Ok(path)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn broadcast_update(&mut self, update: &Command) {
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,7 @@ pub enum ShuffleState {
 | 
			
		||||
 | 
			
		||||
pub enum QueueAction {
 | 
			
		||||
    AddRandomSong(Vec<usize>),
 | 
			
		||||
    /// `partial: bool`, if true, indicates that we only shuffle what is beyond the current index
 | 
			
		||||
    SetShuffle(Vec<usize>, bool),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,30 +46,64 @@ impl Queue {
 | 
			
		||||
        &mut self.content
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn add_to_end(&mut self, v: Self) -> Option<usize> {
 | 
			
		||||
    pub fn add_to_end(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        v: Vec<Self>,
 | 
			
		||||
        mut path: Vec<usize>,
 | 
			
		||||
        actions: &mut Vec<QueueAction>,
 | 
			
		||||
    ) -> Option<usize> {
 | 
			
		||||
        match &mut self.content {
 | 
			
		||||
            QueueContent::Song(_) => None,
 | 
			
		||||
            QueueContent::Folder(_, vec, _) => {
 | 
			
		||||
                let len = vec.len();
 | 
			
		||||
                for (i, mut v) in v.into_iter().enumerate() {
 | 
			
		||||
                    path.push(len + i);
 | 
			
		||||
                    v.init(path.clone(), actions);
 | 
			
		||||
                    vec.push(v);
 | 
			
		||||
                Some(vec.len() - 1)
 | 
			
		||||
                    path.pop();
 | 
			
		||||
                }
 | 
			
		||||
                Some(len)
 | 
			
		||||
            }
 | 
			
		||||
            QueueContent::Loop(..) => None,
 | 
			
		||||
            QueueContent::Random(q) => {
 | 
			
		||||
                // insert new elements
 | 
			
		||||
                let len = q.len();
 | 
			
		||||
                for (i, mut v) in v.into_iter().enumerate() {
 | 
			
		||||
                    path.push(len + i);
 | 
			
		||||
                    v.init(path.clone(), actions);
 | 
			
		||||
                    q.push_back(v);
 | 
			
		||||
                Some(q.len() - 1)
 | 
			
		||||
                    path.pop();
 | 
			
		||||
                }
 | 
			
		||||
                Some(len)
 | 
			
		||||
            }
 | 
			
		||||
            QueueContent::Shuffle { .. } => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn insert(&mut self, v: Self, index: usize) -> bool {
 | 
			
		||||
    pub fn insert(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        v: Vec<Self>,
 | 
			
		||||
        index: usize,
 | 
			
		||||
        mut path: Vec<usize>,
 | 
			
		||||
        actions: &mut Vec<QueueAction>,
 | 
			
		||||
    ) -> bool {
 | 
			
		||||
        match &mut self.content {
 | 
			
		||||
            QueueContent::Song(_) => false,
 | 
			
		||||
            QueueContent::Folder(current, vec, _) => {
 | 
			
		||||
                if index <= vec.len() {
 | 
			
		||||
                    if *current >= index {
 | 
			
		||||
                        *current += 1;
 | 
			
		||||
                        *current += v.len();
 | 
			
		||||
                    }
 | 
			
		||||
                    vec.insert(index, v);
 | 
			
		||||
                    // remove the elements starting at the insertion point
 | 
			
		||||
                    let end = vec.split_off(index);
 | 
			
		||||
                    // insert new elements
 | 
			
		||||
                    for (i, mut v) in v.into_iter().enumerate() {
 | 
			
		||||
                        path.push(index + i);
 | 
			
		||||
                        v.init(path.clone(), actions);
 | 
			
		||||
                        vec.push(v);
 | 
			
		||||
                        path.pop();
 | 
			
		||||
                    }
 | 
			
		||||
                    // re-add previously removed elements
 | 
			
		||||
                    vec.extend(end);
 | 
			
		||||
                    true
 | 
			
		||||
                } else {
 | 
			
		||||
                    false
 | 
			
		||||
@ -268,7 +303,9 @@ impl Queue {
 | 
			
		||||
            QueueContent::Shuffle { inner, state } => {
 | 
			
		||||
                let mut p = path.clone();
 | 
			
		||||
                p.push(0);
 | 
			
		||||
                if matches!(state, ShuffleState::NotShuffled | ShuffleState::Modified) {
 | 
			
		||||
                if inner.len() == 0 {
 | 
			
		||||
                    *state = ShuffleState::NotShuffled;
 | 
			
		||||
                } else if matches!(state, ShuffleState::NotShuffled | ShuffleState::Modified) {
 | 
			
		||||
                    actions.push(QueueAction::SetShuffle(
 | 
			
		||||
                        path,
 | 
			
		||||
                        matches!(state, ShuffleState::Modified),
 | 
			
		||||
@ -287,7 +324,7 @@ impl Queue {
 | 
			
		||||
                        if let Some(song) = db.songs().keys().choose(&mut rand::thread_rng()) {
 | 
			
		||||
                            db.apply_command(Command::QueueAdd(
 | 
			
		||||
                                path,
 | 
			
		||||
                                QueueContent::Song(*song).into(),
 | 
			
		||||
                                vec![QueueContent::Song(*song).into()],
 | 
			
		||||
                            ));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@ -394,6 +431,7 @@ impl Queue {
 | 
			
		||||
                let mut p = path.clone();
 | 
			
		||||
                p.push(0);
 | 
			
		||||
                if !inner.advance_index_inner(p, actions) {
 | 
			
		||||
                    // end of inner Folder element, reshuffle for next time
 | 
			
		||||
                    *state = ShuffleState::Shuffled;
 | 
			
		||||
                    actions.push(QueueAction::SetShuffle(path, false));
 | 
			
		||||
                    false
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,8 @@ use std::{
 | 
			
		||||
    thread::JoinHandle,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use colorize::AnsiColor;
 | 
			
		||||
 | 
			
		||||
use crate::load::ToFromBytes;
 | 
			
		||||
 | 
			
		||||
use super::{
 | 
			
		||||
@ -139,20 +141,20 @@ impl Song {
 | 
			
		||||
    ) -> Option<Vec<u8>> {
 | 
			
		||||
        match src {
 | 
			
		||||
            Ok(path) => {
 | 
			
		||||
                eprintln!("[info] loading song from {:?}", path);
 | 
			
		||||
                eprintln!("[{}] loading song from {:?}", "INFO".cyan(), path);
 | 
			
		||||
                match std::fs::read(&path) {
 | 
			
		||||
                    Ok(v) => {
 | 
			
		||||
                        eprintln!("[info] loaded song from {:?}", path);
 | 
			
		||||
                        eprintln!("[{}] loaded song from {:?}", "INFO".green(), path);
 | 
			
		||||
                        Some(v)
 | 
			
		||||
                    }
 | 
			
		||||
                    Err(e) => {
 | 
			
		||||
                        eprintln!("[info] error loading {:?}: {e:?}", path);
 | 
			
		||||
                        eprintln!("[{}] error loading {:?}: {e:?}", "ERR!".red(), path);
 | 
			
		||||
                        None
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Err((id, dlcon)) => {
 | 
			
		||||
                eprintln!("[info] loading song {id}");
 | 
			
		||||
                eprintln!("[{}] loading song {id}", "INFO".cyan());
 | 
			
		||||
                match dlcon
 | 
			
		||||
                    .lock()
 | 
			
		||||
                    .unwrap()
 | 
			
		||||
@ -161,7 +163,7 @@ impl Song {
 | 
			
		||||
                {
 | 
			
		||||
                    Ok(data) => Some(data),
 | 
			
		||||
                    Err(e) => {
 | 
			
		||||
                        eprintln!("[WARN] error loading song {id}: {e}");
 | 
			
		||||
                        eprintln!("[{}] error loading song {id}: {e}", "ERR!".red());
 | 
			
		||||
                        None
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ use awedio::{
 | 
			
		||||
    sounds::wrappers::{AsyncCompletionNotifier, Controller, Pausable},
 | 
			
		||||
    Sound,
 | 
			
		||||
};
 | 
			
		||||
use colorize::AnsiColor;
 | 
			
		||||
use rc_u8_reader::ArcU8Reader;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
@ -148,7 +149,10 @@ impl Player {
 | 
			
		||||
                                    self.manager.play(Box::new(sound));
 | 
			
		||||
                                }
 | 
			
		||||
                                Err(e) => {
 | 
			
		||||
                                    eprintln!("[player] Can't play, skipping! {e}");
 | 
			
		||||
                                    eprintln!(
 | 
			
		||||
                                        "[{}] [player] Can't play, skipping! {e}",
 | 
			
		||||
                                        "INFO".blue()
 | 
			
		||||
                                    );
 | 
			
		||||
                                    apply_command!(Command::NextSong);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,8 @@ use std::{
 | 
			
		||||
    sync::{mpsc, Arc, Mutex},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use colorize::AnsiColor;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::{
 | 
			
		||||
        album::Album,
 | 
			
		||||
@ -34,8 +36,8 @@ pub enum Command {
 | 
			
		||||
    NextSong,
 | 
			
		||||
    SyncDatabase(Vec<Artist>, Vec<Album>, Vec<Song>),
 | 
			
		||||
    QueueUpdate(Vec<usize>, Queue),
 | 
			
		||||
    QueueAdd(Vec<usize>, Queue),
 | 
			
		||||
    QueueInsert(Vec<usize>, usize, Queue),
 | 
			
		||||
    QueueAdd(Vec<usize>, Vec<Queue>),
 | 
			
		||||
    QueueInsert(Vec<usize>, usize, Vec<Queue>),
 | 
			
		||||
    QueueRemove(Vec<usize>),
 | 
			
		||||
    QueueGoto(Vec<usize>),
 | 
			
		||||
    QueueSetShuffle(Vec<usize>, Vec<usize>),
 | 
			
		||||
@ -165,7 +167,7 @@ pub fn run_server(
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                eprintln!("[WARN] Couldn't start TCP listener: {e}");
 | 
			
		||||
                eprintln!("[{}] Couldn't start TCP listener: {e}", "ERR!".red());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -484,7 +486,10 @@ impl ToFromBytes for Command {
 | 
			
		||||
            BYTE_SAVE => Self::Save,
 | 
			
		||||
            BYTE_ERRORINFO => Self::ErrorInfo(from_bytes!(), from_bytes!()),
 | 
			
		||||
            _ => {
 | 
			
		||||
                eprintln!("unexpected byte when reading command; stopping playback.");
 | 
			
		||||
                eprintln!(
 | 
			
		||||
                    "[{}] unexpected byte when reading command; stopping playback.",
 | 
			
		||||
                    "WARN".yellow()
 | 
			
		||||
                );
 | 
			
		||||
                Self::Stop
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
@ -287,7 +287,7 @@ pub async fn main(db: Arc<Mutex<Database>>, sender: mpsc::Sender<Command>, addr:
 | 
			
		||||
            post(move |Path(song_id)| async move {
 | 
			
		||||
                _ = s6.send(Command::QueueAdd(
 | 
			
		||||
                    vec![],
 | 
			
		||||
                    QueueContent::Song(song_id).into(),
 | 
			
		||||
                    vec![QueueContent::Song(song_id).into()],
 | 
			
		||||
                ));
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
@ -297,7 +297,7 @@ pub async fn main(db: Arc<Mutex<Database>>, sender: mpsc::Sender<Command>, addr:
 | 
			
		||||
                if let Some(album) = db1.lock().unwrap().albums().get(&album_id) {
 | 
			
		||||
                    _ = s7.send(Command::QueueAdd(
 | 
			
		||||
                        vec![],
 | 
			
		||||
                        QueueContent::Folder(
 | 
			
		||||
                        vec![QueueContent::Folder(
 | 
			
		||||
                            0,
 | 
			
		||||
                            album
 | 
			
		||||
                                .songs
 | 
			
		||||
@ -306,7 +306,7 @@ pub async fn main(db: Arc<Mutex<Database>>, sender: mpsc::Sender<Command>, addr:
 | 
			
		||||
                                .collect(),
 | 
			
		||||
                            album.name.clone(),
 | 
			
		||||
                        )
 | 
			
		||||
                        .into(),
 | 
			
		||||
                        .into()],
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
            }),
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user