Add a field that indicates album ownership #156
@ -102,9 +102,7 @@ impl AlbumMonth {
|
|||||||
pub struct AlbumSeq(pub u8);
|
pub struct AlbumSeq(pub u8);
|
||||||
|
|
||||||
/// The album's ownership status.
|
/// The album's ownership status.
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Ord, Eq, Hash)]
|
|
||||||
pub enum AlbumStatus {
|
pub enum AlbumStatus {
|
||||||
#[default]
|
|
||||||
None,
|
None,
|
||||||
Owned(TrackFormat),
|
Owned(TrackFormat),
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,20 @@ use musichoard::collection::{
|
|||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Alignment, Rect},
|
layout::{Alignment, Rect},
|
||||||
style::{Color, Style},
|
style::{Color, Style},
|
||||||
|
text::Line,
|
||||||
widgets::{Block, BorderType, Borders, Clear, List, ListItem, ListState, Paragraph, Wrap},
|
widgets::{Block, BorderType, Borders, Clear, List, ListItem, ListState, Paragraph, Wrap},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::tui::app::{AppPublicState, AppState, Category, IAppAccess, Selection, WidgetState};
|
use crate::tui::app::{AppPublicState, AppState, Category, IAppAccess, Selection, WidgetState};
|
||||||
|
|
||||||
|
const COLOR_BG: Color = Color::Black;
|
||||||
|
const COLOR_BG_HL: Color = Color::DarkGray;
|
||||||
|
const COLOR_FG: Color = Color::White;
|
||||||
|
const COLOR_FG_ERR: Color = Color::Red;
|
||||||
|
const COLOR_FG_WARN: Color = Color::LightYellow;
|
||||||
|
const COLOR_FG_GOOD: Color = Color::LightGreen;
|
||||||
|
|
||||||
pub trait IUi {
|
pub trait IUi {
|
||||||
fn render<APP: IAppAccess>(app: &mut APP, frame: &mut Frame);
|
fn render<APP: IAppAccess>(app: &mut APP, frame: &mut Frame);
|
||||||
}
|
}
|
||||||
@ -280,7 +288,7 @@ impl<'a, 'b> AlbumState<'a, 'b> {
|
|||||||
let list = List::new(
|
let list = List::new(
|
||||||
albums
|
albums
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| ListItem::new(a.id.title.as_str()))
|
.map(Self::to_list_item)
|
||||||
.collect::<Vec<ListItem>>(),
|
.collect::<Vec<ListItem>>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -310,6 +318,17 @@ impl<'a, 'b> AlbumState<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_list_item(album: &Album) -> ListItem {
|
||||||
|
let line = match album.get_status() {
|
||||||
|
AlbumStatus::None => Line::raw(album.id.title.as_str()),
|
||||||
|
AlbumStatus::Owned(format) => match format {
|
||||||
|
TrackFormat::Mp3 => Line::styled(album.id.title.as_str(), COLOR_FG_WARN),
|
||||||
|
TrackFormat::Flac => Line::styled(album.id.title.as_str(), COLOR_FG_GOOD),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ListItem::new(line)
|
||||||
|
}
|
||||||
|
|
||||||
fn display_album_date(date: &AlbumDate) -> String {
|
fn display_album_date(date: &AlbumDate) -> String {
|
||||||
if date.month.is_none() {
|
if date.month.is_none() {
|
||||||
format!("{}", date.year)
|
format!("{}", date.year)
|
||||||
@ -463,11 +482,11 @@ pub struct Ui;
|
|||||||
|
|
||||||
impl Ui {
|
impl Ui {
|
||||||
fn style(_active: bool, error: bool) -> Style {
|
fn style(_active: bool, error: bool) -> Style {
|
||||||
let style = Style::default().bg(Color::Black);
|
let style = Style::default().bg(COLOR_BG);
|
||||||
if error {
|
if error {
|
||||||
style.fg(Color::Red)
|
style.fg(COLOR_FG_ERR)
|
||||||
} else {
|
} else {
|
||||||
style.fg(Color::White)
|
style.fg(COLOR_FG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,10 +495,11 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn highlight_style(active: bool) -> Style {
|
fn highlight_style(active: bool) -> Style {
|
||||||
|
// Do not set foreground colour to not overwrite any list-specific customisation.
|
||||||
if active {
|
if active {
|
||||||
Style::default().fg(Color::White).bg(Color::DarkGray)
|
Style::default().bg(COLOR_BG_HL)
|
||||||
} else {
|
} else {
|
||||||
Self::style(false, false)
|
Style::default().bg(COLOR_BG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,6 +741,8 @@ impl IUi for Ui {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use musichoard::collection::{album::AlbumId, artist::ArtistId};
|
||||||
|
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
app::{AppPublic, AppPublicInner, Delta},
|
app::{AppPublic, AppPublicInner, Delta},
|
||||||
testmod::COLLECTION,
|
testmod::COLLECTION,
|
||||||
@ -839,6 +861,20 @@ mod tests {
|
|||||||
draw_test_suite(&artists, &mut selection);
|
draw_test_suite(&artists, &mut selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_album() {
|
||||||
|
let mut artists: Vec<Artist> = vec![Artist::new(ArtistId::new("An artist"))];
|
||||||
|
artists[0].albums.push(Album {
|
||||||
|
id: AlbumId::new("An album"),
|
||||||
|
date: AlbumDate::default(),
|
||||||
|
seq: AlbumSeq::default(),
|
||||||
|
tracks: vec![],
|
||||||
|
});
|
||||||
|
let mut selection = Selection::new(&artists);
|
||||||
|
|
||||||
|
draw_test_suite(&artists, &mut selection);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn collection() {
|
fn collection() {
|
||||||
let artists = &COLLECTION;
|
let artists = &COLLECTION;
|
||||||
|
Loading…
Reference in New Issue
Block a user