From bf939a4702ebf5570b60fa2018eeb6a29beb2aa4 Mon Sep 17 00:00:00 2001 From: krolxon Date: Sun, 28 Apr 2024 14:34:30 +0530 Subject: [PATCH] Major changes to queue pushing added search feature to playlist and queue --- README.md | 1 + src/app.rs | 49 +++++++++++++++++++++++++++++++- src/browser.rs | 55 +++++++++++++++--------------------- src/handler.rs | 76 ++++++++++++++++++++++++++++++++++++++------------ src/list.rs | 4 +++ 5 files changed, 134 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index b2d5f76..ffe2998 100755 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ A MPD client in Rust - [ ] improvements on queue control - [x] add to playlists - [ ] view playlist +- [ ] change playlist name - [x] search for songs - [ ] metadata based tree view - [x] Humantime format diff --git a/src/app.rs b/src/app.rs index 292ef63..7444ef6 100755 --- a/src/app.rs +++ b/src/app.rs @@ -46,6 +46,7 @@ impl App { Self::get_queue(&mut conn, &mut queue_list.list); let browser = FileBrowser::new(); + Ok(Self { running: true, conn, @@ -122,7 +123,12 @@ impl App { } SelectedTab::Queue => { - file = self.queue_list.list.get(self.queue_list.index).unwrap().to_string(); + file = self + .queue_list + .list + .get(self.queue_list.index) + .unwrap() + .to_string(); } _ => {} @@ -145,6 +151,47 @@ impl App { }; } + pub fn handle_enter(&mut self) -> AppResult<()> { + let browser = &mut self.browser; + let (t, path) = browser.filetree.get(browser.selected).unwrap(); + if t == "directory" { + if path != "." { + browser.prev_path = browser.path.clone(); + browser.path = browser.prev_path.clone() + "/" + path; + browser.update_directory(&mut self.conn)?; + // self.get_all_rsongs(conn)?; + browser.prev_selected = browser.selected; + browser.selected = 0; + } + } else { + // let list = conn + // .songs_filenames + // .iter() + // .map(|f| f.as_str()) + // .collect::>(); + // let (filename, _) = rust_fuzzy_search::fuzzy_search_sorted(&path, &list) + // .get(0) + // .unwrap() + // .clone(); + let index = self.queue_list.list.iter().position(|x| x.contains(path)); + + if index.is_some() { + self.conn.conn.switch(index.unwrap() as u32)?; + } else { + for filename in self.conn.songs_filenames.clone().iter() { + if filename.contains(path) { + let song = self.conn.get_song_with_only_filename(filename); + self.conn.push(&song)?; + } + } + + // updating queue, to avoid multiple pushes of the same songs if we enter multiple times before the queue gets updated + self.update_queue(); + } + } + Ok(()) + } + pub fn search_song(&mut self) -> AppResult<()> { let filename = self.conn.get_full_path(&self.search_input)?; let song = self.conn.get_song_with_only_filename(&filename); diff --git a/src/browser.rs b/src/browser.rs index 88d1db1..9add421 100755 --- a/src/browser.rs +++ b/src/browser.rs @@ -1,4 +1,8 @@ -use crate::{app::AppResult, connection::Connection}; +use crate::{ + app::{App, AppResult}, + connection::Connection, + song::RSong, +}; #[derive(Debug)] pub struct FileBrowser { @@ -7,6 +11,8 @@ pub struct FileBrowser { pub prev_selected: usize, pub path: String, pub prev_path: String, + + pub rsongs: Vec>, } impl FileBrowser { @@ -17,6 +23,7 @@ impl FileBrowser { prev_selected: 0, path: ".".to_string(), prev_path: ".".to_string(), + rsongs: Vec::new(), } } @@ -32,6 +39,21 @@ impl FileBrowser { Ok(()) } + // read all songs into a vec of RSongs + pub fn get_all_rsongs(&mut self, conn: &mut Connection) -> AppResult>> { + for (t, s) in self.filetree.iter() { + if t == "file" { + let s = conn.get_full_path(s)?; + let s = RSong::new(&mut conn.conn, s); + self.rsongs.push(Some(s)); + } else if t == "directory" { + self.rsongs.push(None) + } + } + + Ok(self.rsongs.clone()) + } + // Go to next item in filetree pub fn next(&mut self) { // if self.selected < self.filetree.len() - 1 { @@ -54,38 +76,7 @@ impl FileBrowser { } } - pub fn handle_enter(&mut self, conn: &mut Connection) -> AppResult<()> { - let (t, path) = self.filetree.get(self.selected).unwrap(); - if t == "directory" { - if path != "." { - self.prev_path = self.path.clone(); - self.path = self.prev_path.clone() + "/" + path; - self.update_directory(conn)?; - self.prev_selected = self.selected; - self.selected = 0; - // println!("self.path: {}", self.path); - // println!("self.prev_pat: {}", self.prev_path); - } - } else { - // let list = conn - // .songs_filenames - // .iter() - // .map(|f| f.as_str()) - // .collect::>(); - // let (filename, _) = rust_fuzzy_search::fuzzy_search_sorted(&path, &list) - // .get(0) - // .unwrap() - // .clone(); - for filename in conn.songs_filenames.clone().iter() { - if filename.contains(path) { - let song = conn.get_song_with_only_filename(filename); - conn.push(&song)?; - } - } - } - Ok(()) - } pub fn handle_go_back(&mut self, conn: &mut Connection) -> AppResult<()> { if self.prev_path != "." { diff --git a/src/handler.rs b/src/handler.rs index 2a18a1c..ab09050 100755 --- a/src/handler.rs +++ b/src/handler.rs @@ -9,20 +9,58 @@ use rust_fuzzy_search::{self, fuzzy_search_sorted}; pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { if app.inputmode == InputMode::Editing { - // Live update - let list: Vec<&str> = app - .browser - .filetree - .iter() - .map(|(_, f)| f.as_str()) - .collect::>(); + // Live search update + match app.selected_tab { + SelectedTab::DirectoryBrowser => { + let list: Vec<&str> = app + .browser + .filetree + .iter() + .map(|(_, f)| f.as_str()) + .collect::>(); - let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list); - let res = res.iter().map(|(x, _)| *x).collect::>(); + let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list); + let res = res.iter().map(|(x, _)| *x).collect::>(); - for (i, (_, item)) in app.browser.filetree.iter().enumerate() { - if item.contains(res.get(0).unwrap()) { - app.browser.selected = i; + for (i, (_, item)) in app.browser.filetree.iter().enumerate() { + if item.contains(res.get(0).unwrap()) { + app.browser.selected = i; + } + } + } + + SelectedTab::Queue => { + let list: Vec<&str> = app + .queue_list + .list + .iter() + .map(|f| f.as_str()) + .collect::>(); + let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list); + let res = res.iter().map(|(x, _)| *x).collect::>(); + + for (i, item) in app.queue_list.list.iter().enumerate() { + if item.contains(res.get(0).unwrap()) { + app.queue_list.index = i; + } + } + } + + SelectedTab::Playlists => { + let list: Vec<&str> = app + .pl_list + .list + .iter() + .map(|f| f.as_str()) + .collect::>(); + let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list); + let res = res.iter().map(|(x, _)| *x).collect::>(); + + for (i, item) in app.pl_list.list.iter().enumerate() { + if item.contains(res.get(0).unwrap()) { + app.pl_list.index = i; + } + } } } @@ -126,6 +164,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { app.conn.conn.clear()?; app.conn.update_status(); app.queue_list.list.clear(); + app.queue_list.reset_index(); } } @@ -149,15 +188,13 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { match app.selected_tab { SelectedTab::DirectoryBrowser => { - app.browser.handle_enter(&mut app.conn)?; + app.handle_enter()?; } SelectedTab::Queue => { - let song = app.conn.get_song_with_only_filename( - app.queue_list.list.get(app.queue_list.index).unwrap(), - ); - app.conn.push(&song)?; + app.conn.conn.switch(app.queue_list.index as u32)?; } + SelectedTab::Playlists => { app.conn .push_playlist(app.pl_list.list.get(app.pl_list.index).unwrap())?; @@ -285,10 +322,13 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { } // Remove from Current Playlsit - KeyCode::Backspace => { + KeyCode::Char(' ') | KeyCode::Backspace => { app.remove_from_current_playlist(); } + // Change playlist name + KeyCode::Char('e') => if app.selected_tab == SelectedTab::Playlists {}, + _ => {} } } diff --git a/src/list.rs b/src/list.rs index 631c40d..6294f44 100755 --- a/src/list.rs +++ b/src/list.rs @@ -39,4 +39,8 @@ impl ContentList { self.index -= 1; } } + + pub fn reset_index(&mut self) { + self.index = 0; + } }