Show tracks + duration of album, playlist, queue

Stats are in the top right

Fixes #475
This commit is contained in:
Henrik Friedrichsen
2021-04-08 22:13:07 +02:00
parent 577e7ebd87
commit 32cb6e70d3
7 changed files with 83 additions and 0 deletions

View File

@@ -69,6 +69,7 @@ mod theme;
mod track;
mod traits;
mod ui;
mod utils;
#[cfg(feature = "mpris")]
mod mpris;

View File

@@ -55,6 +55,10 @@ pub trait ViewExt: View {
"".into()
}
fn title_sub(&self) -> String {
"".into()
}
fn on_leave(&self) {}
fn on_command(&mut self, _s: &mut Cursive, _cmd: &Command) -> Result<CommandResult, String> {
@@ -67,6 +71,10 @@ impl<V: ViewExt> ViewExt for NamedView<V> {
self.with_view(|v| v.title()).unwrap_or_default()
}
fn title_sub(&self) -> String {
self.with_view(|v| v.title_sub()).unwrap_or_default()
}
fn on_leave(&self) {
self.with_view(|v| v.on_leave());
}

View File

@@ -66,6 +66,17 @@ impl ViewExt for AlbumView {
format!("{} ({})", self.album.title, self.album.year)
}
fn title_sub(&self) -> String {
if let Some(tracks) = &self.album.tracks {
let duration_secs: u64 = tracks.iter().map(|t| t.duration as u64 / 1000).sum();
let duration = std::time::Duration::from_secs(duration_secs);
let duration_str = crate::utils::format_duration(&duration);
format!("{} tracks, {}", tracks.len(), duration_str)
} else {
"".to_string()
}
}
fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
self.tabs.on_command(s, cmd)
}

View File

@@ -219,6 +219,11 @@ impl View for Layout {
printer.print((offset, 0), &view.title());
});
printer.with_color(ColorStyle::secondary(), |printer| {
let offset = HAlign::Right.get_offset(view.title_sub().width(), printer.size.x);
printer.print((offset, 0), &view.title_sub());
});
// screen content
let printer = &printer
.offset((0, 1))

View File

@@ -62,6 +62,20 @@ impl ViewExt for PlaylistView {
self.playlist.name.clone()
}
fn title_sub(&self) -> String {
if let Some(tracks) = self.playlist.tracks.as_ref() {
let duration_secs = tracks.iter().map(|p| p.duration as u64 / 1000).sum();
let duration = std::time::Duration::from_secs(duration_secs);
format!(
"{} tracks, {}",
tracks.len(),
crate::utils::format_duration(&duration)
)
} else {
"".to_string()
}
}
fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
if let Command::Delete = cmd {
let pos = self.list.get_selected_index();

View File

@@ -93,6 +93,29 @@ impl ViewExt for QueueView {
"Queue".to_string()
}
fn title_sub(&self) -> String {
let track_count = self.queue.len();
let duration_secs: u64 = self
.queue
.queue
.read()
.unwrap()
.iter()
.map(|p| p.duration() as u64 / 1000)
.sum();
if duration_secs > 0 {
let duration = std::time::Duration::from_secs(duration_secs);
format!(
"{} tracks, {}",
track_count,
crate::utils::format_duration(&duration)
)
} else {
"".to_string()
}
}
fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
match cmd {
Command::Play => {

21
src/utils.rs Normal file
View File

@@ -0,0 +1,21 @@
/// Returns a human readable String of a Duration
///
/// Example: `3h 12m 53s`
pub fn format_duration(d: &std::time::Duration) -> String {
let mut s = String::new();
let mut append_unit = |value, unit| {
if value > 0 {
s.push_str(&format!("{}{}", value, unit));
}
};
let seconds = d.as_secs() % 60;
let minutes = (d.as_secs() / 60) % 60;
let hours = (d.as_secs() / 60) / 60;
append_unit(hours, "h ");
append_unit(minutes, "m ");
append_unit(seconds, "s ");
s.trim_end().to_string()
}