diff --git a/src/handlers/sonarr_handlers/library/library_handler_tests.rs b/src/handlers/sonarr_handlers/library/library_handler_tests.rs index ca8bece..9d5c93b 100644 --- a/src/handlers/sonarr_handlers/library/library_handler_tests.rs +++ b/src/handlers/sonarr_handlers/library/library_handler_tests.rs @@ -12,7 +12,7 @@ mod tests { use crate::handlers::sonarr_handlers::library::{series_sorting_options, LibraryHandler}; use crate::handlers::KeyEventHandler; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SERIES_BLOCKS}; - use crate::models::sonarr_models::{Series, SeriesType}; + use crate::models::sonarr_models::{Series, SeriesStatus, SeriesType}; use crate::models::stateful_table::SortOption; use crate::models::HorizontallyScrollableText; @@ -1563,8 +1563,13 @@ mod tests { } #[test] - fn test_series_sorting_options_runtime() { - let expected_cmp_fn: fn(&Series, &Series) -> Ordering = |a, b| a.runtime.cmp(&b.runtime); + fn test_series_sorting_options_status() { + let expected_cmp_fn: fn(&Series, &Series) -> Ordering = |a, b| { + a.status + .to_string() + .to_lowercase() + .cmp(&b.status.to_string().to_lowercase()) + }; let mut expected_series_vec = series_vec(); expected_series_vec.sort_by(expected_cmp_fn); @@ -1573,7 +1578,7 @@ mod tests { sorted_series_vec.sort_by(sort_option.cmp_fn.unwrap()); assert_eq!(sorted_series_vec, expected_series_vec); - assert_str_eq!(sort_option.name, "Runtime"); + assert_str_eq!(sort_option.name, "Status"); } #[test] @@ -1766,7 +1771,7 @@ mod tests { year: 2024, monitored: false, season_folder: false, - runtime: 12.into(), + status: SeriesStatus::Ended, quality_profile_id: 1, language_profile_id: 1, certification: Some("TV-MA".to_owned()), @@ -1781,7 +1786,7 @@ mod tests { year: 1998, monitored: false, season_folder: false, - runtime: 60.into(), + status: SeriesStatus::Continuing, quality_profile_id: 2, language_profile_id: 2, certification: Some("TV-PG".to_owned()), @@ -1796,7 +1801,7 @@ mod tests { year: 1954, monitored: true, season_folder: false, - runtime: 120.into(), + status: SeriesStatus::Upcoming, quality_profile_id: 3, language_profile_id: 3, certification: Some("TV-G".to_owned()), diff --git a/src/handlers/sonarr_handlers/library/mod.rs b/src/handlers/sonarr_handlers/library/mod.rs index 3cde86b..55dc92e 100644 --- a/src/handlers/sonarr_handlers/library/mod.rs +++ b/src/handlers/sonarr_handlers/library/mod.rs @@ -403,8 +403,13 @@ fn series_sorting_options() -> Vec> { }), }, SortOption { - name: "Runtime", - cmp_fn: Some(|a, b| a.runtime.cmp(&b.runtime)), + name: "Status", + cmp_fn: Some(|a, b| { + a.status + .to_string() + .to_lowercase() + .cmp(&b.status.to_string().to_lowercase()) + }), }, SortOption { name: "Rating", diff --git a/src/ui/sonarr_ui/library/mod.rs b/src/ui/sonarr_ui/library/mod.rs index 6b77a47..a9661b3 100644 --- a/src/ui/sonarr_ui/library/mod.rs +++ b/src/ui/sonarr_ui/library/mod.rs @@ -4,6 +4,11 @@ use ratatui::{ Frame, }; +use crate::ui::widgets::{ + confirmation_prompt::ConfirmationPrompt, + message::Message, + popup::{Popup, Size}, +}; use crate::{ app::App, models::{ @@ -12,12 +17,12 @@ use crate::{ EnumDisplayStyle, Route, }, ui::{ + draw_input_box_popup, draw_popup_over, styles::ManagarrStyle, utils::{get_width_from_percentage, layout_block_top_border}, widgets::managarr_table::ManagarrTable, DrawUi, }, - utils::convert_runtime, }; #[cfg(test)] @@ -40,6 +45,44 @@ impl DrawUi for LibraryUi { let mut series_ui_matchers = |active_sonarr_block: ActiveSonarrBlock| match active_sonarr_block { ActiveSonarrBlock::Series | ActiveSonarrBlock::SeriesSortPrompt => draw_series(f, app, area), + ActiveSonarrBlock::SearchSeries => draw_popup_over( + f, + app, + area, + draw_series, + draw_series_search_box, + Size::InputBox, + ), + ActiveSonarrBlock::SearchSeriesError => { + let popup = Popup::new(Message::new("Series not found!")).size(Size::Message); + + draw_series(f, app, area); + f.render_widget(popup, f.area()); + } + ActiveSonarrBlock::FilterSeries => draw_popup_over( + f, + app, + area, + draw_series, + draw_filter_series_box, + Size::InputBox, + ), + ActiveSonarrBlock::FilterSeriesError => { + let popup = Popup::new(Message::new("No series found matching the given filter!")) + .size(Size::Message); + + draw_series(f, app, area); + f.render_widget(popup, f.area()); + } + ActiveSonarrBlock::UpdateAllSeriesPrompt => { + let confirmation_prompt = ConfirmationPrompt::new() + .title("Update All Series") + .prompt("Do you want to update info and scan your disks for all of your series?") + .yes_no_value(app.data.sonarr_data.prompt_confirm); + + draw_series(f, app, area); + f.render_widget(Popup::new(confirmation_prompt).size(Size::Prompt), f.area()); + } _ => (), }; @@ -71,12 +114,11 @@ pub(super) fn draw_series(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let series_table_row_mapping = |series: &Series| { series.title.scroll_left_or_reset( - get_width_from_percentage(area, 27), + get_width_from_percentage(area, 23), *series == current_selection, app.tick_count % app.ticks_until_scroll == 0, ); let monitored = if series.monitored { "🏷" } else { "" }; - let (hours, minutes) = convert_runtime(series.runtime); let certification = series.certification.clone().unwrap_or_default(); let network = series.network.clone().unwrap_or_default(); let quality_profile = quality_profile_map @@ -109,7 +151,7 @@ pub(super) fn draw_series(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { Cell::from(series.title.to_string()), Cell::from(series.year.to_string()), Cell::from(network), - Cell::from(format!("{hours}h {minutes}m")), + Cell::from(series.status.to_display_str()), Cell::from(certification), Cell::from(series.series_type.to_display_str()), Cell::from(quality_profile), @@ -128,7 +170,7 @@ pub(super) fn draw_series(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { "Title", "Year", "Network", - "Runtime", + "Status", "Rating", "Type", "Quality Profile", @@ -137,9 +179,9 @@ pub(super) fn draw_series(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { "Tags", ]) .constraints([ - Constraint::Percentage(27), + Constraint::Percentage(23), Constraint::Percentage(4), - Constraint::Percentage(10), + Constraint::Percentage(14), Constraint::Percentage(6), Constraint::Percentage(6), Constraint::Percentage(6), @@ -177,3 +219,21 @@ fn decorate_series_row_with_style<'a>(series: &Series, row: Row<'a>) -> Row<'a> _ => row.missing(), } } + +fn draw_series_search_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + draw_input_box_popup( + f, + area, + "Search", + app.data.sonarr_data.series.search.as_ref().unwrap(), + ); +} + +fn draw_filter_series_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + draw_input_box_popup( + f, + area, + "Filter", + app.data.sonarr_data.series.filter.as_ref().unwrap(), + ) +}