diff --git a/src/config.rs b/src/config.rs index c42d111b..db23cca3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -44,6 +44,7 @@ pub struct TrackFormat { pub left: Option, pub center: Option, pub right: Option, + pub number_format: Option, } impl TrackFormat { @@ -52,6 +53,7 @@ impl TrackFormat { left: Some(String::from("%artists - %title")), center: Some(String::from("%album")), right: Some(String::from("%saved %duration")), + number_format: Some(String::from("{:>2}")), } } } @@ -61,6 +63,7 @@ impl TrackFormat { pub struct NotificationFormat { pub title: Option, pub body: Option, + pub number_format: Option, } impl NotificationFormat { @@ -68,6 +71,7 @@ impl NotificationFormat { Self { title: Some(String::from("%title")), body: Some(String::from("%artists")), + number_format: Some(String::from("{0:2}")), } } } @@ -98,6 +102,7 @@ pub struct ConfigValues { pub track_format: Option, pub notification_format: Option, pub statusbar_format: Option, + pub number_format: Option, pub library_tabs: Option>, pub hide_display_names: Option, pub ap_port: Option, diff --git a/src/model/playable.rs b/src/model/playable.rs index 72cf2c36..619219f3 100644 --- a/src/model/playable.rs +++ b/src/model/playable.rs @@ -10,6 +10,7 @@ use crate::queue::Queue; use crate::traits::{ListItem, ViewExt}; use crate::utils::ms_to_hms; use std::fmt; +use std::fmt::Display; use std::sync::Arc; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -19,8 +20,26 @@ pub enum Playable { Episode(Episode), } +fn fmt_number(num_fmt: &str, num: T) -> String { + match num_fmt { + "{:01}" => format!("{:01}", num), + "{:02}" => format!("{:02}", num), + "{:03}" => format!("{:03}", num), + "{:04}" => format!("{:04}", num), + "{:05}" => format!("{:05}", num), + "{:>1}" => format!("{:>1}", num), + "{:>2}" => format!("{:>2}", num), + "{:>3}" => format!("{:>3}", num), + "{:>4}" => format!("{:>4}", num), + "{:>5}" => format!("{:>5}", num), + _ => { + num.to_string() + } + } +} + impl Playable { - pub fn format(playable: &Self, formatting: &str, library: &Library) -> String { + pub fn format(playable: &Self, formatting: &str, number_format: &str, library: &Library) -> String { formatting .replace( "%artists", @@ -52,6 +71,22 @@ impl Playable { } .as_str(), ) + .replace( + "%track_number", + match playable.clone() { + Self::Episode(episode) => episode.list_index.to_string(), + Self::Track(track) => fmt_number(&number_format, &track.track_number), + } + .as_str(), + ) + .replace( + "%disc_number", + match playable.clone() { + Self::Track(track) => track.disc_number.to_string(), + Self::Episode(_episode) => String::new(), + } + .as_str(), + ) .replace( "%album", match playable.clone() { diff --git a/src/model/track.rs b/src/model/track.rs index 66dfde79..ca788219 100644 --- a/src/model/track.rs +++ b/src/model/track.rs @@ -185,9 +185,11 @@ impl ListItem for Track { .clone() .unwrap_or_default(); let default = config::TrackFormat::default().left.unwrap(); + let default_tno_fmt = config::TrackFormat::default().number_format.unwrap(); let left = formatting.left.unwrap_or_else(|| default.clone()); + let tno_fmt = formatting.number_format.unwrap_or_else(|| default_tno_fmt.clone()); if left != default { - Playable::format(&Playable::Track(self.clone()), &left, library) + Playable::format(&Playable::Track(self.clone()), &left, &tno_fmt, library) } else { format!("{self}") } @@ -201,9 +203,11 @@ impl ListItem for Track { .clone() .unwrap_or_default(); let default = config::TrackFormat::default().center.unwrap(); + let default_tno_fmt = config::TrackFormat::default().number_format.unwrap(); let center = formatting.center.unwrap_or_else(|| default.clone()); + let tno_fmt = formatting.number_format.unwrap_or_else(|| default_tno_fmt.clone()); if center != default { - Playable::format(&Playable::Track(self.clone()), ¢er, library) + Playable::format(&Playable::Track(self.clone()), ¢er, &tno_fmt, library) } else { self.album.clone().unwrap_or_default() } @@ -217,9 +221,11 @@ impl ListItem for Track { .clone() .unwrap_or_default(); let default = config::TrackFormat::default().right.unwrap(); + let default_tno_fmt = config::TrackFormat::default().number_format.unwrap(); let right = formatting.right.unwrap_or_else(|| default.clone()); + let tno_fmt = formatting.number_format.unwrap_or_else(|| default_tno_fmt.clone()); if right != default { - Playable::format(&Playable::Track(self.clone()), &right, library) + Playable::format(&Playable::Track(self.clone()), &right, &tno_fmt, library) } else { let saved = if library.is_saved_track(&Playable::Track(self.clone())) { if library.cfg.values().use_nerdfont.unwrap_or(false) { diff --git a/src/queue.rs b/src/queue.rs index e200ffc5..85a12bf6 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -308,8 +308,8 @@ impl Queue { let default_body = crate::config::NotificationFormat::default().body.unwrap(); let body = format.body.unwrap_or_else(|| default_body.clone()); - let summary_txt = Playable::format(track, &title, &self.library); - let body_txt = Playable::format(track, &body, &self.library); + let summary_txt = Playable::format(track, &title, "", &self.library); + let body_txt = Playable::format(track, &body, "", &self.library); let cover_url = track.cover_url(); move || send_notification(&summary_txt, &body_txt, cover_url) }); diff --git a/src/ui/statusbar.rs b/src/ui/statusbar.rs index 437601de..bb533371 100644 --- a/src/ui/statusbar.rs +++ b/src/ui/statusbar.rs @@ -79,7 +79,14 @@ impl StatusBar { .statusbar_format .clone() .unwrap_or_else(|| "%artists - %title".to_string()); - Playable::format(t, &format, &self.library) + let number_format = self + .library + .cfg + .values() + .number_format + .clone() + .unwrap_or_else(|| "{:>2}".to_string()); + Playable::format(t, &format, &number_format, &self.library) } }