Added help that's always visible for modals with new shortcuts for accepting all modals, or closing all modals without the need of seeing the UI

This commit is contained in:
2024-11-03 14:25:33 -07:00
parent c1da8592b4
commit a0fe51c57b
51 changed files with 880 additions and 106 deletions
@@ -461,6 +461,16 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
.tags
)
}
ActiveRadarrBlock::AddMoviePrompt => {
if self.app.data.radarr_data.selected_block.get_active_block()
== &ActiveRadarrBlock::AddMovieConfirmPrompt
&& *key == DEFAULT_KEYBINDINGS.confirm.key
{
self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::AddMovie(None));
self.app.pop_navigation_stack();
}
}
_ => (),
}
}
@@ -1494,7 +1494,13 @@ mod tests {
mod test_handle_key_char {
use super::*;
use crate::models::servarr_data::radarr::modals::AddMovieModal;
use crate::{
models::{
servarr_data::radarr::{modals::AddMovieModal, radarr_data::ADD_MOVIE_SELECTION_BLOCKS},
BlockSelectionState,
},
network::radarr_network::RadarrEvent,
};
#[test]
fn test_add_movie_search_input_backspace() {
@@ -1588,6 +1594,35 @@ mod tests {
"h"
);
}
#[test]
fn test_add_movie_confirm_prompt_prompt_confirmation_confirm() {
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.selected_block = BlockSelectionState::new(&ADD_MOVIE_SELECTION_BLOCKS);
app
.data
.radarr_data
.selected_block
.set_index(ADD_MOVIE_SELECTION_BLOCKS.len() - 1);
AddMovieHandler::with(
&DEFAULT_KEYBINDINGS.confirm.key,
&mut app,
&ActiveRadarrBlock::AddMoviePrompt,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert_eq!(
app.data.radarr_data.prompt_confirm_action,
Some(RadarrEvent::AddMovie(None))
);
assert!(app.data.radarr_data.add_movie_modal.is_some());
}
}
#[test]
@@ -1,3 +1,4 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App;
use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
@@ -100,5 +101,17 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DeleteMovieHandler<'
}
}
fn handle_char_key_event(&mut self) {}
fn handle_char_key_event(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::DeleteMoviePrompt
&& self.app.data.radarr_data.selected_block.get_active_block()
== &ActiveRadarrBlock::DeleteMovieConfirmPrompt
&& *self.key == DEFAULT_KEYBINDINGS.confirm.key
{
self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteMovie(None));
self.app.should_refresh = true;
self.app.pop_navigation_stack();
}
}
}
@@ -250,6 +250,51 @@ mod tests {
}
}
mod test_handle_key_char {
use crate::{
models::{
servarr_data::radarr::radarr_data::DELETE_MOVIE_SELECTION_BLOCKS, BlockSelectionState,
},
network::radarr_network::RadarrEvent,
};
use super::*;
#[test]
fn test_delete_movie_confirm_prompt_prompt_confirm() {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true;
app.data.radarr_data.selected_block =
BlockSelectionState::new(&DELETE_MOVIE_SELECTION_BLOCKS);
app
.data
.radarr_data
.selected_block
.set_index(DELETE_MOVIE_SELECTION_BLOCKS.len() - 1);
DeleteMovieHandler::with(
&DEFAULT_KEYBINDINGS.confirm.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(None))
);
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_handler_accepts() {
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
@@ -327,6 +327,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a,
.tags
)
}
ActiveRadarrBlock::EditMoviePrompt => {
if self.app.data.radarr_data.selected_block.get_active_block()
== &ActiveRadarrBlock::EditMovieConfirmPrompt
&& *key == DEFAULT_KEYBINDINGS.confirm.key
{
self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditMovie(None));
self.app.should_refresh = true;
self.app.pop_navigation_stack();
}
}
_ => (),
}
}
@@ -940,7 +940,16 @@ mod tests {
mod test_handle_key_char {
use super::*;
use crate::models::servarr_data::radarr::modals::EditMovieModal;
use crate::{
models::{
servarr_data::radarr::{
modals::EditMovieModal,
radarr_data::{EDIT_COLLECTION_SELECTION_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS},
},
BlockSelectionState,
},
network::radarr_network::RadarrEvent,
};
#[test]
fn test_edit_movie_path_input_backspace() {
@@ -1051,6 +1060,36 @@ mod tests {
"h"
);
}
#[test]
fn test_edit_movie_confirm_prompt_prompt_confirm() {
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.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS);
app
.data
.radarr_data
.selected_block
.set_index(EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1);
EditMovieHandler::with(
&DEFAULT_KEYBINDINGS.confirm.key,
&mut app,
&ActiveRadarrBlock::EditMoviePrompt,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert_eq!(
app.data.radarr_data.prompt_confirm_action,
Some(RadarrEvent::EditMovie(None))
);
assert!(app.data.radarr_data.edit_movie_modal.is_some());
assert!(app.should_refresh);
}
}
#[test]
@@ -996,6 +996,7 @@ mod tests {
RadarrData, EDIT_MOVIE_SELECTION_BLOCKS,
};
use crate::network::radarr_network::RadarrEvent;
use crate::test_edit_movie_key;
use super::*;
@@ -1452,6 +1453,33 @@ mod tests {
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(app.data.radarr_data.movies.sort.is_none());
}
#[test]
fn test_update_all_movies_prompt_confirm() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.confirm.key,
&mut app,
&ActiveRadarrBlock::UpdateAllMoviesPrompt,
&None,
)
.handle();
assert!(app.data.radarr_data.prompt_confirm);
assert_eq!(
app.data.radarr_data.prompt_confirm_action,
Some(RadarrEvent::UpdateAllMovies)
);
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
}
}
#[rstest]
@@ -386,6 +386,14 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
self.app.data.radarr_data.movies.filter.as_mut().unwrap()
)
}
ActiveRadarrBlock::UpdateAllMoviesPrompt => {
if *key == DEFAULT_KEYBINDINGS.confirm.key {
self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateAllMovies);
self.app.pop_navigation_stack();
}
}
_ => (),
}
}
@@ -464,6 +464,32 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
}
_ => (),
},
ActiveRadarrBlock::AutomaticallySearchMoviePrompt => {
if *key == DEFAULT_KEYBINDINGS.confirm.key {
self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action =
Some(RadarrEvent::TriggerAutomaticSearch(None));
self.app.pop_navigation_stack();
}
}
ActiveRadarrBlock::UpdateAndScanPrompt => {
if *key == DEFAULT_KEYBINDINGS.confirm.key {
self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateAndScan(None));
self.app.pop_navigation_stack();
}
}
ActiveRadarrBlock::ManualSearchConfirmPrompt => {
if *key == DEFAULT_KEYBINDINGS.confirm.key {
self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action =
Some(RadarrEvent::DownloadRelease(None));
self.app.pop_navigation_stack();
}
}
_ => (),
}
}
@@ -1468,6 +1468,7 @@ mod tests {
use crate::models::servarr_data::radarr::radarr_data::{
RadarrData, EDIT_MOVIE_SELECTION_BLOCKS,
};
use crate::network::radarr_network::RadarrEvent;
use crate::test_edit_movie_key;
use super::*;
@@ -1780,6 +1781,50 @@ mod tests {
assert_eq!(app.get_current_route(), &active_radarr_block.into());
assert!(app.is_routing);
}
#[rstest]
#[case(
ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
RadarrEvent::TriggerAutomaticSearch(None)
)]
#[case(
ActiveRadarrBlock::UpdateAndScanPrompt,
RadarrEvent::UpdateAndScan(None)
)]
#[case(
ActiveRadarrBlock::ManualSearchConfirmPrompt,
RadarrEvent::DownloadRelease(None)
)]
fn test_movie_info_prompt_confirm(
#[case] prompt_block: ActiveRadarrBlock,
#[case] expected_action: RadarrEvent,
) {
let mut app = App::default();
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
movie_details: ScrollableText::with_string("test".to_owned()),
..MovieDetailsModal::default()
});
app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into());
app.push_navigation_stack(prompt_block.into());
MovieDetailsHandler::with(
&DEFAULT_KEYBINDINGS.confirm.key,
&mut app,
&prompt_block,
&None,
)
.handle();
assert!(app.data.radarr_data.prompt_confirm);
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::MovieDetails.into()
);
assert_eq!(
app.data.radarr_data.prompt_confirm_action,
Some(expected_action)
);
}
}
#[test]