Krolyxon
Commit a816152

rmptuia816152

add keymaps to readme.md and minor changes

Author
krolxon
Date
2024-04-25 15:51 +0530
Parent
00c5c12
Commit
a8161521d099c8add12b54db519c74f976e2a55c

+76 −95

6 files changed

  1. M README.md +21 −1
  2. M src/app.rs +1 −1
  3. M src/browser.rs +0 −2
  4. M src/connection.rs +8 −2
  5. M src/handler.rs +6 −11
  6. M src/ui.rs +40 −78
M README.md View
@@ -1,4 +1,24 @@
11 A MPD client in Rust
22
3−# Keys
3+### Keys
4+- 'q' OR 'Ctr+C' to quit
5+- 'p' to toggle pause
6+- '+' to increase volume
7+- '-' to decrease volume
8+- 'D' to get dmenu prompt
9+- 'j' to scroll down
10+- 'k' to scroll up
11+- 'l' add song to playlist or go inside the directory
12+- 'h' to go back to previous directory
13+- `Tab` to cycle through tabs
14+- '1' to go to directory tree
15+- '2' to go to current playing queue
16+- '3' to go to playlists view
17+- 'Enter' to add song/playlist to current playlist
18+- 'a' to append the song to current playing queue
19+- 'f' to go forward
20+- 'b' to go backwords
21+- '>' to play next song from queue
22+- '<' to play previous song from queue
23+- 'U' to update the MPD database
424
M src/app.rs View
@@ -65,6 +65,7 @@ impl App {
6565 pub fn tick(&mut self) {
6666 self.conn.update_state();
6767 self.conn.update_progress();
68+ self.conn.update_volume();
6869 self.update_queue();
6970 self.browser.update_directory(&mut self.conn).unwrap();
7071 }
@@ -97,7 +98,6 @@ impl App {
9798
9899 pub fn get_playlist(conn: &mut Client) -> AppResult<Vec<String>> {
99100 let list: Vec<String> = conn.playlists()?.iter().map(|p| p.clone().name).collect();
100−
101101 Ok(list)
102102 }
103103
M src/browser.rs View
@@ -1,5 +1,3 @@
1−use mpd::Query;
2−
31 use crate::{app::AppResult, connection::Connection};
42
53 #[derive(Debug)]
M src/connection.rs View
@@ -14,6 +14,7 @@ pub struct Connection {
1414 pub state: String,
1515 pub elapsed: Duration,
1616 pub total_duration: Duration,
17+ pub volume: u8,
1718 }
1819
1920 impl Connection {
@@ -26,8 +27,8 @@ impl Connection {
2627 .into_iter()
2728 .map(|x| x.file)
2829 .collect();
29−
3030 let (elapsed, total) = conn.status().unwrap().time.unwrap_or_default();
31+ let volume: u8 = conn.status().unwrap_or_default().volume as u8;
3132
3233 Ok(Self {
3334 conn,
@@ -35,6 +36,7 @@ impl Connection {
3536 state: "Stopped".to_string(),
3637 elapsed,
3738 total_duration: total,
39+ volume,
3840 })
3941 }
4042
@@ -77,6 +79,10 @@ impl Connection {
7779 self.total_duration = total;
7880 }
7981
82+ pub fn update_volume(&mut self) {
83+ self.volume = self.conn.status().unwrap_or_default().volume as u8;
84+ }
85+
8086 pub fn get_progress_ratio(&self) -> f64 {
8187 let total = self.total_duration.as_secs_f64();
8288 if total == 0.0 {
@@ -84,7 +90,7 @@ impl Connection {
8490 } else {
8591 let ratio = self.elapsed.as_secs_f64() / self.total_duration.as_secs_f64();
8692 if ratio > 1.0 || ratio == 0.0 {
87− 1.0
93+ 0.0
8894 } else {
8995 ratio
9096 }
M src/handler.rs View
@@ -2,8 +2,6 @@ use std::time::Duration;
22
33 use crate::app::{App, AppResult, SelectedTab};
44 use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
5−use mpd::{Query, Term};
6−use ratatui::style::Modifier;
75 use rust_fuzzy_search;
86 use simple_dmenu::dmenu;
97
@@ -13,6 +11,8 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
1311 KeyCode::Char('c') | KeyCode::Char('C') => {
1412 if key_event.modifiers == KeyModifiers::CONTROL {
1513 app.quit();
14+ } else {
15+ app.conn.conn.clear()?;
1616 }
1717 }
1818
@@ -68,12 +68,6 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
6868 app.conn.pause();
6969 }
7070
71− // Clear Queue
72− KeyCode::Char('x') => {
73− app.conn.conn.clear()?;
74− // app.update_queue();
75− }
76−
7771 // Dmenu prompt
7872 KeyCode::Char('D') => {
7973 app.conn.play_dmenu()?;
@@ -122,22 +116,23 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
122116 app.selected_tab = SelectedTab::Playlists;
123117 }
124118
125−
126− KeyCode::Char('n') => {
119+ KeyCode::Char('>') => {
127120 app.conn.conn.next()?;
128121 }
129122
130− KeyCode::Char('N') => {
123+ KeyCode::Char('<') => {
131124 app.conn.conn.prev()?;
132125 }
133126
134127 // Volume controls
135128 KeyCode::Char('=') => {
136129 app.conn.inc_volume(2);
130+ app.conn.update_volume();
137131 }
138132
139133 KeyCode::Char('-') => {
140134 app.conn.dec_volume(2);
135+ app.conn.update_volume();
141136 }
142137
143138 // Delete highlighted song from the queue
M src/ui.rs View
@@ -1,7 +1,4 @@
1−use crate::{
2− app::{App, AppResult, SelectedTab},
3− browser::FileBrowser,
4−};
1+use crate::app::{App, SelectedTab};
52 use ratatui::{
63 prelude::*,
74 widgets::{block::Title, *},
@@ -17,73 +14,62 @@ pub fn render(app: &mut App, frame: &mut Frame) {
1714 // Layout
1815 let layout = Layout::default()
1916 .direction(Direction::Vertical)
20− .constraints(vec![
21− Constraint::Percentage(0),
22− // Constraint::Percentage(88),
23− Constraint::Percentage(93),
24− Constraint::Percentage(7),
25− ])
17+ .constraints(vec![Constraint::Percentage(93), Constraint::Percentage(7)])
2618 .split(frame.size());
27− //
28− // let outer_layout = Layout::default()
29− // .direction(Direction::Horizontal)
30− // .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
31− // .split(main_layout[1]);
32− //
33− // let inner_layout = Layout::default()
34− // .direction(Direction::Vertical)
35− // .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
36− // .split(outer_layout[1]);
37−
38− // draw_song_list(frame, app, outer_layout[0]);
39− // draw_queue(frame, app, inner_layout[0]);
40− // draw_playlists(frame, app, inner_layout[1]);
41− draw_progress_bar(frame, app, layout[2]);
42−
43− // let highlight_style = (Color::default(), tailwind::YELLOW.c700);
44− // let tab = Tabs::new(vec!["Songs List", "Play Queue", "Playlists"])
45− // .block(Block::default().title("Tabs").borders(Borders::ALL))
46− // .style(Style::default().white())
47− // .highlight_style(highlight_style)
48− // .divider(" ")
49− // .select(app.selected_tab.clone() as usize)
50− // .padding("", "");
51− // frame.render_widget(tab, layout[0]);
5219
5320 match app.selected_tab {
54− // SelectedTab::SongList => draw_song_list(frame, app, layout[1]),
55− SelectedTab::Queue => draw_queue(frame, app, layout[1]),
56− SelectedTab::Playlists => draw_playlists(frame, app, layout[1]),
57− SelectedTab::DirectoryBrowser => draw_directory_browser(frame, app, layout[1]),
21+ SelectedTab::Queue => draw_queue(frame, app, layout[0]),
22+ SelectedTab::Playlists => draw_playlists(frame, app, layout[0]),
23+ SelectedTab::DirectoryBrowser => draw_directory_browser(frame, app, layout[0]),
5824 }
25+
26+ draw_progress_bar(frame, app, layout[1]);
5927 }
6028
61−/// draws list of songs
62−fn draw_song_list(frame: &mut Frame, app: &mut App, size: Rect) {
29+/// Draws the file tree browser
30+fn draw_directory_browser(frame: &mut Frame, app: &mut App, size: Rect) {
6331 let mut song_state = ListState::default();
6432 let total_songs = app.conn.conn.stats().unwrap().songs.to_string();
65− let list = List::new(app.conn.songs_filenames.clone())
33+ let mut list: Vec<String> = vec![];
34+ for (t, s) in app.browser.filetree.iter() {
35+ if t == "file" {
36+ list.push(s.to_string());
37+ } else {
38+ list.push(format!("[{}]", *s));
39+ }
40+ }
41+ let list = List::new(list)
6642 .block(
6743 Block::default()
68− .title("Song List".green().bold())
44+ .title(format!("File Browser: {}", app.browser.path.clone()).bold())
6945 .title(
7046 Title::from(format!("Total Songs: {}", total_songs).bold().green())
47+ .alignment(Alignment::Center),
48+ )
49+ .title(
50+ Title::from(format!("Volume: {}%", app.conn.volume).bold().green())
7151 .alignment(Alignment::Right),
7252 )
7353 .borders(Borders::ALL),
7454 )
7555 .highlight_style(Style::new().add_modifier(Modifier::REVERSED))
7656 .highlight_symbol(">>")
77− .repeat_highlight_symbol(true);
57+ .repeat_highlight_symbol(true)
58+ .scroll_padding(20);
7859
79− song_state.select(Some(app.song_list.index));
60+ song_state.select(Some(app.browser.selected));
8061 frame.render_stateful_widget(list, size, &mut song_state);
8162 }
8263
8364 /// draws playing queue
8465 fn draw_queue(frame: &mut Frame, app: &mut App, size: Rect) {
8566 let mut queue_state = ListState::default();
86− let title = Block::default().title(Title::from("Play Queue".green().bold()));
67+ let title = Block::default()
68+ .title(Title::from("Play Queue".green().bold()))
69+ .title(
70+ Title::from(format!("Volume: {}%", app.conn.volume).bold().green())
71+ .alignment(Alignment::Right),
72+ );
8773 let list = List::new(app.queue_list.list.clone())
8874 .block(title.borders(Borders::ALL))
8975 .highlight_style(Style::new().add_modifier(Modifier::REVERSED))
@@ -98,7 +84,13 @@ fn draw_queue(frame: &mut Frame, app: &mut App, size: Rect) {
9884 fn draw_playlists(frame: &mut Frame, app: &mut App, size: Rect) {
9985 let mut state = ListState::default();
10086
101− let title = Block::default().title(Title::from("Playlist".green().bold()));
87+ let title = Block::default()
88+ .title(Title::from("Playlist".green().bold()))
89+ .title(
90+ Title::from(format!("Volume: {}%", app.conn.volume).bold().green())
91+ .alignment(Alignment::Right),
92+ );
93+
10294 let list = List::new(app.pl_list.list.clone())
10395 .block(title.borders(Borders::ALL))
10496 .highlight_style(Style::new().add_modifier(Modifier::REVERSED))
@@ -109,7 +101,7 @@ fn draw_playlists(frame: &mut Frame, app: &mut App, size: Rect) {
109101 frame.render_stateful_widget(list, size, &mut state);
110102 }
111103
112−// Progress Bar
104+/// Draws Progress Bar
113105 fn draw_progress_bar(frame: &mut Frame, app: &mut App, size: Rect) {
114106 let song = app
115107 .conn
@@ -151,33 +143,3 @@ fn draw_progress_bar(frame: &mut Frame, app: &mut App, size: Rect) {
151143
152144 frame.render_widget(progress_bar, size);
153145 }
154−
155−fn draw_directory_browser(frame: &mut Frame, app: &mut App, size: Rect) {
156− let mut song_state = ListState::default();
157− let total_songs = app.conn.conn.stats().unwrap().songs.to_string();
158− let mut list: Vec<String> = vec![];
159− for (t, s) in app.browser.filetree.iter() {
160− if t == "file" {
161− list.push(s.to_string());
162− } else {
163− list.push(format!("[{}]", *s));
164− }
165− }
166− let list = List::new(list)
167− .block(
168− Block::default()
169− .title(format!("File Browser: {}", app.browser.path.clone()).bold())
170− .title(
171− Title::from(format!("Total Songs: {}", total_songs).bold().green())
172− .alignment(Alignment::Right),
173− )
174− .borders(Borders::ALL),
175− )
176− .highlight_style(Style::new().add_modifier(Modifier::REVERSED))
177− .highlight_symbol(">>")
178− .repeat_highlight_symbol(true)
179− .scroll_padding(20);
180−
181− song_state.select(Some(app.browser.selected));
182− frame.render_stateful_widget(list, size, &mut song_state);
183−}