diff --git a/src/ui/mod.rs b/src/ui/mod.rs index fe098c7..4d8c939 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -20,6 +20,7 @@ use crate::ui::utils::{ use crate::ui::widgets::button::Button; use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; +use crate::ui::widgets::popup::Size; mod radarr_ui; mod styles; @@ -112,21 +113,17 @@ pub fn draw_popup( f: &mut Frame<'_>, app: &mut App<'_>, popup_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - percent_x: u16, - percent_y: u16, + size: Size, ) { + let (percent_x, percent_y) = size.to_percent(); let popup_area = centered_rect(percent_x, percent_y, f.size()); f.render_widget(Clear, popup_area); f.render_widget(background_block(), popup_area); popup_fn(f, app, popup_area); } -pub fn draw_popup_ui( - f: &mut Frame<'_>, - app: &mut App<'_>, - percent_x: u16, - percent_y: u16, -) { +fn draw_popup_ui(f: &mut Frame<'_>, app: &mut App<'_>, size: Size) { + let (percent_x, percent_y) = size.to_percent(); let popup_area = centered_rect(percent_x, percent_y, f.size()); f.render_widget(Clear, popup_area); f.render_widget(background_block(), popup_area); @@ -139,12 +136,11 @@ pub fn draw_popup_over( area: Rect, background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), popup_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - percent_x: u16, - percent_y: u16, + size: Size, ) { background_fn(f, app, area); - draw_popup(f, app, popup_fn, percent_x, percent_y); + draw_popup(f, app, popup_fn, size); } pub fn draw_popup_over_ui( @@ -152,61 +148,11 @@ pub fn draw_popup_over_ui( app: &mut App<'_>, area: Rect, background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - percent_x: u16, - percent_y: u16, + size: Size, ) { background_fn(f, app, area); - draw_popup_ui::(f, app, percent_x, percent_y); -} - -pub fn draw_prompt_popup_over( - f: &mut Frame<'_>, - app: &mut App<'_>, - area: Rect, - background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - popup_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), -) { - draw_popup_over(f, app, area, background_fn, popup_fn, 35, 35); -} - -pub fn draw_small_popup_over( - f: &mut Frame<'_>, - app: &mut App<'_>, - area: Rect, - background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - popup_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), -) { - draw_popup_over(f, app, area, background_fn, popup_fn, 40, 40); -} - -pub fn draw_medium_popup_over( - f: &mut Frame<'_>, - app: &mut App<'_>, - area: Rect, - background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - popup_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), -) { - draw_popup_over(f, app, area, background_fn, popup_fn, 60, 60); -} - -pub fn draw_large_popup_over( - f: &mut Frame<'_>, - app: &mut App<'_>, - area: Rect, - background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - popup_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), -) { - draw_popup_over(f, app, area, background_fn, popup_fn, 75, 75); -} - -pub fn draw_large_popup_over_background_fn_with_ui( - f: &mut Frame<'_>, - app: &mut App<'_>, - area: Rect, - background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), -) { - draw_popup_over_ui::(f, app, area, background_fn, 75, 75); + draw_popup_ui::(f, app, size); } fn draw_tabs(f: &mut Frame<'_>, area: Rect, title: &str, tab_state: &TabState) -> Rect { diff --git a/src/ui/radarr_ui/collections/collection_details_ui.rs b/src/ui/radarr_ui/collections/collection_details_ui.rs index 623fcf4..1e03b7b 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui.rs @@ -19,7 +19,8 @@ use crate::ui::utils::{ title_style, }; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::{draw_large_popup_over, draw_small_popup_over, DrawUi}; +use crate::ui::widgets::popup::Size; +use crate::ui::{draw_popup_over, DrawUi}; use crate::utils::convert_runtime; #[cfg(test)] @@ -44,24 +45,26 @@ impl DrawUi for CollectionDetailsUi { .unwrap_or(active_radarr_block) { ActiveRadarrBlock::ViewMovieOverview => { - draw_small_popup_over( + draw_popup_over( f, app, popup_area, draw_collection_details, draw_movie_overview, + Size::Small, ); } ActiveRadarrBlock::CollectionDetails => draw_collection_details(f, app, popup_area), _ => (), }; - draw_large_popup_over( + draw_popup_over( f, app, area, draw_collections, draw_collection_details_popup, + Size::Large, ); } } diff --git a/src/ui/radarr_ui/collections/edit_collection_ui.rs b/src/ui/radarr_ui/collections/edit_collection_ui.rs index be3d839..1c1255b 100644 --- a/src/ui/radarr_ui/collections/edit_collection_ui.rs +++ b/src/ui/radarr_ui/collections/edit_collection_ui.rs @@ -16,11 +16,9 @@ use crate::ui::utils::{layout_paragraph_borderless, title_block_centered}; use crate::ui::widgets::button::Button; use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; -use crate::ui::widgets::popup::Popup; +use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{ - draw_large_popup_over_background_fn_with_ui, draw_medium_popup_over, draw_popup, DrawUi, -}; +use crate::ui::{draw_popup, draw_popup_over, draw_popup_over_ui, DrawUi}; #[cfg(test)] #[path = "edit_collection_ui_tests.rs"] @@ -60,17 +58,17 @@ impl DrawUi for EditCollectionUi { if let Some(context) = context_option { match context { - ActiveRadarrBlock::Collections => { - draw_medium_popup_over(f, app, area, draw_collections, draw_edit_collection_prompt) - } + ActiveRadarrBlock::Collections => draw_popup_over( + f, + app, + area, + draw_collections, + draw_edit_collection_prompt, + Size::Medium, + ), _ if COLLECTION_DETAILS_BLOCKS.contains(&context) => { - draw_large_popup_over_background_fn_with_ui::( - f, - app, - area, - draw_collections, - ); - draw_popup(f, app, draw_edit_collection_prompt, 60, 60); + draw_popup_over_ui::(f, app, area, draw_collections, Size::Large); + draw_popup(f, app, draw_edit_collection_prompt, Size::Medium); } _ => (), } @@ -182,15 +180,12 @@ fn draw_edit_collection_select_minimum_availability_popup(f: &mut Frame<'_>, app .minimum_availability_list, |minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()), ); - let popup = Popup::new(min_availability_list, 20, 30); + let popup = Popup::new(min_availability_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } -fn draw_edit_collection_select_quality_profile_popup( - f: &mut Frame<'_>, - app: &mut App<'_>, -) { +fn draw_edit_collection_select_quality_profile_popup(f: &mut Frame<'_>, app: &mut App<'_>) { let quality_profile_list = SelectableList::new( &mut app .data @@ -201,7 +196,7 @@ fn draw_edit_collection_select_quality_profile_popup( .quality_profile_list, |quality_profile| ListItem::new(quality_profile.clone()), ); - let popup = Popup::new(quality_profile_list, 20, 30); + let popup = Popup::new(quality_profile_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } diff --git a/src/ui/radarr_ui/collections/mod.rs b/src/ui/radarr_ui/collections/mod.rs index 244a449..54c7cca 100644 --- a/src/ui/radarr_ui/collections/mod.rs +++ b/src/ui/radarr_ui/collections/mod.rs @@ -14,9 +14,8 @@ use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{get_width_from_percentage, layout_block_top_border}; use crate::ui::widgets::error_message::ErrorMessage; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::{ - draw_input_box_popup, draw_popup_over, draw_prompt_box, draw_prompt_popup_over, DrawUi, -}; +use crate::ui::widgets::popup::{Popup, Size}; +use crate::ui::{draw_input_box_popup, draw_popup_over, draw_prompt_box, DrawUi}; mod collection_details_ui; #[cfg(test)] @@ -47,42 +46,36 @@ impl DrawUi for CollectionsUi { area, draw_collections, draw_collection_search_box, - 30, - 13, - ), - ActiveRadarrBlock::SearchCollectionError => draw_popup_over( - f, - app, - area, - draw_collections, - draw_search_collection_error_box, - 30, - 8, + Size::InputBox, ), + ActiveRadarrBlock::SearchCollectionError => { + draw_collections(f, app, area); + let popup = Popup::new(ErrorMessage::new("Collection not found!")).size(Size::Error); + f.render_widget(popup, f.size()); + } ActiveRadarrBlock::FilterCollections => draw_popup_over( f, app, area, draw_collections, draw_filter_collections_box, - 30, - 13, + Size::InputBox, ), - ActiveRadarrBlock::FilterCollectionsError => draw_popup_over( - f, - app, - area, - draw_collections, - draw_filter_collections_error_box, - 30, - 8, - ), - ActiveRadarrBlock::UpdateAllCollectionsPrompt => draw_prompt_popup_over( + ActiveRadarrBlock::FilterCollectionsError => { + draw_collections(f, app, area); + let popup = Popup::new(ErrorMessage::new( + "No collections found matching the given filter!", + )) + .size(Size::Error); + f.render_widget(popup, f.size()); + } + ActiveRadarrBlock::UpdateAllCollectionsPrompt => draw_popup_over( f, app, area, draw_collections, draw_update_all_collections_prompt, + Size::Prompt, ), _ => (), }; @@ -193,14 +186,3 @@ fn draw_filter_collections_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) app.data.radarr_data.collections.filter.as_ref().unwrap(), ) } - -fn draw_search_collection_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) { - f.render_widget(ErrorMessage::new("Collection not found!"), area); -} - -fn draw_filter_collections_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) { - f.render_widget( - ErrorMessage::new("No collections found matching the given filter!"), - area, - ); -} diff --git a/src/ui/radarr_ui/downloads/mod.rs b/src/ui/radarr_ui/downloads/mod.rs index a5cae55..f9af419 100644 --- a/src/ui/radarr_ui/downloads/mod.rs +++ b/src/ui/radarr_ui/downloads/mod.rs @@ -9,7 +9,8 @@ use crate::models::{HorizontallyScrollableText, Route}; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{get_width_from_percentage, layout_block_top_border}; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::{draw_prompt_box, draw_prompt_popup_over, DrawUi}; +use crate::ui::widgets::popup::Size; +use crate::ui::{draw_popup_over, draw_prompt_box, DrawUi}; use crate::utils::convert_to_gb; #[cfg(test)] @@ -31,12 +32,22 @@ impl DrawUi for DownloadsUi { if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { match active_radarr_block { ActiveRadarrBlock::Downloads => draw_downloads(f, app, area), - ActiveRadarrBlock::DeleteDownloadPrompt => { - draw_prompt_popup_over(f, app, area, draw_downloads, draw_delete_download_prompt) - } - ActiveRadarrBlock::UpdateDownloadsPrompt => { - draw_prompt_popup_over(f, app, area, draw_downloads, draw_update_downloads_prompt) - } + ActiveRadarrBlock::DeleteDownloadPrompt => draw_popup_over( + f, + app, + area, + draw_downloads, + draw_delete_download_prompt, + Size::Prompt, + ), + ActiveRadarrBlock::UpdateDownloadsPrompt => draw_popup_over( + f, + app, + area, + draw_downloads, + draw_update_downloads_prompt, + Size::Prompt, + ), _ => (), } } diff --git a/src/ui/radarr_ui/indexers/edit_indexer_ui.rs b/src/ui/radarr_ui/indexers/edit_indexer_ui.rs index 8f0d150..d16699d 100644 --- a/src/ui/radarr_ui/indexers/edit_indexer_ui.rs +++ b/src/ui/radarr_ui/indexers/edit_indexer_ui.rs @@ -9,6 +9,7 @@ use crate::ui::widgets::button::Button; use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::loading_block::LoadingBlock; +use crate::ui::widgets::popup::Size; use crate::ui::{draw_popup_over, DrawUi}; use ratatui::layout::{Constraint, Flex, Layout, Rect}; use ratatui::Frame; @@ -35,8 +36,7 @@ impl DrawUi for EditIndexerUi { area, draw_indexers, draw_edit_indexer_prompt, - 70, - 45, + Size::LargePrompt, ); } } diff --git a/src/ui/radarr_ui/indexers/indexer_settings_ui.rs b/src/ui/radarr_ui/indexers/indexer_settings_ui.rs index 6fb0d83..6e55d7c 100644 --- a/src/ui/radarr_ui/indexers/indexer_settings_ui.rs +++ b/src/ui/radarr_ui/indexers/indexer_settings_ui.rs @@ -14,6 +14,7 @@ use crate::ui::widgets::button::Button; use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::loading_block::LoadingBlock; +use crate::ui::widgets::popup::Size; use crate::ui::{draw_popup_over, DrawUi}; #[cfg(test)] @@ -38,8 +39,7 @@ impl DrawUi for IndexerSettingsUi { area, draw_indexers, draw_edit_indexer_settings_prompt, - 70, - 45, + Size::LargePrompt, ); } } diff --git a/src/ui/radarr_ui/indexers/mod.rs b/src/ui/radarr_ui/indexers/mod.rs index 096c011..b96dba9 100644 --- a/src/ui/radarr_ui/indexers/mod.rs +++ b/src/ui/radarr_ui/indexers/mod.rs @@ -13,7 +13,8 @@ use crate::ui::radarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::layout_block_top_border; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::{draw_prompt_box, draw_prompt_popup_over, DrawUi}; +use crate::ui::widgets::popup::Size; +use crate::ui::{draw_popup_over, draw_prompt_box, DrawUi}; mod edit_indexer_ui; mod indexer_settings_ui; @@ -41,9 +42,14 @@ impl DrawUi for IndexersUi { let route = *app.get_current_route(); let mut indexers_matchers = |active_radarr_block| match active_radarr_block { ActiveRadarrBlock::Indexers => draw_indexers(f, app, area), - ActiveRadarrBlock::DeleteIndexerPrompt => { - draw_prompt_popup_over(f, app, area, draw_indexers, draw_delete_indexer_prompt) - } + ActiveRadarrBlock::DeleteIndexerPrompt => draw_popup_over( + f, + app, + area, + draw_indexers, + draw_delete_indexer_prompt, + Size::Prompt, + ), _ => (), }; diff --git a/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs b/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs index b7c6faf..e1a1b59 100644 --- a/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs +++ b/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs @@ -7,7 +7,8 @@ use crate::ui::radarr_ui::indexers::draw_indexers; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{borderless_block, get_width_from_percentage, title_block}; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::{draw_large_popup_over, DrawUi}; +use crate::ui::widgets::popup::Size; +use crate::ui::{draw_popup_over, DrawUi}; use ratatui::layout::{Alignment, Constraint, Rect}; use ratatui::widgets::{Cell, Row}; use ratatui::Frame; @@ -28,12 +29,13 @@ impl DrawUi for TestAllIndexersUi { } fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { - draw_large_popup_over( + draw_popup_over( f, app, area, draw_indexers, draw_test_all_indexers_test_results, + Size::Large, ); } } diff --git a/src/ui/radarr_ui/library/add_movie_ui.rs b/src/ui/radarr_ui/library/add_movie_ui.rs index be0e9cc..9cf8af1 100644 --- a/src/ui/radarr_ui/library/add_movie_ui.rs +++ b/src/ui/radarr_ui/library/add_movie_ui.rs @@ -20,9 +20,9 @@ use crate::ui::widgets::button::Button; use crate::ui::widgets::error_message::ErrorMessage; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::widgets::popup::Popup; +use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_large_popup_over, draw_medium_popup_over, DrawUi}; +use crate::ui::{draw_popup_over, DrawUi}; use crate::utils::convert_runtime; use crate::{render_selectable_input_box, App}; @@ -57,25 +57,30 @@ impl DrawUi for AddMovieUi { | ActiveRadarrBlock::AddMovieSelectRootFolder | ActiveRadarrBlock::AddMovieTagsInput => { if context_option.is_some() { - draw_medium_popup_over( + draw_popup_over( f, app, area, draw_collection_details, draw_confirmation_popup, + Size::Medium, ); } else { - draw_medium_popup_over(f, app, area, draw_add_movie_search, draw_confirmation_popup); + draw_popup_over( + f, + app, + area, + draw_add_movie_search, + draw_confirmation_popup, + Size::Medium, + ); } } ActiveRadarrBlock::AddMovieAlreadyInLibrary => { draw_add_movie_search(f, app, area); f.render_widget( - Popup::new( - ErrorMessage::new("This film is already in your library"), - 25, - 8, - ), + Popup::new(ErrorMessage::new("This film is already in your library")) + .size(Size::Error), f.size(), ); } @@ -85,9 +90,23 @@ impl DrawUi for AddMovieUi { match active_radarr_block { _ if ADD_MOVIE_BLOCKS.contains(&active_radarr_block) => { if context_option.is_some() { - draw_large_popup_over(f, app, area, draw_collections, draw_add_movie_search_popup) + draw_popup_over( + f, + app, + area, + draw_collections, + draw_add_movie_search_popup, + Size::Large, + ) } else { - draw_large_popup_over(f, app, area, draw_library, draw_add_movie_search_popup) + draw_popup_over( + f, + app, + area, + draw_library, + draw_add_movie_search_popup, + Size::Large, + ) } } _ => (), @@ -202,7 +221,7 @@ fn draw_add_movie_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { .block(borderless_block()) .alignment(Alignment::Center); let error_message = ErrorMessage::new("No movies found matching your query!"); - let error_message_popup = Popup::new(error_message, 25, 8); + let error_message_popup = Popup::new(error_message).size(Size::Error); f.render_widget(layout_block(), results_area); f.render_widget(error_message_popup, f.size()); @@ -427,7 +446,7 @@ fn draw_add_movie_select_monitor_popup(f: &mut Frame<'_>, app: &mut App<'_>) { .monitor_list, |monitor| ListItem::new(monitor.to_display_str().to_owned()), ); - let popup = Popup::new(monitor_list, 20, 30); + let popup = Popup::new(monitor_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } @@ -443,7 +462,7 @@ fn draw_add_movie_select_minimum_availability_popup(f: &mut Frame<'_>, app: &mut .minimum_availability_list, |minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()), ); - let popup = Popup::new(minimum_availability_list, 20, 30); + let popup = Popup::new(minimum_availability_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } @@ -459,7 +478,7 @@ fn draw_add_movie_select_quality_profile_popup(f: &mut Frame<'_>, app: &mut App< .quality_profile_list, |quality_profile| ListItem::new(quality_profile.clone()), ); - let popup = Popup::new(quality_profile_list, 20, 30); + let popup = Popup::new(quality_profile_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } @@ -475,7 +494,7 @@ fn draw_add_movie_select_root_folder_popup(f: &mut Frame<'_>, app: &mut App<'_>) .root_folder_list, |root_folder| ListItem::new(root_folder.path.to_owned()), ); - let popup = Popup::new(root_folder_list, 20, 30); + let popup = Popup::new(root_folder_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } diff --git a/src/ui/radarr_ui/library/delete_movie_ui.rs b/src/ui/radarr_ui/library/delete_movie_ui.rs index b8e325f..63b330d 100644 --- a/src/ui/radarr_ui/library/delete_movie_ui.rs +++ b/src/ui/radarr_ui/library/delete_movie_ui.rs @@ -5,7 +5,8 @@ use crate::app::App; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::library::draw_library; -use crate::ui::{draw_prompt_box_with_checkboxes, draw_prompt_popup_over, DrawUi}; +use crate::ui::widgets::popup::Size; +use crate::ui::{draw_popup_over, draw_prompt_box_with_checkboxes, DrawUi}; #[cfg(test)] #[path = "delete_movie_ui_tests.rs"] @@ -55,7 +56,14 @@ impl DrawUi for DeleteMovieUi { ) }; - draw_prompt_popup_over(f, app, area, draw_library, draw_delete_movie_prompt); + draw_popup_over( + f, + app, + area, + draw_library, + draw_delete_movie_prompt, + Size::Prompt, + ); } } } diff --git a/src/ui/radarr_ui/library/edit_movie_ui.rs b/src/ui/radarr_ui/library/edit_movie_ui.rs index 57e643c..e1136ad 100644 --- a/src/ui/radarr_ui/library/edit_movie_ui.rs +++ b/src/ui/radarr_ui/library/edit_movie_ui.rs @@ -18,11 +18,9 @@ use crate::ui::utils::{layout_paragraph_borderless, title_block_centered}; use crate::ui::widgets::button::Button; use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; -use crate::ui::widgets::popup::Popup; +use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{ - draw_large_popup_over_background_fn_with_ui, draw_medium_popup_over, draw_popup, DrawUi, -}; +use crate::ui::{draw_popup, draw_popup_over, draw_popup_over_ui, DrawUi}; #[cfg(test)] #[path = "edit_movie_ui_tests.rs"] @@ -63,16 +61,18 @@ impl DrawUi for EditMovieUi { if let Some(context) = context_option { match context { ActiveRadarrBlock::Movies => { - draw_medium_popup_over(f, app, area, draw_library, draw_edit_movie_prompt); - } - _ if MOVIE_DETAILS_BLOCKS.contains(&context) => { - draw_large_popup_over_background_fn_with_ui::( + draw_popup_over( f, app, area, draw_library, + draw_edit_movie_prompt, + Size::Medium, ); - draw_popup(f, app, draw_edit_movie_prompt, 60, 60); + } + _ if MOVIE_DETAILS_BLOCKS.contains(&context) => { + draw_popup_over_ui::(f, app, area, draw_library, Size::Large); + draw_popup(f, app, draw_edit_movie_prompt, Size::Medium); } _ => (), } @@ -192,7 +192,7 @@ fn draw_edit_movie_select_minimum_availability_popup(f: &mut Frame<'_>, app: &mu .minimum_availability_list, |minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()), ); - let popup = Popup::new(minimum_availability_list, 20, 30); + let popup = Popup::new(minimum_availability_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } @@ -208,7 +208,7 @@ fn draw_edit_movie_select_quality_profile_popup(f: &mut Frame<'_>, app: &mut App .quality_profile_list, |quality_profile| ListItem::new(quality_profile.clone()), ); - let popup = Popup::new(quality_profile_list, 20, 30); + let popup = Popup::new(quality_profile_list).size(Size::Dropdown); f.render_widget(popup, f.size()); } diff --git a/src/ui/radarr_ui/library/mod.rs b/src/ui/radarr_ui/library/mod.rs index 1b4e838..1c5b79f 100644 --- a/src/ui/radarr_ui/library/mod.rs +++ b/src/ui/radarr_ui/library/mod.rs @@ -14,9 +14,8 @@ use crate::ui::radarr_ui::library::movie_details_ui::MovieDetailsUi; use crate::ui::utils::{get_width_from_percentage, layout_block_top_border}; use crate::ui::widgets::error_message::ErrorMessage; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::{ - draw_input_box_popup, draw_popup_over, draw_prompt_box, draw_prompt_popup_over, DrawUi, -}; +use crate::ui::widgets::popup::{Popup, Size}; +use crate::ui::{draw_input_box_popup, draw_popup_over, draw_prompt_box, DrawUi}; use crate::utils::{convert_runtime, convert_to_gb}; mod add_movie_ui; @@ -48,33 +47,43 @@ impl DrawUi for LibraryUi { let mut library_ui_matchers = |active_radarr_block: ActiveRadarrBlock| match active_radarr_block { ActiveRadarrBlock::Movies => draw_library(f, app, area), - ActiveRadarrBlock::SearchMovie => { - draw_popup_over(f, app, area, draw_library, draw_movie_search_box, 30, 13) - } - ActiveRadarrBlock::SearchMovieError => draw_popup_over( + ActiveRadarrBlock::SearchMovie => draw_popup_over( f, app, area, draw_library, - draw_search_movie_error_box, - 30, - 8, + draw_movie_search_box, + Size::InputBox, ), - ActiveRadarrBlock::FilterMovies => { - draw_popup_over(f, app, area, draw_library, draw_filter_movies_box, 30, 13) + ActiveRadarrBlock::SearchMovieError => { + draw_library(f, app, area); + let popup = Popup::new(ErrorMessage::new("Movie not found!")).size(Size::Error); + f.render_widget(popup, f.size()); } - ActiveRadarrBlock::FilterMoviesError => draw_popup_over( + ActiveRadarrBlock::FilterMovies => draw_popup_over( f, app, area, draw_library, - draw_filter_movies_error_box, - 30, - 8, + draw_filter_movies_box, + Size::InputBox, ), - ActiveRadarrBlock::UpdateAllMoviesPrompt => { - draw_prompt_popup_over(f, app, area, draw_library, draw_update_all_movies_prompt) + ActiveRadarrBlock::FilterMoviesError => { + draw_library(f, app, area); + let popup = Popup::new(ErrorMessage::new( + "No movies found matching the given filter!", + )) + .size(Size::Error); + f.render_widget(popup, f.size()); } + ActiveRadarrBlock::UpdateAllMoviesPrompt => draw_popup_over( + f, + app, + area, + draw_library, + draw_update_all_movies_prompt, + Size::Prompt, + ), _ => (), }; @@ -209,14 +218,3 @@ fn draw_filter_movies_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { app.data.radarr_data.movies.filter.as_ref().unwrap(), ) } - -fn draw_search_movie_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) { - f.render_widget(ErrorMessage::new("Movie not found!"), area); -} - -fn draw_filter_movies_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) { - f.render_widget( - ErrorMessage::new("No movies found matching the given filter!"), - area, - ); -} diff --git a/src/ui/radarr_ui/library/movie_details_ui.rs b/src/ui/radarr_ui/library/movie_details_ui.rs index b8ae581..ea4d740 100644 --- a/src/ui/radarr_ui/library/movie_details_ui.rs +++ b/src/ui/radarr_ui/library/movie_details_ui.rs @@ -17,9 +17,9 @@ use crate::ui::utils::{ }; use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::managarr_table::ManagarrTable; +use crate::ui::widgets::popup::Size; use crate::ui::{ - draw_large_popup_over, draw_prompt_box, draw_prompt_box_with_content, draw_prompt_popup_over, - draw_small_popup_over, draw_tabs, DrawUi, + draw_popup_over, draw_prompt_box, draw_prompt_box_with_content, draw_tabs, DrawUi, }; use crate::utils::convert_to_gb; @@ -49,32 +49,42 @@ impl DrawUi for MovieDetailsUi { ); match context_option.unwrap_or(active_radarr_block) { - ActiveRadarrBlock::AutomaticallySearchMoviePrompt => draw_prompt_popup_over( + ActiveRadarrBlock::AutomaticallySearchMoviePrompt => draw_popup_over( f, app, content_area, draw_movie_info, draw_search_movie_prompt, + Size::Prompt, ), - ActiveRadarrBlock::UpdateAndScanPrompt => draw_prompt_popup_over( + ActiveRadarrBlock::UpdateAndScanPrompt => draw_popup_over( f, app, content_area, draw_movie_info, draw_update_and_scan_prompt, + Size::Prompt, ), - ActiveRadarrBlock::ManualSearchConfirmPrompt => draw_small_popup_over( + ActiveRadarrBlock::ManualSearchConfirmPrompt => draw_popup_over( f, app, content_area, draw_movie_info, draw_manual_search_confirm_prompt, + Size::Small, ), _ => draw_movie_info(f, app, content_area), } }; - draw_large_popup_over(f, app, area, draw_library, draw_movie_info_popup); + draw_popup_over( + f, + app, + area, + draw_library, + draw_movie_info_popup, + Size::Large, + ); } } } diff --git a/src/ui/radarr_ui/root_folders/mod.rs b/src/ui/radarr_ui/root_folders/mod.rs index cb92603..7e070e1 100644 --- a/src/ui/radarr_ui/root_folders/mod.rs +++ b/src/ui/radarr_ui/root_folders/mod.rs @@ -9,9 +9,8 @@ use crate::models::Route; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::layout_block_top_border; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::{ - draw_input_box_popup, draw_popup_over, draw_prompt_box, draw_prompt_popup_over, DrawUi, -}; +use crate::ui::widgets::popup::Size; +use crate::ui::{draw_input_box_popup, draw_popup_over, draw_prompt_box, DrawUi}; use crate::utils::convert_to_gb; #[cfg(test)] @@ -39,15 +38,15 @@ impl DrawUi for RootFoldersUi { area, draw_root_folders, draw_add_root_folder_prompt_box, - 30, - 13, + Size::InputBox, ), - ActiveRadarrBlock::DeleteRootFolderPrompt => draw_prompt_popup_over( + ActiveRadarrBlock::DeleteRootFolderPrompt => draw_popup_over( f, app, area, draw_root_folders, draw_delete_root_folder_prompt, + Size::Prompt, ), _ => (), } diff --git a/src/ui/radarr_ui/system/system_details_ui.rs b/src/ui/radarr_ui/system/system_details_ui.rs index 8043645..2cfbd7b 100644 --- a/src/ui/radarr_ui/system/system_details_ui.rs +++ b/src/ui/radarr_ui/system/system_details_ui.rs @@ -18,11 +18,9 @@ use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{borderless_block, title_block}; use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::widgets::popup::Popup; +use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{ - draw_large_popup_over, draw_medium_popup_over, draw_prompt_box, draw_prompt_popup_over, DrawUi, -}; +use crate::ui::{draw_popup_over, draw_prompt_box, DrawUi}; #[cfg(test)] #[path = "system_details_ui_tests.rs"] @@ -47,11 +45,23 @@ impl DrawUi for SystemDetailsUi { draw_logs_popup(f, app); } ActiveRadarrBlock::SystemTasks | ActiveRadarrBlock::SystemTaskStartConfirmPrompt => { - draw_large_popup_over(f, app, area, draw_system_ui_layout, draw_tasks_popup) - } - ActiveRadarrBlock::SystemQueuedEvents => { - draw_medium_popup_over(f, app, area, draw_system_ui_layout, draw_queued_events) + draw_popup_over( + f, + app, + area, + draw_system_ui_layout, + draw_tasks_popup, + Size::Large, + ) } + ActiveRadarrBlock::SystemQueuedEvents => draw_popup_over( + f, + app, + area, + draw_system_ui_layout, + draw_queued_events, + Size::Medium, + ), ActiveRadarrBlock::SystemUpdates => { draw_system_ui_layout(f, app, area); draw_updates_popup(f, app); @@ -71,7 +81,8 @@ fn draw_logs_popup(f: &mut Frame<'_>, app: &mut App<'_>) { if app.data.radarr_data.log_details.items.is_empty() { let loading = LoadingBlock::new(app.is_loading, borderless_block()); - let popup = Popup::new(loading, 75, 75) + let popup = Popup::new(loading) + .size(Size::Large) .block(block) .footer(&help_footer); @@ -86,7 +97,8 @@ fn draw_logs_popup(f: &mut Frame<'_>, app: &mut App<'_>) { style_log_list_item(ListItem::new(Text::from(Span::raw(log_line))), level) }) .block(borderless_block()); - let popup = Popup::new(logs_list, 75, 75) + let popup = Popup::new(logs_list) + .size(Size::Large) .block(block) .footer(&help_footer); @@ -125,7 +137,14 @@ fn draw_tasks_popup(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { app.get_current_route(), Route::Radarr(ActiveRadarrBlock::SystemTaskStartConfirmPrompt, _) ) { - draw_prompt_popup_over(f, app, area, tasks_popup_table, draw_start_task_prompt) + draw_popup_over( + f, + app, + area, + tasks_popup_table, + draw_start_task_prompt, + Size::Prompt, + ) } else { tasks_popup_table(f, app, area); } @@ -157,14 +176,16 @@ fn draw_updates_popup(f: &mut Frame<'_>, app: &mut App<'_>) { let updates_paragraph = Paragraph::new(Text::from(updates)) .block(borderless_block()) .scroll((app.data.radarr_data.updates.offset, 0)); - let popup = Popup::new(updates_paragraph, 75, 75) + let popup = Popup::new(updates_paragraph) + .size(Size::Large) .block(block) .footer(&help_footer); f.render_widget(popup, f.size()); } else { let loading = LoadingBlock::new(app.is_loading, borderless_block()); - let popup = Popup::new(loading, 75, 75) + let popup = Popup::new(loading) + .size(Size::Large) .block(block) .footer(&help_footer); diff --git a/src/ui/widgets/managarr_table.rs b/src/ui/widgets/managarr_table.rs index c121757..7d348f5 100644 --- a/src/ui/widgets/managarr_table.rs +++ b/src/ui/widgets/managarr_table.rs @@ -156,7 +156,9 @@ where let selectable_list = SelectableList::new(content.sort.as_mut().unwrap(), |item| { ListItem::new(Text::from(item.name)) }); - Popup::new(selectable_list, 20, 50).render(table_area, buf); + Popup::new(selectable_list) + .dimensions(20, 50) + .render(table_area, buf); } } else { loading_block.render(table_area, buf); diff --git a/src/ui/widgets/popup.rs b/src/ui/widgets/popup.rs index 7df1dc3..22a8156 100644 --- a/src/ui/widgets/popup.rs +++ b/src/ui/widgets/popup.rs @@ -9,27 +9,64 @@ use ratatui::widgets::{Block, Clear, Paragraph, Widget}; #[path = "popup_tests.rs"] mod popup_tests; +pub enum Size { + Prompt, + LargePrompt, + Error, + InputBox, + Dropdown, + Small, + Medium, + Large, +} + +impl Size { + pub fn to_percent(&self) -> (u16, u16) { + match self { + Size::Prompt => (35, 35), + Size::LargePrompt => (70, 45), + Size::Error => (25, 8), + Size::InputBox => (30, 13), + Size::Dropdown => (20, 30), + Size::Small => (40, 40), + Size::Medium => (60, 60), + Size::Large => (75, 75), + } + } +} + pub struct Popup<'a, T: Widget> { widget: T, percent_x: u16, percent_y: u16, block: Option>, footer: Option<&'a str>, - footer_alignment: Alignment, } impl<'a, T: Widget> Popup<'a, T> { - pub fn new(widget: T, percent_x: u16, percent_y: u16) -> Self { + pub fn new(widget: T) -> Self { Self { widget, - percent_x, - percent_y, + percent_x: 0, + percent_y: 0, block: None, footer: None, - footer_alignment: Alignment::Left, } } + pub fn size(mut self, size: Size) -> Self { + let (percent_x, percent_y) = size.to_percent(); + self.percent_x = percent_x; + self.percent_y = percent_y; + self + } + + pub fn dimensions(mut self, percent_x: u16, percent_y: u16) -> Self { + self.percent_x = percent_x; + self.percent_y = percent_y; + self + } + pub fn block(mut self, block: Block<'a>) -> Self { self.block = Some(block); self @@ -40,11 +77,6 @@ impl<'a, T: Widget> Popup<'a, T> { self } - pub fn footer_alignment(mut self, alignment: Alignment) -> Self { - self.footer_alignment = alignment; - self - } - fn render_popup(self, area: Rect, buf: &mut Buffer) { let popup_area = centered_rect(self.percent_x, self.percent_y, area); Clear.render(popup_area, buf); @@ -62,7 +94,7 @@ impl<'a, T: Widget> Popup<'a, T> { Paragraph::new(Text::from(format!(" {footer}").help())) .block(layout_block_top_border()) - .alignment(self.footer_alignment) + .alignment(Alignment::Left) .render(help_footer_area, buf); content_area diff --git a/src/ui/widgets/popup_tests.rs b/src/ui/widgets/popup_tests.rs index 293c12c..52fe461 100644 --- a/src/ui/widgets/popup_tests.rs +++ b/src/ui/widgets/popup_tests.rs @@ -1,55 +1,73 @@ #[cfg(test)] mod tests { - use crate::ui::widgets::popup::Popup; + use crate::ui::widgets::popup::{Popup, Size}; use pretty_assertions::assert_eq; - use ratatui::layout::Alignment; use ratatui::widgets::Block; + #[test] + fn test_dimensions_to_percent() { + assert_eq!(Size::Prompt.to_percent(), (35, 35)); + assert_eq!(Size::LargePrompt.to_percent(), (70, 45)); + assert_eq!(Size::Error.to_percent(), (25, 8)); + assert_eq!(Size::InputBox.to_percent(), (30, 13)); + assert_eq!(Size::Dropdown.to_percent(), (20, 30)); + assert_eq!(Size::Small.to_percent(), (40, 40)); + assert_eq!(Size::Medium.to_percent(), (60, 60)); + assert_eq!(Size::Large.to_percent(), (75, 75)); + } + #[test] fn test_popup_new() { - let popup = Popup::new(Block::new(), 50, 50); + let popup = Popup::new(Block::new()); assert_eq!(popup.widget, Block::new()); - assert_eq!(popup.percent_x, 50); - assert_eq!(popup.percent_y, 50); + assert_eq!(popup.percent_x, 0); + assert_eq!(popup.percent_y, 0); + assert_eq!(popup.block, None); + assert_eq!(popup.footer, None); + } + + #[test] + fn test_popup_size() { + let popup = Popup::new(Block::new()).size(Size::Small); + + assert_eq!(popup.percent_x, 40); + assert_eq!(popup.percent_y, 40); + assert_eq!(popup.widget, Block::new()); + assert_eq!(popup.block, None); + assert_eq!(popup.footer, None); + } + + #[test] + fn test_popup_dimensions() { + let popup = Popup::new(Block::new()).dimensions(25, 50); + + assert_eq!(popup.percent_x, 25); + assert_eq!(popup.percent_y, 50); + assert_eq!(popup.widget, Block::new()); assert_eq!(popup.block, None); assert_eq!(popup.footer, None); - assert_eq!(popup.footer_alignment, Alignment::Left); } #[test] fn test_popup_block() { - let popup = Popup::new(Block::new(), 50, 50).block(Block::new()); + let popup = Popup::new(Block::new()).block(Block::new()); assert_eq!(popup.block, Some(Block::new())); assert_eq!(popup.widget, Block::new()); - assert_eq!(popup.percent_x, 50); - assert_eq!(popup.percent_y, 50); + assert_eq!(popup.percent_x, 0); + assert_eq!(popup.percent_y, 0); assert_eq!(popup.footer, None); - assert_eq!(popup.footer_alignment, Alignment::Left); } #[test] fn test_popup_footer() { - let popup = Popup::new(Block::new(), 50, 50).footer("footer"); + let popup = Popup::new(Block::new()).footer("footer"); assert_eq!(popup.footer, Some("footer")); assert_eq!(popup.widget, Block::new()); - assert_eq!(popup.percent_x, 50); - assert_eq!(popup.percent_y, 50); + assert_eq!(popup.percent_x, 0); + assert_eq!(popup.percent_y, 0); assert_eq!(popup.block, None); - assert_eq!(popup.footer_alignment, Alignment::Left); - } - - #[test] - fn test_popup_footer_alignment() { - let popup = Popup::new(Block::new(), 50, 50).footer_alignment(Alignment::Center); - - assert_eq!(popup.footer_alignment, Alignment::Center); - assert_eq!(popup.widget, Block::new()); - assert_eq!(popup.percent_x, 50); - assert_eq!(popup.percent_y, 50); - assert_eq!(popup.block, None); - assert_eq!(popup.footer, None); } }