aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkrolxon <krolyxon@tutanota.com>2024-04-29 16:27:23 +0530
committerkrolxon <krolyxon@tutanota.com>2024-04-29 16:27:23 +0530
commitbf531facb0349c528f6f8965d05257a46a7f3fd3 (patch)
tree1f0c80bd822bd7eaeb15c8921bd6286091821b68
parentc61b0503c7b9f112a72829004ea5308083f39185 (diff)
add metadata in queue list
-rwxr-xr-xREADME.md2
-rwxr-xr-xsrc/browser.rs23
-rwxr-xr-xsrc/handler.rs4
-rwxr-xr-xsrc/list.rs32
-rwxr-xr-xsrc/ui.rs189
5 files changed, 134 insertions, 116 deletions
diff --git a/README.md b/README.md
index 67d599a..5997eb4 100755
--- a/README.md
+++ b/README.md
@@ -38,6 +38,6 @@ A MPD client in Rust
- [x] add to playlists
- [x] search for songs
- [x] Humantime format
+- [x] metadata based tree view
- [ ] view playlist
- [ ] change playlist name
-- [ ] metadata based tree view
diff --git a/src/browser.rs b/src/browser.rs
index e82692a..212618e 100755
--- a/src/browser.rs
+++ b/src/browser.rs
@@ -98,24 +98,27 @@ impl FileBrowser {
// 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 {
+ 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 {
+ if self.selected != 0 {
self.selected -= 1;
}
+ // if self.selected == 0 {
+ // self.selected = self.filetree.len() - 1;
+ // } else {
+ // self.selected -= 1;
+ // }
}
pub fn handle_go_back(&mut self, conn: &mut Connection) -> AppResult<()> {
diff --git a/src/handler.rs b/src/handler.rs
index 6d8c32c..cf5df27 100755
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -62,7 +62,6 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
}
}
}
-
}
match key_event.code {
@@ -200,7 +199,6 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
app.conn
.load_playlist(app.pl_list.list.get(app.pl_list.index).unwrap())?;
}
-
}
app.conn.update_status();
}
@@ -279,6 +277,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
KeyCode::Char('>') => {
if !app.queue_list.list.is_empty() {
app.conn.conn.next()?;
+ app.update_queue();
}
}
@@ -286,6 +285,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
KeyCode::Char('<') => {
if !app.queue_list.list.is_empty() {
app.conn.conn.prev()?;
+ app.update_queue();
}
}
diff --git a/src/list.rs b/src/list.rs
index 6294f44..219b9a4 100755
--- a/src/list.rs
+++ b/src/list.rs
@@ -14,30 +14,36 @@ impl<T> ContentList<T> {
// Go to next item in list
pub fn next(&mut self) {
- // if self.index < self.list.len() - 1 {
- // self.index += 1;
- // }
-
let len = self.list.len();
if len != 0 {
- if self.index == self.list.len() - 1 {
- self.index = 0;
- } else {
+ if self.index < len - 1 {
self.index += 1;
}
}
+
+ // let len = self.list.len();
+ // if len != 0 {
+ // if self.index == self.list.len() - 1 {
+ // self.index = 0;
+ // } else {
+ // self.index += 1;
+ // }
+ // }
}
/// Go to previous item in list
pub fn prev(&mut self) {
- if self.index == 0 {
- let len = self.list.len();
- if len != 0 {
- self.index = len - 1;
- }
- } else {
+ if self.index != 0 {
self.index -= 1;
}
+ // if self.index == 0 {
+ // let len = self.list.len();
+ // if len != 0 {
+ // self.index = len - 1;
+ // }
+ // } else {
+ // self.index -= 1;
+ // }
}
pub fn reset_index(&mut self) {
diff --git a/src/ui.rs b/src/ui.rs
index 93dcd53..b4b789d 100755
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -1,6 +1,7 @@
use std::time::Duration;
use crate::app::{App, SelectedTab};
+use mpd::Song;
use ratatui::{
prelude::*,
widgets::{block::Title, *},
@@ -32,8 +33,7 @@ pub fn render(app: &mut App, frame: &mut Frame) {
match app.selected_tab {
SelectedTab::Queue => draw_queue(frame, app, layout[0]),
SelectedTab::Playlists => draw_playlists(frame, app, layout[0]),
- SelectedTab::DirectoryBrowser => draw_song_browser(frame, app, layout[0]),
- // SelectedTab::SongBrowser => draw_song_browser(frame, app, layout[0]),
+ SelectedTab::DirectoryBrowser => draw_directory_browser(frame, app, layout[0]),
}
match app.inputmode {
@@ -50,63 +50,8 @@ pub fn render(app: &mut App, frame: &mut Frame) {
}
}
-/// Draws the file tree browser
+/// Draws the directory
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<ListItem> = vec![];
- for (t, s) in app.browser.filetree.iter() {
- if t == "file" {
- let mut status: bool = false;
- for sn in app.queue_list.list.iter() {
- if sn.contains(s) {
- status = true;
- }
- }
- if status {
- list.push(ListItem::new(s.clone().magenta().bold()));
- } else {
- // list.push(ListItem::new(s.clone()));
- list.push(ListItem::new(s.clone()));
- }
- } else {
- list.push(ListItem::new(Line::styled(
- format!("[{}]", *s),
- Style::default(),
- )));
- }
- }
- let list = List::new(list)
- .block(
- Block::default()
- .title(format!("Directory 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()
- .fg(Color::Cyan)
- .bg(Color::Black)
- .add_modifier(Modifier::BOLD)
- .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);
-}
-
-/// Draws the song browser
-fn draw_song_browser(frame: &mut Frame, app: &mut App, size: Rect) {
let total_songs = app.conn.conn.stats().unwrap().songs.to_string();
let rows = app.browser.filetree.iter().enumerate().map(|(i, (t, s))| {
@@ -149,7 +94,7 @@ fn draw_song_browser(frame: &mut Frame, app: &mut App, size: Rect) {
Cell::from(track.green()),
Cell::from(title),
Cell::from(album),
- Cell::from(time.to_string().red()),
+ Cell::from(time.to_string().magenta()),
]);
row.magenta().bold()
} else {
@@ -158,7 +103,7 @@ fn draw_song_browser(frame: &mut Frame, app: &mut App, size: Rect) {
Cell::from(track.green()),
Cell::from(title),
Cell::from(album),
- Cell::from(time.to_string().red()),
+ Cell::from(time.to_string().magenta()),
]);
row
}
@@ -178,9 +123,9 @@ fn draw_song_browser(frame: &mut Frame, app: &mut App, size: Rect) {
let table = Table::new(
rows,
[
- Constraint::Percentage(33),
+ Constraint::Percentage(20),
Constraint::Percentage(3),
- Constraint::Percentage(30),
+ Constraint::Min(30),
Constraint::Percentage(30),
Constraint::Percentage(3),
],
@@ -205,7 +150,8 @@ fn draw_song_browser(frame: &mut Frame, app: &mut App, size: Rect) {
.bg(Color::Black),
)
.highlight_symbol(">>")
- .header(header);
+ .header(header)
+ .flex(layout::Flex::Legacy);
state.select(Some(app.browser.selected));
frame.render_stateful_widget(table, size, &mut state);
@@ -213,38 +159,101 @@ fn draw_song_browser(frame: &mut Frame, app: &mut App, size: Rect) {
/// 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()))
- .title(Title::from(
- format!("({} items)", app.queue_list.list.len()).bold(),
- ))
- .title(
- Title::from(format!("Volume: {}%", app.conn.volume).bold().green())
- .alignment(Alignment::Right),
+ let rows = app.queue_list.list.iter().map(|s| {
+ // metadata
+ let song = app
+ .conn
+ .conn
+ .lsinfo(&Song {
+ file: app.conn.get_full_path(&s).unwrap_or_default(),
+ ..Default::default()
+ })
+ .unwrap_or_default();
+ let song = song.get(0).unwrap();
+ let title = song.clone().title.unwrap_or_else(|| song.clone().file);
+ let artist = song.clone().artist.unwrap_or_default().cyan();
+ let album = song
+ .tags
+ .iter()
+ .filter(|(x, _)| x == "Album")
+ .map(|(_, l)| l.clone())
+ .collect::<Vec<String>>()
+ .join("");
+
+ let track = song
+ .tags
+ .iter()
+ .filter(|(x, _)| x == "Track")
+ .map(|(_, l)| l.clone())
+ .collect::<Vec<String>>()
+ .join("");
+
+ let time = humantime::format_duration(
+ song.clone().duration.unwrap_or_else(|| Duration::new(0, 0)),
);
- let mut items: Vec<ListItem> = vec![];
- for item in app.queue_list.list.iter() {
- if item.contains(&app.conn.current_song.file) {
- items.push(ListItem::new(item.clone().magenta().bold()))
+ if s.contains(&app.conn.current_song.file) {
+ let row = Row::new(vec![
+ Cell::from(artist),
+ Cell::from(track.green()),
+ Cell::from(title),
+ Cell::from(album),
+ Cell::from(time.to_string().magenta()),
+ ]);
+ row.magenta().bold()
} else {
- items.push(ListItem::new(item.clone()));
+ let row = Row::new(vec![
+ Cell::from(artist),
+ Cell::from(track.green()),
+ Cell::from(title),
+ Cell::from(album),
+ Cell::from(time.to_string().magenta()),
+ ]);
+ row
}
- }
- let list = List::new(items)
- .block(title.borders(Borders::ALL))
- .highlight_style(
- Style::new()
- .fg(Color::Cyan)
- .bg(Color::Black)
- .add_modifier(Modifier::BOLD)
- .add_modifier(Modifier::REVERSED),
- )
- .highlight_symbol(">>");
+ });
+
+ let mut state = TableState::new();
+ let header = ["Artist", "Track", "Title", "Album", "Time"]
+ .into_iter()
+ .map(Cell::from)
+ .collect::<Row>()
+ .bold()
+ .height(1);
+ let table = Table::new(
+ rows,
+ [
+ Constraint::Percentage(20),
+ Constraint::Percentage(3),
+ Constraint::Min(30),
+ Constraint::Percentage(30),
+ Constraint::Percentage(3),
+ ],
+ )
+ .block(
+ Block::default()
+ .title(Title::from("Play Queue".green().bold()))
+ .title(Title::from(
+ format!("({} items)", app.queue_list.list.len()).bold(),
+ ))
+ .title(
+ Title::from(format!("Volume: {}%", app.conn.volume).bold().green())
+ .alignment(Alignment::Right),
+ )
+ .borders(Borders::ALL),
+ )
+ .highlight_style(
+ Style::default()
+ .add_modifier(Modifier::REVERSED)
+ .fg(Color::Cyan)
+ .bg(Color::Black),
+ )
+ .highlight_symbol(">>")
+ .header(header)
+ .flex(layout::Flex::Legacy);
- queue_state.select(Some(app.queue_list.index));
- frame.render_stateful_widget(list, size, &mut queue_state);
+ state.select(Some(app.queue_list.index));
+ frame.render_stateful_widget(table, size, &mut state);
}
/// draws all playlists