Major changes to queue pushing added search feature to playlist and queue

This commit is contained in:
krolxon 2024-04-28 14:34:30 +05:30
parent 828c0a50dc
commit bf939a4702
5 changed files with 134 additions and 51 deletions

View File

@ -35,6 +35,7 @@ A MPD client in Rust
- [ ] improvements on queue control - [ ] improvements on queue control
- [x] add to playlists - [x] add to playlists
- [ ] view playlist - [ ] view playlist
- [ ] change playlist name
- [x] search for songs - [x] search for songs
- [ ] metadata based tree view - [ ] metadata based tree view
- [x] Humantime format - [x] Humantime format

View File

@ -46,6 +46,7 @@ impl App {
Self::get_queue(&mut conn, &mut queue_list.list); Self::get_queue(&mut conn, &mut queue_list.list);
let browser = FileBrowser::new(); let browser = FileBrowser::new();
Ok(Self { Ok(Self {
running: true, running: true,
conn, conn,
@ -122,7 +123,12 @@ impl App {
} }
SelectedTab::Queue => { 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::<Vec<&str>>();
// 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<()> { pub fn search_song(&mut self) -> AppResult<()> {
let filename = self.conn.get_full_path(&self.search_input)?; let filename = self.conn.get_full_path(&self.search_input)?;
let song = self.conn.get_song_with_only_filename(&filename); let song = self.conn.get_song_with_only_filename(&filename);

View File

@ -1,4 +1,8 @@
use crate::{app::AppResult, connection::Connection}; use crate::{
app::{App, AppResult},
connection::Connection,
song::RSong,
};
#[derive(Debug)] #[derive(Debug)]
pub struct FileBrowser { pub struct FileBrowser {
@ -7,6 +11,8 @@ pub struct FileBrowser {
pub prev_selected: usize, pub prev_selected: usize,
pub path: String, pub path: String,
pub prev_path: String, pub prev_path: String,
pub rsongs: Vec<Option<RSong>>,
} }
impl FileBrowser { impl FileBrowser {
@ -17,6 +23,7 @@ impl FileBrowser {
prev_selected: 0, prev_selected: 0,
path: ".".to_string(), path: ".".to_string(),
prev_path: ".".to_string(), prev_path: ".".to_string(),
rsongs: Vec::new(),
} }
} }
@ -32,6 +39,21 @@ impl FileBrowser {
Ok(()) Ok(())
} }
// read all songs into a vec of RSongs
pub fn get_all_rsongs(&mut self, conn: &mut Connection) -> AppResult<Vec<Option<RSong>>> {
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 // Go to next item in filetree
pub fn next(&mut self) { pub fn next(&mut self) {
// if self.selected < self.filetree.len() - 1 { // 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::<Vec<&str>>();
// 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<()> { pub fn handle_go_back(&mut self, conn: &mut Connection) -> AppResult<()> {
if self.prev_path != "." { if self.prev_path != "." {

View File

@ -9,20 +9,58 @@ use rust_fuzzy_search::{self, fuzzy_search_sorted};
pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
if app.inputmode == InputMode::Editing { if app.inputmode == InputMode::Editing {
// Live update // Live search update
let list: Vec<&str> = app match app.selected_tab {
.browser SelectedTab::DirectoryBrowser => {
.filetree let list: Vec<&str> = app
.iter() .browser
.map(|(_, f)| f.as_str()) .filetree
.collect::<Vec<&str>>(); .iter()
.map(|(_, f)| f.as_str())
.collect::<Vec<&str>>();
let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list); let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>(); let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
for (i, (_, item)) in app.browser.filetree.iter().enumerate() { for (i, (_, item)) in app.browser.filetree.iter().enumerate() {
if item.contains(res.get(0).unwrap()) { if item.contains(res.get(0).unwrap()) {
app.browser.selected = i; app.browser.selected = i;
}
}
}
SelectedTab::Queue => {
let list: Vec<&str> = app
.queue_list
.list
.iter()
.map(|f| f.as_str())
.collect::<Vec<&str>>();
let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
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::<Vec<&str>>();
let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
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.conn.clear()?;
app.conn.update_status(); app.conn.update_status();
app.queue_list.list.clear(); 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 { match app.selected_tab {
SelectedTab::DirectoryBrowser => { SelectedTab::DirectoryBrowser => {
app.browser.handle_enter(&mut app.conn)?; app.handle_enter()?;
} }
SelectedTab::Queue => { SelectedTab::Queue => {
let song = app.conn.get_song_with_only_filename( app.conn.conn.switch(app.queue_list.index as u32)?;
app.queue_list.list.get(app.queue_list.index).unwrap(),
);
app.conn.push(&song)?;
} }
SelectedTab::Playlists => { SelectedTab::Playlists => {
app.conn app.conn
.push_playlist(app.pl_list.list.get(app.pl_list.index).unwrap())?; .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 // Remove from Current Playlsit
KeyCode::Backspace => { KeyCode::Char(' ') | KeyCode::Backspace => {
app.remove_from_current_playlist(); app.remove_from_current_playlist();
} }
// Change playlist name
KeyCode::Char('e') => if app.selected_tab == SelectedTab::Playlists {},
_ => {} _ => {}
} }
} }

View File

@ -39,4 +39,8 @@ impl<T> ContentList<T> {
self.index -= 1; self.index -= 1;
} }
} }
pub fn reset_index(&mut self) {
self.index = 0;
}
} }