From a8161521d099c8add12b54db519c74f976e2a55c Mon Sep 17 00:00:00 2001 From: krolxon Date: Thu, 25 Apr 2024 15:51:31 +0530 Subject: [PATCH] add keymaps to readme.md and minor changes --- README.md | 22 ++++++++- src/app.rs | 2 +- src/browser.rs | 2 - src/connection.rs | 10 +++- src/handler.rs | 17 +++---- src/ui.rs | 118 ++++++++++++++++------------------------------ 6 files changed, 76 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index a167298..ae5dba5 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,24 @@ A MPD client in Rust -# Keys +### Keys +- 'q' OR 'Ctr+C' to quit +- 'p' to toggle pause +- '+' to increase volume +- '-' to decrease volume +- 'D' to get dmenu prompt +- 'j' to scroll down +- 'k' to scroll up +- 'l' add song to playlist or go inside the directory +- 'h' to go back to previous directory +- `Tab` to cycle through tabs +- '1' to go to directory tree +- '2' to go to current playing queue +- '3' to go to playlists view +- 'Enter' to add song/playlist to current playlist +- 'a' to append the song to current playing queue +- 'f' to go forward +- 'b' to go backwords +- '>' to play next song from queue +- '<' to play previous song from queue +- 'U' to update the MPD database diff --git a/src/app.rs b/src/app.rs index deee711..be7c358 100755 --- a/src/app.rs +++ b/src/app.rs @@ -65,6 +65,7 @@ impl App { pub fn tick(&mut self) { self.conn.update_state(); self.conn.update_progress(); + self.conn.update_volume(); self.update_queue(); self.browser.update_directory(&mut self.conn).unwrap(); } @@ -97,7 +98,6 @@ impl App { pub fn get_playlist(conn: &mut Client) -> AppResult> { let list: Vec = conn.playlists()?.iter().map(|p| p.clone().name).collect(); - Ok(list) } diff --git a/src/browser.rs b/src/browser.rs index 0ed94ff..0efec1b 100755 --- a/src/browser.rs +++ b/src/browser.rs @@ -1,5 +1,3 @@ -use mpd::Query; - use crate::{app::AppResult, connection::Connection}; #[derive(Debug)] diff --git a/src/connection.rs b/src/connection.rs index a741206..b77da1b 100755 --- a/src/connection.rs +++ b/src/connection.rs @@ -14,6 +14,7 @@ pub struct Connection { pub state: String, pub elapsed: Duration, pub total_duration: Duration, + pub volume: u8, } impl Connection { @@ -26,8 +27,8 @@ impl Connection { .into_iter() .map(|x| x.file) .collect(); - let (elapsed, total) = conn.status().unwrap().time.unwrap_or_default(); + let volume: u8 = conn.status().unwrap_or_default().volume as u8; Ok(Self { conn, @@ -35,6 +36,7 @@ impl Connection { state: "Stopped".to_string(), elapsed, total_duration: total, + volume, }) } @@ -77,6 +79,10 @@ impl Connection { self.total_duration = total; } + pub fn update_volume(&mut self) { + self.volume = self.conn.status().unwrap_or_default().volume as u8; + } + pub fn get_progress_ratio(&self) -> f64 { let total = self.total_duration.as_secs_f64(); if total == 0.0 { @@ -84,7 +90,7 @@ impl Connection { } else { let ratio = self.elapsed.as_secs_f64() / self.total_duration.as_secs_f64(); if ratio > 1.0 || ratio == 0.0 { - 1.0 + 0.0 } else { ratio } diff --git a/src/handler.rs b/src/handler.rs index 81a8639..15d5c49 100755 --- a/src/handler.rs +++ b/src/handler.rs @@ -2,8 +2,6 @@ use std::time::Duration; use crate::app::{App, AppResult, SelectedTab}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; -use mpd::{Query, Term}; -use ratatui::style::Modifier; use rust_fuzzy_search; use simple_dmenu::dmenu; @@ -13,6 +11,8 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { KeyCode::Char('c') | KeyCode::Char('C') => { if key_event.modifiers == KeyModifiers::CONTROL { app.quit(); + } else { + app.conn.conn.clear()?; } } @@ -68,12 +68,6 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { app.conn.pause(); } - // Clear Queue - KeyCode::Char('x') => { - app.conn.conn.clear()?; - // app.update_queue(); - } - // Dmenu prompt KeyCode::Char('D') => { app.conn.play_dmenu()?; @@ -122,22 +116,23 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { app.selected_tab = SelectedTab::Playlists; } - - KeyCode::Char('n') => { + KeyCode::Char('>') => { app.conn.conn.next()?; } - KeyCode::Char('N') => { + KeyCode::Char('<') => { app.conn.conn.prev()?; } // Volume controls KeyCode::Char('=') => { app.conn.inc_volume(2); + app.conn.update_volume(); } KeyCode::Char('-') => { app.conn.dec_volume(2); + app.conn.update_volume(); } // Delete highlighted song from the queue diff --git a/src/ui.rs b/src/ui.rs index 76a4c09..2f1bca3 100755 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,7 +1,4 @@ -use crate::{ - app::{App, AppResult, SelectedTab}, - browser::FileBrowser, -}; +use crate::app::{App, SelectedTab}; use ratatui::{ prelude::*, widgets::{block::Title, *}, @@ -17,73 +14,62 @@ pub fn render(app: &mut App, frame: &mut Frame) { // Layout let layout = Layout::default() .direction(Direction::Vertical) - .constraints(vec![ - Constraint::Percentage(0), - // Constraint::Percentage(88), - Constraint::Percentage(93), - Constraint::Percentage(7), - ]) + .constraints(vec![Constraint::Percentage(93), Constraint::Percentage(7)]) .split(frame.size()); - // - // let outer_layout = Layout::default() - // .direction(Direction::Horizontal) - // .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)]) - // .split(main_layout[1]); - // - // let inner_layout = Layout::default() - // .direction(Direction::Vertical) - // .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)]) - // .split(outer_layout[1]); - - // draw_song_list(frame, app, outer_layout[0]); - // draw_queue(frame, app, inner_layout[0]); - // draw_playlists(frame, app, inner_layout[1]); - draw_progress_bar(frame, app, layout[2]); - - // let highlight_style = (Color::default(), tailwind::YELLOW.c700); - // let tab = Tabs::new(vec!["Songs List", "Play Queue", "Playlists"]) - // .block(Block::default().title("Tabs").borders(Borders::ALL)) - // .style(Style::default().white()) - // .highlight_style(highlight_style) - // .divider(" ") - // .select(app.selected_tab.clone() as usize) - // .padding("", ""); - // frame.render_widget(tab, layout[0]); match app.selected_tab { - // 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]), + SelectedTab::Queue => draw_queue(frame, app, layout[0]), + SelectedTab::Playlists => draw_playlists(frame, app, layout[0]), + SelectedTab::DirectoryBrowser => draw_directory_browser(frame, app, layout[0]), } + + draw_progress_bar(frame, app, layout[1]); } -/// draws list of songs -fn draw_song_list(frame: &mut Frame, app: &mut App, size: Rect) { +/// Draws the file tree browser +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 list = List::new(app.conn.songs_filenames.clone()) + let mut list: Vec = 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("Song List".green().bold()) + .title(format!("File Browser: {}", app.browser.path.clone()).bold()) .title( Title::from(format!("Total Songs: {}", total_songs).bold().green()) + .alignment(Alignment::Center), + ) + .title( + Title::from(format!("Volume: {}%", app.conn.volume).bold().green()) .alignment(Alignment::Right), ) .borders(Borders::ALL), ) .highlight_style(Style::new().add_modifier(Modifier::REVERSED)) .highlight_symbol(">>") - .repeat_highlight_symbol(true); + .repeat_highlight_symbol(true) + .scroll_padding(20); - song_state.select(Some(app.song_list.index)); + song_state.select(Some(app.browser.selected)); frame.render_stateful_widget(list, size, &mut song_state); } /// draws playing queue fn draw_queue(frame: &mut Frame, app: &mut App, size: Rect) { let mut queue_state = ListState::default(); - let title = Block::default().title(Title::from("Play Queue".green().bold())); + let title = Block::default() + .title(Title::from("Play Queue".green().bold())) + .title( + Title::from(format!("Volume: {}%", app.conn.volume).bold().green()) + .alignment(Alignment::Right), + ); let list = List::new(app.queue_list.list.clone()) .block(title.borders(Borders::ALL)) .highlight_style(Style::new().add_modifier(Modifier::REVERSED)) @@ -98,7 +84,13 @@ fn draw_queue(frame: &mut Frame, app: &mut App, size: Rect) { fn draw_playlists(frame: &mut Frame, app: &mut App, size: Rect) { let mut state = ListState::default(); - let title = Block::default().title(Title::from("Playlist".green().bold())); + let title = Block::default() + .title(Title::from("Playlist".green().bold())) + .title( + Title::from(format!("Volume: {}%", app.conn.volume).bold().green()) + .alignment(Alignment::Right), + ); + let list = List::new(app.pl_list.list.clone()) .block(title.borders(Borders::ALL)) .highlight_style(Style::new().add_modifier(Modifier::REVERSED)) @@ -109,7 +101,7 @@ fn draw_playlists(frame: &mut Frame, app: &mut App, size: Rect) { frame.render_stateful_widget(list, size, &mut state); } -// Progress Bar +/// Draws Progress Bar fn draw_progress_bar(frame: &mut Frame, app: &mut App, size: Rect) { let song = app .conn @@ -151,33 +143,3 @@ 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 = 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); -}