aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkrolxon <krolyxon@tutanota.com>2024-04-25 14:31:50 +0530
committerkrolxon <krolyxon@tutanota.com>2024-04-25 14:31:50 +0530
commit00c5c12d82a2d6b9ca5f56f6ca468b2b3212c792 (patch)
tree5c4d3c7fbd6080187b17bc8e3cb28e6f29ee6ff9
parentf665c4e9f3b4eaa226b0c813f6845e247a4e6977 (diff)
use filetree view instead of all song list
-rwxr-xr-xsrc/app.rs19
-rwxr-xr-xsrc/browser.rs92
-rwxr-xr-xsrc/handler.rs23
-rwxr-xr-xsrc/lib.rs3
-rwxr-xr-xsrc/ui.rs38
5 files changed, 158 insertions, 17 deletions
diff --git a/src/app.rs b/src/app.rs
index f129fe3..deee711 100755
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,5 +1,6 @@
use std::time::Duration;
+use crate::browser::FileBrowser;
use crate::connection::Connection;
use crate::list::ContentList;
use mpd::Client;
@@ -17,11 +18,12 @@ pub struct App {
pub queue_list: ContentList<String>,
pub pl_list: ContentList<String>,
pub selected_tab: SelectedTab,
+ pub browser: FileBrowser,
}
#[derive(Debug, PartialEq, Clone)]
pub enum SelectedTab {
- SongList,
+ DirectoryBrowser,
Queue,
Playlists,
}
@@ -29,9 +31,9 @@ pub enum SelectedTab {
impl SelectedTab {
fn as_usize(&self) {
match self {
- SelectedTab::SongList => 0,
- SelectedTab::Queue => 1,
- SelectedTab::Playlists => 2,
+ SelectedTab::Queue => 0,
+ SelectedTab::Playlists => 1,
+ SelectedTab::DirectoryBrowser => 2,
};
}
}
@@ -48,13 +50,15 @@ impl App {
let mut song_list = ContentList::new();
song_list.list = conn.songs_filenames.clone();
+ let browser = FileBrowser::new();
Ok(Self {
running: true,
conn,
song_list,
queue_list,
pl_list,
- selected_tab: SelectedTab::SongList,
+ selected_tab: SelectedTab::DirectoryBrowser,
+ browser,
})
}
@@ -62,6 +66,7 @@ impl App {
self.conn.update_state();
self.conn.update_progress();
self.update_queue();
+ self.browser.update_directory(&mut self.conn).unwrap();
}
pub fn quit(&mut self) {
@@ -103,9 +108,9 @@ impl App {
pub fn cycle_tabls(&mut self) {
self.selected_tab = match self.selected_tab {
- SelectedTab::SongList => SelectedTab::Queue,
+ SelectedTab::DirectoryBrowser => SelectedTab::Queue,
SelectedTab::Queue => SelectedTab::Playlists,
- SelectedTab::Playlists => SelectedTab::SongList,
+ SelectedTab::Playlists => SelectedTab::DirectoryBrowser,
};
}
}
diff --git a/src/browser.rs b/src/browser.rs
new file mode 100755
index 0000000..0ed94ff
--- /dev/null
+++ b/src/browser.rs
@@ -0,0 +1,92 @@
+use mpd::Query;
+
+use crate::{app::AppResult, connection::Connection};
+
+#[derive(Debug)]
+pub struct FileBrowser {
+ pub filetree: Vec<(String, String)>,
+ pub selected: usize,
+ pub prev_selected: usize,
+ pub path: String,
+ pub prev_path: String,
+}
+
+impl FileBrowser {
+ pub fn new() -> FileBrowser {
+ FileBrowser {
+ filetree: Vec::new(),
+ selected: 0,
+ prev_selected: 0,
+ path: ".".to_string(),
+ prev_path: ".".to_string(),
+ }
+ }
+
+ pub fn update_directory(&mut self, conn: &mut Connection) -> AppResult<()> {
+ self.filetree.clear();
+ self.filetree = conn
+ .conn
+ .listfiles(self.path.as_str())?
+ .into_iter()
+ .filter(|(f, _)| f == "directory" || f == "file")
+ .collect::<Vec<(String, String)>>();
+
+ Ok(())
+ }
+
+ // Go to next item in filetree
+ pub fn next(&mut self) {
+ // if self.selected < self.filetree.len() - 1 {
+ // self.selected += 1;
+ // }
+
+ if self.selected == self.filetree.len() - 1 {
+ self.selected = 0;
+ } else {
+ self.selected += 1;
+ }
+ }
+
+ /// Go to previous item in filetree
+ pub fn prev(&mut self) {
+ if self.selected == 0 {
+ self.selected = self.filetree.len() - 1;
+ } else {
+ self.selected -= 1;
+ }
+ }
+
+ 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 = path.to_string();
+ self.update_directory(conn)?;
+ self.prev_selected = self.selected;
+ self.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 song = conn.get_song_with_only_filename(filename);
+ conn.push(&song)?;
+ }
+ Ok(())
+ }
+
+ pub fn handle_go_back(&mut self, conn: &mut Connection) -> AppResult<()> {
+ self.path = self.prev_path.clone();
+ self.selected = self.prev_selected;
+ self.update_directory(conn)?;
+ Ok(())
+ }
+}
diff --git a/src/handler.rs b/src/handler.rs
index fce3aa8..81a8639 100755
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -17,13 +17,13 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
}
KeyCode::Char('j') | KeyCode::Down => match app.selected_tab {
- SelectedTab::SongList => app.song_list.next(),
+ SelectedTab::DirectoryBrowser => app.browser.next(),
SelectedTab::Queue => app.queue_list.next(),
SelectedTab::Playlists => app.pl_list.next(),
},
KeyCode::Char('k') | KeyCode::Up => match app.selected_tab {
- SelectedTab::SongList => app.song_list.prev(),
+ SelectedTab::DirectoryBrowser => app.browser.prev(),
SelectedTab::Queue => app.queue_list.prev(),
SelectedTab::Playlists => app.pl_list.prev(),
},
@@ -32,12 +32,10 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
// app.update_queue();
match app.selected_tab {
- SelectedTab::SongList => {
- let song = app.conn.get_song_with_only_filename(
- app.conn.songs_filenames.get(app.song_list.index).unwrap(),
- );
- app.conn.push(&song)?;
+ SelectedTab::DirectoryBrowser => {
+ app.browser.handle_enter(&mut app.conn)?;
}
+
SelectedTab::Queue => {
let song = app.conn.get_song_with_only_filename(
app.queue_list.list.get(app.queue_list.index).unwrap(),
@@ -51,6 +49,14 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
}
}
+ KeyCode::Char('h') => match app.selected_tab {
+ SelectedTab::DirectoryBrowser => {
+ app.browser.handle_go_back(&mut app.conn)?;
+ }
+ SelectedTab::Queue => {}
+ SelectedTab::Playlists => {}
+ },
+
// Playback controls
// Toggle Pause
KeyCode::Char('p') => {
@@ -105,7 +111,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
}
KeyCode::Char('1') => {
- app.selected_tab = SelectedTab::SongList;
+ app.selected_tab = SelectedTab::DirectoryBrowser;
}
KeyCode::Char('2') => {
@@ -116,6 +122,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
app.selected_tab = SelectedTab::Playlists;
}
+
KeyCode::Char('n') => {
app.conn.conn.next()?;
}
diff --git a/src/lib.rs b/src/lib.rs
index 60df19e..71a2e93 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,6 +13,9 @@ pub mod tui;
/// Content list
pub mod list;
+/// File Browser
+pub mod browser;
+
/// Event Handler
pub mod event;
diff --git a/src/ui.rs b/src/ui.rs
index d9ef39b..76a4c09 100755
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -1,4 +1,7 @@
-use crate::app::{App, AppResult, SelectedTab};
+use crate::{
+ app::{App, AppResult, SelectedTab},
+ browser::FileBrowser,
+};
use ratatui::{
prelude::*,
widgets::{block::Title, *},
@@ -48,9 +51,10 @@ pub fn render(app: &mut App, frame: &mut Frame) {
// frame.render_widget(tab, layout[0]);
match app.selected_tab {
- SelectedTab::SongList => draw_song_list(frame, app, layout[1]),
+ // SelectedTab::SongList => draw_song_list(frame, app, layout[1]),
SelectedTab::Queue => draw_queue(frame, app, layout[1]),
SelectedTab::Playlists => draw_playlists(frame, app, layout[1]),
+ SelectedTab::DirectoryBrowser => draw_directory_browser(frame, app, layout[1]),
}
}
@@ -147,3 +151,33 @@ fn draw_progress_bar(frame: &mut Frame, app: &mut App, size: Rect) {
frame.render_widget(progress_bar, size);
}
+
+fn draw_directory_browser(frame: &mut Frame, app: &mut App, size: Rect) {
+ let mut song_state = ListState::default();
+ let total_songs = app.conn.conn.stats().unwrap().songs.to_string();
+ let mut list: Vec<String> = vec![];
+ for (t, s) in app.browser.filetree.iter() {
+ if t == "file" {
+ list.push(s.to_string());
+ } else {
+ list.push(format!("[{}]", *s));
+ }
+ }
+ let list = List::new(list)
+ .block(
+ Block::default()
+ .title(format!("File Browser: {}", app.browser.path.clone()).bold())
+ .title(
+ Title::from(format!("Total Songs: {}", total_songs).bold().green())
+ .alignment(Alignment::Right),
+ )
+ .borders(Borders::ALL),
+ )
+ .highlight_style(Style::new().add_modifier(Modifier::REVERSED))
+ .highlight_symbol(">>")
+ .repeat_highlight_symbol(true)
+ .scroll_padding(20);
+
+ song_state.select(Some(app.browser.selected));
+ frame.render_stateful_widget(list, size, &mut song_state);
+}