Added two new checkboxes to the delete movie UI that allows users to specify to delete the file and/or add an exclusion for the selected film on deletion. Also fixed the refresh bug in the root folders UI where you have to manually refresh to get the changes to show before 20 seconds. Also cleaned up code a bit and removed some unnecessary clone calls and references-dereferences since the types were copyable and not necessary to be referenced since they were all dereferenced anyway and copied. Made sense to just cut out the middleman on the copies.

This commit is contained in:
2023-08-08 10:50:06 -06:00
parent b7d00f4827
commit 435926f6f0
15 changed files with 618 additions and 132 deletions
@@ -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;
@@ -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<ActiveRadarrBlock>,
}
impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for DeleteMovieHandler<'a> {
fn with(
key: &'a Key,
app: &'a mut App,
active_block: &'a ActiveRadarrBlock,
_context: &'a Option<ActiveRadarrBlock>,
) -> 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(), &current_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(), &current_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);
}
}
}
@@ -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
)]
@@ -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
)]
+30 -30
View File
@@ -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,
) {