Display all the extra album info #173
119
src/tui/ui.rs
119
src/tui/ui.rs
@ -198,15 +198,18 @@ impl<'a, 'b> ArtistState<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
struct InfoOverlay;
|
||||
|
||||
impl InfoOverlay {
|
||||
const ITEM_INDENT: &'static str = " ";
|
||||
const LIST_INDENT: &'static str = " - ";
|
||||
}
|
||||
|
||||
struct ArtistOverlay<'a> {
|
||||
properties: Paragraph<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ArtistOverlay<'a> {
|
||||
fn opt_opt_to_str<S: AsRef<str> + ?Sized>(opt: Option<Option<&S>>) -> &str {
|
||||
opt.flatten().map(|item| item.as_ref()).unwrap_or("")
|
||||
}
|
||||
|
||||
fn opt_hashmap_to_string<K: Ord + AsRef<str>, T: AsRef<str>>(
|
||||
opt_map: Option<&HashMap<K, Vec<T>>>,
|
||||
item_indent: &str,
|
||||
@ -254,8 +257,8 @@ impl<'a> ArtistOverlay<'a> {
|
||||
fn new(artists: &'a [Artist], state: &ListState) -> ArtistOverlay<'a> {
|
||||
let artist = state.selected().map(|i| &artists[i]);
|
||||
|
||||
let item_indent = " ";
|
||||
let list_indent = " - ";
|
||||
let item_indent = InfoOverlay::ITEM_INDENT;
|
||||
let list_indent = InfoOverlay::LIST_INDENT;
|
||||
|
||||
let double_item_indent = format!("{item_indent}{item_indent}");
|
||||
let double_list_indent = format!("{item_indent}{list_indent}");
|
||||
@ -265,7 +268,9 @@ impl<'a> ArtistOverlay<'a> {
|
||||
MusicBrainz: {}\n{item_indent}\
|
||||
Properties: {}",
|
||||
artist.map(|a| a.id.name.as_str()).unwrap_or(""),
|
||||
Self::opt_opt_to_str(artist.map(|a| a.musicbrainz.as_ref().map(|mb| mb.url()))),
|
||||
artist
|
||||
.and_then(|a| a.musicbrainz.as_ref().map(|mb| mb.url().as_str()))
|
||||
.unwrap_or(""),
|
||||
Self::opt_hashmap_to_string(
|
||||
artist.map(|a| &a.properties),
|
||||
&double_item_indent,
|
||||
@ -413,6 +418,29 @@ impl<'a, 'b> AlbumState<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
struct AlbumOverlay<'a> {
|
||||
properties: Paragraph<'a>,
|
||||
}
|
||||
|
||||
impl<'a> AlbumOverlay<'a> {
|
||||
fn new(albums: &'a [Album], state: &ListState) -> AlbumOverlay<'a> {
|
||||
let album = state.selected().map(|i| &albums[i]);
|
||||
|
||||
let item_indent = InfoOverlay::ITEM_INDENT;
|
||||
|
||||
let properties = Paragraph::new(format!(
|
||||
"Album: {}\n\n{item_indent}\
|
||||
MusicBrainz: {}",
|
||||
album.map(|a| a.id.title.as_str()).unwrap_or(""),
|
||||
album
|
||||
.and_then(|a| a.musicbrainz.as_ref().map(|mb| mb.url().as_str()))
|
||||
.unwrap_or(""),
|
||||
));
|
||||
|
||||
AlbumOverlay { properties }
|
||||
}
|
||||
}
|
||||
|
||||
struct TrackState<'a, 'b> {
|
||||
active: bool,
|
||||
list: List<'a>,
|
||||
@ -750,9 +778,18 @@ impl Ui {
|
||||
fn render_info_overlay(artists: &Collection, selection: &mut Selection, frame: &mut Frame) {
|
||||
let area = OverlayBuilder::default().build(frame.size());
|
||||
|
||||
let artist_overlay = ArtistOverlay::new(artists, &selection.widget_state_artist().list);
|
||||
|
||||
Self::render_overlay_widget("Artist", artist_overlay.properties, area, false, frame);
|
||||
if selection.category() == Category::Artist {
|
||||
let artist_overlay = ArtistOverlay::new(artists, &selection.widget_state_artist().list);
|
||||
Self::render_overlay_widget("Artist", artist_overlay.properties, area, false, frame);
|
||||
} else {
|
||||
let no_albums: Vec<Album> = vec![];
|
||||
let albums = selection
|
||||
.state_album(artists)
|
||||
.map(|st| st.list)
|
||||
.unwrap_or_else(|| &no_albums);
|
||||
let album_overlay = AlbumOverlay::new(albums, &selection.widget_state_album().list);
|
||||
Self::render_overlay_widget("Album", album_overlay.properties, area, false, frame);
|
||||
}
|
||||
}
|
||||
|
||||
fn render_reload_overlay(frame: &mut Frame) {
|
||||
@ -880,6 +917,68 @@ mod tests {
|
||||
assert_eq!(AlbumState::display_date(&date, &AlbumSeq(5)), "1990 (5)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_primary_type() {
|
||||
assert_eq!(
|
||||
AlbumState::display_primary_type(&AlbumPrimaryType::Album),
|
||||
"Album"
|
||||
);
|
||||
assert_eq!(
|
||||
AlbumState::display_primary_type(&AlbumPrimaryType::Single),
|
||||
"Single"
|
||||
);
|
||||
assert_eq!(
|
||||
AlbumState::display_primary_type(&AlbumPrimaryType::Ep),
|
||||
"EP"
|
||||
);
|
||||
assert_eq!(
|
||||
AlbumState::display_primary_type(&AlbumPrimaryType::Broadcast),
|
||||
"Broadcast"
|
||||
);
|
||||
assert_eq!(
|
||||
AlbumState::display_primary_type(&AlbumPrimaryType::Other),
|
||||
"Other"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_secondary_types() {
|
||||
assert_eq!(
|
||||
AlbumState::display_secondary_types(&vec![
|
||||
AlbumSecondaryType::Compilation,
|
||||
AlbumSecondaryType::Soundtrack,
|
||||
AlbumSecondaryType::Spokenword,
|
||||
AlbumSecondaryType::Interview,
|
||||
AlbumSecondaryType::Audiobook,
|
||||
AlbumSecondaryType::AudioDrama,
|
||||
AlbumSecondaryType::Live,
|
||||
AlbumSecondaryType::Remix,
|
||||
AlbumSecondaryType::DjMix,
|
||||
AlbumSecondaryType::MixtapeStreet,
|
||||
AlbumSecondaryType::Demo,
|
||||
AlbumSecondaryType::FieldRecording,
|
||||
]),
|
||||
"Compilation, Soundtrack, Spokenword, Interview, Audiobook, Audio drama, Live, Remix, \
|
||||
DJ-mix, Mixtape/Street, Demo, Field recording"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_type() {
|
||||
assert_eq!(AlbumState::display_type(&None, &vec![]), "");
|
||||
assert_eq!(
|
||||
AlbumState::display_type(&Some(AlbumPrimaryType::Album), &vec![]),
|
||||
"Album"
|
||||
);
|
||||
assert_eq!(
|
||||
AlbumState::display_type(
|
||||
&Some(AlbumPrimaryType::Album),
|
||||
&vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation]
|
||||
),
|
||||
"Album (Live, Compilation)"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_album_status() {
|
||||
assert_eq!(AlbumState::display_album_status(&AlbumStatus::None), "None");
|
||||
|
Loading…
Reference in New Issue
Block a user