194 lines
5.6 KiB
Rust
194 lines
5.6 KiB
Rust
use delete_artist_ui::DeleteArtistUi;
|
|
use ratatui::{
|
|
Frame,
|
|
layout::{Constraint, Rect},
|
|
widgets::{Cell, Row},
|
|
};
|
|
|
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
|
use crate::utils::convert_to_gb;
|
|
use crate::{
|
|
app::App,
|
|
models::{
|
|
Route,
|
|
lidarr_models::{Artist, ArtistStatus},
|
|
servarr_data::lidarr::lidarr_data::{ActiveLidarrBlock, LIBRARY_BLOCKS},
|
|
},
|
|
ui::{
|
|
DrawUi,
|
|
styles::ManagarrStyle,
|
|
utils::{get_width_from_percentage, layout_block_top_border},
|
|
},
|
|
};
|
|
|
|
mod delete_artist_ui;
|
|
|
|
#[cfg(test)]
|
|
#[path = "library_ui_tests.rs"]
|
|
mod library_ui_tests;
|
|
|
|
pub(super) struct LibraryUi;
|
|
|
|
impl DrawUi for LibraryUi {
|
|
fn accepts(route: Route) -> bool {
|
|
if let Route::Lidarr(active_lidarr_block, _) = route {
|
|
return DeleteArtistUi::accepts(route) || LIBRARY_BLOCKS.contains(&active_lidarr_block);
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|
let route = app.get_current_route();
|
|
draw_library(f, app, area);
|
|
|
|
if DeleteArtistUi::accepts(route) {
|
|
DeleteArtistUi::draw(f, app, area);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|
if let Route::Lidarr(active_lidarr_block, _) = app.get_current_route() {
|
|
let current_selection = if !app.data.lidarr_data.artists.items.is_empty() {
|
|
app.data.lidarr_data.artists.current_selection().clone()
|
|
} else {
|
|
Artist::default()
|
|
};
|
|
let quality_profile_map = &app.data.lidarr_data.quality_profile_map;
|
|
let metadata_profile_map = &app.data.lidarr_data.metadata_profile_map;
|
|
let tags_map = &app.data.lidarr_data.tags_map;
|
|
let content = Some(&mut app.data.lidarr_data.artists);
|
|
|
|
let artists_table_row_mapping = |artist: &Artist| {
|
|
artist.artist_name.scroll_left_or_reset(
|
|
get_width_from_percentage(area, 25),
|
|
*artist == current_selection,
|
|
app.ui_scroll_tick_count == 0,
|
|
);
|
|
let monitored = if artist.monitored { "🏷" } else { "" };
|
|
let artist_type = artist.artist_type.clone().unwrap_or_default();
|
|
let size = artist
|
|
.statistics
|
|
.as_ref()
|
|
.map_or(0f64, |stats| convert_to_gb(stats.size_on_disk));
|
|
let quality_profile = quality_profile_map
|
|
.get_by_left(&artist.quality_profile_id)
|
|
.cloned()
|
|
.unwrap_or_default();
|
|
let metadata_profile = metadata_profile_map
|
|
.get_by_left(&artist.metadata_profile_id)
|
|
.cloned()
|
|
.unwrap_or_default();
|
|
let albums = artist
|
|
.statistics
|
|
.as_ref()
|
|
.map_or(0, |stats| stats.album_count);
|
|
let tracks = artist
|
|
.statistics
|
|
.as_ref()
|
|
.map_or(String::new(), |stats| {
|
|
format!("{}/{}", stats.track_file_count, stats.total_track_count)
|
|
});
|
|
let tags = artist
|
|
.tags
|
|
.iter()
|
|
.filter_map(|tag_id| {
|
|
let id = tag_id.as_i64()?;
|
|
tags_map.get_by_left(&id).cloned()
|
|
})
|
|
.collect::<Vec<_>>()
|
|
.join(", ");
|
|
|
|
decorate_artist_row_with_style(
|
|
artist,
|
|
Row::new(vec![
|
|
Cell::from(artist.artist_name.to_string()),
|
|
Cell::from(artist_type),
|
|
Cell::from(artist.status.to_display_str()),
|
|
Cell::from(quality_profile),
|
|
Cell::from(metadata_profile),
|
|
Cell::from(albums.to_string()),
|
|
Cell::from(tracks),
|
|
Cell::from(format!("{size:.2} GB")),
|
|
Cell::from(monitored.to_owned()),
|
|
Cell::from(tags),
|
|
]),
|
|
)
|
|
};
|
|
let artists_table = ManagarrTable::new(content, artists_table_row_mapping)
|
|
.block(layout_block_top_border())
|
|
.loading(app.is_loading)
|
|
.sorting(active_lidarr_block == ActiveLidarrBlock::ArtistsSortPrompt)
|
|
.searching(active_lidarr_block == ActiveLidarrBlock::SearchArtists)
|
|
.filtering(active_lidarr_block == ActiveLidarrBlock::FilterArtists)
|
|
.search_produced_empty_results(active_lidarr_block == ActiveLidarrBlock::SearchArtistsError)
|
|
.filter_produced_empty_results(active_lidarr_block == ActiveLidarrBlock::FilterArtistsError)
|
|
.headers([
|
|
"Name",
|
|
"Type",
|
|
"Status",
|
|
"Quality Profile",
|
|
"Metadata Profile",
|
|
"Albums",
|
|
"Tracks",
|
|
"Size",
|
|
"Monitored",
|
|
"Tags",
|
|
])
|
|
.constraints([
|
|
Constraint::Percentage(22),
|
|
Constraint::Percentage(8),
|
|
Constraint::Percentage(8),
|
|
Constraint::Percentage(12),
|
|
Constraint::Percentage(12),
|
|
Constraint::Percentage(6),
|
|
Constraint::Percentage(8),
|
|
Constraint::Percentage(7),
|
|
Constraint::Percentage(6),
|
|
Constraint::Percentage(11),
|
|
]);
|
|
|
|
if [
|
|
ActiveLidarrBlock::SearchArtists,
|
|
ActiveLidarrBlock::FilterArtists,
|
|
]
|
|
.contains(&active_lidarr_block)
|
|
{
|
|
artists_table.show_cursor(f, area);
|
|
}
|
|
|
|
f.render_widget(artists_table, area);
|
|
}
|
|
}
|
|
|
|
fn decorate_artist_row_with_style<'a>(artist: &Artist, row: Row<'a>) -> Row<'a> {
|
|
if !artist.monitored {
|
|
return row.unmonitored();
|
|
}
|
|
|
|
match artist.status {
|
|
ArtistStatus::Ended => {
|
|
if let Some(ref stats) = artist.statistics {
|
|
return if stats.track_file_count == stats.total_track_count && stats.total_track_count > 0 {
|
|
row.downloaded()
|
|
} else {
|
|
row.missing()
|
|
};
|
|
}
|
|
row.indeterminate()
|
|
}
|
|
ArtistStatus::Continuing => {
|
|
if let Some(ref stats) = artist.statistics {
|
|
return if stats.track_file_count == stats.total_track_count && stats.total_track_count > 0 {
|
|
row.unreleased()
|
|
} else {
|
|
row.missing()
|
|
};
|
|
}
|
|
row.indeterminate()
|
|
}
|
|
_ => row.indeterminate(),
|
|
}
|
|
}
|