From 2d624e264806d1dcf57bd681320cade4d7cb2be0 Mon Sep 17 00:00:00 2001 From: Dark-Alex-17 Date: Tue, 8 Aug 2023 10:50:07 -0600 Subject: [PATCH] Refactored the Edit/Add modals into their own structs so that adding similar modals in the future is more consistent, uses less RAM (since it's wrapped in an Option now), and is easier to implement. This comes with an initial example of the IndexerSettings UI that needs its own modal now. The modal has been created but it is still not used just yet so that's the next step. --- .cargo-husky/hooks/pre-commit | 0 .cargo-husky/hooks/pre-push | 0 Cargo.toml | 2 +- src/app/app_tests.rs | 2 +- src/app/mod.rs | 2 +- src/app/radarr/mod.rs | 2 +- src/handlers/handler_test_utils.rs | 66 -- .../collections/collection_details_handler.rs | 10 +- .../collection_details_handler_tests.rs | 40 +- .../collections/collections_handler_tests.rs | 12 +- .../collections/edit_collection_handler.rs | 134 +++- .../edit_collection_handler_tests.rs | 458 +++++++++-- .../radarr_handlers/collections/mod.rs | 4 +- .../downloads/downloads_handler_tests.rs | 2 +- src/handlers/radarr_handlers/downloads/mod.rs | 2 +- .../indexers/edit_indexer_settings_handler.rs | 4 +- .../edit_indexer_settings_handler_tests.rs | 8 +- .../indexers/indexers_handler_tests.rs | 4 +- src/handlers/radarr_handlers/indexers/mod.rs | 2 +- .../library/add_movie_handler.rs | 185 ++++- .../library/add_movie_handler_tests.rs | 729 +++++++++++++++--- .../library/delete_movie_handler.rs | 2 +- .../library/delete_movie_handler_tests.rs | 6 +- .../library/edit_movie_handler.rs | 158 +++- .../library/edit_movie_handler_tests.rs | 599 ++++++++++++-- .../library/library_handler_tests.rs | 14 +- src/handlers/radarr_handlers/library/mod.rs | 4 +- .../library/movie_details_handler.rs | 4 +- .../library/movie_details_handler_tests.rs | 115 ++- src/handlers/radarr_handlers/mod.rs | 2 +- .../radarr_handler_test_utils.rs | 125 ++- .../radarr_handlers/radarr_handler_tests.rs | 2 +- .../radarr_handlers/root_folders/mod.rs | 2 +- .../root_folders_handler_tests.rs | 2 +- src/handlers/radarr_handlers/system/mod.rs | 2 +- .../system/system_details_handler.rs | 6 +- .../system/system_details_handler_tests.rs | 4 +- .../system/system_handler_tests.rs | 4 +- src/models/mod.rs | 2 +- src/models/model_tests.rs | 2 +- src/models/servarr_data/mod.rs | 2 +- src/models/servarr_data/radarr/mod.rs | 2 + src/models/servarr_data/radarr/modals.rs | 193 +++++ .../servarr_data/radarr/modals_tests.rs | 161 ++++ .../servarr_data/{ => radarr}/radarr_data.rs | 159 +--- .../{ => radarr}/radarr_data_tests.rs | 211 +---- .../{ => radarr}/radarr_test_utils.rs | 22 +- src/network/radarr_network.rs | 195 +++-- src/network/radarr_network_tests.rs | 118 ++- src/ui/mod.rs | 24 +- .../collections/collection_details_ui.rs | 4 +- .../collection_details_ui_tests.rs | 4 +- .../collections/collections_ui_tests.rs | 2 +- .../collections/edit_collection_ui.rs | 78 +- .../collections/edit_collection_ui_tests.rs | 4 +- src/ui/radarr_ui/collections/mod.rs | 2 +- .../radarr_ui/downloads/downloads_ui_tests.rs | 2 +- src/ui/radarr_ui/downloads/mod.rs | 2 +- .../radarr_ui/indexers/indexer_settings_ui.rs | 172 ++++- .../indexers/indexer_settings_ui_tests.rs | 4 +- .../radarr_ui/indexers/indexers_ui_tests.rs | 2 +- src/ui/radarr_ui/indexers/mod.rs | 2 +- src/ui/radarr_ui/library/add_movie_ui.rs | 132 +++- .../radarr_ui/library/add_movie_ui_tests.rs | 2 +- src/ui/radarr_ui/library/delete_movie_ui.rs | 2 +- .../library/delete_movie_ui_tests.rs | 2 +- src/ui/radarr_ui/library/edit_movie_ui.rs | 81 +- .../radarr_ui/library/edit_movie_ui_tests.rs | 2 +- src/ui/radarr_ui/library/library_ui_tests.rs | 2 +- src/ui/radarr_ui/library/mod.rs | 2 +- src/ui/radarr_ui/library/movie_details_ui.rs | 2 +- .../library/movie_details_ui_tests.rs | 2 +- src/ui/radarr_ui/mod.rs | 43 +- src/ui/radarr_ui/radarr_ui_tests.rs | 2 +- src/ui/radarr_ui/root_folders/mod.rs | 2 +- .../root_folders/root_folders_ui_tests.rs | 2 +- src/ui/radarr_ui/system/mod.rs | 2 +- src/ui/radarr_ui/system/system_details_ui.rs | 2 +- .../system/system_details_ui_tests.rs | 4 +- src/ui/radarr_ui/system/system_ui_tests.rs | 4 +- 80 files changed, 3264 insertions(+), 1114 deletions(-) mode change 100755 => 100644 .cargo-husky/hooks/pre-commit mode change 100755 => 100644 .cargo-husky/hooks/pre-push create mode 100644 src/models/servarr_data/radarr/mod.rs create mode 100644 src/models/servarr_data/radarr/modals.rs create mode 100644 src/models/servarr_data/radarr/modals_tests.rs rename src/models/servarr_data/{ => radarr}/radarr_data.rs (82%) rename src/models/servarr_data/{ => radarr}/radarr_data_tests.rs (78%) rename src/models/servarr_data/{ => radarr}/radarr_test_utils.rs (83%) diff --git a/.cargo-husky/hooks/pre-commit b/.cargo-husky/hooks/pre-commit old mode 100755 new mode 100644 diff --git a/.cargo-husky/hooks/pre-push b/.cargo-husky/hooks/pre-push old mode 100755 new mode 100644 diff --git a/Cargo.toml b/Cargo.toml index 89143f6..9fb8d5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "managarr" -version = "0.0.19" +version = "0.0.20" authors = ["Alex Clarke "] description = "A TUI for managing *arr servers" keywords = ["managarr", "tui-rs", "dashboard", "servarr"] diff --git a/src/app/app_tests.rs b/src/app/app_tests.rs index 1beb12c..115ffad 100644 --- a/src/app/app_tests.rs +++ b/src/app/app_tests.rs @@ -6,7 +6,7 @@ mod tests { use crate::app::context_clues::{build_context_clue_string, SERVARR_CONTEXT_CLUES}; use crate::app::{App, Data, RadarrConfig, DEFAULT_ROUTE}; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, RadarrData}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData}; use crate::models::{HorizontallyScrollableText, Route, TabRoute}; use crate::network::radarr_network::RadarrEvent; use crate::network::NetworkEvent; diff --git a/src/app/mod.rs b/src/app/mod.rs index 305f135..d38821d 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -6,7 +6,7 @@ use tokio::time::Instant; use tokio_util::sync::CancellationToken; use crate::app::context_clues::{build_context_clue_string, SERVARR_CONTEXT_CLUES}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, RadarrData}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData}; use crate::models::{HorizontallyScrollableText, Route, TabRoute, TabState}; use crate::network::NetworkEvent; diff --git a/src/app/radarr/mod.rs b/src/app/radarr/mod.rs index e9d45f8..b70fdba 100644 --- a/src/app/radarr/mod.rs +++ b/src/app/radarr/mod.rs @@ -1,5 +1,5 @@ use crate::app::App; -use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; +use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::network::radarr_network::RadarrEvent; pub mod radarr_context_clues; diff --git a/src/handlers/handler_test_utils.rs b/src/handlers/handler_test_utils.rs index c241b32..ed09f47 100644 --- a/src/handlers/handler_test_utils.rs +++ b/src/handlers/handler_test_utils.rs @@ -202,42 +202,6 @@ mod test_utils { }; } - #[macro_export] - macro_rules! test_enum_scroll { - ($func:ident, $handler:ident, $name:ident, $data_ref:ident, $block:expr, $context:expr) => { - #[rstest] - fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { - let reference_vec = Vec::from_iter($name::iter()); - let mut app = App::default(); - app - .data - .radarr_data - .$data_ref - .set_items(reference_vec.clone()); - - if key == Key::Up { - for i in (0..reference_vec.len()).rev() { - $handler::with(&key, &mut app, &$block, &$context).handle(); - - assert_eq!( - app.data.radarr_data.$data_ref.current_selection(), - &reference_vec[i] - ); - } - } else { - for i in 0..reference_vec.len() { - $handler::with(&key, &mut app, &$block, &$context).handle(); - - assert_eq!( - app.data.radarr_data.$data_ref.current_selection(), - &reference_vec[(i + 1) % reference_vec.len()] - ); - } - } - } - }; - } - #[macro_export] macro_rules! test_scrollable_text_scroll { ($func:ident, $handler:ident, $data_ref:ident, $block:expr) => { @@ -362,36 +326,6 @@ mod test_utils { }; } - #[macro_export] - macro_rules! test_enum_home_and_end { - ($func:ident, $handler:ident, $name:ident, $data_ref:ident, $block:expr, $context:expr) => { - #[test] - fn $func() { - let reference_vec = Vec::from_iter($name::iter()); - let mut app = App::default(); - app - .data - .radarr_data - .$data_ref - .set_items(reference_vec.clone()); - - $handler::with(&DEFAULT_KEYBINDINGS.end.key, &mut app, &$block, &$context).handle(); - - assert_eq!( - app.data.radarr_data.$data_ref.current_selection(), - &reference_vec[reference_vec.len() - 1] - ); - - $handler::with(&DEFAULT_KEYBINDINGS.home.key, &mut app, &$block, &$context).handle(); - - assert_eq!( - app.data.radarr_data.$data_ref.current_selection(), - &reference_vec[0] - ); - } - }; - } - #[macro_export] macro_rules! test_scrollable_text_home_and_end { ($func:ident, $handler:ident, $data_ref:ident, $block:expr) => { diff --git a/src/handlers/radarr_handlers/collections/collection_details_handler.rs b/src/handlers/radarr_handlers/collections/collection_details_handler.rs index 7adb1b7..44c67b5 100644 --- a/src/handlers/radarr_handlers/collections/collection_details_handler.rs +++ b/src/handlers/radarr_handlers/collections/collection_details_handler.rs @@ -2,11 +2,11 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::KeyEventHandler; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, ADD_MOVIE_SELECTION_BLOCKS, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS, }; -use crate::models::{BlockSelectionState, Scrollable}; +use crate::models::{BlockSelectionState, Scrollable, StatefulTable}; #[cfg(test)] #[path = "collection_details_handler_tests.rs"] @@ -108,7 +108,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan ); self.app.data.radarr_data.selected_block = BlockSelectionState::new(&ADD_MOVIE_SELECTION_BLOCKS); - self.app.data.radarr_data.populate_preferences_lists(); + self.app.data.radarr_data.add_movie_modal = Some((&self.app.data.radarr_data).into()); } } } @@ -116,8 +116,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan fn handle_esc(&mut self) { match self.active_radarr_block { ActiveRadarrBlock::CollectionDetails => { + self.app.data.radarr_data.collection_movies = StatefulTable::default(); self.app.pop_navigation_stack(); - self.app.data.radarr_data.reset_movie_collection_table(); } ActiveRadarrBlock::ViewMovieOverview => self.app.pop_navigation_stack(), _ => (), @@ -135,7 +135,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan ) .into(), ); - self.app.data.radarr_data.populate_edit_collection_fields(); + self.app.data.radarr_data.edit_collection_modal = Some((&self.app.data.radarr_data).into()); self.app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_COLLECTION_SELECTION_BLOCKS); } diff --git a/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs b/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs index 103b404..e626456 100644 --- a/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs @@ -9,7 +9,9 @@ mod tests { use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::CollectionMovie; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, + }; use crate::models::HorizontallyScrollableText; mod test_handle_scroll_up_and_down { @@ -53,7 +55,7 @@ mod tests { use pretty_assertions::assert_eq; use crate::models::radarr_models::Movie; - use crate::models::servarr_data::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; use crate::models::BlockSelectionState; use super::*; @@ -93,7 +95,15 @@ mod tests { ) .into() ); - assert!(!app.data.radarr_data.monitor_list.items.is_empty()); + assert!(!app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .monitor_list + .items + .is_empty()); assert_eq!( app.data.radarr_data.selected_block.get_active_block(), &ActiveRadarrBlock::AddMovieSelectRootFolder @@ -101,14 +111,28 @@ mod tests { assert!(!app .data .radarr_data + .add_movie_modal + .as_ref() + .unwrap() .minimum_availability_list .items .is_empty()); - assert!(!app.data.radarr_data.quality_profile_list.items.is_empty()); + assert!(!app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .items + .is_empty()); assert_str_eq!( app .data .radarr_data + .add_movie_modal + .as_ref() + .unwrap() .quality_profile_list .current_selection(), "A - Test 1" @@ -205,9 +229,11 @@ mod tests { use strum::IntoEnumIterator; use crate::models::radarr_models::{Collection, MinimumAvailability}; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::models::servarr_data::radarr_data::{RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS}; - use crate::models::HorizontallyScrollableText; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::{ + RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS, + }; + use crate::models::StatefulTable; use crate::test_edit_collection_key; diff --git a/src/handlers/radarr_handlers/collections/collections_handler_tests.rs b/src/handlers/radarr_handlers/collections/collections_handler_tests.rs index 7753e21..b21df8a 100644 --- a/src/handlers/radarr_handlers/collections/collections_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/collections_handler_tests.rs @@ -10,7 +10,7 @@ mod tests { use crate::handlers::radarr_handlers::collections::CollectionsHandler; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::Collection; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTIONS_BLOCKS, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_BLOCKS, }; use crate::models::HorizontallyScrollableText; @@ -375,7 +375,7 @@ mod tests { mod test_handle_esc { use pretty_assertions::assert_eq; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; use crate::{assert_filter_reset, assert_search_reset}; use super::*; @@ -479,9 +479,11 @@ mod tests { use strum::IntoEnumIterator; use crate::models::radarr_models::MinimumAvailability; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::models::servarr_data::radarr_data::{RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS}; - use crate::models::HorizontallyScrollableText; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::{ + RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS, + }; + use crate::models::StatefulTable; use crate::{assert_refresh_key, test_edit_collection_key}; diff --git a/src/handlers/radarr_handlers/collections/edit_collection_handler.rs b/src/handlers/radarr_handlers/collections/edit_collection_handler.rs index 25c46b5..465d1dd 100644 --- a/src/handlers/radarr_handlers/collections/edit_collection_handler.rs +++ b/src/handlers/radarr_handlers/collections/edit_collection_handler.rs @@ -2,7 +2,7 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS}; use crate::models::Scrollable; use crate::network::radarr_network::RadarrEvent; use crate::{handle_text_box_keys, handle_text_box_left_right_keys}; @@ -47,11 +47,20 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle .app .data .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_up(), - ActiveRadarrBlock::EditCollectionSelectQualityProfile => { - self.app.data.radarr_data.quality_profile_list.scroll_up() - } + ActiveRadarrBlock::EditCollectionSelectQualityProfile => self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .quality_profile_list + .scroll_up(), ActiveRadarrBlock::EditCollectionPrompt => { self.app.data.radarr_data.selected_block.previous() } @@ -65,11 +74,20 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle .app .data .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_down(), - ActiveRadarrBlock::EditCollectionSelectQualityProfile => { - self.app.data.radarr_data.quality_profile_list.scroll_down() - } + ActiveRadarrBlock::EditCollectionSelectQualityProfile => self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .quality_profile_list + .scroll_down(), ActiveRadarrBlock::EditCollectionPrompt => self.app.data.radarr_data.selected_block.next(), _ => (), } @@ -81,17 +99,29 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle .app .data .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_to_top(), ActiveRadarrBlock::EditCollectionSelectQualityProfile => self .app .data .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() .quality_profile_list .scroll_to_top(), - ActiveRadarrBlock::EditCollectionRootFolderPathInput => { - self.app.data.radarr_data.edit_path.scroll_home() - } + ActiveRadarrBlock::EditCollectionRootFolderPathInput => self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .path + .scroll_home(), _ => (), } } @@ -102,17 +132,29 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle .app .data .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_to_bottom(), ActiveRadarrBlock::EditCollectionSelectQualityProfile => self .app .data .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() .quality_profile_list .scroll_to_bottom(), - ActiveRadarrBlock::EditCollectionRootFolderPathInput => { - self.app.data.radarr_data.edit_path.reset_offset() - } + ActiveRadarrBlock::EditCollectionRootFolderPathInput => self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .path + .reset_offset(), _ => (), } } @@ -123,7 +165,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle match self.active_radarr_block { ActiveRadarrBlock::EditCollectionPrompt => handle_prompt_toggle(self.app, self.key), ActiveRadarrBlock::EditCollectionRootFolderPathInput => { - handle_text_box_left_right_keys!(self, self.key, self.app.data.radarr_data.edit_path) + handle_text_box_left_right_keys!( + self, + self.key, + self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .path + ) } _ => (), } @@ -162,16 +215,42 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle self.app.should_ignore_quit_key = true; } ActiveRadarrBlock::EditCollectionToggleMonitored => { - self.app.data.radarr_data.edit_monitored = - Some(!self.app.data.radarr_data.edit_monitored.unwrap_or_default()) - } - ActiveRadarrBlock::EditCollectionToggleSearchOnAdd => { - self.app.data.radarr_data.edit_search_on_add = Some( + self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .monitored = Some( !self .app .data .radarr_data - .edit_search_on_add + .edit_collection_modal + .as_mut() + .unwrap() + .monitored + .unwrap_or_default(), + ) + } + ActiveRadarrBlock::EditCollectionToggleSearchOnAdd => { + self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .search_on_add = Some( + !self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .search_on_add .unwrap_or_default(), ) } @@ -196,7 +275,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle } ActiveRadarrBlock::EditCollectionPrompt => { self.app.pop_navigation_stack(); - self.app.data.radarr_data.reset_add_edit_media_fields(); + self.app.data.radarr_data.edit_collection_modal = None; self.app.data.radarr_data.prompt_confirm = false; } ActiveRadarrBlock::EditCollectionSelectMinimumAvailability @@ -208,7 +287,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle fn handle_char_key_event(&mut self) { let key = self.key; if self.active_radarr_block == &ActiveRadarrBlock::EditCollectionRootFolderPathInput { - handle_text_box_keys!(self, key, self.app.data.radarr_data.edit_path) + handle_text_box_keys!( + self, + key, + self + .app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .path + ) } } } diff --git a/src/handlers/radarr_handlers/collections/edit_collection_handler_tests.rs b/src/handlers/radarr_handlers/collections/edit_collection_handler_tests.rs index 92f5916..fed1ec8 100644 --- a/src/handlers/radarr_handlers/collections/edit_collection_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/edit_collection_handler_tests.rs @@ -9,35 +9,139 @@ mod tests { use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::MinimumAvailability; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS, + }; mod test_handle_scroll_up_and_down { use pretty_assertions::assert_eq; use rstest::rstest; use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::EDIT_COLLECTION_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::modals::EditCollectionModal; + use crate::models::servarr_data::radarr::radarr_data::EDIT_COLLECTION_SELECTION_BLOCKS; use crate::models::BlockSelectionState; - use crate::{test_enum_scroll, test_iterable_scroll}; use super::*; - test_enum_scroll!( - test_edit_collection_select_minimum_availability_scroll, - EditCollectionHandler, - MinimumAvailability, - minimum_availability_list, - ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, - None - ); + #[rstest] + fn test_edit_collection_select_minimum_availability_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); + let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); + app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .minimum_availability_list + .set_items(minimum_availability_vec.clone()); - test_iterable_scroll!( - test_edit_collection_select_quality_profile_scroll, - EditCollectionHandler, - quality_profile_list, - ActiveRadarrBlock::EditCollectionSelectQualityProfile, - None - ); + if key == Key::Up { + for i in (0..minimum_availability_vec.len()).rev() { + EditCollectionHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[i] + ); + } + } else { + for i in 0..minimum_availability_vec.len() { + EditCollectionHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[(i + 1) % minimum_availability_vec.len()] + ); + } + } + } + + #[rstest] + fn test_edit_collection_select_quality_profile_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); + app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .quality_profile_list + .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); + + EditCollectionHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 2" + ); + + EditCollectionHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 1" + ); + } #[rstest] fn test_edit_collection_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { @@ -69,44 +173,182 @@ mod tests { } mod test_handle_home_end { + use pretty_assertions::assert_eq; use strum::IntoEnumIterator; - use crate::{test_enum_home_and_end, test_iterable_home_and_end, test_text_box_home_end_keys}; + use crate::models::servarr_data::radarr::modals::EditCollectionModal; use super::*; - test_enum_home_and_end!( - test_edit_collection_select_minimum_availability_home_end, - EditCollectionHandler, - MinimumAvailability, - minimum_availability_list, - ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, - None - ); + #[test] + fn test_edit_collection_select_minimum_availability_home_end() { + let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); + let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); + app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .minimum_availability_list + .set_items(minimum_availability_vec.clone()); - test_iterable_home_and_end!( - test_edit_collection_select_quality_profile_scroll, - EditCollectionHandler, - quality_profile_list, - ActiveRadarrBlock::EditCollectionSelectQualityProfile, - None - ); + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[minimum_availability_vec.len() - 1] + ); + + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[0] + ); + } + + #[test] + fn test_edit_collection_select_quality_profile_scroll() { + let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); + app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .quality_profile_list + .set_items(vec![ + "Test 1".to_owned(), + "Test 2".to_owned(), + "Test 3".to_owned(), + ]); + + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 3" + ); + + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::EditCollectionSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 1" + ); + } #[test] fn test_edit_collection_root_folder_path_input_home_end_keys() { - test_text_box_home_end_keys!( - EditCollectionHandler, - ActiveRadarrBlock::EditCollectionRootFolderPathInput, - edit_path + let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal { + path: "Test".into(), + ..EditCollectionModal::default() + }); + + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::EditCollectionRootFolderPathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 4 + ); + + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::EditCollectionRootFolderPathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 0 ); } } mod test_handle_left_right_action { + use crate::models::servarr_data::radarr::modals::EditCollectionModal; use rstest::rstest; - use crate::test_text_box_left_right_keys; - use super::*; #[rstest] @@ -136,10 +378,52 @@ mod tests { #[test] fn test_edit_collection_root_folder_path_input_left_right_keys() { - test_text_box_left_right_keys!( - EditCollectionHandler, - ActiveRadarrBlock::EditCollectionRootFolderPathInput, - edit_path + let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal { + path: "Test".into(), + ..EditCollectionModal::default() + }); + + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.left.key, + &mut app, + &ActiveRadarrBlock::EditCollectionRootFolderPathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 1 + ); + + EditCollectionHandler::with( + &DEFAULT_KEYBINDINGS.right.key, + &mut app, + &ActiveRadarrBlock::EditCollectionRootFolderPathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 0 ); } } @@ -148,7 +432,8 @@ mod tests { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::models::servarr_data::radarr_data::EDIT_COLLECTION_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::modals::EditCollectionModal; + use crate::models::servarr_data::radarr::radarr_data::EDIT_COLLECTION_SELECTION_BLOCKS; use crate::models::{BlockSelectionState, Route}; use crate::network::radarr_network::RadarrEvent; @@ -248,6 +533,7 @@ mod tests { Some(ActiveRadarrBlock::Collections), )); let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_COLLECTION_SELECTION_BLOCKS); app.push_navigation_stack(current_route); @@ -261,7 +547,16 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ¤t_route); - assert_eq!(app.data.radarr_data.edit_monitored, Some(true)); + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .monitored, + Some(true) + ); EditCollectionHandler::with( &SUBMIT_KEY, @@ -272,7 +567,16 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ¤t_route); - assert_eq!(app.data.radarr_data.edit_monitored, Some(false)); + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .monitored, + Some(false) + ); } #[test] @@ -282,6 +586,7 @@ mod tests { Some(ActiveRadarrBlock::Collections), )); let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_COLLECTION_SELECTION_BLOCKS); app @@ -300,7 +605,16 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ¤t_route); - assert_eq!(app.data.radarr_data.edit_search_on_add, Some(true)); + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .search_on_add, + Some(true) + ); EditCollectionHandler::with( &SUBMIT_KEY, @@ -311,7 +625,16 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ¤t_route); - assert_eq!(app.data.radarr_data.edit_search_on_add, Some(false)); + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .search_on_add, + Some(false) + ); } #[rstest] @@ -389,8 +712,7 @@ mod tests { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::{assert_edit_media_reset, assert_preferences_selections_reset}; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; use super::*; @@ -440,8 +762,7 @@ mod tests { ); let radarr_data = &app.data.radarr_data; - assert_preferences_selections_reset!(radarr_data); - assert_edit_media_reset!(radarr_data); + assert!(radarr_data.edit_collection_modal.is_none()); assert!(!radarr_data.prompt_confirm); } @@ -469,11 +790,15 @@ mod tests { mod test_handle_key_char { use super::*; + use crate::models::servarr_data::radarr::modals::EditCollectionModal; #[test] fn test_edit_collection_root_folder_path_input_backspace() { let mut app = App::default(); - app.data.radarr_data.edit_path = "Test".to_owned().into(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal { + path: "Test".into(), + ..EditCollectionModal::default() + }); EditCollectionHandler::with( &DEFAULT_KEYBINDINGS.backspace.key, @@ -483,12 +808,23 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_path.text, "Tes"); + assert_str_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .path + .text, + "Tes" + ); } #[test] fn test_edit_collection_root_folder_path_input_char_key() { let mut app = App::default(); + app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); EditCollectionHandler::with( &Key::Char('h'), @@ -498,7 +834,17 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_path.text, "h"); + assert_str_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .path + .text, + "h" + ); } } diff --git a/src/handlers/radarr_handlers/collections/mod.rs b/src/handlers/radarr_handlers/collections/mod.rs index 39d747a..5350626 100644 --- a/src/handlers/radarr_handlers/collections/mod.rs +++ b/src/handlers/radarr_handlers/collections/mod.rs @@ -7,7 +7,7 @@ use crate::handlers::radarr_handlers::{ filter_table, handle_change_tab_left_right_keys, search_table, }; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTIONS_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS, }; use crate::models::{BlockSelectionState, Scrollable}; @@ -287,7 +287,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<' ) .into(), ); - self.app.data.radarr_data.populate_edit_collection_fields(); + self.app.data.radarr_data.edit_collection_modal = Some((&self.app.data.radarr_data).into()); self.app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_COLLECTION_SELECTION_BLOCKS); } diff --git a/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs b/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs index 744d12f..40de244 100644 --- a/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs +++ b/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs @@ -8,7 +8,7 @@ mod tests { use crate::event::Key; use crate::handlers::radarr_handlers::downloads::DownloadsHandler; use crate::handlers::KeyEventHandler; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; mod test_handle_scroll_up_and_down { use rstest::rstest; diff --git a/src/handlers/radarr_handlers/downloads/mod.rs b/src/handlers/radarr_handlers/downloads/mod.rs index 5530fa7..57a773d 100644 --- a/src/handlers/radarr_handlers/downloads/mod.rs +++ b/src/handlers/radarr_handlers/downloads/mod.rs @@ -3,7 +3,7 @@ use crate::app::App; use crate::event::Key; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; use crate::models::Scrollable; use crate::network::radarr_network::RadarrEvent; diff --git a/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler.rs b/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler.rs index 5637dc3..f957877 100644 --- a/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler.rs +++ b/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler.rs @@ -1,7 +1,9 @@ use crate::app::App; use crate::event::Key; use crate::handlers::KeyEventHandler; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS, +}; #[cfg(test)] #[path = "./edit_indexer_settings_handler_tests.rs"] diff --git a/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler_tests.rs b/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler_tests.rs index 87af7de..9e6f9fb 100644 --- a/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler_tests.rs +++ b/src/handlers/radarr_handlers/indexers/edit_indexer_settings_handler_tests.rs @@ -7,13 +7,15 @@ mod tests { use crate::event::Key; use crate::handlers::radarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler; use crate::handlers::KeyEventHandler; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS, + }; mod test_handle_scroll_up_and_down { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::models::servarr_data::radarr_data::INDEXER_SETTINGS_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::radarr_data::INDEXER_SETTINGS_SELECTION_BLOCKS; use crate::models::BlockSelectionState; use super::*; @@ -56,7 +58,7 @@ mod tests { mod test_handle_esc { use pretty_assertions::assert_eq; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; use super::*; diff --git a/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs b/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs index fd21060..2fb5f20 100644 --- a/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs +++ b/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs @@ -9,7 +9,7 @@ mod tests { use crate::event::Key; use crate::handlers::radarr_handlers::indexers::IndexersHandler; use crate::handlers::KeyEventHandler; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, INDEXERS_BLOCKS, INDEXER_SETTINGS_BLOCKS, }; use crate::test_handler_delegation; @@ -254,7 +254,7 @@ mod tests { use pretty_assertions::assert_eq; use crate::assert_refresh_key; - use crate::models::servarr_data::radarr_data::INDEXER_SETTINGS_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::radarr_data::INDEXER_SETTINGS_SELECTION_BLOCKS; use super::*; diff --git a/src/handlers/radarr_handlers/indexers/mod.rs b/src/handlers/radarr_handlers/indexers/mod.rs index e6577d5..7cf2caf 100644 --- a/src/handlers/radarr_handlers/indexers/mod.rs +++ b/src/handlers/radarr_handlers/indexers/mod.rs @@ -4,7 +4,7 @@ use crate::event::Key; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, INDEXERS_BLOCKS, INDEXER_SETTINGS_SELECTION_BLOCKS, }; use crate::models::{BlockSelectionState, Scrollable}; diff --git a/src/handlers/radarr_handlers/library/add_movie_handler.rs b/src/handlers/radarr_handlers/library/add_movie_handler.rs index 2e47039..3ab212f 100644 --- a/src/handlers/radarr_handlers/library/add_movie_handler.rs +++ b/src/handlers/radarr_handlers/library/add_movie_handler.rs @@ -1,6 +1,6 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, ADD_MOVIE_BLOCKS, ADD_MOVIE_SELECTION_BLOCKS, }; use crate::models::{BlockSelectionState, Scrollable, StatefulTable}; @@ -46,21 +46,42 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, ActiveRadarrBlock::AddMovieSearchResults => { self.app.data.radarr_data.add_searched_movies.scroll_up() } - ActiveRadarrBlock::AddMovieSelectMonitor => { - self.app.data.radarr_data.monitor_list.scroll_up() - } + ActiveRadarrBlock::AddMovieSelectMonitor => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .monitor_list + .scroll_up(), ActiveRadarrBlock::AddMovieSelectMinimumAvailability => self .app .data .radarr_data + .add_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_up(), - ActiveRadarrBlock::AddMovieSelectQualityProfile => { - self.app.data.radarr_data.quality_profile_list.scroll_up() - } - ActiveRadarrBlock::AddMovieSelectRootFolder => { - self.app.data.radarr_data.root_folder_list.scroll_up() - } + ActiveRadarrBlock::AddMovieSelectQualityProfile => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .scroll_up(), + ActiveRadarrBlock::AddMovieSelectRootFolder => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .root_folder_list + .scroll_up(), ActiveRadarrBlock::AddMoviePrompt => self.app.data.radarr_data.selected_block.previous(), _ => (), } @@ -71,21 +92,42 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, ActiveRadarrBlock::AddMovieSearchResults => { self.app.data.radarr_data.add_searched_movies.scroll_down() } - ActiveRadarrBlock::AddMovieSelectMonitor => { - self.app.data.radarr_data.monitor_list.scroll_down() - } + ActiveRadarrBlock::AddMovieSelectMonitor => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .monitor_list + .scroll_down(), ActiveRadarrBlock::AddMovieSelectMinimumAvailability => self .app .data .radarr_data + .add_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_down(), - ActiveRadarrBlock::AddMovieSelectQualityProfile => { - self.app.data.radarr_data.quality_profile_list.scroll_down() - } - ActiveRadarrBlock::AddMovieSelectRootFolder => { - self.app.data.radarr_data.root_folder_list.scroll_down() - } + ActiveRadarrBlock::AddMovieSelectQualityProfile => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .scroll_down(), + ActiveRadarrBlock::AddMovieSelectRootFolder => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .root_folder_list + .scroll_down(), ActiveRadarrBlock::AddMoviePrompt => self.app.data.radarr_data.selected_block.next(), _ => (), } @@ -99,26 +141,52 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, .radarr_data .add_searched_movies .scroll_to_top(), - ActiveRadarrBlock::AddMovieSelectMonitor => { - self.app.data.radarr_data.monitor_list.scroll_to_top() - } + ActiveRadarrBlock::AddMovieSelectMonitor => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .monitor_list + .scroll_to_top(), ActiveRadarrBlock::AddMovieSelectMinimumAvailability => self .app .data .radarr_data + .add_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_to_top(), ActiveRadarrBlock::AddMovieSelectQualityProfile => self .app .data .radarr_data + .add_movie_modal + .as_mut() + .unwrap() .quality_profile_list .scroll_to_top(), - ActiveRadarrBlock::AddMovieSelectRootFolder => { - self.app.data.radarr_data.root_folder_list.scroll_to_top() - } + ActiveRadarrBlock::AddMovieSelectRootFolder => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .root_folder_list + .scroll_to_top(), ActiveRadarrBlock::AddMovieSearchInput => self.app.data.radarr_data.search.scroll_home(), - ActiveRadarrBlock::AddMovieTagsInput => self.app.data.radarr_data.edit_tags.scroll_home(), + ActiveRadarrBlock::AddMovieTagsInput => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .tags + .scroll_home(), _ => (), } } @@ -131,29 +199,52 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, .radarr_data .add_searched_movies .scroll_to_bottom(), - ActiveRadarrBlock::AddMovieSelectMonitor => { - self.app.data.radarr_data.monitor_list.scroll_to_bottom() - } + ActiveRadarrBlock::AddMovieSelectMonitor => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .monitor_list + .scroll_to_bottom(), ActiveRadarrBlock::AddMovieSelectMinimumAvailability => self .app .data .radarr_data + .add_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_to_bottom(), ActiveRadarrBlock::AddMovieSelectQualityProfile => self .app .data .radarr_data + .add_movie_modal + .as_mut() + .unwrap() .quality_profile_list .scroll_to_bottom(), ActiveRadarrBlock::AddMovieSelectRootFolder => self .app .data .radarr_data + .add_movie_modal + .as_mut() + .unwrap() .root_folder_list .scroll_to_bottom(), ActiveRadarrBlock::AddMovieSearchInput => self.app.data.radarr_data.search.reset_offset(), - ActiveRadarrBlock::AddMovieTagsInput => self.app.data.radarr_data.edit_tags.reset_offset(), + ActiveRadarrBlock::AddMovieTagsInput => self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .tags + .reset_offset(), _ => (), } } @@ -167,7 +258,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, handle_text_box_left_right_keys!(self, self.key, self.app.data.radarr_data.search) } ActiveRadarrBlock::AddMovieTagsInput => { - handle_text_box_left_right_keys!(self, self.key, self.app.data.radarr_data.edit_tags) + handle_text_box_left_right_keys!( + self, + self.key, + self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .tags + ) } _ => (), } @@ -175,7 +277,9 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, fn handle_submit(&mut self) { match self.active_radarr_block { - ActiveRadarrBlock::AddMovieSearchInput => { + _ if *self.active_radarr_block == ActiveRadarrBlock::AddMovieSearchInput + && !self.app.data.radarr_data.search.text.is_empty() => + { self .app .push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); @@ -215,7 +319,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, self .app .push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); - self.app.data.radarr_data.populate_preferences_lists(); + self.app.data.radarr_data.add_movie_modal = Some((&self.app.data.radarr_data).into()); self.app.data.radarr_data.selected_block = BlockSelectionState::new(&ADD_MOVIE_SELECTION_BLOCKS); } @@ -278,7 +382,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, } ActiveRadarrBlock::AddMoviePrompt => { self.app.pop_navigation_stack(); - self.app.data.radarr_data.reset_add_edit_media_fields(); + self.app.data.radarr_data.add_movie_modal = None; self.app.data.radarr_data.prompt_confirm = false; } ActiveRadarrBlock::AddMovieSelectMonitor @@ -301,7 +405,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, handle_text_box_keys!(self, key, self.app.data.radarr_data.search) } ActiveRadarrBlock::AddMovieTagsInput => { - handle_text_box_keys!(self, key, self.app.data.radarr_data.edit_tags) + handle_text_box_keys!( + self, + key, + self + .app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .tags + ) } _ => (), } diff --git a/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs b/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs index f9d26fa..4cdd1b6 100644 --- a/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs @@ -11,7 +11,7 @@ mod tests { use crate::models::radarr_models::{ AddMovieSearchResult, MinimumAvailability, Monitor, RootFolder, }; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; use crate::models::HorizontallyScrollableText; mod test_handle_scroll_up_and_down { @@ -19,9 +19,10 @@ mod tests { use rstest::rstest; use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::modals::AddMovieModal; + use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; use crate::models::BlockSelectionState; - use crate::{simple_stateful_iterable_vec, test_enum_scroll, test_iterable_scroll}; + use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; use super::*; @@ -36,41 +37,245 @@ mod tests { to_string ); - test_enum_scroll!( - test_add_movie_select_monitor_scroll, - AddMovieHandler, - Monitor, - monitor_list, - ActiveRadarrBlock::AddMovieSelectMonitor, - None - ); + #[rstest] + fn test_add_movie_select_monitor_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let monitor_vec = Vec::from_iter(Monitor::iter()); + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .monitor_list + .set_items(monitor_vec.clone()); - test_enum_scroll!( - test_add_movie_select_minimum_availability_scroll, - AddMovieHandler, - MinimumAvailability, - minimum_availability_list, - ActiveRadarrBlock::AddMovieSelectMinimumAvailability, - None - ); + if key == Key::Up { + for i in (0..monitor_vec.len()).rev() { + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMonitor, + &None, + ) + .handle(); - test_iterable_scroll!( - test_add_movie_select_quality_profile_scroll, - AddMovieHandler, - quality_profile_list, - ActiveRadarrBlock::AddMovieSelectQualityProfile, - None - ); + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .monitor_list + .current_selection(), + &monitor_vec[i] + ); + } + } else { + for i in 0..monitor_vec.len() { + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMonitor, + &None, + ) + .handle(); - test_iterable_scroll!( - test_add_movie_select_root_folder_scroll, - AddMovieHandler, - root_folder_list, - simple_stateful_iterable_vec!(RootFolder, String, path), - ActiveRadarrBlock::AddMovieSelectRootFolder, - None, - path - ); + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .monitor_list + .current_selection(), + &monitor_vec[(i + 1) % monitor_vec.len()] + ); + } + } + } + + #[rstest] + fn test_add_movie_select_minimum_availability_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .minimum_availability_list + .set_items(minimum_availability_vec.clone()); + + if key == Key::Up { + for i in (0..minimum_availability_vec.len()).rev() { + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[i] + ); + } + } else { + for i in 0..minimum_availability_vec.len() { + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[(i + 1) % minimum_availability_vec.len()] + ); + } + } + } + + #[rstest] + fn test_add_movie_select_quality_profile_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); + + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 2" + ); + + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 1" + ); + } + + #[rstest] + fn test_add_movie_select_root_folder_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .root_folder_list + .set_items(simple_stateful_iterable_vec!(RootFolder, String, path)); + + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectRootFolder, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .root_folder_list + .current_selection() + .path, + "Test 2" + ); + + AddMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectRootFolder, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .root_folder_list + .current_selection() + .path, + "Test 1" + ); + } #[rstest] fn test_add_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { @@ -97,9 +302,9 @@ mod tests { mod test_handle_home_end { use strum::IntoEnumIterator; + use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::{ - extended_stateful_iterable_vec, test_enum_home_and_end, test_iterable_home_and_end, - test_text_box_home_end_keys, + extended_stateful_iterable_vec, test_iterable_home_and_end, test_text_box_home_end_keys, }; use super::*; @@ -115,41 +320,229 @@ mod tests { to_string ); - test_enum_home_and_end!( - test_add_movie_select_monitor_home_end, - AddMovieHandler, - Monitor, - monitor_list, - ActiveRadarrBlock::AddMovieSelectMonitor, - None - ); + #[test] + fn test_add_movie_select_monitor_home_end() { + let monitor_vec = Vec::from_iter(Monitor::iter()); + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .monitor_list + .set_items(monitor_vec.clone()); - test_enum_home_and_end!( - test_add_movie_select_minimum_availability_home_end, - AddMovieHandler, - MinimumAvailability, - minimum_availability_list, - ActiveRadarrBlock::AddMovieSelectMinimumAvailability, - None - ); + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMonitor, + &None, + ) + .handle(); - test_iterable_home_and_end!( - test_add_movie_select_quality_profile_home_end, - AddMovieHandler, - quality_profile_list, - ActiveRadarrBlock::AddMovieSelectQualityProfile, - None - ); + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .monitor_list + .current_selection(), + &monitor_vec[monitor_vec.len() - 1] + ); - test_iterable_home_and_end!( - test_add_movie_select_root_folder_home_end, - AddMovieHandler, - root_folder_list, - extended_stateful_iterable_vec!(RootFolder, String, path), - ActiveRadarrBlock::AddMovieSelectRootFolder, - None, - path - ); + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMonitor, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .monitor_list + .current_selection(), + &monitor_vec[0] + ); + } + + #[test] + fn test_add_movie_select_minimum_availability_home_end() { + let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .minimum_availability_list + .set_items(minimum_availability_vec.clone()); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[minimum_availability_vec.len() - 1] + ); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[0] + ); + } + + #[test] + fn test_add_movie_select_quality_profile_home_end() { + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .set_items(vec![ + "Test 1".to_owned(), + "Test 2".to_owned(), + "Test 3".to_owned(), + ]); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 3" + ); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 1" + ); + } + + #[test] + fn test_add_movie_select_root_folder_home_end() { + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); + app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .root_folder_list + .set_items(extended_stateful_iterable_vec!(RootFolder, String, path)); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectRootFolder, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .root_folder_list + .current_selection() + .path, + "Test 3" + ); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::AddMovieSelectRootFolder, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .root_folder_list + .current_selection() + .path, + "Test 1" + ); + } #[test] fn test_add_movie_search_input_home_end_keys() { @@ -162,15 +555,58 @@ mod tests { #[test] fn test_add_movie_tags_input_home_end_keys() { - test_text_box_home_end_keys!( - AddMovieHandler, - ActiveRadarrBlock::AddMovieTagsInput, - edit_tags + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal { + tags: "Test".into(), + ..AddMovieModal::default() + }); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::AddMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 4 + ); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::AddMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 0 ); } } mod test_handle_left_right_action { + use crate::models::servarr_data::radarr::modals::AddMovieModal; use rstest::rstest; use crate::test_text_box_left_right_keys; @@ -201,10 +637,52 @@ mod tests { #[test] fn test_add_movie_tags_input_left_right_keys() { - test_text_box_left_right_keys!( - AddMovieHandler, - ActiveRadarrBlock::AddMovieTagsInput, - edit_tags + let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal { + tags: "Test".into(), + ..AddMovieModal::default() + }); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.left.key, + &mut app, + &ActiveRadarrBlock::AddMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 1 + ); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.right.key, + &mut app, + &ActiveRadarrBlock::AddMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 0 ); } } @@ -215,7 +693,8 @@ mod tests { use rstest::rstest; use crate::models::radarr_models::Movie; - use crate::models::servarr_data::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::modals::AddMovieModal; + use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; use crate::models::BlockSelectionState; use crate::network::radarr_network::RadarrEvent; @@ -227,6 +706,7 @@ mod tests { fn test_add_movie_search_input_submit() { let mut app = App::default(); app.should_ignore_quit_key = true; + app.data.radarr_data.search = "test".into(); AddMovieHandler::with( &SUBMIT_KEY, @@ -243,6 +723,27 @@ mod tests { ); } + #[test] + fn test_add_movie_search_input_submit_noop_on_empty_search() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); + app.should_ignore_quit_key = true; + + AddMovieHandler::with( + &SUBMIT_KEY, + &mut app, + &ActiveRadarrBlock::AddMovieSearchInput, + &None, + ) + .handle(); + + assert!(app.should_ignore_quit_key); + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::AddMovieSearchInput.into() + ); + } + #[test] fn test_add_movie_search_results_submit() { let mut app = App::default(); @@ -270,18 +771,41 @@ mod tests { app.data.radarr_data.selected_block.get_active_block(), &ActiveRadarrBlock::AddMovieSelectRootFolder ); - assert!(!app.data.radarr_data.monitor_list.items.is_empty()); + assert!(app.data.radarr_data.add_movie_modal.is_some()); assert!(!app .data .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .monitor_list + .items + .is_empty()); + assert!(!app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() .minimum_availability_list .items .is_empty()); - assert!(!app.data.radarr_data.quality_profile_list.items.is_empty()); + assert!(!app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .items + .is_empty()); assert_str_eq!( app .data .radarr_data + .add_movie_modal + .as_ref() + .unwrap() .quality_profile_list .current_selection(), "A - Test 1" @@ -361,6 +885,7 @@ mod tests { #[test] fn test_add_movie_confirm_prompt_prompt_confirmation_submit() { let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.data.radarr_data.prompt_confirm = true; @@ -384,6 +909,7 @@ mod tests { app.data.radarr_data.prompt_confirm_action, Some(RadarrEvent::AddMovie) ); + assert!(app.data.radarr_data.add_movie_modal.is_some()); } #[rstest] @@ -464,11 +990,9 @@ mod tests { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::{ - assert_edit_media_reset, assert_preferences_selections_reset, assert_search_reset, - simple_stateful_iterable_vec, - }; + use crate::models::servarr_data::radarr::modals::AddMovieModal; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::{assert_search_reset, simple_stateful_iterable_vec}; use super::*; @@ -571,6 +1095,7 @@ mod tests { #[test] fn test_add_movie_prompt_esc() { let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data = create_test_radarr_data(); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); @@ -588,8 +1113,7 @@ mod tests { app.get_current_route(), &ActiveRadarrBlock::AddMovieSearchResults.into() ); - assert_preferences_selections_reset!(app.data.radarr_data); - assert_edit_media_reset!(app.data.radarr_data); + assert!(app.data.radarr_data.add_movie_modal.is_none()); } #[test] @@ -662,6 +1186,7 @@ mod tests { mod test_handle_key_char { use super::*; + use crate::models::servarr_data::radarr::modals::AddMovieModal; #[test] fn test_add_movie_search_input_backspace() { @@ -682,7 +1207,10 @@ mod tests { #[test] fn test_add_movie_tags_input_backspace() { let mut app = App::default(); - app.data.radarr_data.edit_tags = "Test".to_owned().into(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal { + tags: "Test".into(), + ..AddMovieModal::default() + }); AddMovieHandler::with( &DEFAULT_KEYBINDINGS.backspace.key, @@ -692,7 +1220,17 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_tags.text, "Tes"); + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .tags + .text, + "Tes" + ); } #[test] @@ -713,6 +1251,7 @@ mod tests { #[test] fn test_add_movie_tags_input_char_key() { let mut app = App::default(); + app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); AddMovieHandler::with( &Key::Char('h'), @@ -722,7 +1261,17 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_tags.text, "h"); + assert_str_eq!( + app + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .tags + .text, + "h" + ); } } diff --git a/src/handlers/radarr_handlers/library/delete_movie_handler.rs b/src/handlers/radarr_handlers/library/delete_movie_handler.rs index 6f7d422..8317f4a 100644 --- a/src/handlers/radarr_handlers/library/delete_movie_handler.rs +++ b/src/handlers/radarr_handlers/library/delete_movie_handler.rs @@ -1,7 +1,7 @@ use crate::app::App; use crate::event::Key; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; use crate::network::radarr_network::RadarrEvent; #[cfg(test)] diff --git a/src/handlers/radarr_handlers/library/delete_movie_handler_tests.rs b/src/handlers/radarr_handlers/library/delete_movie_handler_tests.rs index 91bb8d8..9619fad 100644 --- a/src/handlers/radarr_handlers/library/delete_movie_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/delete_movie_handler_tests.rs @@ -7,13 +7,13 @@ mod tests { use crate::event::Key; use crate::handlers::radarr_handlers::library::delete_movie_handler::DeleteMovieHandler; use crate::handlers::KeyEventHandler; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; mod test_handle_scroll_up_and_down { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::models::servarr_data::radarr_data::DELETE_MOVIE_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::radarr_data::DELETE_MOVIE_SELECTION_BLOCKS; use crate::models::BlockSelectionState; use super::*; @@ -66,7 +66,7 @@ mod tests { mod test_handle_submit { use pretty_assertions::assert_eq; - use crate::models::servarr_data::radarr_data::DELETE_MOVIE_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::radarr_data::DELETE_MOVIE_SELECTION_BLOCKS; use crate::models::BlockSelectionState; use crate::network::radarr_network::RadarrEvent; diff --git a/src/handlers/radarr_handlers/library/edit_movie_handler.rs b/src/handlers/radarr_handlers/library/edit_movie_handler.rs index 25e2e6e..5dffc26 100644 --- a/src/handlers/radarr_handlers/library/edit_movie_handler.rs +++ b/src/handlers/radarr_handlers/library/edit_movie_handler.rs @@ -2,7 +2,7 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; use crate::models::Scrollable; use crate::network::radarr_network::RadarrEvent; use crate::{handle_text_box_keys, handle_text_box_left_right_keys}; @@ -47,11 +47,20 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, .app .data .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_up(), - ActiveRadarrBlock::EditMovieSelectQualityProfile => { - self.app.data.radarr_data.quality_profile_list.scroll_up() - } + ActiveRadarrBlock::EditMovieSelectQualityProfile => self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .scroll_up(), ActiveRadarrBlock::EditMoviePrompt => self.app.data.radarr_data.selected_block.previous(), _ => (), } @@ -63,11 +72,20 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, .app .data .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_down(), - ActiveRadarrBlock::EditMovieSelectQualityProfile => { - self.app.data.radarr_data.quality_profile_list.scroll_down() - } + ActiveRadarrBlock::EditMovieSelectQualityProfile => self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .scroll_down(), ActiveRadarrBlock::EditMoviePrompt => self.app.data.radarr_data.selected_block.next(), _ => (), } @@ -79,16 +97,38 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, .app .data .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_to_top(), ActiveRadarrBlock::EditMovieSelectQualityProfile => self .app .data .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() .quality_profile_list .scroll_to_top(), - ActiveRadarrBlock::EditMoviePathInput => self.app.data.radarr_data.edit_path.scroll_home(), - ActiveRadarrBlock::EditMovieTagsInput => self.app.data.radarr_data.edit_tags.scroll_home(), + ActiveRadarrBlock::EditMoviePathInput => self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .path + .scroll_home(), + ActiveRadarrBlock::EditMovieTagsInput => self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .tags + .scroll_home(), _ => (), } } @@ -99,16 +139,38 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, .app .data .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() .minimum_availability_list .scroll_to_bottom(), ActiveRadarrBlock::EditMovieSelectQualityProfile => self .app .data .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() .quality_profile_list .scroll_to_bottom(), - ActiveRadarrBlock::EditMoviePathInput => self.app.data.radarr_data.edit_path.reset_offset(), - ActiveRadarrBlock::EditMovieTagsInput => self.app.data.radarr_data.edit_tags.reset_offset(), + ActiveRadarrBlock::EditMoviePathInput => self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .path + .reset_offset(), + ActiveRadarrBlock::EditMovieTagsInput => self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .tags + .reset_offset(), _ => (), } } @@ -119,10 +181,32 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, match self.active_radarr_block { ActiveRadarrBlock::EditMoviePrompt => handle_prompt_toggle(self.app, self.key), ActiveRadarrBlock::EditMoviePathInput => { - handle_text_box_left_right_keys!(self, self.key, self.app.data.radarr_data.edit_path) + handle_text_box_left_right_keys!( + self, + self.key, + self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .path + ) } ActiveRadarrBlock::EditMovieTagsInput => { - handle_text_box_left_right_keys!(self, self.key, self.app.data.radarr_data.edit_tags) + handle_text_box_left_right_keys!( + self, + self.key, + self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .tags + ) } _ => (), } @@ -159,8 +243,24 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, self.app.should_ignore_quit_key = true; } ActiveRadarrBlock::EditMovieToggleMonitored => { - self.app.data.radarr_data.edit_monitored = - Some(!self.app.data.radarr_data.edit_monitored.unwrap_or_default()) + self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .monitored = Some( + !self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .monitored + .unwrap_or_default(), + ) } _ => (), } @@ -183,7 +283,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, } ActiveRadarrBlock::EditMoviePrompt => { self.app.pop_navigation_stack(); - self.app.data.radarr_data.reset_add_edit_media_fields(); + self.app.data.radarr_data.edit_movie_modal = None; self.app.data.radarr_data.prompt_confirm = false; } ActiveRadarrBlock::EditMovieSelectMinimumAvailability @@ -196,10 +296,32 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a, let key = self.key; match self.active_radarr_block { ActiveRadarrBlock::EditMoviePathInput => { - handle_text_box_keys!(self, key, self.app.data.radarr_data.edit_path) + handle_text_box_keys!( + self, + key, + self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .path + ) } ActiveRadarrBlock::EditMovieTagsInput => { - handle_text_box_keys!(self, key, self.app.data.radarr_data.edit_tags) + handle_text_box_keys!( + self, + key, + self + .app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .tags + ) } _ => (), } diff --git a/src/handlers/radarr_handlers/library/edit_movie_handler_tests.rs b/src/handlers/radarr_handlers/library/edit_movie_handler_tests.rs index 5151c43..0163f4c 100644 --- a/src/handlers/radarr_handlers/library/edit_movie_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/edit_movie_handler_tests.rs @@ -9,35 +9,137 @@ mod tests { use crate::handlers::radarr_handlers::library::edit_movie_handler::EditMovieHandler; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::MinimumAvailability; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; mod test_handle_scroll_up_and_down { use pretty_assertions::assert_eq; use rstest::rstest; use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::EDIT_MOVIE_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::modals::EditMovieModal; + use crate::models::servarr_data::radarr::radarr_data::EDIT_MOVIE_SELECTION_BLOCKS; use crate::models::BlockSelectionState; - use crate::{test_enum_scroll, test_iterable_scroll}; use super::*; - test_enum_scroll!( - test_edit_movie_select_minimum_availability_scroll, - EditMovieHandler, - MinimumAvailability, - minimum_availability_list, - ActiveRadarrBlock::EditMovieSelectMinimumAvailability, - None - ); + #[rstest] + fn test_edit_movie_select_minimum_availability_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); + app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .minimum_availability_list + .set_items(minimum_availability_vec.clone()); - test_iterable_scroll!( - test_edit_movie_select_quality_profile_scroll, - EditMovieHandler, - quality_profile_list, - ActiveRadarrBlock::EditMovieSelectQualityProfile, - None - ); + if key == Key::Up { + for i in (0..minimum_availability_vec.len()).rev() { + EditMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[i] + ); + } + } else { + for i in 0..minimum_availability_vec.len() { + EditMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[(i + 1) % minimum_availability_vec.len()] + ); + } + } + } + + #[rstest] + fn test_edit_movie_select_quality_profile_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); + app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); + + EditMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 2" + ); + + EditMovieHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 1" + ); + } #[rstest] fn test_edit_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { @@ -64,51 +166,230 @@ mod tests { mod test_handle_home_end { use strum::IntoEnumIterator; - use crate::{test_enum_home_and_end, test_iterable_home_and_end, test_text_box_home_end_keys}; + use crate::models::servarr_data::radarr::modals::EditMovieModal; use super::*; - test_enum_home_and_end!( - test_edit_movie_select_minimum_availability_home_end, - EditMovieHandler, - MinimumAvailability, - minimum_availability_list, - ActiveRadarrBlock::EditMovieSelectMinimumAvailability, - None - ); + #[test] + fn test_edit_movie_select_minimum_availability_home_end() { + let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); + app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .minimum_availability_list + .set_items(minimum_availability_vec.clone()); - test_iterable_home_and_end!( - test_edit_movie_select_quality_profile_scroll, - EditMovieHandler, - quality_profile_list, - ActiveRadarrBlock::EditMovieSelectQualityProfile, - None - ); + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[minimum_availability_vec.len() - 1] + ); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectMinimumAvailability, + &None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .current_selection(), + &minimum_availability_vec[0] + ); + } + + #[test] + fn test_edit_movie_select_quality_profile_scroll() { + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); + app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .quality_profile_list + .set_items(vec![ + "Test 1".to_owned(), + "Test 2".to_owned(), + "Test 3".to_owned(), + ]); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 3" + ); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::EditMovieSelectQualityProfile, + &None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .current_selection(), + "Test 1" + ); + } #[test] fn test_edit_movie_path_input_home_end_keys() { - test_text_box_home_end_keys!( - EditMovieHandler, - ActiveRadarrBlock::EditMoviePathInput, - edit_path + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + path: "Test".into(), + ..EditMovieModal::default() + }); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::EditMoviePathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 4 + ); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::EditMoviePathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 0 ); } #[test] fn test_edit_movie_tags_input_home_end_keys() { - test_text_box_home_end_keys!( - EditMovieHandler, - ActiveRadarrBlock::EditMovieTagsInput, - edit_tags + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + tags: "Test".into(), + ..EditMovieModal::default() + }); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::EditMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 4 + ); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::EditMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 0 ); } } mod test_handle_left_right_action { + use crate::models::servarr_data::radarr::modals::EditMovieModal; use rstest::rstest; - use crate::test_text_box_left_right_keys; - use super::*; #[rstest] @@ -126,19 +407,103 @@ mod tests { #[test] fn test_edit_movie_path_input_left_right_keys() { - test_text_box_left_right_keys!( - EditMovieHandler, - ActiveRadarrBlock::EditMoviePathInput, - edit_path + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + path: "Test".into(), + ..EditMovieModal::default() + }); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.left.key, + &mut app, + &ActiveRadarrBlock::EditMoviePathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 1 + ); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.right.key, + &mut app, + &ActiveRadarrBlock::EditMoviePathInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .offset + .borrow(), + 0 ); } #[test] fn test_edit_movie_tags_input_left_right_keys() { - test_text_box_left_right_keys!( - EditMovieHandler, - ActiveRadarrBlock::EditMovieTagsInput, - edit_tags + let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + tags: "Test".into(), + ..EditMovieModal::default() + }); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.left.key, + &mut app, + &ActiveRadarrBlock::EditMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 1 + ); + + EditMovieHandler::with( + &DEFAULT_KEYBINDINGS.right.key, + &mut app, + &ActiveRadarrBlock::EditMovieTagsInput, + &None, + ) + .handle(); + + assert_eq!( + *app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .offset + .borrow(), + 0 ); } } @@ -147,7 +512,8 @@ mod tests { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::modals::EditMovieModal; + use crate::models::servarr_data::radarr::radarr_data::{ EDIT_COLLECTION_SELECTION_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, }; use crate::models::{BlockSelectionState, Route}; @@ -161,7 +527,10 @@ mod tests { fn test_edit_movie_path_input_submit() { let mut app = App::default(); app.should_ignore_quit_key = true; - app.data.radarr_data.edit_path = "Test Path".to_owned().into(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + path: "Test Path".into(), + ..EditMovieModal::default() + }); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePathInput.into()); @@ -174,7 +543,15 @@ mod tests { .handle(); assert!(!app.should_ignore_quit_key); - assert!(!app.data.radarr_data.edit_path.text.is_empty()); + assert!(!app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .text + .is_empty()); assert_eq!( app.get_current_route(), &ActiveRadarrBlock::EditMoviePrompt.into() @@ -185,7 +562,10 @@ mod tests { fn test_edit_movie_tags_input_submit() { let mut app = App::default(); app.should_ignore_quit_key = true; - app.data.radarr_data.edit_tags = "Test Tags".to_owned().into(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + tags: "Test Tags".into(), + ..EditMovieModal::default() + }); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePathInput.into()); @@ -198,7 +578,15 @@ mod tests { .handle(); assert!(!app.should_ignore_quit_key); - assert!(!app.data.radarr_data.edit_tags.text.is_empty()); + assert!(!app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .tags + .text + .is_empty()); assert_eq!( app.get_current_route(), &ActiveRadarrBlock::EditMoviePrompt.into() @@ -232,6 +620,7 @@ mod tests { #[test] fn test_edit_movie_confirm_prompt_prompt_confirmation_submit() { let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.data.radarr_data.prompt_confirm = true; @@ -255,6 +644,7 @@ mod tests { app.data.radarr_data.prompt_confirm_action, Some(RadarrEvent::EditMovie) ); + assert!(app.data.radarr_data.edit_movie_modal.is_some()); assert!(app.should_refresh); } @@ -265,6 +655,7 @@ mod tests { Some(ActiveRadarrBlock::Movies), )); let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS); app.push_navigation_stack(current_route); @@ -277,7 +668,16 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ¤t_route); - assert_eq!(app.data.radarr_data.edit_monitored, Some(true)); + assert_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .monitored, + Some(true) + ); EditMovieHandler::with( &SUBMIT_KEY, @@ -288,7 +688,16 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ¤t_route); - assert_eq!(app.data.radarr_data.edit_monitored, Some(false)); + assert_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .monitored, + Some(false) + ); } #[rstest] @@ -371,8 +780,8 @@ mod tests { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::{assert_edit_media_reset, assert_preferences_selections_reset}; + use crate::models::servarr_data::radarr::modals::EditMovieModal; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; use super::*; @@ -406,6 +815,7 @@ mod tests { let mut app = App::default(); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.data.radarr_data = create_test_radarr_data(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); EditMovieHandler::with( &ESC_KEY, @@ -416,11 +826,9 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); - let radarr_data = &app.data.radarr_data; - assert_preferences_selections_reset!(radarr_data); - assert_edit_media_reset!(radarr_data); - assert!(!radarr_data.prompt_confirm); + assert!(app.data.radarr_data.edit_movie_modal.is_none()); + assert!(!app.data.radarr_data.prompt_confirm); } #[rstest] @@ -443,11 +851,15 @@ mod tests { mod test_handle_key_char { use super::*; + use crate::models::servarr_data::radarr::modals::EditMovieModal; #[test] fn test_edit_movie_path_input_backspace() { let mut app = App::default(); - app.data.radarr_data.edit_path = "Test".to_owned().into(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + path: "Test".into(), + ..EditMovieModal::default() + }); EditMovieHandler::with( &DEFAULT_KEYBINDINGS.backspace.key, @@ -457,13 +869,26 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_path.text, "Tes"); + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .text, + "Tes" + ); } #[test] fn test_edit_movie_tags_input_backspace() { let mut app = App::default(); - app.data.radarr_data.edit_tags = "Test".to_owned().into(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + tags: "Test".into(), + ..EditMovieModal::default() + }); EditMovieHandler::with( &DEFAULT_KEYBINDINGS.backspace.key, @@ -473,12 +898,23 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_tags.text, "Tes"); + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .text, + "Tes" + ); } #[test] fn test_edit_movie_path_input_char_key() { let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); EditMovieHandler::with( &Key::Char('h'), @@ -488,12 +924,23 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_path.text, "h"); + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .text, + "h" + ); } #[test] fn test_edit_movie_tags_input_char_key() { let mut app = App::default(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); EditMovieHandler::with( &Key::Char('h'), @@ -503,7 +950,17 @@ mod tests { ) .handle(); - assert_str_eq!(app.data.radarr_data.edit_tags.text, "h"); + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .text, + "h" + ); } } diff --git a/src/handlers/radarr_handlers/library/library_handler_tests.rs b/src/handlers/radarr_handlers/library/library_handler_tests.rs index d5d1ba6..924f877 100644 --- a/src/handlers/radarr_handlers/library/library_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/library_handler_tests.rs @@ -10,7 +10,7 @@ mod tests { use crate::handlers::radarr_handlers::library::LibraryHandler; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::Movie; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, ADD_MOVIE_BLOCKS, DELETE_MOVIE_BLOCKS, EDIT_MOVIE_BLOCKS, LIBRARY_BLOCKS, MOVIE_DETAILS_BLOCKS, }; @@ -91,7 +91,7 @@ mod tests { use pretty_assertions::assert_eq; use crate::assert_delete_prompt; - use crate::models::servarr_data::radarr_data::DELETE_MOVIE_SELECTION_BLOCKS; + use crate::models::servarr_data::radarr::radarr_data::DELETE_MOVIE_SELECTION_BLOCKS; use super::*; @@ -365,7 +365,7 @@ mod tests { mod test_handle_esc { use pretty_assertions::assert_eq; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; use crate::{assert_filter_reset, assert_search_reset}; use super::*; @@ -445,9 +445,11 @@ mod tests { use strum::IntoEnumIterator; use crate::models::radarr_models::MinimumAvailability; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::models::servarr_data::radarr_data::{RadarrData, EDIT_MOVIE_SELECTION_BLOCKS}; - use crate::models::HorizontallyScrollableText; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::{ + RadarrData, EDIT_MOVIE_SELECTION_BLOCKS, + }; + use crate::models::StatefulTable; use crate::{assert_refresh_key, test_edit_movie_key}; diff --git a/src/handlers/radarr_handlers/library/mod.rs b/src/handlers/radarr_handlers/library/mod.rs index ee196e7..7da2949 100644 --- a/src/handlers/radarr_handlers/library/mod.rs +++ b/src/handlers/radarr_handlers/library/mod.rs @@ -9,7 +9,7 @@ use crate::handlers::radarr_handlers::{ filter_table, handle_change_tab_left_right_keys, search_table, }; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, DELETE_MOVIE_SELECTION_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, LIBRARY_BLOCKS, }; use crate::models::{BlockSelectionState, Scrollable}; @@ -266,7 +266,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, ' ) .into(), ); - self.app.data.radarr_data.populate_edit_movie_fields(); + self.app.data.radarr_data.edit_movie_modal = Some((&self.app.data.radarr_data).into()); self.app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS); } diff --git a/src/handlers/radarr_handlers/library/movie_details_handler.rs b/src/handlers/radarr_handlers/library/movie_details_handler.rs index d5a4742..b3f2734 100644 --- a/src/handlers/radarr_handlers/library/movie_details_handler.rs +++ b/src/handlers/radarr_handlers/library/movie_details_handler.rs @@ -8,7 +8,7 @@ use crate::app::App; use crate::event::Key; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::models::radarr_models::{Language, Release, ReleaseField}; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, EDIT_MOVIE_SELECTION_BLOCKS, MOVIE_DETAILS_BLOCKS, }; use crate::models::{BlockSelectionState, Scrollable}; @@ -243,7 +243,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler< ) .into(), ); - self.app.data.radarr_data.populate_edit_movie_fields(); + self.app.data.radarr_data.edit_movie_modal = Some((&self.app.data.radarr_data).into()); self.app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS); } diff --git a/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs b/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs index d317084..0b67eb5 100644 --- a/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs @@ -15,7 +15,7 @@ mod tests { use crate::models::radarr_models::{ Credit, Language, MovieHistoryItem, Quality, QualityWrapper, Release, ReleaseField, }; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; use crate::models::{HorizontallyScrollableText, ScrollableText}; mod test_handle_scroll_up_and_down { @@ -24,10 +24,7 @@ mod tests { use strum::IntoEnumIterator; use crate::models::radarr_models::ReleaseField; - use crate::{ - simple_stateful_iterable_vec, test_enum_scroll, test_iterable_scroll, - test_scrollable_text_scroll, - }; + use crate::{simple_stateful_iterable_vec, test_iterable_scroll, test_scrollable_text_scroll}; use super::*; @@ -82,14 +79,50 @@ mod tests { to_string ); - test_enum_scroll!( - test_manual_search_sort_scroll, - MovieDetailsHandler, - ReleaseField, - movie_releases_sort, - ActiveRadarrBlock::ManualSearchSortPrompt, - None - ); + #[rstest] + fn test_manual_search_sort_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let release_field_vec = Vec::from_iter(ReleaseField::iter()); + let mut app = App::default(); + app + .data + .radarr_data + .movie_releases_sort + .set_items(release_field_vec.clone()); + + if key == Key::Up { + for i in (0..release_field_vec.len()).rev() { + MovieDetailsHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::ManualSearchSortPrompt, + &None, + ) + .handle(); + + assert_eq!( + app.data.radarr_data.movie_releases_sort.current_selection(), + &release_field_vec[i] + ); + } + } else { + for i in 0..release_field_vec.len() { + MovieDetailsHandler::with( + &key, + &mut app, + &ActiveRadarrBlock::ManualSearchSortPrompt, + &None, + ) + .handle(); + + assert_eq!( + app.data.radarr_data.movie_releases_sort.current_selection(), + &release_field_vec[(i + 1) % release_field_vec.len()] + ); + } + } + } } mod test_handle_home_end { @@ -97,8 +130,7 @@ mod tests { use crate::models::radarr_models::ReleaseField; use crate::{ - extended_stateful_iterable_vec, test_enum_home_and_end, test_iterable_home_and_end, - test_scrollable_text_home_and_end, + extended_stateful_iterable_vec, test_iterable_home_and_end, test_scrollable_text_home_and_end, }; use super::*; @@ -154,14 +186,42 @@ mod tests { to_string ); - test_enum_home_and_end!( - test_manual_search_sort_home_end, - MovieDetailsHandler, - ReleaseField, - movie_releases_sort, - ActiveRadarrBlock::ManualSearchSortPrompt, - None - ); + #[test] + fn test_manual_search_sort_home_end() { + let release_field_vec = Vec::from_iter(ReleaseField::iter()); + let mut app = App::default(); + app + .data + .radarr_data + .movie_releases_sort + .set_items(release_field_vec.clone()); + + MovieDetailsHandler::with( + &DEFAULT_KEYBINDINGS.end.key, + &mut app, + &ActiveRadarrBlock::ManualSearchSortPrompt, + &None, + ) + .handle(); + + assert_eq!( + app.data.radarr_data.movie_releases_sort.current_selection(), + &release_field_vec[release_field_vec.len() - 1] + ); + + MovieDetailsHandler::with( + &DEFAULT_KEYBINDINGS.home.key, + &mut app, + &ActiveRadarrBlock::ManualSearchSortPrompt, + &None, + ) + .handle(); + + assert_eq!( + app.data.radarr_data.movie_releases_sort.current_selection(), + &release_field_vec[0] + ); + } } mod test_handle_left_right_action { @@ -355,7 +415,7 @@ mod tests { use rstest::rstest; use crate::assert_movie_info_tabs_reset; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; use super::*; @@ -413,9 +473,10 @@ mod tests { use strum::IntoEnumIterator; use crate::models::radarr_models::{MinimumAvailability, Movie}; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::models::servarr_data::radarr_data::{RadarrData, EDIT_MOVIE_SELECTION_BLOCKS}; - use crate::models::HorizontallyScrollableText; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::{ + RadarrData, EDIT_MOVIE_SELECTION_BLOCKS, + }; use crate::models::StatefulTable; use crate::test_edit_movie_key; diff --git a/src/handlers/radarr_handlers/mod.rs b/src/handlers/radarr_handlers/mod.rs index c07405d..3c8a26c 100644 --- a/src/handlers/radarr_handlers/mod.rs +++ b/src/handlers/radarr_handlers/mod.rs @@ -6,7 +6,7 @@ use crate::handlers::radarr_handlers::library::LibraryHandler; use crate::handlers::radarr_handlers::root_folders::RootFoldersHandler; use crate::handlers::radarr_handlers::system::SystemHandler; use crate::handlers::KeyEventHandler; -use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; +use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::utils::strip_non_search_characters; use crate::{App, Key}; diff --git a/src/handlers/radarr_handlers/radarr_handler_test_utils.rs b/src/handlers/radarr_handlers/radarr_handler_test_utils.rs index a8dae82..b0a4b35 100644 --- a/src/handlers/radarr_handlers/radarr_handler_test_utils.rs +++ b/src/handlers/radarr_handlers/radarr_handler_test_utils.rs @@ -6,10 +6,6 @@ mod utils { ($handler:ident, $block:expr, $context:expr) => { let mut app = App::default(); let mut radarr_data = RadarrData { - edit_path: HorizontallyScrollableText::default(), - edit_tags: HorizontallyScrollableText::default(), - edit_monitored: None, - edit_search_on_add: None, quality_profile_map: BiMap::from_iter([ (2222, "HD - 1080p".to_owned()), (1111, "Any".to_owned()), @@ -39,32 +35,81 @@ mod utils { &ActiveRadarrBlock::EditMovieToggleMonitored ); assert_eq!( - app.data.radarr_data.minimum_availability_list.items, + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .minimum_availability_list + .items, Vec::from_iter(MinimumAvailability::iter()) ); assert_eq!( app .data .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() .minimum_availability_list .current_selection(), &MinimumAvailability::Released ); assert_eq!( - app.data.radarr_data.quality_profile_list.items, + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .quality_profile_list + .items, vec!["Any".to_owned(), "HD - 1080p".to_owned()] ); assert_str_eq!( app .data .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() .quality_profile_list .current_selection(), "HD - 1080p" ); - assert_str_eq!(app.data.radarr_data.edit_path.text, "/nfs/movies/Test"); - assert_str_eq!(app.data.radarr_data.edit_tags.text, "test"); - assert_eq!(app.data.radarr_data.edit_monitored, Some(true)); + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .path + .text, + "/nfs/movies/Test" + ); + assert_str_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .text, + "test" + ); + assert_eq!( + app + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .monitored, + Some(true) + ); assert_eq!( app.data.radarr_data.selected_block.blocks, &EDIT_MOVIE_SELECTION_BLOCKS @@ -77,10 +122,6 @@ mod utils { ($handler:ident, $block:expr, $context:expr) => { let mut app = App::default(); let mut radarr_data = RadarrData { - edit_path: HorizontallyScrollableText::default(), - edit_tags: HorizontallyScrollableText::default(), - edit_monitored: None, - edit_search_on_add: None, quality_profile_map: BiMap::from_iter([ (2222, "HD - 1080p".to_owned()), (1111, "Any".to_owned()), @@ -109,32 +150,80 @@ mod utils { &ActiveRadarrBlock::EditCollectionToggleMonitored ); assert_eq!( - app.data.radarr_data.minimum_availability_list.items, + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .minimum_availability_list + .items, Vec::from_iter(MinimumAvailability::iter()) ); assert_eq!( app .data .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() .minimum_availability_list .current_selection(), &MinimumAvailability::Released ); assert_eq!( - app.data.radarr_data.quality_profile_list.items, + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .quality_profile_list + .items, vec!["Any".to_owned(), "HD - 1080p".to_owned()] ); assert_str_eq!( app .data .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() .quality_profile_list .current_selection(), "HD - 1080p" ); - assert_str_eq!(app.data.radarr_data.edit_path.text, "/nfs/movies/Test"); - assert_eq!(app.data.radarr_data.edit_monitored, Some(true)); - assert_eq!(app.data.radarr_data.edit_search_on_add, Some(true)); + assert_str_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .path + .text, + "/nfs/movies/Test" + ); + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .monitored, + Some(true) + ); + assert_eq!( + app + .data + .radarr_data + .edit_collection_modal + .as_ref() + .unwrap() + .search_on_add, + Some(true) + ); assert_eq!( app.data.radarr_data.selected_block.blocks, &EDIT_COLLECTION_SELECTION_BLOCKS diff --git a/src/handlers/radarr_handlers/radarr_handler_tests.rs b/src/handlers/radarr_handlers/radarr_handler_tests.rs index d684982..c7339be 100644 --- a/src/handlers/radarr_handlers/radarr_handler_tests.rs +++ b/src/handlers/radarr_handlers/radarr_handler_tests.rs @@ -11,7 +11,7 @@ mod tests { }; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::Movie; - use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; + use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::HorizontallyScrollableText; use crate::{extended_stateful_iterable_vec, test_handler_delegation}; diff --git a/src/handlers/radarr_handlers/root_folders/mod.rs b/src/handlers/radarr_handlers/root_folders/mod.rs index 0a65b0b..cfa21c9 100644 --- a/src/handlers/radarr_handlers/root_folders/mod.rs +++ b/src/handlers/radarr_handlers/root_folders/mod.rs @@ -3,7 +3,7 @@ use crate::app::App; use crate::event::Key; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; use crate::models::{HorizontallyScrollableText, Scrollable}; use crate::network::radarr_network::RadarrEvent; use crate::{handle_text_box_keys, handle_text_box_left_right_keys}; diff --git a/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs b/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs index e5efce9..5c35f3e 100644 --- a/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs +++ b/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs @@ -8,7 +8,7 @@ mod tests { use crate::event::Key; use crate::handlers::radarr_handlers::root_folders::RootFoldersHandler; use crate::handlers::KeyEventHandler; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; use crate::models::HorizontallyScrollableText; mod test_handle_scroll_up_and_down { diff --git a/src/handlers/radarr_handlers/system/mod.rs b/src/handlers/radarr_handlers/system/mod.rs index 7b92d48..d940317 100644 --- a/src/handlers/radarr_handlers/system/mod.rs +++ b/src/handlers/radarr_handlers/system/mod.rs @@ -4,7 +4,7 @@ use crate::event::Key; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::system::system_details_handler::SystemDetailsHandler; use crate::handlers::{handle_clear_errors, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; +use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::Scrollable; mod system_details_handler; diff --git a/src/handlers/radarr_handlers/system/system_details_handler.rs b/src/handlers/radarr_handlers/system/system_details_handler.rs index e1bb248..47e9cdf 100644 --- a/src/handlers/radarr_handlers/system/system_details_handler.rs +++ b/src/handlers/radarr_handlers/system/system_details_handler.rs @@ -2,8 +2,8 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; -use crate::models::Scrollable; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; +use crate::models::{Scrollable, StatefulList}; use crate::network::radarr_network::RadarrEvent; #[cfg(test)] @@ -141,7 +141,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler fn handle_esc(&mut self) { match self.active_radarr_block { ActiveRadarrBlock::SystemLogs => { - self.app.data.radarr_data.reset_log_details_list(); + self.app.data.radarr_data.log_details = StatefulList::default(); self.app.pop_navigation_stack() } ActiveRadarrBlock::SystemQueuedEvents diff --git a/src/handlers/radarr_handlers/system/system_details_handler_tests.rs b/src/handlers/radarr_handlers/system/system_details_handler_tests.rs index 7d8c7bd..6216f99 100644 --- a/src/handlers/radarr_handlers/system/system_details_handler_tests.rs +++ b/src/handlers/radarr_handlers/system/system_details_handler_tests.rs @@ -9,7 +9,9 @@ mod tests { use crate::handlers::radarr_handlers::system::system_details_handler::SystemDetailsHandler; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::{QueueEvent, Task}; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS, + }; mod test_handle_scroll_up_and_down { use rstest::rstest; diff --git a/src/handlers/radarr_handlers/system/system_handler_tests.rs b/src/handlers/radarr_handlers/system/system_handler_tests.rs index 5e9b558..566c4bf 100644 --- a/src/handlers/radarr_handlers/system/system_handler_tests.rs +++ b/src/handlers/radarr_handlers/system/system_handler_tests.rs @@ -9,7 +9,9 @@ mod tests { use crate::event::Key; use crate::handlers::radarr_handlers::system::SystemHandler; use crate::handlers::KeyEventHandler; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS, + }; use crate::test_handler_delegation; mod test_handle_left_right_action { diff --git a/src/models/mod.rs b/src/models/mod.rs index 93ff44f..f35768d 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,7 +1,7 @@ use std::cell::RefCell; use std::fmt::{Debug, Display, Formatter}; -use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; +use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use serde::Deserialize; use tui::widgets::{ListState, TableState}; diff --git a/src/models/model_tests.rs b/src/models/model_tests.rs index da45919..4584ada 100644 --- a/src/models/model_tests.rs +++ b/src/models/model_tests.rs @@ -4,7 +4,7 @@ mod tests { use pretty_assertions::{assert_eq, assert_str_eq}; - use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; + use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::{ BlockSelectionState, HorizontallyScrollableText, Scrollable, ScrollableText, StatefulList, StatefulTable, TabRoute, TabState, diff --git a/src/models/servarr_data/mod.rs b/src/models/servarr_data/mod.rs index f6d800f..c430c1a 100644 --- a/src/models/servarr_data/mod.rs +++ b/src/models/servarr_data/mod.rs @@ -1 +1 @@ -pub mod radarr_data; +pub mod radarr; diff --git a/src/models/servarr_data/radarr/mod.rs b/src/models/servarr_data/radarr/mod.rs new file mode 100644 index 0000000..8594793 --- /dev/null +++ b/src/models/servarr_data/radarr/mod.rs @@ -0,0 +1,2 @@ +pub mod modals; +pub mod radarr_data; diff --git a/src/models/servarr_data/radarr/modals.rs b/src/models/servarr_data/radarr/modals.rs new file mode 100644 index 0000000..358ee09 --- /dev/null +++ b/src/models/servarr_data/radarr/modals.rs @@ -0,0 +1,193 @@ +use crate::models::radarr_models::{Collection, MinimumAvailability, Monitor, Movie, RootFolder}; +use crate::models::servarr_data::radarr::radarr_data::RadarrData; +use crate::models::{HorizontallyScrollableText, StatefulList}; +use strum::IntoEnumIterator; + +#[cfg(test)] +#[path = "modals_tests.rs"] +mod modals_tests; + +#[derive(Default)] +pub struct EditMovieModal { + pub minimum_availability_list: StatefulList, + pub quality_profile_list: StatefulList, + pub monitored: Option, + pub path: HorizontallyScrollableText, + pub tags: HorizontallyScrollableText, +} + +impl From<&RadarrData<'_>> for EditMovieModal { + fn from(radarr_data: &RadarrData<'_>) -> EditMovieModal { + let mut edit_movie_modal = EditMovieModal::default(); + let Movie { + path, + tags, + monitored, + minimum_availability, + quality_profile_id, + .. + } = if radarr_data.filtered_movies.items.is_empty() { + radarr_data.movies.current_selection() + } else { + radarr_data.filtered_movies.current_selection() + }; + + edit_movie_modal + .minimum_availability_list + .set_items(Vec::from_iter(MinimumAvailability::iter())); + edit_movie_modal.path = path.clone().into(); + edit_movie_modal.tags = tags + .iter() + .map(|tag_id| { + radarr_data + .tags_map + .get_by_left(&tag_id.as_u64().unwrap()) + .unwrap() + .clone() + }) + .collect::>() + .join(", ") + .into(); + + edit_movie_modal.monitored = Some(*monitored); + + let minimum_availability_index = edit_movie_modal + .minimum_availability_list + .items + .iter() + .position(|ma| ma == minimum_availability); + edit_movie_modal + .minimum_availability_list + .state + .select(minimum_availability_index); + + let mut quality_profile_names: Vec = radarr_data + .quality_profile_map + .right_values() + .cloned() + .collect(); + quality_profile_names.sort(); + edit_movie_modal + .quality_profile_list + .set_items(quality_profile_names); + let quality_profile_name = radarr_data + .quality_profile_map + .get_by_left(&quality_profile_id.as_u64().unwrap()) + .unwrap(); + let quality_profile_index = edit_movie_modal + .quality_profile_list + .items + .iter() + .position(|profile| profile == quality_profile_name); + edit_movie_modal + .quality_profile_list + .state + .select(quality_profile_index); + + edit_movie_modal + } +} + +#[derive(Default)] +pub struct AddMovieModal { + pub root_folder_list: StatefulList, + pub monitor_list: StatefulList, + pub minimum_availability_list: StatefulList, + pub quality_profile_list: StatefulList, + pub tags: HorizontallyScrollableText, +} + +impl From<&RadarrData<'_>> for AddMovieModal { + fn from(radarr_data: &RadarrData<'_>) -> AddMovieModal { + let mut add_movie_modal = AddMovieModal::default(); + add_movie_modal + .monitor_list + .set_items(Vec::from_iter(Monitor::iter())); + add_movie_modal + .minimum_availability_list + .set_items(Vec::from_iter(MinimumAvailability::iter())); + let mut quality_profile_names: Vec = radarr_data + .quality_profile_map + .right_values() + .cloned() + .collect(); + quality_profile_names.sort(); + add_movie_modal + .quality_profile_list + .set_items(quality_profile_names); + add_movie_modal + .root_folder_list + .set_items(radarr_data.root_folders.items.to_vec()); + + add_movie_modal + } +} + +#[derive(Default)] +pub struct EditCollectionModal { + pub monitored: Option, + pub minimum_availability_list: StatefulList, + pub quality_profile_list: StatefulList, + pub path: HorizontallyScrollableText, + pub search_on_add: Option, +} + +impl From<&RadarrData<'_>> for EditCollectionModal { + fn from(radarr_data: &RadarrData<'_>) -> EditCollectionModal { + let mut edit_collection_modal = EditCollectionModal::default(); + let Collection { + root_folder_path, + monitored, + search_on_add, + minimum_availability, + quality_profile_id, + .. + } = if radarr_data.filtered_collections.items.is_empty() { + radarr_data.collections.current_selection() + } else { + radarr_data.filtered_collections.current_selection() + }; + + edit_collection_modal.path = root_folder_path.clone().unwrap_or_default().into(); + edit_collection_modal.monitored = Some(*monitored); + edit_collection_modal.search_on_add = Some(*search_on_add); + edit_collection_modal + .minimum_availability_list + .set_items(Vec::from_iter(MinimumAvailability::iter())); + let mut quality_profile_names: Vec = radarr_data + .quality_profile_map + .right_values() + .cloned() + .collect(); + quality_profile_names.sort(); + edit_collection_modal + .quality_profile_list + .set_items(quality_profile_names); + + let minimum_availability_index = edit_collection_modal + .minimum_availability_list + .items + .iter() + .position(|ma| ma == minimum_availability); + edit_collection_modal + .minimum_availability_list + .state + .select(minimum_availability_index); + + let quality_profile_name = radarr_data + .quality_profile_map + .get_by_left(&quality_profile_id.as_u64().unwrap()) + .unwrap(); + let quality_profile_index = edit_collection_modal + .quality_profile_list + .items + .iter() + .position(|profile| profile == quality_profile_name); + edit_collection_modal + .quality_profile_list + .state + .select(quality_profile_index); + + edit_collection_modal + } +} diff --git a/src/models/servarr_data/radarr/modals_tests.rs b/src/models/servarr_data/radarr/modals_tests.rs new file mode 100644 index 0000000..bc4f27d --- /dev/null +++ b/src/models/servarr_data/radarr/modals_tests.rs @@ -0,0 +1,161 @@ +#[cfg(test)] +mod test { + use crate::models::radarr_models::{Collection, MinimumAvailability, Monitor, Movie, RootFolder}; + use crate::models::servarr_data::radarr::modals::{ + AddMovieModal, EditCollectionModal, EditMovieModal, + }; + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::servarr_data::radarr::radarr_data::RadarrData; + use crate::models::{HorizontallyScrollableText, StatefulTable}; + use bimap::BiMap; + use pretty_assertions::{assert_eq, assert_str_eq}; + use rstest::rstest; + use serde_json::Number; + use strum::IntoEnumIterator; + + #[rstest] + fn test_edit_movie_modal_from_radarr_data(#[values(true, false)] test_filtered_movies: bool) { + let mut radarr_data = RadarrData { + edit_path: HorizontallyScrollableText::default(), + edit_tags: HorizontallyScrollableText::default(), + edit_monitored: None, + quality_profile_map: BiMap::from_iter([ + (2222, "HD - 1080p".to_owned()), + (1111, "Any".to_owned()), + ]), + tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]), + filtered_movies: StatefulTable::default(), + ..create_test_radarr_data() + }; + let movie = Movie { + path: "/nfs/movies/Test".to_owned(), + monitored: true, + quality_profile_id: Number::from(2222), + minimum_availability: MinimumAvailability::Released, + tags: vec![Number::from(1), Number::from(2)], + ..Movie::default() + }; + + if test_filtered_movies { + radarr_data.filtered_movies.set_items(vec![movie]); + } else { + radarr_data.movies.set_items(vec![movie]); + } + + let edit_movie_modal = EditMovieModal::from(&radarr_data); + + assert_eq!( + edit_movie_modal.minimum_availability_list.items, + Vec::from_iter(MinimumAvailability::iter()) + ); + assert_eq!( + edit_movie_modal + .minimum_availability_list + .current_selection(), + &MinimumAvailability::Released + ); + assert_eq!( + edit_movie_modal.quality_profile_list.items, + vec!["Any".to_owned(), "HD - 1080p".to_owned()] + ); + assert_str_eq!( + edit_movie_modal.quality_profile_list.current_selection(), + "HD - 1080p" + ); + assert_str_eq!(edit_movie_modal.path.text, "/nfs/movies/Test"); + assert_str_eq!(edit_movie_modal.tags.text, "usenet, test"); + assert_eq!(edit_movie_modal.monitored, Some(true)); + } + + #[test] + fn test_add_movie_modal_from_radarr_data() { + let root_folder = RootFolder { + id: Number::from(1), + path: "/nfs".to_owned(), + accessible: true, + free_space: Number::from(219902325555200u64), + unmapped_folders: None, + }; + let mut radarr_data = RadarrData { + quality_profile_map: BiMap::from_iter([ + (2222, "HD - 1080p".to_owned()), + (1111, "Any".to_owned()), + ]), + ..RadarrData::default() + }; + radarr_data + .root_folders + .set_items(vec![root_folder.clone()]); + + let add_movie_modal = AddMovieModal::from(&radarr_data); + + assert_eq!( + add_movie_modal.monitor_list.items, + Vec::from_iter(Monitor::iter()) + ); + assert_eq!( + add_movie_modal.minimum_availability_list.items, + Vec::from_iter(MinimumAvailability::iter()) + ); + assert_eq!( + add_movie_modal.quality_profile_list.items, + vec!["Any".to_owned(), "HD - 1080p".to_owned()] + ); + assert_eq!(add_movie_modal.root_folder_list.items, vec![root_folder]); + assert!(add_movie_modal.tags.text.is_empty()); + } + + #[rstest] + fn test_edit_collection_modal_from_radarr_data( + #[values(true, false)] test_filtered_collections: bool, + ) { + let mut radarr_data = RadarrData { + quality_profile_map: BiMap::from_iter([ + (2222, "HD - 1080p".to_owned()), + (1111, "Any".to_owned()), + ]), + filtered_collections: StatefulTable::default(), + ..create_test_radarr_data() + }; + let collection = Collection { + root_folder_path: Some("/nfs/movies/Test".to_owned()), + monitored: true, + search_on_add: true, + quality_profile_id: Number::from(2222), + minimum_availability: MinimumAvailability::Released, + ..Collection::default() + }; + + if test_filtered_collections { + radarr_data.filtered_collections.set_items(vec![collection]); + } else { + radarr_data.collections.set_items(vec![collection]); + } + + let edit_collection_modal = EditCollectionModal::from(&radarr_data); + + assert_eq!( + edit_collection_modal.minimum_availability_list.items, + Vec::from_iter(MinimumAvailability::iter()) + ); + assert_eq!( + edit_collection_modal + .minimum_availability_list + .current_selection(), + &MinimumAvailability::Released + ); + assert_eq!( + edit_collection_modal.quality_profile_list.items, + vec!["Any".to_owned(), "HD - 1080p".to_owned()] + ); + assert_str_eq!( + edit_collection_modal + .quality_profile_list + .current_selection(), + "HD - 1080p" + ); + assert_str_eq!(edit_collection_modal.path.text, "/nfs/movies/Test"); + assert_eq!(edit_collection_modal.monitored, Some(true)); + assert_eq!(edit_collection_modal.search_on_add, Some(true)); + } +} diff --git a/src/models/servarr_data/radarr_data.rs b/src/models/servarr_data/radarr/radarr_data.rs similarity index 82% rename from src/models/servarr_data/radarr_data.rs rename to src/models/servarr_data/radarr/radarr_data.rs index 792f1ef..9a9d7bf 100644 --- a/src/models/servarr_data/radarr_data.rs +++ b/src/models/servarr_data/radarr/radarr_data.rs @@ -10,6 +10,9 @@ use crate::models::radarr_models::{ IndexerSettings, MinimumAvailability, Monitor, Movie, MovieHistoryItem, QueueEvent, Release, ReleaseField, RootFolder, Task, }; +use crate::models::servarr_data::radarr::modals::{ + AddMovieModal, EditCollectionModal, EditMovieModal, +}; use crate::models::{ BlockSelectionState, HorizontallyScrollableText, Route, ScrollableText, StatefulList, StatefulTable, TabRoute, TabState, @@ -17,7 +20,7 @@ use crate::models::{ use crate::network::radarr_network::RadarrEvent; use bimap::BiMap; use chrono::{DateTime, Utc}; -use strum::{EnumIter, IntoEnumIterator}; +use strum::EnumIter; #[cfg(test)] #[path = "radarr_data_tests.rs"] @@ -67,6 +70,9 @@ pub struct RadarrData<'a> { pub movie_info_tabs: TabState, pub search: HorizontallyScrollableText, pub filter: HorizontallyScrollableText, + pub add_movie_modal: Option, + pub edit_movie_modal: Option, + pub edit_collection_modal: Option, pub edit_path: HorizontallyScrollableText, pub edit_tags: HorizontallyScrollableText, pub edit_monitored: Option, @@ -80,14 +86,6 @@ pub struct RadarrData<'a> { } impl<'a> RadarrData<'a> { - pub fn reset_movie_collection_table(&mut self) { - self.collection_movies = StatefulTable::default(); - } - - pub fn reset_log_details_list(&mut self) { - self.log_details = StatefulList::default(); - } - pub fn reset_delete_movie_preferences(&mut self) { self.delete_movie_files = false; self.add_list_exclusion = false; @@ -109,14 +107,6 @@ impl<'a> RadarrData<'a> { self.filtered_collections = StatefulTable::default(); } - pub fn reset_add_edit_media_fields(&mut self) { - self.edit_monitored = None; - self.edit_search_on_add = None; - self.edit_path = HorizontallyScrollableText::default(); - self.edit_tags = HorizontallyScrollableText::default(); - self.reset_preferences_selections(); - } - pub fn reset_movie_info_tabs(&mut self) { self.file_details = String::default(); self.audio_details = String::default(); @@ -130,126 +120,6 @@ impl<'a> RadarrData<'a> { self.sort_ascending = None; self.movie_info_tabs.index = 0; } - - pub fn reset_preferences_selections(&mut self) { - self.monitor_list = StatefulList::default(); - self.minimum_availability_list = StatefulList::default(); - self.quality_profile_list = StatefulList::default(); - self.root_folder_list = StatefulList::default(); - } - - pub fn populate_preferences_lists(&mut self) { - self.monitor_list.set_items(Vec::from_iter(Monitor::iter())); - self - .minimum_availability_list - .set_items(Vec::from_iter(MinimumAvailability::iter())); - let mut quality_profile_names: Vec = - self.quality_profile_map.right_values().cloned().collect(); - quality_profile_names.sort(); - self.quality_profile_list.set_items(quality_profile_names); - self - .root_folder_list - .set_items(self.root_folders.items.to_vec()); - } - - pub fn populate_edit_movie_fields(&mut self) { - self.populate_preferences_lists(); - let Movie { - path, - tags, - monitored, - minimum_availability, - quality_profile_id, - .. - } = if self.filtered_movies.items.is_empty() { - self.movies.current_selection() - } else { - self.filtered_movies.current_selection() - }; - - self.edit_path = path.clone().into(); - self.edit_tags = tags - .iter() - .map(|tag_id| { - self - .tags_map - .get_by_left(&tag_id.as_u64().unwrap()) - .unwrap() - .clone() - }) - .collect::>() - .join(", ") - .into(); - self.edit_monitored = Some(*monitored); - - let minimum_availability_index = self - .minimum_availability_list - .items - .iter() - .position(|ma| ma == minimum_availability); - self - .minimum_availability_list - .state - .select(minimum_availability_index); - - let quality_profile_name = self - .quality_profile_map - .get_by_left(&quality_profile_id.as_u64().unwrap()) - .unwrap(); - let quality_profile_index = self - .quality_profile_list - .items - .iter() - .position(|profile| profile == quality_profile_name); - self - .quality_profile_list - .state - .select(quality_profile_index); - } - - pub fn populate_edit_collection_fields(&mut self) { - self.populate_preferences_lists(); - let Collection { - root_folder_path, - monitored, - search_on_add, - minimum_availability, - quality_profile_id, - .. - } = if self.filtered_collections.items.is_empty() { - self.collections.current_selection() - } else { - self.filtered_collections.current_selection() - }; - - self.edit_path = root_folder_path.clone().unwrap_or_default().into(); - self.edit_monitored = Some(*monitored); - self.edit_search_on_add = Some(*search_on_add); - - let minimum_availability_index = self - .minimum_availability_list - .items - .iter() - .position(|ma| ma == minimum_availability); - self - .minimum_availability_list - .state - .select(minimum_availability_index); - - let quality_profile_name = self - .quality_profile_map - .get_by_left(&quality_profile_id.as_u64().unwrap()) - .unwrap(); - let quality_profile_index = self - .quality_profile_list - .items - .iter() - .position(|profile| profile == quality_profile_name); - self - .quality_profile_list - .state - .select(quality_profile_index); - } } impl<'a> Default for RadarrData<'a> { @@ -292,6 +162,9 @@ impl<'a> Default for RadarrData<'a> { prompt_confirm_action: None, search: HorizontallyScrollableText::default(), filter: HorizontallyScrollableText::default(), + add_movie_modal: None, + edit_movie_modal: None, + edit_collection_modal: None, edit_path: HorizontallyScrollableText::default(), edit_tags: HorizontallyScrollableText::default(), edit_monitored: None, @@ -623,3 +496,15 @@ impl From<(ActiveRadarrBlock, Option)> for Route { Route::Radarr(value.0, value.1) } } + +pub struct EditIndexerSettings { + pub allow_hardcoded_subs: bool, + pub availability_delay: HorizontallyScrollableText, + pub id: HorizontallyScrollableText, + pub maximum_size: HorizontallyScrollableText, + pub minimum_age: HorizontallyScrollableText, + pub prefer_indexer_flags: bool, + pub retention: HorizontallyScrollableText, + pub rss_sync_interval: HorizontallyScrollableText, + pub whitelisted_hardcoded_subs: HorizontallyScrollableText, +} diff --git a/src/models/servarr_data/radarr_data_tests.rs b/src/models/servarr_data/radarr/radarr_data_tests.rs similarity index 78% rename from src/models/servarr_data/radarr_data_tests.rs rename to src/models/servarr_data/radarr/radarr_data_tests.rs index 57eff39..35d3eab 100644 --- a/src/models/servarr_data/radarr_data_tests.rs +++ b/src/models/servarr_data/radarr/radarr_data_tests.rs @@ -1,12 +1,9 @@ #[cfg(test)] mod tests { mod radarr_data_tests { - use bimap::BiMap; + use chrono::{DateTime, Utc}; use pretty_assertions::{assert_eq, assert_str_eq}; - use rstest::rstest; - use serde_json::Number; - use strum::IntoEnumIterator; use crate::app::context_clues::build_context_clue_string; use crate::app::radarr::radarr_context_clues::{ @@ -15,18 +12,13 @@ mod tests { MANUAL_MOVIE_SEARCH_CONTEXT_CLUES, MOVIE_DETAILS_CONTEXT_CLUES, ROOT_FOLDERS_CONTEXT_CLUES, SYSTEM_CONTEXT_CLUES, }; - use crate::models::radarr_models::{ - Collection, MinimumAvailability, Monitor, Movie, RootFolder, - }; - use crate::models::servarr_data::radarr_data::radarr_test_utils::utils; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, RadarrData}; + + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData}; use crate::models::Route; - use crate::models::StatefulTable; - use crate::models::{BlockSelectionState, HorizontallyScrollableText}; - use crate::{ - assert_edit_media_reset, assert_filter_reset, assert_movie_info_tabs_reset, - assert_preferences_selections_reset, assert_search_reset, - }; + + use crate::models::BlockSelectionState; + use crate::{assert_filter_reset, assert_movie_info_tabs_reset, assert_search_reset}; #[test] fn test_from_tuple_to_route_with_context() { @@ -42,24 +34,6 @@ mod tests { ); } - #[test] - fn test_reset_movie_collection_table() { - let mut radarr_data = utils::create_test_radarr_data(); - - radarr_data.reset_movie_collection_table(); - - assert!(radarr_data.collection_movies.items.is_empty()); - } - - #[test] - fn test_reset_log_details_list() { - let mut radarr_data = utils::create_test_radarr_data(); - - radarr_data.reset_log_details_list(); - - assert!(radarr_data.log_details.items.is_empty()); - } - #[test] fn test_reset_delete_movie_preferences() { let mut radarr_data = utils::create_test_radarr_data(); @@ -97,172 +71,6 @@ mod tests { assert_movie_info_tabs_reset!(radarr_data); } - #[test] - fn test_reset_add_edit_media_fields() { - let mut radarr_data = RadarrData { - edit_monitored: Some(true), - edit_search_on_add: Some(true), - edit_path: "test path".to_owned().into(), - edit_tags: "test tag".to_owned().into(), - ..RadarrData::default() - }; - - radarr_data.reset_add_edit_media_fields(); - - assert_edit_media_reset!(radarr_data); - } - - #[test] - fn test_reset_preferences_selections() { - let mut radarr_data = utils::create_test_radarr_data(); - - radarr_data.reset_preferences_selections(); - - assert_preferences_selections_reset!(radarr_data); - } - - #[test] - fn test_populate_preferences_lists() { - let root_folder = RootFolder { - id: Number::from(1), - path: "/nfs".to_owned(), - accessible: true, - free_space: Number::from(219902325555200u64), - unmapped_folders: None, - }; - let mut radarr_data = RadarrData { - quality_profile_map: BiMap::from_iter([ - (2222, "HD - 1080p".to_owned()), - (1111, "Any".to_owned()), - ]), - ..RadarrData::default() - }; - radarr_data - .root_folders - .set_items(vec![root_folder.clone()]); - - radarr_data.populate_preferences_lists(); - - assert_eq!( - radarr_data.monitor_list.items, - Vec::from_iter(Monitor::iter()) - ); - assert_eq!( - radarr_data.minimum_availability_list.items, - Vec::from_iter(MinimumAvailability::iter()) - ); - assert_eq!( - radarr_data.quality_profile_list.items, - vec!["Any".to_owned(), "HD - 1080p".to_owned()] - ); - assert_eq!(radarr_data.root_folder_list.items, vec![root_folder]); - } - - #[rstest] - fn test_populate_edit_movie_fields(#[values(true, false)] test_filtered_movies: bool) { - let mut radarr_data = RadarrData { - edit_path: HorizontallyScrollableText::default(), - edit_tags: HorizontallyScrollableText::default(), - edit_monitored: None, - quality_profile_map: BiMap::from_iter([ - (2222, "HD - 1080p".to_owned()), - (1111, "Any".to_owned()), - ]), - tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]), - filtered_movies: StatefulTable::default(), - ..utils::create_test_radarr_data() - }; - let movie = Movie { - path: "/nfs/movies/Test".to_owned(), - monitored: true, - quality_profile_id: Number::from(2222), - minimum_availability: MinimumAvailability::Released, - tags: vec![Number::from(1), Number::from(2)], - ..Movie::default() - }; - - if test_filtered_movies { - radarr_data.filtered_movies.set_items(vec![movie]); - } else { - radarr_data.movies.set_items(vec![movie]); - } - - radarr_data.populate_edit_movie_fields(); - - assert_eq!( - radarr_data.minimum_availability_list.items, - Vec::from_iter(MinimumAvailability::iter()) - ); - assert_eq!( - radarr_data.minimum_availability_list.current_selection(), - &MinimumAvailability::Released - ); - assert_eq!( - radarr_data.quality_profile_list.items, - vec!["Any".to_owned(), "HD - 1080p".to_owned()] - ); - assert_str_eq!( - radarr_data.quality_profile_list.current_selection(), - "HD - 1080p" - ); - assert_str_eq!(radarr_data.edit_path.text, "/nfs/movies/Test"); - assert_str_eq!(radarr_data.edit_tags.text, "usenet, test"); - assert_eq!(radarr_data.edit_monitored, Some(true)); - } - - #[rstest] - fn test_populate_edit_collection_fields( - #[values(true, false)] test_filtered_collections: bool, - ) { - let mut radarr_data = RadarrData { - edit_path: HorizontallyScrollableText::default(), - edit_monitored: None, - edit_search_on_add: None, - quality_profile_map: BiMap::from_iter([ - (2222, "HD - 1080p".to_owned()), - (1111, "Any".to_owned()), - ]), - filtered_collections: StatefulTable::default(), - ..utils::create_test_radarr_data() - }; - let collection = Collection { - root_folder_path: Some("/nfs/movies/Test".to_owned()), - monitored: true, - search_on_add: true, - quality_profile_id: Number::from(2222), - minimum_availability: MinimumAvailability::Released, - ..Collection::default() - }; - - if test_filtered_collections { - radarr_data.filtered_collections.set_items(vec![collection]); - } else { - radarr_data.collections.set_items(vec![collection]); - } - - radarr_data.populate_edit_collection_fields(); - - assert_eq!( - radarr_data.minimum_availability_list.items, - Vec::from_iter(MinimumAvailability::iter()) - ); - assert_eq!( - radarr_data.minimum_availability_list.current_selection(), - &MinimumAvailability::Released - ); - assert_eq!( - radarr_data.quality_profile_list.items, - vec!["Any".to_owned(), "HD - 1080p".to_owned()] - ); - assert_str_eq!( - radarr_data.quality_profile_list.current_selection(), - "HD - 1080p" - ); - assert_str_eq!(radarr_data.edit_path.text, "/nfs/movies/Test"); - assert_eq!(radarr_data.edit_monitored, Some(true)); - assert_eq!(radarr_data.edit_search_on_add, Some(true)); - } - #[test] fn test_radarr_data_defaults() { let radarr_data = RadarrData::default(); @@ -304,6 +112,9 @@ mod tests { assert!(radarr_data.prompt_confirm_action.is_none()); assert!(radarr_data.search.text.is_empty()); assert!(radarr_data.filter.text.is_empty()); + assert!(radarr_data.add_movie_modal.is_none()); + assert!(radarr_data.edit_movie_modal.is_none()); + assert!(radarr_data.edit_collection_modal.is_none()); assert!(radarr_data.edit_path.text.is_empty()); assert!(radarr_data.edit_tags.text.is_empty()); assert!(radarr_data.edit_monitored.is_none()); @@ -471,7 +282,7 @@ mod tests { mod active_radarr_block_tests { use pretty_assertions::assert_eq; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, ADD_MOVIE_BLOCKS, ADD_MOVIE_SELECTION_BLOCKS, COLLECTIONS_BLOCKS, COLLECTION_DETAILS_BLOCKS, DELETE_MOVIE_BLOCKS, DELETE_MOVIE_SELECTION_BLOCKS, DOWNLOADS_BLOCKS, EDIT_COLLECTION_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS, diff --git a/src/models/servarr_data/radarr_test_utils.rs b/src/models/servarr_data/radarr/radarr_test_utils.rs similarity index 83% rename from src/models/servarr_data/radarr_test_utils.rs rename to src/models/servarr_data/radarr/radarr_test_utils.rs index ef5180f..19024bc 100644 --- a/src/models/servarr_data/radarr_test_utils.rs +++ b/src/models/servarr_data/radarr/radarr_test_utils.rs @@ -4,7 +4,7 @@ pub mod utils { AddMovieSearchResult, Collection, CollectionMovie, Credit, MinimumAvailability, Monitor, Movie, MovieHistoryItem, Release, ReleaseField, RootFolder, }; - use crate::models::servarr_data::radarr_data::RadarrData; + use crate::models::servarr_data::radarr::radarr_data::RadarrData; use crate::models::{HorizontallyScrollableText, ScrollableText}; pub fn create_test_radarr_data<'a>() -> RadarrData<'a> { @@ -79,16 +79,6 @@ pub mod utils { }; } - #[macro_export] - macro_rules! assert_edit_media_reset { - ($radarr_data:expr) => { - assert!($radarr_data.edit_monitored.is_none()); - assert!($radarr_data.edit_search_on_add.is_none()); - assert!($radarr_data.edit_path.text.is_empty()); - assert!($radarr_data.edit_tags.text.is_empty()); - }; - } - #[macro_export] macro_rules! assert_filter_reset { ($radarr_data:expr) => { @@ -115,14 +105,4 @@ pub mod utils { assert_eq!($radarr_data.movie_info_tabs.index, 0); }; } - - #[macro_export] - macro_rules! assert_preferences_selections_reset { - ($radarr_data:expr) => { - assert!($radarr_data.monitor_list.items.is_empty()); - assert!($radarr_data.minimum_availability_list.items.is_empty()); - assert!($radarr_data.quality_profile_list.items.is_empty()); - assert!($radarr_data.root_folder_list.items.is_empty()); - }; - } } diff --git a/src/network/radarr_network.rs b/src/network/radarr_network.rs index a523523..08a6041 100644 --- a/src/network/radarr_network.rs +++ b/src/network/radarr_network.rs @@ -13,7 +13,10 @@ use crate::models::radarr_models::{ IndexerSettings, LogResponse, Movie, MovieCommandBody, MovieHistoryItem, QualityProfile, QueueEvent, Release, ReleaseDownloadBody, RootFolder, SystemStatus, Tag, Task, Update, }; -use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; +use crate::models::servarr_data::radarr::modals::{ + AddMovieModal, EditCollectionModal, EditMovieModal, +}; +use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText}; use crate::network::{Network, NetworkEvent, RequestMethod, RequestProps}; use crate::utils::{convert_runtime, convert_to_gb}; @@ -151,55 +154,76 @@ impl<'a, 'b> Network<'a, 'b> { async fn add_movie(&mut self) { info!("Adding new movie to Radarr"); let body = { - let quality_profile_id = self.extract_quality_profile_id().await; - let tag_ids_vec = self.extract_and_add_tag_ids_vec().await; - let app = self.app.lock().await; - let root_folders = app.data.radarr_data.root_folders.items.to_vec(); - let (tmdb_id, title) = if let Route::Radarr(active_radarr_block, _) = app.get_current_route() + let tags = self + .app + .lock() + .await + .data + .radarr_data + .add_movie_modal + .as_ref() + .unwrap() + .tags + .text + .clone(); + let tag_ids_vec = self.extract_and_add_tag_ids_vec(tags).await; + let mut app = self.app.lock().await; + let AddMovieModal { + root_folder_list, + monitor_list, + minimum_availability_list, + quality_profile_list, + .. + } = app.data.radarr_data.add_movie_modal.as_ref().unwrap(); + let (tmdb_id, title) = if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { - if *active_radarr_block == ActiveRadarrBlock::CollectionDetails { - let CollectionMovie { tmdb_id, title, .. } = - app.data.radarr_data.collection_movies.current_selection(); + if active_radarr_block == ActiveRadarrBlock::CollectionDetails { + let CollectionMovie { tmdb_id, title, .. } = app + .data + .radarr_data + .collection_movies + .current_selection() + .clone(); (tmdb_id, title.text.clone()) } else { - let AddMovieSearchResult { tmdb_id, title, .. } = - app.data.radarr_data.add_searched_movies.current_selection(); + let AddMovieSearchResult { tmdb_id, title, .. } = app + .data + .radarr_data + .add_searched_movies + .current_selection() + .clone(); (tmdb_id, title.text.clone()) } } else { - let AddMovieSearchResult { tmdb_id, title, .. } = - app.data.radarr_data.add_searched_movies.current_selection(); + let AddMovieSearchResult { tmdb_id, title, .. } = app + .data + .radarr_data + .add_searched_movies + .current_selection() + .clone(); (tmdb_id, title.text.clone()) }; - - let RootFolder { path, .. } = root_folders + let quality_profile = quality_profile_list.current_selection(); + let quality_profile_id = *app + .data + .radarr_data + .quality_profile_map .iter() - .filter(|folder| folder.accessible) - .reduce(|a, b| { - if a.free_space.as_u64().unwrap() > b.free_space.as_u64().unwrap() { - a - } else { - b - } - }) + .filter(|(_, value)| *value == quality_profile) + .map(|(key, _)| key) + .next() .unwrap(); - let monitor = app - .data - .radarr_data - .monitor_list - .current_selection() - .to_string(); - let minimum_availability = app - .data - .radarr_data - .minimum_availability_list - .current_selection() - .to_string(); + + let path = root_folder_list.current_selection().path.clone(); + let monitor = monitor_list.current_selection().to_string(); + let minimum_availability = minimum_availability_list.current_selection().to_string(); + + app.data.radarr_data.add_movie_modal = None; AddMovieBody { tmdb_id: tmdb_id.as_u64().unwrap(), title, - root_folder_path: path.to_owned(), + root_folder_path: path, minimum_availability, monitored: true, quality_profile_id, @@ -462,21 +486,31 @@ impl<'a, 'b> Network<'a, 'b> { info!("Constructing edit collection body"); let body = { - let quality_profile_id = self.extract_quality_profile_id().await; let mut app = self.app.lock().await; let response = app.response.drain(..).collect::(); let mut detailed_collection_body: Value = serde_json::from_str(&response).unwrap(); - - let root_folder_path: String = app.data.radarr_data.edit_path.drain(); - - let monitored = app.data.radarr_data.edit_monitored.unwrap_or_default(); - let search_on_add = app.data.radarr_data.edit_search_on_add.unwrap_or_default(); - let minimum_availability = app + let EditCollectionModal { + path, + search_on_add, + minimum_availability_list, + monitored, + quality_profile_list, + } = app.data.radarr_data.edit_collection_modal.as_ref().unwrap(); + let quality_profile = quality_profile_list.current_selection(); + let quality_profile_id = *app .data .radarr_data - .minimum_availability_list - .current_selection() - .to_string(); + .quality_profile_map + .iter() + .filter(|(_, value)| *value == quality_profile) + .map(|(key, _)| key) + .next() + .unwrap(); + + let root_folder_path: String = path.text.clone(); + let monitored = monitored.unwrap_or_default(); + let search_on_add = search_on_add.unwrap_or_default(); + let minimum_availability = minimum_availability_list.current_selection().to_string(); *detailed_collection_body.get_mut("monitored").unwrap() = json!(monitored); *detailed_collection_body @@ -488,6 +522,8 @@ impl<'a, 'b> Network<'a, 'b> { *detailed_collection_body.get_mut("rootFolderPath").unwrap() = json!(root_folder_path); *detailed_collection_body.get_mut("searchOnAdd").unwrap() = json!(search_on_add); + app.data.radarr_data.edit_collection_modal = None; + detailed_collection_body }; @@ -533,28 +569,50 @@ impl<'a, 'b> Network<'a, 'b> { info!("Constructing edit movie body"); let body = { - let quality_profile_id = self.extract_quality_profile_id().await; - let tag_ids_vec = self.extract_and_add_tag_ids_vec().await; + let tags = self + .app + .lock() + .await + .data + .radarr_data + .edit_movie_modal + .as_ref() + .unwrap() + .tags + .text + .clone(); + let tag_ids_vec = self.extract_and_add_tag_ids_vec(tags).await; let mut app = self.app.lock().await; let response = app.response.drain(..).collect::(); let mut detailed_movie_body: Value = serde_json::from_str(&response).unwrap(); - let path: String = app.data.radarr_data.edit_path.drain(); - - let monitored = app.data.radarr_data.edit_monitored.unwrap_or_default(); - let minimum_availability = app + let EditMovieModal { + monitored, + path, + minimum_availability_list, + quality_profile_list, + .. + } = app.data.radarr_data.edit_movie_modal.as_ref().unwrap(); + let quality_profile = quality_profile_list.current_selection(); + let quality_profile_id = *app .data .radarr_data - .minimum_availability_list - .current_selection() - .to_string(); + .quality_profile_map + .iter() + .filter(|(_, value)| *value == quality_profile) + .map(|(key, _)| key) + .next() + .unwrap(); - *detailed_movie_body.get_mut("monitored").unwrap() = json!(monitored); - *detailed_movie_body.get_mut("minimumAvailability").unwrap() = json!(minimum_availability); + *detailed_movie_body.get_mut("monitored").unwrap() = json!(monitored.unwrap_or_default()); + *detailed_movie_body.get_mut("minimumAvailability").unwrap() = + json!(minimum_availability_list.current_selection().to_string()); *detailed_movie_body.get_mut("qualityProfileId").unwrap() = json!(quality_profile_id); - *detailed_movie_body.get_mut("path").unwrap() = json!(path); + *detailed_movie_body.get_mut("path").unwrap() = json!(path.text.clone()); *detailed_movie_body.get_mut("tags").unwrap() = json!(tag_ids_vec); + app.data.radarr_data.edit_movie_modal = None; + detailed_movie_body }; @@ -1408,27 +1466,8 @@ impl<'a, 'b> Network<'a, 'b> { } } - async fn extract_quality_profile_id(&mut self) -> u64 { - let app = self.app.lock().await; - let quality_profile = app - .data - .radarr_data - .quality_profile_list - .current_selection(); - *app - .data - .radarr_data - .quality_profile_map - .iter() - .filter(|(_, value)| *value == quality_profile) - .map(|(key, _)| key) - .next() - .unwrap() - } - - async fn extract_and_add_tag_ids_vec(&mut self) -> Vec { + async fn extract_and_add_tag_ids_vec(&mut self, edit_tags: String) -> Vec { let tags_map = self.app.lock().await.data.radarr_data.tags_map.clone(); - let edit_tags = self.app.lock().await.data.radarr_data.edit_tags.drain(); let tags = edit_tags.clone(); let missing_tags_vec = edit_tags .split(',') diff --git a/src/network/radarr_network_tests.rs b/src/network/radarr_network_tests.rs index 33b298e..3251cb9 100644 --- a/src/network/radarr_network_tests.rs +++ b/src/network/radarr_network_tests.rs @@ -16,7 +16,7 @@ mod test { CollectionMovie, IndexerField, IndexerSelectOption, Language, MediaInfo, MinimumAvailability, Monitor, MovieFile, Quality, QualityWrapper, Rating, RatingsList, }; - use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; + use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::HorizontallyScrollableText; use crate::App; @@ -1481,7 +1481,7 @@ mod test { Some(json!({ "tmdbId": 1234, "title": "Test", - "rootFolderPath": "/nfs", + "rootFolderPath": "/nfs2", "minimumAvailability": "announced", "monitored": true, "qualityProfileId": 2222, @@ -1498,7 +1498,11 @@ mod test { { let mut app = app_arc.lock().await; - app.data.radarr_data.root_folders.set_items(vec![ + let mut add_movie_modal = AddMovieModal { + tags: "usenet, testing".into(), + ..AddMovieModal::default() + }; + add_movie_modal.root_folder_list.set_items(vec![ RootFolder { id: Number::from(1), path: "/nfs".to_owned(), @@ -1514,26 +1518,21 @@ mod test { unmapped_folders: None, }, ]); + add_movie_modal.root_folder_list.state.select(Some(1)); + add_movie_modal + .quality_profile_list + .set_items(vec!["HD - 1080p".to_owned()]); + add_movie_modal + .monitor_list + .set_items(Vec::from_iter(Monitor::iter())); + add_movie_modal + .minimum_availability_list + .set_items(Vec::from_iter(MinimumAvailability::iter())); + app.data.radarr_data.add_movie_modal = Some(add_movie_modal); app.data.radarr_data.quality_profile_map = BiMap::from_iter([(2222, "HD - 1080p".to_owned())]); app.data.radarr_data.tags_map = BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]); - app.data.radarr_data.edit_tags = "usenet, testing".to_owned().into(); - app - .data - .radarr_data - .quality_profile_list - .set_items(vec!["HD - 1080p".to_owned()]); - app - .data - .radarr_data - .monitor_list - .set_items(Vec::from_iter(Monitor::iter())); - app - .data - .radarr_data - .minimum_availability_list - .set_items(Vec::from_iter(MinimumAvailability::iter())); if movie_details_context { app .data @@ -1554,6 +1553,13 @@ mod test { network.handle_radarr_event(RadarrEvent::AddMovie).await; async_server.assert_async().await; + assert!(app_arc + .lock() + .await + .data + .radarr_data + .add_movie_modal + .is_none()); } #[tokio::test] @@ -1617,19 +1623,19 @@ mod test { let mut app = app_arc.lock().await; app.data.radarr_data.tags_map = BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]); - app.data.radarr_data.edit_tags = "usenet, testing".to_owned().into(); - app.data.radarr_data.edit_path = "/nfs/Test Path".to_owned().into(); - app.data.radarr_data.edit_monitored = Some(false); - app - .data - .radarr_data + let mut edit_movie = EditMovieModal { + tags: "usenet, testing".to_owned().into(), + path: "/nfs/Test Path".to_owned().into(), + monitored: Some(false), + ..EditMovieModal::default() + }; + edit_movie .quality_profile_list .set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]); - app - .data - .radarr_data + edit_movie .minimum_availability_list .set_items(Vec::from_iter(MinimumAvailability::iter())); + app.data.radarr_data.edit_movie_modal = Some(edit_movie); app.data.radarr_data.movies.set_items(vec![Movie { monitored: false, ..movie() @@ -1646,8 +1652,7 @@ mod test { let app = app_arc.lock().await; assert!(app.response.is_empty()); - assert!(app.data.radarr_data.edit_path.text.is_empty()); - assert!(app.data.radarr_data.edit_tags.text.is_empty()); + assert!(app.data.radarr_data.edit_movie_modal.is_none()); assert!(app.data.radarr_data.movie_details.items.is_empty()); } @@ -1711,19 +1716,19 @@ mod test { .await; { let mut app = app_arc.lock().await; - app.data.radarr_data.edit_path = "/nfs/Test Path".to_owned().into(); - app.data.radarr_data.edit_monitored = Some(false); - app.data.radarr_data.edit_search_on_add = Some(false); - app - .data - .radarr_data + let mut edit_collection_modal = EditCollectionModal { + path: "/nfs/Test Path".into(), + monitored: Some(false), + search_on_add: Some(false), + ..EditCollectionModal::default() + }; + edit_collection_modal .quality_profile_list .set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]); - app - .data - .radarr_data + edit_collection_modal .minimum_availability_list .set_items(Vec::from_iter(MinimumAvailability::iter())); + app.data.radarr_data.edit_collection_modal = Some(edit_collection_modal); app.data.radarr_data.collections.set_items(vec![Collection { monitored: false, search_on_add: false, @@ -1743,7 +1748,7 @@ mod test { let app = app_arc.lock().await; assert!(app.response.is_empty()); - assert!(app.data.radarr_data.edit_path.text.is_empty()); + assert!(app.data.radarr_data.edit_collection_modal.is_none()); assert!(app.data.radarr_data.movie_details.items.is_empty()); } @@ -1775,30 +1780,12 @@ mod test { async_server.assert_async().await; } - #[tokio::test] - async fn test_extract_quality_profile_id() { - let app_arc = Arc::new(Mutex::new(App::default())); - { - let mut app = app_arc.lock().await; - app - .data - .radarr_data - .quality_profile_list - .set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]); - app.data.radarr_data.quality_profile_map = - BiMap::from_iter([(1, "Any".to_owned()), (2, "HD - 1080p".to_owned())]); - } - let mut network = Network::new(&app_arc, CancellationToken::new()); - - assert_eq!(network.extract_quality_profile_id().await, 1); - } - #[tokio::test] async fn test_extract_and_add_tag_ids_vec() { let app_arc = Arc::new(Mutex::new(App::default())); + let tags = " test,hi ,, usenet ".to_owned(); { let mut app = app_arc.lock().await; - app.data.radarr_data.edit_tags = " test,hi ,, usenet ".to_owned().into(); app.data.radarr_data.tags_map = BiMap::from_iter([ (1, "usenet".to_owned()), (2, "test".to_owned()), @@ -1807,7 +1794,10 @@ mod test { } let mut network = Network::new(&app_arc, CancellationToken::new()); - assert_eq!(network.extract_and_add_tag_ids_vec().await, vec![2, 3, 1]); + assert_eq!( + network.extract_and_add_tag_ids_vec(tags).await, + vec![2, 3, 1] + ); } #[tokio::test] @@ -1819,15 +1809,19 @@ mod test { RadarrEvent::GetTags.resource(), ) .await; + let tags = "usenet, test, testing".to_owned(); { let mut app = app_arc.lock().await; - app.data.radarr_data.edit_tags = "usenet, test, testing".to_owned().into(); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { + tags: tags.clone().into(), + ..EditMovieModal::default() + }); app.data.radarr_data.tags_map = BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]); } let mut network = Network::new(&app_arc, CancellationToken::new()); - let tag_ids_vec = network.extract_and_add_tag_ids_vec().await; + let tag_ids_vec = network.extract_and_add_tag_ids_vec(tags).await; async_server.assert_async().await; assert_eq!(tag_ids_vec, vec![1, 2, 3]); diff --git a/src/ui/mod.rs b/src/ui/mod.rs index e387eaa..c6f0c6d 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -497,7 +497,11 @@ pub fn draw_checkbox_with_label( is_selected: bool, ) { let horizontal_chunks = horizontal_chunks( - vec![Constraint::Percentage(50), Constraint::Percentage(50)], + vec![ + Constraint::Percentage(48), + Constraint::Percentage(48), + Constraint::Percentage(4), + ], area, ); @@ -528,7 +532,11 @@ pub fn draw_button_with_icon( let icon_paragraph = layout_button_paragraph_borderless(is_selected, icon, Alignment::Right); let horizontal_chunks = horizontal_chunks_with_margin( - vec![Constraint::Percentage(50), Constraint::Percentage(50)], + vec![ + Constraint::Percentage(50), + Constraint::Percentage(49), + Constraint::Percentage(1), + ], area, 1, ); @@ -549,7 +557,11 @@ pub fn draw_drop_down_menu_button( is_selected: bool, ) { let horizontal_chunks = horizontal_chunks( - vec![Constraint::Percentage(50), Constraint::Percentage(50)], + vec![ + Constraint::Percentage(48), + Constraint::Percentage(48), + Constraint::Percentage(4), + ], area, ); @@ -679,7 +691,11 @@ pub fn draw_text_box_with_label( should_show_cursor: bool, ) { let horizontal_chunks = horizontal_chunks( - vec![Constraint::Percentage(50), Constraint::Percentage(50)], + vec![ + Constraint::Percentage(48), + Constraint::Percentage(48), + Constraint::Percentage(4), + ], area, ); diff --git a/src/ui/radarr_ui/collections/collection_details_ui.rs b/src/ui/radarr_ui/collections/collection_details_ui.rs index 97f2d90..e09ca9b 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui.rs @@ -8,7 +8,9 @@ use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CL use crate::app::radarr::radarr_context_clues::COLLECTION_DETAILS_CONTEXT_CLUES; use crate::app::App; use crate::models::radarr_models::CollectionMovie; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, +}; use crate::models::Route; use crate::ui::radarr_ui::collections::draw_collections; use crate::ui::utils::{ diff --git a/src/ui/radarr_ui/collections/collection_details_ui_tests.rs b/src/ui/radarr_ui/collections/collection_details_ui_tests.rs index 48a0dca..440fdf8 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui_tests.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui_tests.rs @@ -2,7 +2,9 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, + }; use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/collections/collections_ui_tests.rs b/src/ui/radarr_ui/collections/collections_ui_tests.rs index 94a7996..1f66677 100644 --- a/src/ui/radarr_ui/collections/collections_ui_tests.rs +++ b/src/ui/radarr_ui/collections/collections_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTIONS_BLOCKS, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_BLOCKS, }; use crate::ui::radarr_ui::collections::CollectionsUi; diff --git a/src/ui/radarr_ui/collections/edit_collection_ui.rs b/src/ui/radarr_ui/collections/edit_collection_ui.rs index ab7fe7c..3d7aca6 100644 --- a/src/ui/radarr_ui/collections/edit_collection_ui.rs +++ b/src/ui/radarr_ui/collections/edit_collection_ui.rs @@ -1,24 +1,23 @@ use tui::backend::Backend; use tui::layout::{Constraint, Rect}; +use tui::widgets::ListItem; use tui::Frame; use crate::app::App; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::modals::EditCollectionModal; +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_BLOCKS, }; use crate::models::Route; use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi; use crate::ui::radarr_ui::collections::draw_collections; -use crate::ui::radarr_ui::{ - draw_select_minimum_availability_popup, draw_select_quality_profile_popup, -}; use crate::ui::utils::{ horizontal_chunks, layout_paragraph_borderless, title_block_centered, vertical_chunks_with_margin, }; use crate::ui::{ draw_button, draw_checkbox_with_label, draw_drop_down_menu_button, draw_drop_down_popup, draw_large_popup_over_background_fn_with_ui, draw_medium_popup_over, draw_popup, - draw_text_box_with_label, DrawUi, + draw_selectable_list, draw_text_box_with_label, DrawUi, }; #[cfg(test)] @@ -46,7 +45,7 @@ impl DrawUi for EditCollectionUi { app, prompt_area, draw_edit_collection_confirmation_prompt, - draw_select_minimum_availability_popup, + draw_edit_collection_select_minimum_availability_popup, ); } ActiveRadarrBlock::EditCollectionSelectQualityProfile => { @@ -55,7 +54,7 @@ impl DrawUi for EditCollectionUi { app, prompt_area, draw_edit_collection_confirmation_prompt, - draw_select_quality_profile_popup, + draw_edit_collection_select_quality_profile_popup, ); } ActiveRadarrBlock::EditCollectionPrompt @@ -141,17 +140,16 @@ fn draw_edit_collection_confirmation_prompt( let yes_no_value = app.data.radarr_data.prompt_confirm; let selected_block = app.data.radarr_data.selected_block.get_active_block(); let highlight_yes_no = selected_block == &ActiveRadarrBlock::EditCollectionConfirmPrompt; + let EditCollectionModal { + minimum_availability_list, + quality_profile_list, + monitored, + search_on_add, + path, + } = app.data.radarr_data.edit_collection_modal.as_ref().unwrap(); - let selected_minimum_availability = app - .data - .radarr_data - .minimum_availability_list - .current_selection(); - let selected_quality_profile = app - .data - .radarr_data - .quality_profile_list - .current_selection(); + let selected_minimum_availability = minimum_availability_list.current_selection(); + let selected_quality_profile = quality_profile_list.current_selection(); f.render_widget(title_block_centered(&title), prompt_area); @@ -182,7 +180,7 @@ fn draw_edit_collection_confirmation_prompt( f, chunks[1], "Monitored", - app.data.radarr_data.edit_monitored.unwrap_or_default(), + monitored.unwrap_or_default(), selected_block == &ActiveRadarrBlock::EditCollectionToggleMonitored, ); @@ -206,8 +204,8 @@ fn draw_edit_collection_confirmation_prompt( f, chunks[4], "Root Folder", - &app.data.radarr_data.edit_path.text, - *app.data.radarr_data.edit_path.offset.borrow(), + &path.text, + *path.offset.borrow(), selected_block == &ActiveRadarrBlock::EditCollectionRootFolderPathInput, active_radarr_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput, ); @@ -217,7 +215,7 @@ fn draw_edit_collection_confirmation_prompt( f, chunks[5], "Search on Add", - app.data.radarr_data.edit_search_on_add.unwrap_or_default(), + search_on_add.unwrap_or_default(), selected_block == &ActiveRadarrBlock::EditCollectionToggleSearchOnAdd, ); @@ -234,3 +232,41 @@ fn draw_edit_collection_confirmation_prompt( !yes_no_value && highlight_yes_no, ); } + +fn draw_edit_collection_select_minimum_availability_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .minimum_availability_list, + |minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()), + ); +} + +fn draw_edit_collection_select_quality_profile_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .edit_collection_modal + .as_mut() + .unwrap() + .quality_profile_list, + |quality_profile| ListItem::new(quality_profile.clone()), + ); +} diff --git a/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs b/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs index 32c9ec7..be9fbc4 100644 --- a/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs +++ b/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs @@ -2,7 +2,9 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS, + }; use crate::ui::radarr_ui::collections::edit_collection_ui::EditCollectionUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/collections/mod.rs b/src/ui/radarr_ui/collections/mod.rs index ee7e39e..b8dc22d 100644 --- a/src/ui/radarr_ui/collections/mod.rs +++ b/src/ui/radarr_ui/collections/mod.rs @@ -7,7 +7,7 @@ pub(super) use collection_details_ui::draw_collection_details; use crate::app::App; use crate::models::radarr_models::Collection; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, COLLECTIONS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, COLLECTIONS_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi; use crate::ui::radarr_ui::collections::edit_collection_ui::EditCollectionUi; diff --git a/src/ui/radarr_ui/downloads/downloads_ui_tests.rs b/src/ui/radarr_ui/downloads/downloads_ui_tests.rs index 596a596..c6b6bc0 100644 --- a/src/ui/radarr_ui/downloads/downloads_ui_tests.rs +++ b/src/ui/radarr_ui/downloads/downloads_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; use crate::ui::radarr_ui::downloads::DownloadsUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/downloads/mod.rs b/src/ui/radarr_ui/downloads/mod.rs index ddcf209..b2ca8b6 100644 --- a/src/ui/radarr_ui/downloads/mod.rs +++ b/src/ui/radarr_ui/downloads/mod.rs @@ -5,7 +5,7 @@ use tui::Frame; use crate::app::App; use crate::models::radarr_models::DownloadRecord; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; use crate::models::{HorizontallyScrollableText, Route}; use crate::ui::utils::{get_width_from_percentage, layout_block_top_border, style_primary}; use crate::ui::{draw_prompt_box, draw_prompt_popup_over, draw_table, DrawUi, TableProps}; diff --git a/src/ui/radarr_ui/indexers/indexer_settings_ui.rs b/src/ui/radarr_ui/indexers/indexer_settings_ui.rs index 774ea38..b9a37c3 100644 --- a/src/ui/radarr_ui/indexers/indexer_settings_ui.rs +++ b/src/ui/radarr_ui/indexers/indexer_settings_ui.rs @@ -1,11 +1,21 @@ +use std::iter; use tui::backend::Backend; -use tui::layout::Rect; +use tui::layout::{Constraint, Rect}; use tui::Frame; use crate::app::App; -use crate::models::servarr_data::radarr_data::INDEXER_SETTINGS_BLOCKS; +use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS, +}; use crate::models::Route; -use crate::ui::DrawUi; +use crate::ui::radarr_ui::indexers::draw_indexers; +use crate::ui::utils::{ + horizontal_chunks, horizontal_chunks_with_margin, title_block_centered, vertical_chunks, + vertical_chunks_with_margin, +}; +use crate::ui::{ + draw_button, draw_checkbox_with_label, draw_popup_over, draw_text_box_with_label, loading, DrawUi, +}; #[cfg(test)] #[path = "indexer_settings_ui_tests.rs"] @@ -22,5 +32,159 @@ impl DrawUi for IndexerSettingsUi { false } - fn draw(_f: &mut Frame<'_, B>, _app: &mut App<'_>, _content_rect: Rect) {} + fn draw(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) { + draw_popup_over( + f, + app, + content_rect, + draw_indexers, + draw_edit_indexer_settings_prompt, + 60, + 40, + ); + } +} + +fn draw_edit_indexer_settings_prompt( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + prompt_area: Rect, +) { + let block = title_block_centered("Configure All Indexer Settings"); + let yes_no_value = app.data.radarr_data.prompt_confirm; + let selected_block = app.data.radarr_data.selected_block.get_active_block(); + let highlight_yes_no = selected_block == &ActiveRadarrBlock::IndexerSettingsConfirmPrompt; + let indexer_settings_option = &app.data.radarr_data.indexer_settings; + + if indexer_settings_option.is_some() { + let indexer_settings = indexer_settings_option.as_ref().unwrap(); + f.render_widget(block, prompt_area); + + let chunks = vertical_chunks_with_margin( + vec![Constraint::Min(0), Constraint::Length(3)], + prompt_area, + 1, + ); + + let split_chunks = horizontal_chunks_with_margin( + vec![Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)], + chunks[0], + 1, + ); + + let left_chunks = vertical_chunks( + vec![ + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Min(0), + ], + split_chunks[0], + ); + let right_chunks = vertical_chunks( + vec![ + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Min(0), + ], + split_chunks[1], + ); + + if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { + draw_text_box_with_label( + f, + left_chunks[0], + "Minimum Age", + &indexer_settings.minimum_age.to_string(), + 0, + selected_block == &ActiveRadarrBlock::IndexerSettingsMinimumAgeInput, + active_radarr_block == ActiveRadarrBlock::IndexerSettingsMinimumAgeInput, + ); + draw_text_box_with_label( + f, + left_chunks[1], + "Retention", + &indexer_settings.retention.to_string(), + 0, + selected_block == &ActiveRadarrBlock::IndexerSettingsRetentionInput, + active_radarr_block == ActiveRadarrBlock::IndexerSettingsRetentionInput, + ); + draw_text_box_with_label( + f, + left_chunks[2], + "Maximum Size", + &indexer_settings.maximum_size.to_string(), + 0, + selected_block == &ActiveRadarrBlock::IndexerSettingsMaximumSizeInput, + active_radarr_block == ActiveRadarrBlock::IndexerSettingsMaximumSizeInput, + ); + draw_text_box_with_label( + f, + right_chunks[0], + "Availability Delay", + &indexer_settings.availability_delay.to_string(), + 0, + selected_block == &ActiveRadarrBlock::IndexerSettingsAvailabilityDelayInput, + active_radarr_block == ActiveRadarrBlock::IndexerSettingsAvailabilityDelayInput, + ); + draw_text_box_with_label( + f, + right_chunks[1], + "RSS Sync Interval", + &indexer_settings.rss_sync_interval.to_string(), + 0, + selected_block == &ActiveRadarrBlock::IndexerSettingsRssSyncIntervalInput, + active_radarr_block == ActiveRadarrBlock::IndexerSettingsRssSyncIntervalInput, + ); + draw_text_box_with_label( + f, + right_chunks[2], + "Whitelisted Subtitle Tags", + &indexer_settings.whitelisted_hardcoded_subs.to_string(), + 0, + selected_block == &ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, + active_radarr_block == ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, + ); + } + + draw_checkbox_with_label( + f, + left_chunks[3], + "Prefer Indexer Flags", + indexer_settings.prefer_indexer_flags, + selected_block == &ActiveRadarrBlock::IndexerSettingsTogglePreferIndexerFlags, + ); + + draw_checkbox_with_label( + f, + right_chunks[3], + "Allow Hardcoded Subs", + indexer_settings.allow_hardcoded_subs, + selected_block == &ActiveRadarrBlock::IndexerSettingsToggleAllowHardcodedSubs, + ); + + let button_chunks = horizontal_chunks( + iter::repeat(Constraint::Ratio(1, 4)).take(4).collect(), + // vec![Constraint::Percentage(50), Constraint::Percentage(50)], + chunks[1], + ); + + draw_button( + f, + button_chunks[1], + "Save", + yes_no_value && highlight_yes_no, + ); + draw_button( + f, + button_chunks[2], + "Cancel", + !yes_no_value && highlight_yes_no, + ); + } else { + loading(f, block, prompt_area, app.is_loading); + } } diff --git a/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs b/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs index 8877b37..bef1814 100644 --- a/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs +++ b/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs @@ -2,7 +2,9 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS, + }; use crate::ui::radarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/indexers/indexers_ui_tests.rs b/src/ui/radarr_ui/indexers/indexers_ui_tests.rs index 89edd2b..7b6a135 100644 --- a/src/ui/radarr_ui/indexers/indexers_ui_tests.rs +++ b/src/ui/radarr_ui/indexers/indexers_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, INDEXERS_BLOCKS, INDEXER_SETTINGS_BLOCKS, }; use crate::ui::radarr_ui::indexers::IndexersUi; diff --git a/src/ui/radarr_ui/indexers/mod.rs b/src/ui/radarr_ui/indexers/mod.rs index ef314f5..3be49e8 100644 --- a/src/ui/radarr_ui/indexers/mod.rs +++ b/src/ui/radarr_ui/indexers/mod.rs @@ -6,7 +6,7 @@ use tui::Frame; use crate::app::App; use crate::models::radarr_models::Indexer; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, INDEXERS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, INDEXERS_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi; use crate::ui::utils::{layout_block_top_border, style_failure, style_primary, style_success}; diff --git a/src/ui/radarr_ui/library/add_movie_ui.rs b/src/ui/radarr_ui/library/add_movie_ui.rs index 4980984..e4b083d 100644 --- a/src/ui/radarr_ui/library/add_movie_ui.rs +++ b/src/ui/radarr_ui/library/add_movie_ui.rs @@ -7,14 +7,11 @@ use tui::Frame; use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CLUES}; use crate::app::radarr::radarr_context_clues::ADD_MOVIE_SEARCH_RESULTS_CONTEXT_CLUES; use crate::models::radarr_models::AddMovieSearchResult; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; +use crate::models::servarr_data::radarr::modals::AddMovieModal; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::collections::{draw_collection_details, draw_collections}; use crate::ui::radarr_ui::library::draw_library; -use crate::ui::radarr_ui::{ - draw_select_minimum_availability_popup, draw_select_quality_profile_popup, - draw_select_root_folder_popup, -}; use crate::ui::utils::{ borderless_block, get_width_from_percentage, horizontal_chunks, layout_block, layout_paragraph_borderless, style_help, style_primary, title_block_centered, @@ -284,7 +281,7 @@ fn draw_confirmation_popup(f: &mut Frame<'_, B>, app: &mut App<'_>, app, prompt_area, draw_confirmation_prompt, - draw_select_monitor_popup, + draw_add_movie_select_monitor_popup, ); } ActiveRadarrBlock::AddMovieSelectMinimumAvailability => { @@ -293,7 +290,7 @@ fn draw_confirmation_popup(f: &mut Frame<'_, B>, app: &mut App<'_>, app, prompt_area, draw_confirmation_prompt, - draw_select_minimum_availability_popup, + draw_add_movie_select_minimum_availability_popup, ); } ActiveRadarrBlock::AddMovieSelectQualityProfile => { @@ -302,7 +299,7 @@ fn draw_confirmation_popup(f: &mut Frame<'_, B>, app: &mut App<'_>, app, prompt_area, draw_confirmation_prompt, - draw_select_quality_profile_popup, + draw_add_movie_select_quality_profile_popup, ); } ActiveRadarrBlock::AddMovieSelectRootFolder => { @@ -311,7 +308,7 @@ fn draw_confirmation_popup(f: &mut Frame<'_, B>, app: &mut App<'_>, app, prompt_area, draw_confirmation_prompt, - draw_select_root_folder_popup, + draw_add_movie_select_root_folder_popup, ); } ActiveRadarrBlock::AddMoviePrompt | ActiveRadarrBlock::AddMovieTagsInput => { @@ -322,19 +319,6 @@ fn draw_confirmation_popup(f: &mut Frame<'_, B>, app: &mut App<'_>, } } -fn draw_select_monitor_popup( - f: &mut Frame<'_, B>, - app: &mut App<'_>, - popup_area: Rect, -) { - draw_selectable_list( - f, - popup_area, - &mut app.data.radarr_data.monitor_list, - |monitor| ListItem::new(monitor.to_display_str().to_owned()), - ); -} - fn draw_confirmation_prompt( f: &mut Frame<'_, B>, app: &mut App<'_>, @@ -380,19 +364,19 @@ fn draw_confirmation_prompt( let yes_no_value = app.data.radarr_data.prompt_confirm; let selected_block = app.data.radarr_data.selected_block.get_active_block(); let highlight_yes_no = selected_block == &ActiveRadarrBlock::AddMovieConfirmPrompt; + let AddMovieModal { + monitor_list, + minimum_availability_list, + quality_profile_list, + root_folder_list, + tags, + .. + } = app.data.radarr_data.add_movie_modal.as_ref().unwrap(); - let selected_monitor = app.data.radarr_data.monitor_list.current_selection(); - let selected_minimum_availability = app - .data - .radarr_data - .minimum_availability_list - .current_selection(); - let selected_quality_profile = app - .data - .radarr_data - .quality_profile_list - .current_selection(); - let selected_root_folder = app.data.radarr_data.root_folder_list.current_selection(); + let selected_monitor = monitor_list.current_selection(); + let selected_minimum_availability = minimum_availability_list.current_selection(); + let selected_quality_profile = quality_profile_list.current_selection(); + let selected_root_folder = root_folder_list.current_selection(); f.render_widget(title_block_centered(&title), prompt_area); @@ -455,8 +439,8 @@ fn draw_confirmation_prompt( f, chunks[5], "Tags", - &app.data.radarr_data.edit_tags.text, - *app.data.radarr_data.edit_tags.offset.borrow(), + &tags.text, + *tags.offset.borrow(), selected_block == &ActiveRadarrBlock::AddMovieTagsInput, active_radarr_block == ActiveRadarrBlock::AddMovieTagsInput, ); @@ -475,3 +459,79 @@ fn draw_confirmation_prompt( !yes_no_value && highlight_yes_no, ); } + +fn draw_add_movie_select_monitor_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .monitor_list, + |monitor| ListItem::new(monitor.to_display_str().to_owned()), + ); +} + +fn draw_add_movie_select_minimum_availability_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .minimum_availability_list, + |minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()), + ); +} + +fn draw_add_movie_select_quality_profile_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .quality_profile_list, + |quality_profile| ListItem::new(quality_profile.clone()), + ); +} + +fn draw_add_movie_select_root_folder_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .add_movie_modal + .as_mut() + .unwrap() + .root_folder_list, + |root_folder| ListItem::new(root_folder.path.to_owned()), + ); +} diff --git a/src/ui/radarr_ui/library/add_movie_ui_tests.rs b/src/ui/radarr_ui/library/add_movie_ui_tests.rs index 4b9c360..ff24d30 100644 --- a/src/ui/radarr_ui/library/add_movie_ui_tests.rs +++ b/src/ui/radarr_ui/library/add_movie_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; use crate::ui::radarr_ui::library::add_movie_ui::AddMovieUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/library/delete_movie_ui.rs b/src/ui/radarr_ui/library/delete_movie_ui.rs index a30a1ff..34cfbc9 100644 --- a/src/ui/radarr_ui/library/delete_movie_ui.rs +++ b/src/ui/radarr_ui/library/delete_movie_ui.rs @@ -3,7 +3,7 @@ use tui::layout::Rect; use tui::Frame; use crate::app::App; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; +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}; diff --git a/src/ui/radarr_ui/library/delete_movie_ui_tests.rs b/src/ui/radarr_ui/library/delete_movie_ui_tests.rs index 6837d3f..625ce88 100644 --- a/src/ui/radarr_ui/library/delete_movie_ui_tests.rs +++ b/src/ui/radarr_ui/library/delete_movie_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; use crate::ui::radarr_ui::library::delete_movie_ui::DeleteMovieUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/library/edit_movie_ui.rs b/src/ui/radarr_ui/library/edit_movie_ui.rs index f8cfbf0..1d020bd 100644 --- a/src/ui/radarr_ui/library/edit_movie_ui.rs +++ b/src/ui/radarr_ui/library/edit_movie_ui.rs @@ -1,24 +1,24 @@ use tui::backend::Backend; use tui::layout::{Constraint, Rect}; +use tui::widgets::ListItem; use tui::Frame; use crate::app::App; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::modals::EditMovieModal; +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, EDIT_MOVIE_BLOCKS, MOVIE_DETAILS_BLOCKS, }; use crate::models::Route; use crate::ui::radarr_ui::library::draw_library; use crate::ui::radarr_ui::library::movie_details_ui::MovieDetailsUi; -use crate::ui::radarr_ui::{ - draw_select_minimum_availability_popup, draw_select_quality_profile_popup, -}; + use crate::ui::utils::{ horizontal_chunks, layout_paragraph_borderless, title_block_centered, vertical_chunks_with_margin, }; use crate::ui::{ draw_button, draw_checkbox_with_label, draw_drop_down_menu_button, draw_drop_down_popup, draw_large_popup_over_background_fn_with_ui, draw_medium_popup_over, draw_popup, - draw_text_box_with_label, DrawUi, + draw_selectable_list, draw_text_box_with_label, DrawUi, }; #[cfg(test)] @@ -46,7 +46,7 @@ impl DrawUi for EditMovieUi { app, prompt_area, draw_edit_movie_confirmation_prompt, - draw_select_minimum_availability_popup, + draw_edit_movie_select_minimum_availability_popup, ); } ActiveRadarrBlock::EditMovieSelectQualityProfile => { @@ -55,7 +55,7 @@ impl DrawUi for EditMovieUi { app, prompt_area, draw_edit_movie_confirmation_prompt, - draw_select_quality_profile_popup, + draw_edit_movie_select_quality_profile_popup, ); } ActiveRadarrBlock::EditMoviePrompt @@ -134,17 +134,16 @@ fn draw_edit_movie_confirmation_prompt( let yes_no_value = app.data.radarr_data.prompt_confirm; let selected_block = app.data.radarr_data.selected_block.get_active_block(); let highlight_yes_no = selected_block == &ActiveRadarrBlock::EditMovieConfirmPrompt; + let EditMovieModal { + minimum_availability_list, + quality_profile_list, + monitored, + path, + tags, + } = app.data.radarr_data.edit_movie_modal.as_ref().unwrap(); - let selected_minimum_availability = app - .data - .radarr_data - .minimum_availability_list - .current_selection(); - let selected_quality_profile = app - .data - .radarr_data - .quality_profile_list - .current_selection(); + let selected_minimum_availability = minimum_availability_list.current_selection(); + let selected_quality_profile = quality_profile_list.current_selection(); f.render_widget(title_block_centered(&title), prompt_area); @@ -175,7 +174,7 @@ fn draw_edit_movie_confirmation_prompt( f, chunks[1], "Monitored", - app.data.radarr_data.edit_monitored.unwrap_or_default(), + monitored.unwrap_or_default(), selected_block == &ActiveRadarrBlock::EditMovieToggleMonitored, ); @@ -199,8 +198,8 @@ fn draw_edit_movie_confirmation_prompt( f, chunks[4], "Path", - &app.data.radarr_data.edit_path.text, - *app.data.radarr_data.edit_path.offset.borrow(), + &path.text, + *path.offset.borrow(), selected_block == &ActiveRadarrBlock::EditMoviePathInput, active_radarr_block == ActiveRadarrBlock::EditMoviePathInput, ); @@ -208,8 +207,8 @@ fn draw_edit_movie_confirmation_prompt( f, chunks[5], "Tags", - &app.data.radarr_data.edit_tags.text, - *app.data.radarr_data.edit_tags.offset.borrow(), + &tags.text, + *tags.offset.borrow(), selected_block == &ActiveRadarrBlock::EditMovieTagsInput, active_radarr_block == ActiveRadarrBlock::EditMovieTagsInput, ); @@ -228,3 +227,41 @@ fn draw_edit_movie_confirmation_prompt( !yes_no_value && highlight_yes_no, ); } + +fn draw_edit_movie_select_minimum_availability_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .minimum_availability_list, + |minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()), + ); +} + +fn draw_edit_movie_select_quality_profile_popup( + f: &mut Frame<'_, B>, + app: &mut App<'_>, + popup_area: Rect, +) { + draw_selectable_list( + f, + popup_area, + &mut app + .data + .radarr_data + .edit_movie_modal + .as_mut() + .unwrap() + .quality_profile_list, + |quality_profile| ListItem::new(quality_profile.clone()), + ); +} diff --git a/src/ui/radarr_ui/library/edit_movie_ui_tests.rs b/src/ui/radarr_ui/library/edit_movie_ui_tests.rs index 47cdc9c..ccaf1ac 100644 --- a/src/ui/radarr_ui/library/edit_movie_ui_tests.rs +++ b/src/ui/radarr_ui/library/edit_movie_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; use crate::ui::radarr_ui::library::edit_movie_ui::EditMovieUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/library/library_ui_tests.rs b/src/ui/radarr_ui/library/library_ui_tests.rs index c37708a..357def9 100644 --- a/src/ui/radarr_ui/library/library_ui_tests.rs +++ b/src/ui/radarr_ui/library/library_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, ADD_MOVIE_BLOCKS, DELETE_MOVIE_BLOCKS, EDIT_MOVIE_BLOCKS, LIBRARY_BLOCKS, MOVIE_DETAILS_BLOCKS, }; diff --git a/src/ui/radarr_ui/library/mod.rs b/src/ui/radarr_ui/library/mod.rs index 07b0e2a..bf58b8f 100644 --- a/src/ui/radarr_ui/library/mod.rs +++ b/src/ui/radarr_ui/library/mod.rs @@ -5,7 +5,7 @@ use tui::Frame; use crate::app::App; use crate::models::radarr_models::Movie; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, LIBRARY_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, LIBRARY_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::library::add_movie_ui::AddMovieUi; use crate::ui::radarr_ui::library::delete_movie_ui::DeleteMovieUi; diff --git a/src/ui/radarr_ui/library/movie_details_ui.rs b/src/ui/radarr_ui/library/movie_details_ui.rs index f420287..72d3aaf 100644 --- a/src/ui/radarr_ui/library/movie_details_ui.rs +++ b/src/ui/radarr_ui/library/movie_details_ui.rs @@ -9,7 +9,7 @@ use tui::Frame; use crate::app::App; use crate::models::radarr_models::{Credit, MovieHistoryItem, Release, ReleaseField}; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::library::draw_library; use crate::ui::utils::{ diff --git a/src/ui/radarr_ui/library/movie_details_ui_tests.rs b/src/ui/radarr_ui/library/movie_details_ui_tests.rs index d7d1cb1..15f1077 100644 --- a/src/ui/radarr_ui/library/movie_details_ui_tests.rs +++ b/src/ui/radarr_ui/library/movie_details_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; use crate::ui::radarr_ui::library::movie_details_ui::MovieDetailsUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/mod.rs b/src/ui/radarr_ui/mod.rs index a3010d5..f3974d2 100644 --- a/src/ui/radarr_ui/mod.rs +++ b/src/ui/radarr_ui/mod.rs @@ -5,18 +5,16 @@ use tui::backend::Backend; use tui::layout::{Alignment, Constraint, Rect}; use tui::style::{Color, Style}; use tui::text::Text; -use tui::widgets::ListItem; use tui::widgets::Paragraph; use tui::Frame; use crate::app::App; use crate::logos::RADARR_LOGO; use crate::models::radarr_models::{DiskSpace, DownloadRecord, Movie, RootFolder}; -use crate::models::servarr_data::radarr_data::{ +use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, RadarrData, FILTER_BLOCKS, SEARCH_BLOCKS, }; use crate::models::Route; -use crate::ui::draw_selectable_list; use crate::ui::draw_tabs; use crate::ui::loading; use crate::ui::radarr_ui::collections::CollectionsUi; @@ -232,45 +230,6 @@ fn determine_row_style(downloads_vec: &[DownloadRecord], movie: &Movie) -> Style } } -fn draw_select_minimum_availability_popup( - f: &mut Frame<'_, B>, - app: &mut App<'_>, - popup_area: Rect, -) { - draw_selectable_list( - f, - popup_area, - &mut app.data.radarr_data.minimum_availability_list, - |minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()), - ); -} - -fn draw_select_quality_profile_popup( - f: &mut Frame<'_, B>, - app: &mut App<'_>, - popup_area: Rect, -) { - draw_selectable_list( - f, - popup_area, - &mut app.data.radarr_data.quality_profile_list, - |quality_profile| ListItem::new(quality_profile.clone()), - ); -} - -fn draw_select_root_folder_popup( - f: &mut Frame<'_, B>, - app: &mut App<'_>, - popup_area: Rect, -) { - draw_selectable_list( - f, - popup_area, - &mut app.data.radarr_data.root_folder_list, - |root_folder| ListItem::new(root_folder.path.to_owned()), - ); -} - fn draw_search_box(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) { let chunks = vertical_chunks_with_margin(vec![Constraint::Length(3), Constraint::Min(0)], area, 1); diff --git a/src/ui/radarr_ui/radarr_ui_tests.rs b/src/ui/radarr_ui/radarr_ui_tests.rs index d89b78c..a388794 100644 --- a/src/ui/radarr_ui/radarr_ui_tests.rs +++ b/src/ui/radarr_ui/radarr_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; + use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::ui::radarr_ui::RadarrUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/root_folders/mod.rs b/src/ui/radarr_ui/root_folders/mod.rs index 1871761..afe2d52 100644 --- a/src/ui/radarr_ui/root_folders/mod.rs +++ b/src/ui/radarr_ui/root_folders/mod.rs @@ -5,7 +5,7 @@ use tui::Frame; use crate::app::App; use crate::models::radarr_models::RootFolder; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; use crate::models::Route; use crate::ui::utils::{ borderless_block, layout_block_top_border, show_cursor, style_default, style_help, style_primary, diff --git a/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs b/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs index e5a3b8d..5a312c4 100644 --- a/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs +++ b/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs @@ -2,7 +2,7 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; use crate::ui::radarr_ui::root_folders::RootFoldersUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/system/mod.rs b/src/ui/radarr_ui/system/mod.rs index 7cbb3ce..84e4bb9 100644 --- a/src/ui/radarr_ui/system/mod.rs +++ b/src/ui/radarr_ui/system/mod.rs @@ -13,7 +13,7 @@ use tui::{ use crate::app::App; use crate::models::radarr_models::Task; -use crate::models::servarr_data::radarr_data::ActiveRadarrBlock; +use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::ui::radarr_ui::radarr_ui_utils::{ convert_to_minutes_hours_days, determine_log_style_by_level, }; diff --git a/src/ui/radarr_ui/system/system_details_ui.rs b/src/ui/radarr_ui/system/system_details_ui.rs index 28cc537..a076a01 100644 --- a/src/ui/radarr_ui/system/system_details_ui.rs +++ b/src/ui/radarr_ui/system/system_details_ui.rs @@ -7,7 +7,7 @@ use tui::Frame; use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CLUES}; use crate::app::radarr::radarr_context_clues::SYSTEM_TASKS_CONTEXT_CLUES; use crate::app::App; -use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; +use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::radarr_ui_utils::determine_log_style_by_level; use crate::ui::radarr_ui::system::{ diff --git a/src/ui/radarr_ui/system/system_details_ui_tests.rs b/src/ui/radarr_ui/system/system_details_ui_tests.rs index 6792558..0690fb7 100644 --- a/src/ui/radarr_ui/system/system_details_ui_tests.rs +++ b/src/ui/radarr_ui/system/system_details_ui_tests.rs @@ -2,7 +2,9 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS, + }; use crate::ui::radarr_ui::system::system_details_ui::SystemDetailsUi; use crate::ui::DrawUi; diff --git a/src/ui/radarr_ui/system/system_ui_tests.rs b/src/ui/radarr_ui/system/system_ui_tests.rs index f7886f3..797e1b0 100644 --- a/src/ui/radarr_ui/system/system_ui_tests.rs +++ b/src/ui/radarr_ui/system/system_ui_tests.rs @@ -2,7 +2,9 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS, + }; use crate::ui::radarr_ui::system::SystemUi; use crate::ui::DrawUi;