diff --git a/Cargo.toml b/Cargo.toml index bbc4ce0..25969d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "managarr" -version = "0.0.15" +version = "0.0.16" authors = ["Alex Clarke "] description = "A TUI for managing *arr servers" keywords = ["managarr", "tui-rs", "dashboard", "servarr"] diff --git a/src/app/radarr.rs b/src/app/radarr.rs index bbb28de..45c8b1a 100644 --- a/src/app/radarr.rs +++ b/src/app/radarr.rs @@ -51,6 +51,8 @@ pub struct RadarrData { pub edit_search_on_add: Option, pub sort_ascending: Option, pub prompt_confirm: bool, + pub delete_movie_files: bool, + pub add_list_exclusion: bool, pub is_searching: bool, pub is_filtering: bool, } @@ -60,6 +62,11 @@ impl RadarrData { self.collection_movies = StatefulTable::default(); } + pub fn reset_delete_movie_preferences(&mut self) { + self.delete_movie_files = false; + self.add_list_exclusion = false; + } + pub fn reset_search(&mut self) { self.is_searching = false; self.search = HorizontallyScrollableText::default(); @@ -260,6 +267,8 @@ impl Default for RadarrData { is_searching: false, is_filtering: false, prompt_confirm: false, + delete_movie_files: false, + add_list_exclusion: false, main_tabs: TabState::new(vec![ TabRoute { title: "Library".to_owned(), @@ -350,6 +359,9 @@ pub enum ActiveRadarrBlock { Cast, Crew, DeleteMoviePrompt, + DeleteMovieConfirmPrompt, + DeleteMovieToggleDeleteFile, + DeleteMovieToggleAddListExclusion, DeleteDownloadPrompt, DeleteRootFolderPrompt, Downloads, @@ -440,6 +452,12 @@ pub const FILTER_BLOCKS: [ActiveRadarrBlock; 2] = [ ActiveRadarrBlock::FilterMovies, ActiveRadarrBlock::FilterCollections, ]; +pub const DELETE_MOVIE_BLOCKS: [ActiveRadarrBlock; 4] = [ + ActiveRadarrBlock::DeleteMoviePrompt, + ActiveRadarrBlock::DeleteMovieConfirmPrompt, + ActiveRadarrBlock::DeleteMovieToggleDeleteFile, + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion, +]; impl ActiveRadarrBlock { pub fn next_add_movie_prompt_block(&self) -> Self { @@ -493,6 +511,19 @@ impl ActiveRadarrBlock { } } + pub fn next_delete_movie_prompt_block(&self) -> Self { + match self { + ActiveRadarrBlock::DeleteMovieToggleDeleteFile => { + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion + } + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion => { + ActiveRadarrBlock::DeleteMovieConfirmPrompt + } + ActiveRadarrBlock::DeleteMovieConfirmPrompt => ActiveRadarrBlock::DeleteMovieToggleDeleteFile, + _ => ActiveRadarrBlock::DeleteMovieToggleDeleteFile, + } + } + pub fn previous_add_movie_prompt_block(&self) -> Self { match self { ActiveRadarrBlock::AddMovieSelectRootFolder => ActiveRadarrBlock::AddMovieConfirmPrompt, @@ -548,6 +579,19 @@ impl ActiveRadarrBlock { _ => ActiveRadarrBlock::EditCollectionToggleMonitored, } } + + pub fn previous_delete_movie_prompt_block(&self) -> Self { + match self { + ActiveRadarrBlock::DeleteMovieToggleDeleteFile => ActiveRadarrBlock::DeleteMovieConfirmPrompt, + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion => { + ActiveRadarrBlock::DeleteMovieToggleDeleteFile + } + ActiveRadarrBlock::DeleteMovieConfirmPrompt => { + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion + } + _ => ActiveRadarrBlock::DeleteMovieToggleDeleteFile, + } + } } impl From for Route { @@ -683,6 +727,9 @@ impl App { self .dispatch_network_event(RadarrEvent::GetTags.into()) .await; + self + .dispatch_network_event(RadarrEvent::GetRootFolders.into()) + .await; self .dispatch_network_event(RadarrEvent::GetDownloads.into()) .await; @@ -730,6 +777,8 @@ pub mod radarr_test_utils { let mut radarr_data = RadarrData { is_searching: true, is_filtering: true, + delete_movie_files: true, + add_list_exclusion: true, search: "test search".to_owned().into(), filter: "test filter".to_owned().into(), edit_path: "test path".to_owned().into(), @@ -781,13 +830,6 @@ pub mod radarr_test_utils { radarr_data } - #[macro_export] - macro_rules! assert_movie_collection_table_reset { - ($radarr_data:expr) => { - assert!($radarr_data.collection_movies.items.is_empty()); - }; - } - #[macro_export] macro_rules! assert_search_reset { ($radarr_data:expr) => { @@ -887,7 +929,17 @@ mod tests { radarr_data.reset_movie_collection_table(); - assert_movie_collection_table_reset!(radarr_data); + assert!(radarr_data.collection_movies.items.is_empty()); + } + + #[test] + fn test_reset_delete_movie_preferences() { + let mut radarr_data = create_test_radarr_data(); + + radarr_data.reset_delete_movie_preferences(); + + assert!(!radarr_data.delete_movie_files); + assert!(!radarr_data.add_list_exclusion); } #[test] @@ -1128,6 +1180,8 @@ mod tests { assert!(!radarr_data.is_searching); assert!(!radarr_data.is_filtering); assert!(!radarr_data.prompt_confirm); + assert!(!radarr_data.delete_movie_files); + assert!(!radarr_data.add_list_exclusion); assert_eq!(radarr_data.main_tabs.tabs.len(), 4); @@ -1368,6 +1422,25 @@ mod tests { ); } + #[test] + fn test_next_delete_movie_prompt_block() { + let active_block = + ActiveRadarrBlock::DeleteMovieToggleDeleteFile.next_delete_movie_prompt_block(); + + assert_eq!( + active_block, + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion + ); + + let active_block = active_block.next_delete_movie_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieConfirmPrompt); + + let active_block = active_block.next_delete_movie_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieToggleDeleteFile); + } + #[test] fn test_previous_add_movie_prompt_block() { let active_block = @@ -1478,6 +1551,25 @@ mod tests { ActiveRadarrBlock::EditCollectionToggleMonitored ); } + + #[test] + fn test_previous_delete_movie_prompt_block() { + let active_block = + ActiveRadarrBlock::DeleteMovieToggleDeleteFile.previous_delete_movie_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieConfirmPrompt); + + let active_block = active_block.previous_delete_movie_prompt_block(); + + assert_eq!( + active_block, + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion + ); + + let active_block = active_block.previous_delete_movie_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieToggleDeleteFile); + } } mod radarr_tests { @@ -1857,6 +1949,14 @@ mod tests { sync_network_rx.recv().await.unwrap(), RadarrEvent::GetTags.into() ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetRootFolders.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetDownloads.into() + ); assert!(app.is_loading); } @@ -1926,6 +2026,10 @@ mod tests { sync_network_rx.recv().await.unwrap(), RadarrEvent::GetTags.into() ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetRootFolders.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), RadarrEvent::GetDownloads.into() @@ -1974,6 +2078,10 @@ mod tests { sync_network_rx.recv().await.unwrap(), RadarrEvent::GetTags.into() ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetRootFolders.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), RadarrEvent::GetDownloads.into() diff --git a/src/handlers/radarr_handlers/add_movie_handler.rs b/src/handlers/radarr_handlers/add_movie_handler.rs index 7b9be02..4d9aa42 100644 --- a/src/handlers/radarr_handlers/add_movie_handler.rs +++ b/src/handlers/radarr_handlers/add_movie_handler.rs @@ -57,7 +57,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for AddMovieHandler<'a> { .data .radarr_data .selected_block - .clone() .previous_add_movie_prompt_block() } _ => (), @@ -228,10 +227,9 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for AddMovieHandler<'a> { ActiveRadarrBlock::AddMovieConfirmPrompt => { if self.app.data.radarr_data.prompt_confirm { self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::AddMovie); - self.app.pop_navigation_stack(); - } else { - self.app.pop_navigation_stack(); } + + self.app.pop_navigation_stack(); } ActiveRadarrBlock::AddMovieSelectMonitor | ActiveRadarrBlock::AddMovieSelectMinimumAvailability @@ -515,7 +513,6 @@ mod tests { use pretty_assertions::{assert_eq, assert_str_eq}; use rstest::rstest; - use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::models::radarr_models::Movie; use crate::network::radarr_network::RadarrEvent; diff --git a/src/handlers/radarr_handlers/delete_movie_handler.rs b/src/handlers/radarr_handlers/delete_movie_handler.rs new file mode 100644 index 0000000..1adecd3 --- /dev/null +++ b/src/handlers/radarr_handlers/delete_movie_handler.rs @@ -0,0 +1,283 @@ +use crate::app::radarr::ActiveRadarrBlock; +use crate::app::App; +use crate::event::Key; +use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; +use crate::network::radarr_network::RadarrEvent; + +pub(super) struct DeleteMovieHandler<'a> { + key: &'a Key, + app: &'a mut App, + active_radarr_block: &'a ActiveRadarrBlock, + _context: &'a Option, +} + +impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for DeleteMovieHandler<'a> { + fn with( + key: &'a Key, + app: &'a mut App, + active_block: &'a ActiveRadarrBlock, + _context: &'a Option, + ) -> Self { + DeleteMovieHandler { + key, + app, + active_radarr_block: active_block, + _context, + } + } + + fn get_key(&self) -> &Key { + self.key + } + + fn handle_scroll_up(&mut self) { + if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt { + self.app.data.radarr_data.selected_block = self + .app + .data + .radarr_data + .selected_block + .previous_delete_movie_prompt_block(); + } + } + + fn handle_scroll_down(&mut self) { + if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt { + self.app.data.radarr_data.selected_block = self + .app + .data + .radarr_data + .selected_block + .next_delete_movie_prompt_block(); + } + } + + fn handle_home(&mut self) {} + + fn handle_end(&mut self) {} + + fn handle_delete(&mut self) {} + + fn handle_left_right_action(&mut self) { + if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt { + handle_prompt_toggle(self.app, self.key); + } + } + + fn handle_submit(&mut self) { + if self.active_radarr_block == &ActiveRadarrBlock::DeleteMoviePrompt { + match self.app.data.radarr_data.selected_block { + ActiveRadarrBlock::DeleteMovieConfirmPrompt => { + if self.app.data.radarr_data.prompt_confirm { + self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteMovie); + self.app.should_refresh = true; + } else { + self.app.data.radarr_data.reset_delete_movie_preferences(); + } + + self.app.pop_navigation_stack(); + } + ActiveRadarrBlock::DeleteMovieToggleDeleteFile => { + self.app.data.radarr_data.delete_movie_files = + !self.app.data.radarr_data.delete_movie_files; + } + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion => { + self.app.data.radarr_data.add_list_exclusion = + !self.app.data.radarr_data.add_list_exclusion; + } + _ => (), + } + } + } + + fn handle_esc(&mut self) { + if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt { + self.app.pop_navigation_stack(); + self.app.data.radarr_data.reset_delete_movie_preferences(); + self.app.data.radarr_data.prompt_confirm = false; + } + } + + fn handle_char_key_event(&mut self) {} +} + +#[cfg(test)] +mod tests { + use crate::app::key_binding::DEFAULT_KEYBINDINGS; + use crate::app::radarr::ActiveRadarrBlock; + use crate::app::App; + use crate::event::Key; + use crate::handlers::radarr_handlers::delete_movie_handler::DeleteMovieHandler; + use crate::handlers::KeyEventHandler; + + mod test_handle_scroll_up_and_down { + use pretty_assertions::assert_eq; + use rstest::rstest; + + use super::*; + + #[rstest] + fn test_delete_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { + let mut app = App::default(); + app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieToggleAddListExclusion; + + DeleteMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::DeleteMoviePrompt, &None) + .handle(); + + if key == Key::Up { + assert_eq!( + app.data.radarr_data.selected_block, + ActiveRadarrBlock::DeleteMovieToggleDeleteFile + ); + } else { + assert_eq!( + app.data.radarr_data.selected_block, + ActiveRadarrBlock::DeleteMovieConfirmPrompt + ); + } + } + } + + mod test_handle_left_right_action { + use rstest::rstest; + + use super::*; + + #[rstest] + fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { + let mut app = App::default(); + + DeleteMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::DeleteMoviePrompt, &None) + .handle(); + + assert!(app.data.radarr_data.prompt_confirm); + + DeleteMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::DeleteMoviePrompt, &None) + .handle(); + + assert!(!app.data.radarr_data.prompt_confirm); + } + } + + mod test_handle_submit { + use pretty_assertions::assert_eq; + + use crate::network::radarr_network::RadarrEvent; + + use super::*; + + const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key; + + #[test] + fn test_delete_movie_prompt_prompt_decline_submit() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); + app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieConfirmPrompt; + app.data.radarr_data.delete_movie_files = true; + app.data.radarr_data.add_list_exclusion = true; + + DeleteMovieHandler::with( + &SUBMIT_KEY, + &mut app, + &ActiveRadarrBlock::DeleteMoviePrompt, + &None, + ) + .handle(); + + assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); + assert_eq!(app.data.radarr_data.prompt_confirm_action, None); + assert!(!app.data.radarr_data.prompt_confirm); + assert!(!app.data.radarr_data.delete_movie_files); + assert!(!app.data.radarr_data.add_list_exclusion); + } + + #[test] + fn test_delete_movie_confirm_prompt_prompt_confirmation_submit() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); + app.data.radarr_data.prompt_confirm = true; + app.data.radarr_data.delete_movie_files = true; + app.data.radarr_data.add_list_exclusion = true; + app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieConfirmPrompt; + + DeleteMovieHandler::with( + &SUBMIT_KEY, + &mut app, + &ActiveRadarrBlock::DeleteMoviePrompt, + &None, + ) + .handle(); + + assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); + assert_eq!( + app.data.radarr_data.prompt_confirm_action, + Some(RadarrEvent::DeleteMovie) + ); + assert!(app.should_refresh); + assert!(app.data.radarr_data.prompt_confirm); + assert!(app.data.radarr_data.delete_movie_files); + assert!(app.data.radarr_data.add_list_exclusion); + } + + #[test] + fn test_delete_movie_toggle_delete_files_submit() { + let current_route = ActiveRadarrBlock::DeleteMoviePrompt.into(); + let mut app = App::default(); + app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieToggleDeleteFile; + app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); + + DeleteMovieHandler::with( + &SUBMIT_KEY, + &mut app, + &ActiveRadarrBlock::DeleteMoviePrompt, + &None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ¤t_route); + assert_eq!(app.data.radarr_data.delete_movie_files, true); + + DeleteMovieHandler::with( + &SUBMIT_KEY, + &mut app, + &ActiveRadarrBlock::DeleteMoviePrompt, + &None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ¤t_route); + assert_eq!(app.data.radarr_data.delete_movie_files, false); + } + } + + mod test_handle_esc { + use super::*; + + const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; + + #[test] + fn test_delete_movie_prompt_esc() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); + app.data.radarr_data.prompt_confirm = true; + app.data.radarr_data.delete_movie_files = true; + app.data.radarr_data.add_list_exclusion = true; + + DeleteMovieHandler::with( + &ESC_KEY, + &mut app, + &ActiveRadarrBlock::DeleteMoviePrompt, + &None, + ) + .handle(); + + assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); + assert!(!app.data.radarr_data.prompt_confirm); + assert!(!app.data.radarr_data.delete_movie_files); + assert!(!app.data.radarr_data.add_list_exclusion); + } + } +} diff --git a/src/handlers/radarr_handlers/edit_collection_handler.rs b/src/handlers/radarr_handlers/edit_collection_handler.rs index f7893e1..fd9ce21 100644 --- a/src/handlers/radarr_handlers/edit_collection_handler.rs +++ b/src/handlers/radarr_handlers/edit_collection_handler.rs @@ -50,7 +50,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditCollectionHandler<'a> { .data .radarr_data .selected_block - .clone() .previous_edit_collection_prompt_block() } _ => (), @@ -140,11 +139,10 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditCollectionHandler<'a> { ActiveRadarrBlock::EditCollectionConfirmPrompt => { if self.app.data.radarr_data.prompt_confirm { self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditCollection); - self.app.pop_navigation_stack(); self.app.should_refresh = true; - } else { - self.app.pop_navigation_stack(); } + + self.app.pop_navigation_stack(); } ActiveRadarrBlock::EditCollectionSelectMinimumAvailability | ActiveRadarrBlock::EditCollectionSelectQualityProfile => self @@ -193,9 +191,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditCollectionHandler<'a> { self.app.data.radarr_data.reset_add_edit_media_fields(); self.app.data.radarr_data.prompt_confirm = false; } - ActiveRadarrBlock::EditCollectionToggleMonitored - | ActiveRadarrBlock::EditCollectionToggleSearchOnAdd - | ActiveRadarrBlock::EditCollectionSelectMinimumAvailability + ActiveRadarrBlock::EditCollectionSelectMinimumAvailability | ActiveRadarrBlock::EditCollectionSelectQualityProfile => self.app.pop_navigation_stack(), _ => (), } @@ -355,7 +351,6 @@ mod tests { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::models::Route; use crate::network::radarr_network::RadarrEvent; @@ -635,8 +630,6 @@ mod tests { #[rstest] fn test_edit_collection_esc( #[values( - ActiveRadarrBlock::EditCollectionToggleMonitored, - ActiveRadarrBlock::EditCollectionToggleSearchOnAdd, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ActiveRadarrBlock::EditCollectionSelectQualityProfile )] diff --git a/src/handlers/radarr_handlers/edit_movie_handler.rs b/src/handlers/radarr_handlers/edit_movie_handler.rs index cd80a46..0ac5a2c 100644 --- a/src/handlers/radarr_handlers/edit_movie_handler.rs +++ b/src/handlers/radarr_handlers/edit_movie_handler.rs @@ -50,7 +50,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditMovieHandler<'a> { .data .radarr_data .selected_block - .clone() .previous_edit_movie_prompt_block() } _ => (), @@ -141,11 +140,10 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditMovieHandler<'a> { ActiveRadarrBlock::EditMovieConfirmPrompt => { if self.app.data.radarr_data.prompt_confirm { self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditMovie); - self.app.pop_navigation_stack(); self.app.should_refresh = true; - } else { - self.app.pop_navigation_stack(); } + + self.app.pop_navigation_stack(); } ActiveRadarrBlock::EditMovieSelectMinimumAvailability | ActiveRadarrBlock::EditMovieSelectQualityProfile => self @@ -184,8 +182,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditMovieHandler<'a> { self.app.data.radarr_data.reset_add_edit_media_fields(); self.app.data.radarr_data.prompt_confirm = false; } - ActiveRadarrBlock::EditMovieToggleMonitored - | ActiveRadarrBlock::EditMovieSelectMinimumAvailability + ActiveRadarrBlock::EditMovieSelectMinimumAvailability | ActiveRadarrBlock::EditMovieSelectQualityProfile => self.app.pop_navigation_stack(), _ => (), } @@ -350,7 +347,6 @@ mod tests { use pretty_assertions::assert_eq; use rstest::rstest; - use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::models::Route; use crate::network::radarr_network::RadarrEvent; @@ -617,7 +613,6 @@ mod tests { #[rstest] fn test_edit_movie_esc( #[values( - ActiveRadarrBlock::EditMovieToggleMonitored, ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectQualityProfile )] diff --git a/src/handlers/radarr_handlers/mod.rs b/src/handlers/radarr_handlers/mod.rs index c170ab9..6966dc2 100644 --- a/src/handlers/radarr_handlers/mod.rs +++ b/src/handlers/radarr_handlers/mod.rs @@ -1,10 +1,11 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::radarr::{ - ActiveRadarrBlock, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_BLOCKS, - EDIT_MOVIE_BLOCKS, FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS, + ActiveRadarrBlock, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, DELETE_MOVIE_BLOCKS, + EDIT_COLLECTION_BLOCKS, EDIT_MOVIE_BLOCKS, FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS, }; use crate::handlers::radarr_handlers::add_movie_handler::AddMovieHandler; use crate::handlers::radarr_handlers::collection_details_handler::CollectionDetailsHandler; +use crate::handlers::radarr_handlers::delete_movie_handler::DeleteMovieHandler; use crate::handlers::radarr_handlers::edit_collection_handler::EditCollectionHandler; use crate::handlers::radarr_handlers::edit_movie_handler::EditMovieHandler; use crate::handlers::radarr_handlers::movie_details_handler::MovieDetailsHandler; @@ -16,6 +17,7 @@ use crate::{handle_text_box_keys, handle_text_box_left_right_keys, App, Key}; mod add_movie_handler; mod collection_details_handler; +mod delete_movie_handler; mod edit_collection_handler; mod edit_movie_handler; mod movie_details_handler; @@ -44,6 +46,10 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> { _ if EDIT_MOVIE_BLOCKS.contains(self.active_radarr_block) => { EditMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle() } + _ if DELETE_MOVIE_BLOCKS.contains(self.active_radarr_block) => { + DeleteMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context) + .handle() + } _ if EDIT_COLLECTION_BLOCKS.contains(self.active_radarr_block) => { EditCollectionHandler::with(self.key, self.app, self.active_radarr_block, self.context) .handle() @@ -212,9 +218,12 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> { fn handle_delete(&mut self) { match self.active_radarr_block { - ActiveRadarrBlock::Movies => self - .app - .push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()), + ActiveRadarrBlock::Movies => { + self + .app + .push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); + self.app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieToggleDeleteFile; + } ActiveRadarrBlock::Downloads => self .app .push_navigation_stack(ActiveRadarrBlock::DeleteDownloadPrompt.into()), @@ -245,8 +254,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> { } _ => (), }, - ActiveRadarrBlock::DeleteMoviePrompt - | ActiveRadarrBlock::DeleteDownloadPrompt + ActiveRadarrBlock::DeleteDownloadPrompt | ActiveRadarrBlock::DeleteRootFolderPrompt | ActiveRadarrBlock::UpdateAllMoviesPrompt | ActiveRadarrBlock::UpdateAllCollectionsPrompt @@ -359,13 +367,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> { .set_items(filtered_collections); } } - ActiveRadarrBlock::DeleteMoviePrompt => { - if self.app.data.radarr_data.prompt_confirm { - self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteMovie); - } - - self.app.pop_navigation_stack(); - } ActiveRadarrBlock::DeleteDownloadPrompt => { if self.app.data.radarr_data.prompt_confirm { self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteDownload); @@ -429,8 +430,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> { self.app.data.radarr_data.prompt_confirm = false; self.app.should_ignore_quit_key = false; } - ActiveRadarrBlock::DeleteMoviePrompt - | ActiveRadarrBlock::DeleteDownloadPrompt + ActiveRadarrBlock::DeleteDownloadPrompt | ActiveRadarrBlock::DeleteRootFolderPrompt | ActiveRadarrBlock::UpdateAllMoviesPrompt | ActiveRadarrBlock::UpdateAllCollectionsPrompt @@ -950,6 +950,10 @@ mod tests { app.get_current_route(), &ActiveRadarrBlock::DeleteMoviePrompt.into() ); + assert_eq!( + app.data.radarr_data.selected_block, + ActiveRadarrBlock::DeleteMovieToggleDeleteFile + ); } #[test] @@ -1050,7 +1054,6 @@ mod tests { #[rstest] fn test_left_right_prompt_toggle( #[values( - ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteDownloadPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt, @@ -1344,11 +1347,6 @@ mod tests { } #[rstest] - #[case( - ActiveRadarrBlock::Movies, - ActiveRadarrBlock::DeleteMoviePrompt, - RadarrEvent::DeleteMovie - )] #[case( ActiveRadarrBlock::Downloads, ActiveRadarrBlock::DeleteDownloadPrompt, @@ -1395,7 +1393,6 @@ mod tests { } #[rstest] - #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::DeleteMoviePrompt)] #[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::DeleteDownloadPrompt)] #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)] #[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::UpdateDownloadsPrompt)] @@ -1471,7 +1468,6 @@ mod tests { } #[rstest] - #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::DeleteMoviePrompt)] #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)] #[case( ActiveRadarrBlock::RootFolders, @@ -1551,7 +1547,6 @@ mod tests { use serde_json::Number; use strum::IntoEnumIterator; - use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::radarr::radarr_test_utils::create_test_radarr_data; use crate::app::radarr::RadarrData; use crate::models::radarr_models::MinimumAvailability; @@ -1996,23 +1991,28 @@ mod tests { ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectQualityProfile, - ActiveRadarrBlock::EditMovieTagsInput, - ActiveRadarrBlock::EditMovieToggleMonitored + ActiveRadarrBlock::EditMovieTagsInput )] active_radarr_block: ActiveRadarrBlock, ) { test_handler_delegation!(ActiveRadarrBlock::Movies, active_radarr_block); } + #[test] + fn test_delegate_delete_movie_blocks_to_delete_movie_handler() { + test_handler_delegation!( + ActiveRadarrBlock::Movies, + ActiveRadarrBlock::DeleteMoviePrompt + ); + } + #[rstest] fn test_delegate_edit_collection_blocks_to_edit_collection_handler( #[values( ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, - ActiveRadarrBlock::EditCollectionSelectQualityProfile, - ActiveRadarrBlock::EditCollectionToggleSearchOnAdd, - ActiveRadarrBlock::EditCollectionToggleMonitored + ActiveRadarrBlock::EditCollectionSelectQualityProfile )] active_radarr_block: ActiveRadarrBlock, ) { diff --git a/src/network/radarr_network.rs b/src/network/radarr_network.rs index 0f42c35..2187009 100644 --- a/src/network/radarr_network.rs +++ b/src/network/radarr_network.rs @@ -686,12 +686,24 @@ impl<'a> Network<'a> { async fn delete_movie(&self) { let movie_id = self.extract_movie_id().await; + let delete_files = self.app.lock().await.data.radarr_data.delete_movie_files; + let add_import_exclusion = self.app.lock().await.data.radarr_data.add_list_exclusion; - info!("Deleting Radarr movie with id: {}", movie_id); + info!( + "Deleting Radarr movie with id: {} with deleteFiles={} and addImportExclusion={}", + movie_id, delete_files, add_import_exclusion + ); let request_props = self .radarr_request_props_from( - format!("{}/{}", RadarrEvent::DeleteMovie.resource(), movie_id).as_str(), + format!( + "{}/{}?deleteFiles={}&addImportExclusion={}", + RadarrEvent::DeleteMovie.resource(), + movie_id, + delete_files, + add_import_exclusion + ) + .as_str(), RequestMethod::Delete, None::<()>, ) @@ -700,6 +712,14 @@ impl<'a> Network<'a> { self .handle_request::<(), ()>(request_props, |_, _| ()) .await; + + self + .app + .lock() + .await + .data + .radarr_data + .reset_delete_movie_preferences(); } async fn delete_download(&self) { @@ -2200,21 +2220,26 @@ mod test { RequestMethod::Delete, None, None, - format!("{}/1", RadarrEvent::DeleteMovie.resource()).as_str(), + format!( + "{}/1?deleteFiles=true&addImportExclusion=true", + RadarrEvent::DeleteMovie.resource() + ) + .as_str(), ) .await; - app_arc - .lock() - .await - .data - .radarr_data - .movies - .set_items(vec![movie()]); + { + let mut app = app_arc.lock().await; + app.data.radarr_data.movies.set_items(vec![movie()]); + app.data.radarr_data.delete_movie_files = true; + app.data.radarr_data.add_list_exclusion = true; + } let network = Network::new(reqwest::Client::new(), &app_arc); network.handle_radarr_event(RadarrEvent::DeleteMovie).await; async_server.assert_async().await; + assert!(!app_arc.lock().await.data.radarr_data.delete_movie_files); + assert!(!app_arc.lock().await.data.radarr_data.add_list_exclusion); } #[tokio::test] diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 98ca4ba..9b3437e 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,3 +1,5 @@ +use std::iter; + use tui::backend::Backend; use tui::layout::{Alignment, Constraint, Rect}; use tui::style::Modifier; @@ -141,7 +143,7 @@ pub fn draw_prompt_popup_over( background_fn: fn(&mut Frame<'_, B>, &mut App, Rect), popup_fn: fn(&mut Frame<'_, B>, &mut App, Rect), ) { - draw_popup_over(f, app, area, background_fn, popup_fn, 30, 30); + draw_popup_over(f, app, area, background_fn, popup_fn, 35, 35); } pub fn draw_small_popup_over( @@ -334,7 +336,7 @@ pub fn draw_prompt_box( prompt_area: Rect, title: &str, prompt: &str, - yes_no_value: &bool, + yes_no_value: bool, ) { draw_prompt_box_with_content(f, prompt_area, title, prompt, None, yes_no_value); } @@ -345,7 +347,7 @@ pub fn draw_prompt_box_with_content( title: &str, prompt: &str, content: Option>, - yes_no_value: &bool, + yes_no_value: bool, ) { f.render_widget(title_block_centered(title), prompt_area); @@ -384,8 +386,58 @@ pub fn draw_prompt_box_with_content( chunks[2], ); - draw_button(f, horizontal_chunks[0], "Yes", *yes_no_value); - draw_button(f, horizontal_chunks[1], "No", !*yes_no_value); + draw_button(f, horizontal_chunks[0], "Yes", yes_no_value); + draw_button(f, horizontal_chunks[1], "No", !yes_no_value); +} + +pub fn draw_prompt_box_with_checkboxes( + f: &mut Frame<'_, B>, + prompt_area: Rect, + title: &str, + prompt: &str, + checkboxes: Vec<(&str, bool, bool)>, + highlight_yes_no: bool, + yes_no_value: bool, +) { + f.render_widget(title_block_centered(title), prompt_area); + let mut constraints = vec![ + Constraint::Length(4), + Constraint::Min(0), + Constraint::Length(3), + ]; + + constraints.splice( + 1..1, + iter::repeat(Constraint::Length(3)).take(checkboxes.len()), + ); + + let chunks = vertical_chunks_with_margin(constraints, prompt_area, 1); + + let prompt_paragraph = layout_paragraph_borderless(prompt); + f.render_widget(prompt_paragraph, chunks[0]); + + for i in 0..checkboxes.len() { + let (label, is_checked, is_selected) = checkboxes[i]; + draw_checkbox_with_label(f, chunks[i + 1], label, is_checked, is_selected); + } + + let horizontal_chunks = horizontal_chunks( + vec![Constraint::Percentage(50), Constraint::Percentage(50)], + chunks[checkboxes.len() + 2], + ); + + draw_button( + f, + horizontal_chunks[0], + "Yes", + highlight_yes_no && yes_no_value, + ); + draw_button( + f, + horizontal_chunks[1], + "No", + highlight_yes_no && !yes_no_value, + ); } pub fn draw_checkbox( diff --git a/src/ui/radarr_ui/add_movie_ui.rs b/src/ui/radarr_ui/add_movie_ui.rs index 6a169da..6e1e314 100644 --- a/src/ui/radarr_ui/add_movie_ui.rs +++ b/src/ui/radarr_ui/add_movie_ui.rs @@ -327,9 +327,9 @@ fn draw_confirmation_prompt(f: &mut Frame<'_, B>, app: &mut App, pro }; let title = format!("Add Movie - {}", movie_title); let prompt = movie_overview; - let yes_no_value = &app.data.radarr_data.prompt_confirm; - let selected_block = &app.data.radarr_data.selected_block; - let highlight_yes_no = *selected_block == ActiveRadarrBlock::AddMovieConfirmPrompt; + let yes_no_value = app.data.radarr_data.prompt_confirm; + let selected_block = app.data.radarr_data.selected_block; + let highlight_yes_no = selected_block == ActiveRadarrBlock::AddMovieConfirmPrompt; let selected_monitor = app.data.radarr_data.monitor_list.current_selection(); let selected_minimum_availability = app @@ -374,7 +374,7 @@ fn draw_confirmation_prompt(f: &mut Frame<'_, B>, app: &mut App, pro chunks[1], "Root Folder", &selected_root_folder.path, - *selected_block == ActiveRadarrBlock::AddMovieSelectRootFolder, + selected_block == ActiveRadarrBlock::AddMovieSelectRootFolder, ); draw_drop_down_menu_button( @@ -382,7 +382,7 @@ fn draw_confirmation_prompt(f: &mut Frame<'_, B>, app: &mut App, pro chunks[2], "Monitor", selected_monitor.to_display_str(), - *selected_block == ActiveRadarrBlock::AddMovieSelectMonitor, + selected_block == ActiveRadarrBlock::AddMovieSelectMonitor, ); draw_drop_down_menu_button( @@ -390,14 +390,14 @@ fn draw_confirmation_prompt(f: &mut Frame<'_, B>, app: &mut App, pro chunks[3], "Minimum Availability", selected_minimum_availability.to_display_str(), - *selected_block == ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + selected_block == ActiveRadarrBlock::AddMovieSelectMinimumAvailability, ); draw_drop_down_menu_button( f, chunks[4], "Quality Profile", selected_quality_profile, - *selected_block == ActiveRadarrBlock::AddMovieSelectQualityProfile, + selected_block == ActiveRadarrBlock::AddMovieSelectQualityProfile, ); if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { @@ -407,7 +407,7 @@ fn draw_confirmation_prompt(f: &mut Frame<'_, B>, app: &mut App, pro "Tags", &app.data.radarr_data.edit_tags.text, *app.data.radarr_data.edit_tags.offset.borrow(), - *selected_block == ActiveRadarrBlock::AddMovieTagsInput, + selected_block == ActiveRadarrBlock::AddMovieTagsInput, active_radarr_block == ActiveRadarrBlock::AddMovieTagsInput, ); } @@ -416,12 +416,12 @@ fn draw_confirmation_prompt(f: &mut Frame<'_, B>, app: &mut App, pro f, horizontal_chunks[0], "Add", - *yes_no_value && highlight_yes_no, + yes_no_value && highlight_yes_no, ); draw_button( f, horizontal_chunks[1], "Cancel", - !*yes_no_value && highlight_yes_no, + !yes_no_value && highlight_yes_no, ); } diff --git a/src/ui/radarr_ui/delete_movie_ui.rs b/src/ui/radarr_ui/delete_movie_ui.rs new file mode 100644 index 0000000..0552107 --- /dev/null +++ b/src/ui/radarr_ui/delete_movie_ui.rs @@ -0,0 +1,45 @@ +use tui::backend::Backend; +use tui::layout::Rect; +use tui::Frame; + +use crate::app::radarr::ActiveRadarrBlock; +use crate::app::App; +use crate::models::Route; +use crate::ui::draw_prompt_box_with_checkboxes; + +pub(super) fn draw_delete_movie_prompt( + f: &mut Frame<'_, B>, + app: &mut App, + prompt_area: Rect, +) { + if matches!( + *app.get_current_route(), + Route::Radarr(ActiveRadarrBlock::DeleteMoviePrompt, _) + ) { + let selected_block = app.data.radarr_data.selected_block; + draw_prompt_box_with_checkboxes( + f, + prompt_area, + "Delete Movie", + format!( + "Do you really want to delete: {}?", + app.data.radarr_data.movies.current_selection().title + ) + .as_str(), + vec![ + ( + "Delete Movie Files", + app.data.radarr_data.delete_movie_files, + selected_block == ActiveRadarrBlock::DeleteMovieToggleDeleteFile, + ), + ( + "Add List Exclusion", + app.data.radarr_data.add_list_exclusion, + selected_block == ActiveRadarrBlock::DeleteMovieToggleAddListExclusion, + ), + ], + selected_block == ActiveRadarrBlock::DeleteMovieConfirmPrompt, + app.data.radarr_data.prompt_confirm, + ) + } +} diff --git a/src/ui/radarr_ui/edit_collection_ui.rs b/src/ui/radarr_ui/edit_collection_ui.rs index 09032c2..24508ee 100644 --- a/src/ui/radarr_ui/edit_collection_ui.rs +++ b/src/ui/radarr_ui/edit_collection_ui.rs @@ -96,9 +96,9 @@ fn draw_edit_collection_confirmation_prompt( ) }; let title = format!("Edit - {}", collection_title); - let yes_no_value = &app.data.radarr_data.prompt_confirm; - let selected_block = &app.data.radarr_data.selected_block; - let highlight_yes_no = *selected_block == ActiveRadarrBlock::EditCollectionConfirmPrompt; + let yes_no_value = app.data.radarr_data.prompt_confirm; + let selected_block = app.data.radarr_data.selected_block; + let highlight_yes_no = selected_block == ActiveRadarrBlock::EditCollectionConfirmPrompt; let selected_minimum_availability = app .data @@ -141,7 +141,7 @@ fn draw_edit_collection_confirmation_prompt( chunks[1], "Monitored", app.data.radarr_data.edit_monitored.unwrap_or_default(), - *selected_block == ActiveRadarrBlock::EditCollectionToggleMonitored, + selected_block == ActiveRadarrBlock::EditCollectionToggleMonitored, ); draw_drop_down_menu_button( @@ -149,14 +149,14 @@ fn draw_edit_collection_confirmation_prompt( chunks[2], "Minimum Availability", selected_minimum_availability.to_display_str(), - *selected_block == ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, + selected_block == ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ); draw_drop_down_menu_button( f, chunks[3], "Quality Profile", selected_quality_profile, - *selected_block == ActiveRadarrBlock::EditCollectionSelectQualityProfile, + selected_block == ActiveRadarrBlock::EditCollectionSelectQualityProfile, ); if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { @@ -166,7 +166,7 @@ fn draw_edit_collection_confirmation_prompt( "Root Folder", &app.data.radarr_data.edit_path.text, *app.data.radarr_data.edit_path.offset.borrow(), - *selected_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput, + selected_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput, active_radarr_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput, ); } @@ -176,19 +176,19 @@ fn draw_edit_collection_confirmation_prompt( chunks[5], "Search on Add", app.data.radarr_data.edit_search_on_add.unwrap_or_default(), - *selected_block == ActiveRadarrBlock::EditCollectionToggleSearchOnAdd, + selected_block == ActiveRadarrBlock::EditCollectionToggleSearchOnAdd, ); draw_button( f, horizontal_chunks[0], "Save", - *yes_no_value && highlight_yes_no, + yes_no_value && highlight_yes_no, ); draw_button( f, horizontal_chunks[1], "Cancel", - !*yes_no_value && highlight_yes_no, + !yes_no_value && highlight_yes_no, ); } diff --git a/src/ui/radarr_ui/edit_movie_ui.rs b/src/ui/radarr_ui/edit_movie_ui.rs index 868e70f..2c24dd0 100644 --- a/src/ui/radarr_ui/edit_movie_ui.rs +++ b/src/ui/radarr_ui/edit_movie_ui.rs @@ -93,9 +93,9 @@ fn draw_edit_movie_confirmation_prompt( ) }; let title = format!("Edit - {}", movie_title); - let yes_no_value = &app.data.radarr_data.prompt_confirm; - let selected_block = &app.data.radarr_data.selected_block; - let highlight_yes_no = *selected_block == ActiveRadarrBlock::EditMovieConfirmPrompt; + let yes_no_value = app.data.radarr_data.prompt_confirm; + let selected_block = app.data.radarr_data.selected_block; + let highlight_yes_no = selected_block == ActiveRadarrBlock::EditMovieConfirmPrompt; let selected_minimum_availability = app .data @@ -138,7 +138,7 @@ fn draw_edit_movie_confirmation_prompt( chunks[1], "Monitored", app.data.radarr_data.edit_monitored.unwrap_or_default(), - *selected_block == ActiveRadarrBlock::EditMovieToggleMonitored, + selected_block == ActiveRadarrBlock::EditMovieToggleMonitored, ); draw_drop_down_menu_button( @@ -146,14 +146,14 @@ fn draw_edit_movie_confirmation_prompt( chunks[2], "Minimum Availability", selected_minimum_availability.to_display_str(), - *selected_block == ActiveRadarrBlock::EditMovieSelectMinimumAvailability, + selected_block == ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ); draw_drop_down_menu_button( f, chunks[3], "Quality Profile", selected_quality_profile, - *selected_block == ActiveRadarrBlock::EditMovieSelectQualityProfile, + selected_block == ActiveRadarrBlock::EditMovieSelectQualityProfile, ); if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { @@ -163,7 +163,7 @@ fn draw_edit_movie_confirmation_prompt( "Path", &app.data.radarr_data.edit_path.text, *app.data.radarr_data.edit_path.offset.borrow(), - *selected_block == ActiveRadarrBlock::EditMoviePathInput, + selected_block == ActiveRadarrBlock::EditMoviePathInput, active_radarr_block == ActiveRadarrBlock::EditMoviePathInput, ); draw_text_box_with_label( @@ -172,7 +172,7 @@ fn draw_edit_movie_confirmation_prompt( "Tags", &app.data.radarr_data.edit_tags.text, *app.data.radarr_data.edit_tags.offset.borrow(), - *selected_block == ActiveRadarrBlock::EditMovieTagsInput, + selected_block == ActiveRadarrBlock::EditMovieTagsInput, active_radarr_block == ActiveRadarrBlock::EditMovieTagsInput, ); } @@ -181,12 +181,12 @@ fn draw_edit_movie_confirmation_prompt( f, horizontal_chunks[0], "Save", - *yes_no_value && highlight_yes_no, + yes_no_value && highlight_yes_no, ); draw_button( f, horizontal_chunks[1], "Cancel", - !*yes_no_value && highlight_yes_no, + !yes_no_value && highlight_yes_no, ); } diff --git a/src/ui/radarr_ui/mod.rs b/src/ui/radarr_ui/mod.rs index 2cab7f6..b1a01f6 100644 --- a/src/ui/radarr_ui/mod.rs +++ b/src/ui/radarr_ui/mod.rs @@ -10,7 +10,7 @@ use tui::widgets::{Cell, ListItem, Paragraph, Row}; use tui::Frame; use crate::app::radarr::{ - ActiveRadarrBlock, RadarrData, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, + ActiveRadarrBlock, RadarrData, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, DELETE_MOVIE_BLOCKS, EDIT_COLLECTION_BLOCKS, EDIT_MOVIE_BLOCKS, FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS, }; use crate::app::App; @@ -19,6 +19,7 @@ use crate::models::radarr_models::{Collection, DiskSpace, DownloadRecord, Movie, use crate::models::{HorizontallyScrollableText, Route}; use crate::ui::radarr_ui::add_movie_ui::draw_add_movie_search_popup; use crate::ui::radarr_ui::collection_details_ui::draw_collection_details_popup; +use crate::ui::radarr_ui::delete_movie_ui::draw_delete_movie_prompt; use crate::ui::radarr_ui::edit_collection_ui::draw_edit_collection_prompt; use crate::ui::radarr_ui::edit_movie_ui::draw_edit_movie_prompt; use crate::ui::radarr_ui::movie_details_ui::draw_movie_info_popup; @@ -37,6 +38,7 @@ use crate::utils::{convert_runtime, convert_to_gb}; mod add_movie_ui; mod collection_details_ui; +mod delete_movie_ui; mod edit_collection_ui; mod edit_movie_ui; mod movie_details_ui; @@ -150,7 +152,7 @@ pub(super) fn draw_radarr_ui(f: &mut Frame<'_, B>, app: &mut App, ar } } } - ActiveRadarrBlock::DeleteMoviePrompt => { + _ if DELETE_MOVIE_BLOCKS.contains(&active_radarr_block) => { draw_prompt_popup_over(f, app, content_rect, draw_library, draw_delete_movie_prompt) } ActiveRadarrBlock::DeleteDownloadPrompt => draw_prompt_popup_over( @@ -320,7 +322,7 @@ fn draw_update_all_movies_prompt( prompt_area, "Update All Movies", "Do you want to update info and scan your disks for all of your movies?", - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } @@ -334,7 +336,7 @@ fn draw_update_downloads_prompt( prompt_area, "Update Downloads", "Do you want to update your downloads?", - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } @@ -348,21 +350,7 @@ fn draw_update_all_collections_prompt( prompt_area, "Update All Collections", "Do you want to update all of your collections?", - &app.data.radarr_data.prompt_confirm, - ); -} - -fn draw_delete_movie_prompt(f: &mut Frame<'_, B>, app: &mut App, prompt_area: Rect) { - draw_prompt_box( - f, - prompt_area, - "Delete Movie", - format!( - "Do you really want to delete: {}?", - app.data.radarr_data.movies.current_selection().title - ) - .as_str(), - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } @@ -376,7 +364,7 @@ fn draw_delete_download_prompt(f: &mut Frame<'_, B>, app: &mut App, app.data.radarr_data.downloads.current_selection().title ) .as_str(), - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } @@ -394,7 +382,7 @@ fn draw_delete_root_folder_prompt( app.data.radarr_data.root_folders.current_selection().path ) .as_str(), - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } diff --git a/src/ui/radarr_ui/movie_details_ui.rs b/src/ui/radarr_ui/movie_details_ui.rs index 38989d3..8ac93fa 100644 --- a/src/ui/radarr_ui/movie_details_ui.rs +++ b/src/ui/radarr_ui/movie_details_ui.rs @@ -93,7 +93,7 @@ fn draw_search_movie_prompt(f: &mut Frame<'_, B>, app: &mut App, pro app.data.radarr_data.movies.current_selection().title ) .as_str(), - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } @@ -107,7 +107,7 @@ fn draw_update_and_scan_prompt(f: &mut Frame<'_, B>, app: &mut App, app.data.radarr_data.movies.current_selection().title ) .as_str(), - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } @@ -521,7 +521,7 @@ fn draw_manual_search_confirm_prompt( title, &prompt, Some(content_paragraph), - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } else { draw_prompt_box( @@ -529,7 +529,7 @@ fn draw_manual_search_confirm_prompt( prompt_area, title, &prompt, - &app.data.radarr_data.prompt_confirm, + app.data.radarr_data.prompt_confirm, ); } }