From 3fd0a6173770c452cc85f43ab264420cbef8ef96 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Tue, 8 Sep 2026 16:07:19 -0600 Subject: [PATCH] fix: show confirmation prompt clues on delete prompts Delete confirmation prompts had no arm in any of the context clue providers, so they fell through to the main tab's contextual help and displayed the library tab's hints, such as add, sort and edit, while the user was looking at a delete confirmation. Map the delete block arrays in all four servarrs to the shared confirmation prompt clues, matching how the other prompts and selection modals are already wired. --- src/app/lidarr/lidarr_context_clues.rs | 9 +++-- src/app/lidarr/lidarr_context_clues_tests.rs | 36 +++++++++++++++++++ src/app/radarr/radarr_context_clues.rs | 7 ++-- src/app/radarr/radarr_context_clues_tests.rs | 19 ++++++++++ src/app/readarr/readarr_context_clues.rs | 9 +++-- .../readarr/readarr_context_clues_tests.rs | 36 +++++++++++++++++++ src/app/sonarr/sonarr_context_clues.rs | 8 +++-- src/app/sonarr/sonarr_context_clues_tests.rs | 18 ++++++++++ 8 files changed, 134 insertions(+), 8 deletions(-) diff --git a/src/app/lidarr/lidarr_context_clues.rs b/src/app/lidarr/lidarr_context_clues.rs index 2b734f4a..61da0c35 100644 --- a/src/app/lidarr/lidarr_context_clues.rs +++ b/src/app/lidarr/lidarr_context_clues.rs @@ -7,8 +7,8 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::models::Route; use crate::models::servarr_data::lidarr::lidarr_data::{ ADD_ARTIST_BLOCKS, ADD_ROOT_FOLDER_BLOCKS, ALBUM_DETAILS_BLOCKS, ARTIST_DETAILS_BLOCKS, - ActiveLidarrBlock, EDIT_ARTIST_BLOCKS, EDIT_INDEXER_BLOCKS, INDEXER_SETTINGS_BLOCKS, - TRACK_DETAILS_BLOCKS, + ActiveLidarrBlock, DELETE_ALBUM_BLOCKS, DELETE_ARTIST_BLOCKS, EDIT_ARTIST_BLOCKS, + EDIT_INDEXER_BLOCKS, INDEXER_SETTINGS_BLOCKS, TRACK_DETAILS_BLOCKS, }; #[cfg(test)] @@ -203,6 +203,11 @@ impl ContextClueProvider for LidarrContextClueProvider { { Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) } + _ if DELETE_ARTIST_BLOCKS.contains(&active_lidarr_block) + || DELETE_ALBUM_BLOCKS.contains(&active_lidarr_block) => + { + Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) + } ActiveLidarrBlock::AddArtistPrompt | ActiveLidarrBlock::AddArtistSelectMonitor | ActiveLidarrBlock::AddArtistSelectMonitorNewItems diff --git a/src/app/lidarr/lidarr_context_clues_tests.rs b/src/app/lidarr/lidarr_context_clues_tests.rs index 92ef2e6f..57207974 100644 --- a/src/app/lidarr/lidarr_context_clues_tests.rs +++ b/src/app/lidarr/lidarr_context_clues_tests.rs @@ -577,6 +577,42 @@ mod tests { assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); } + #[rstest] + fn test_lidarr_context_clue_provider_confirmation_prompt_context_clues_delete_artist_blocks( + #[values( + ActiveLidarrBlock::DeleteArtistPrompt, + ActiveLidarrBlock::DeleteArtistConfirmPrompt, + ActiveLidarrBlock::DeleteArtistToggleAddListExclusion, + ActiveLidarrBlock::DeleteArtistToggleDeleteFile + )] + active_lidarr_block: ActiveLidarrBlock, + ) { + let mut app = App::test_default(); + app.push_navigation_stack(active_lidarr_block.into()); + + let context_clues = LidarrContextClueProvider::get_context_clues(&mut app); + + assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); + } + + #[rstest] + fn test_lidarr_context_clue_provider_confirmation_prompt_context_clues_delete_album_blocks( + #[values( + ActiveLidarrBlock::DeleteAlbumPrompt, + ActiveLidarrBlock::DeleteAlbumConfirmPrompt, + ActiveLidarrBlock::DeleteAlbumToggleAddListExclusion, + ActiveLidarrBlock::DeleteAlbumToggleDeleteFile + )] + active_lidarr_block: ActiveLidarrBlock, + ) { + let mut app = App::test_default(); + app.push_navigation_stack(active_lidarr_block.into()); + + let context_clues = LidarrContextClueProvider::get_context_clues(&mut app); + + assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); + } + #[test] fn test_lidarr_context_clue_provider_system_tasks_clues() { let mut app = App::test_default(); diff --git a/src/app/radarr/radarr_context_clues.rs b/src/app/radarr/radarr_context_clues.rs index 32221877..e5310f53 100644 --- a/src/app/radarr/radarr_context_clues.rs +++ b/src/app/radarr/radarr_context_clues.rs @@ -6,8 +6,8 @@ use crate::app::context_clues::{ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::models::Route; use crate::models::servarr_data::radarr::radarr_data::{ - ADD_MOVIE_BLOCKS, ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS, EDIT_INDEXER_BLOCKS, - EDIT_MOVIE_BLOCKS, INDEXER_SETTINGS_BLOCKS, MOVIE_DETAILS_BLOCKS, + ADD_MOVIE_BLOCKS, ActiveRadarrBlock, DELETE_MOVIE_BLOCKS, EDIT_COLLECTION_BLOCKS, + EDIT_INDEXER_BLOCKS, EDIT_MOVIE_BLOCKS, INDEXER_SETTINGS_BLOCKS, MOVIE_DETAILS_BLOCKS, }; #[cfg(test)] @@ -120,6 +120,9 @@ impl ContextClueProvider for RadarrContextClueProvider { { Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) } + _ if DELETE_MOVIE_BLOCKS.contains(&active_radarr_block) => { + Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) + } ActiveRadarrBlock::AddMoviePrompt | ActiveRadarrBlock::AddMovieSelectMonitor | ActiveRadarrBlock::AddMovieSelectMinimumAvailability diff --git a/src/app/radarr/radarr_context_clues_tests.rs b/src/app/radarr/radarr_context_clues_tests.rs index a4b4f10a..29ff2922 100644 --- a/src/app/radarr/radarr_context_clues_tests.rs +++ b/src/app/radarr/radarr_context_clues_tests.rs @@ -415,6 +415,25 @@ mod tests { assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); } + #[rstest] + fn test_radarr_context_clue_provider_confirmation_prompt_context_clues_delete_movie_blocks( + #[values( + ActiveRadarrBlock::DeleteMoviePrompt, + ActiveRadarrBlock::DeleteMovieConfirmPrompt, + ActiveRadarrBlock::DeleteMovieToggleAddListExclusion, + ActiveRadarrBlock::DeleteMovieToggleDeleteFile + )] + active_radarr_block: ActiveRadarrBlock, + ) { + let mut app = App::test_default(); + app.data.radarr_data = RadarrData::default(); + app.push_navigation_stack(active_radarr_block.into()); + + let context_clues = RadarrContextClueProvider::get_context_clues(&mut app); + + assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); + } + #[rstest] fn test_radarr_context_clue_provider_add_movie_search_results_context_clues( #[values( diff --git a/src/app/readarr/readarr_context_clues.rs b/src/app/readarr/readarr_context_clues.rs index 442fabbb..9f742241 100644 --- a/src/app/readarr/readarr_context_clues.rs +++ b/src/app/readarr/readarr_context_clues.rs @@ -7,8 +7,8 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::models::Route; use crate::models::servarr_data::readarr::readarr_data::{ ADD_AUTHOR_BLOCKS, ADD_ROOT_FOLDER_BLOCKS, AUTHOR_DETAILS_BLOCKS, ActiveReadarrBlock, - BOOK_DETAILS_BLOCKS, EDIT_AUTHOR_BLOCKS, EDIT_INDEXER_BLOCKS, EDITION_DETAILS_BLOCKS, - INDEXER_SETTINGS_BLOCKS, + BOOK_DETAILS_BLOCKS, DELETE_AUTHOR_BLOCKS, DELETE_BOOK_BLOCKS, EDIT_AUTHOR_BLOCKS, + EDIT_INDEXER_BLOCKS, EDITION_DETAILS_BLOCKS, INDEXER_SETTINGS_BLOCKS, }; #[cfg(test)] @@ -191,6 +191,11 @@ impl ContextClueProvider for ReadarrContextClueProvider { { Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) } + _ if DELETE_AUTHOR_BLOCKS.contains(&active_readarr_block) + || DELETE_BOOK_BLOCKS.contains(&active_readarr_block) => + { + Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) + } ActiveReadarrBlock::AddAuthorPrompt | ActiveReadarrBlock::AddAuthorSelectMonitor | ActiveReadarrBlock::AddAuthorSelectMonitorNewItems diff --git a/src/app/readarr/readarr_context_clues_tests.rs b/src/app/readarr/readarr_context_clues_tests.rs index 76eb259b..76112630 100644 --- a/src/app/readarr/readarr_context_clues_tests.rs +++ b/src/app/readarr/readarr_context_clues_tests.rs @@ -548,6 +548,42 @@ mod tests { assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); } + #[rstest] + fn test_readarr_context_clue_provider_confirmation_prompt_context_clues_delete_author_blocks( + #[values( + ActiveReadarrBlock::DeleteAuthorPrompt, + ActiveReadarrBlock::DeleteAuthorConfirmPrompt, + ActiveReadarrBlock::DeleteAuthorToggleAddListExclusion, + ActiveReadarrBlock::DeleteAuthorToggleDeleteFile + )] + active_readarr_block: ActiveReadarrBlock, + ) { + let mut app = App::test_default(); + app.push_navigation_stack(active_readarr_block.into()); + + let context_clues = ReadarrContextClueProvider::get_context_clues(&mut app); + + assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); + } + + #[rstest] + fn test_readarr_context_clue_provider_confirmation_prompt_context_clues_delete_book_blocks( + #[values( + ActiveReadarrBlock::DeleteBookPrompt, + ActiveReadarrBlock::DeleteBookConfirmPrompt, + ActiveReadarrBlock::DeleteBookToggleAddListExclusion, + ActiveReadarrBlock::DeleteBookToggleDeleteFile + )] + active_readarr_block: ActiveReadarrBlock, + ) { + let mut app = App::test_default(); + app.push_navigation_stack(active_readarr_block.into()); + + let context_clues = ReadarrContextClueProvider::get_context_clues(&mut app); + + assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); + } + #[test] fn test_readarr_context_clue_provider_system_tasks_clues() { let mut app = App::test_default(); diff --git a/src/app/sonarr/sonarr_context_clues.rs b/src/app/sonarr/sonarr_context_clues.rs index 90d8aada..fb5b46c6 100644 --- a/src/app/sonarr/sonarr_context_clues.rs +++ b/src/app/sonarr/sonarr_context_clues.rs @@ -5,8 +5,9 @@ use crate::app::context_clues::{ use crate::app::{App, context_clues::ContextClue, key_binding::DEFAULT_KEYBINDINGS}; use crate::models::Route; use crate::models::servarr_data::sonarr::sonarr_data::{ - ADD_SERIES_BLOCKS, ActiveSonarrBlock, EDIT_INDEXER_BLOCKS, EDIT_SERIES_BLOCKS, - EPISODE_DETAILS_BLOCKS, INDEXER_SETTINGS_BLOCKS, SEASON_DETAILS_BLOCKS, SERIES_DETAILS_BLOCKS, + ADD_SERIES_BLOCKS, ActiveSonarrBlock, DELETE_SERIES_BLOCKS, EDIT_INDEXER_BLOCKS, + EDIT_SERIES_BLOCKS, EPISODE_DETAILS_BLOCKS, INDEXER_SETTINGS_BLOCKS, SEASON_DETAILS_BLOCKS, + SERIES_DETAILS_BLOCKS, }; #[cfg(test)] @@ -207,6 +208,9 @@ impl ContextClueProvider for SonarrContextClueProvider { { Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) } + _ if DELETE_SERIES_BLOCKS.contains(&active_sonarr_block) => { + Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES) + } ActiveSonarrBlock::AddSeriesPrompt | ActiveSonarrBlock::AddSeriesSelectMonitor | ActiveSonarrBlock::AddSeriesSelectSeriesType diff --git a/src/app/sonarr/sonarr_context_clues_tests.rs b/src/app/sonarr/sonarr_context_clues_tests.rs index 4f02fc35..6f3e4322 100644 --- a/src/app/sonarr/sonarr_context_clues_tests.rs +++ b/src/app/sonarr/sonarr_context_clues_tests.rs @@ -603,6 +603,24 @@ mod tests { assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); } + #[rstest] + fn test_sonarr_context_clue_provider_confirmation_prompt_popup_clues_delete_series_blocks( + #[values( + ActiveSonarrBlock::DeleteSeriesPrompt, + ActiveSonarrBlock::DeleteSeriesConfirmPrompt, + ActiveSonarrBlock::DeleteSeriesToggleAddListExclusion, + ActiveSonarrBlock::DeleteSeriesToggleDeleteFile + )] + active_sonarr_block: ActiveSonarrBlock, + ) { + let mut app = App::test_default(); + app.push_navigation_stack(active_sonarr_block.into()); + + let context_clues = SonarrContextClueProvider::get_context_clues(&mut app); + + assert_some_eq_x!(context_clues, &CONFIRMATION_PROMPT_CONTEXT_CLUES); + } + #[rstest] fn test_sonarr_context_clue_provider_add_series_search_results_clues( #[values(