diff --git a/src/app/app_tests.rs b/src/app/app_tests.rs index 1e92f3b..a3902f2 100644 --- a/src/app/app_tests.rs +++ b/src/app/app_tests.rs @@ -223,6 +223,14 @@ mod tests { sync_network_rx.recv().await.unwrap(), RadarrEvent::GetStatus.into() ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetQualityProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetTags.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), RadarrEvent::GetMovies.into() diff --git a/src/app/radarr/mod.rs b/src/app/radarr/mod.rs index 4010b06..173b2c4 100644 --- a/src/app/radarr/mod.rs +++ b/src/app/radarr/mod.rs @@ -17,11 +17,23 @@ impl<'a> App<'a> { .await; } ActiveRadarrBlock::Collections => { + self + .dispatch_network_event(RadarrEvent::GetQualityProfiles.into()) + .await; self .dispatch_network_event(RadarrEvent::GetCollections.into()) .await; + self + .dispatch_network_event(RadarrEvent::GetMovies.into()) + .await; } ActiveRadarrBlock::CollectionDetails => { + self + .dispatch_network_event(RadarrEvent::GetQualityProfiles.into()) + .await; + self + .dispatch_network_event(RadarrEvent::GetTags.into()) + .await; self.is_loading = true; self.populate_movie_collection_table().await; self.is_loading = false; @@ -37,6 +49,12 @@ impl<'a> App<'a> { .await; } ActiveRadarrBlock::Movies => { + self + .dispatch_network_event(RadarrEvent::GetQualityProfiles.into()) + .await; + self + .dispatch_network_event(RadarrEvent::GetTags.into()) + .await; self .dispatch_network_event(RadarrEvent::GetMovies.into()) .await; @@ -45,6 +63,9 @@ impl<'a> App<'a> { .await; } ActiveRadarrBlock::Indexers => { + self + .dispatch_network_event(RadarrEvent::GetTags.into()) + .await; self .dispatch_network_event(RadarrEvent::GetIndexers.into()) .await; diff --git a/src/app/radarr/radarr_context_clues.rs b/src/app/radarr/radarr_context_clues.rs index 2c37e26..d35222b 100644 --- a/src/app/radarr/radarr_context_clues.rs +++ b/src/app/radarr/radarr_context_clues.rs @@ -77,7 +77,8 @@ pub static SYSTEM_TASKS_CONTEXT_CLUES: [ContextClue; 2] = [ (DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc), ]; -pub static COLLECTION_DETAILS_CONTEXT_CLUES: [ContextClue; 2] = [ +pub static COLLECTION_DETAILS_CONTEXT_CLUES: [ContextClue; 3] = [ (DEFAULT_KEYBINDINGS.submit, "show overview/add movie"), + (DEFAULT_KEYBINDINGS.edit, "edit collection"), (DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc), ]; diff --git a/src/app/radarr/radarr_context_clues_tests.rs b/src/app/radarr/radarr_context_clues_tests.rs index d8ca11b..91c2528 100644 --- a/src/app/radarr/radarr_context_clues_tests.rs +++ b/src/app/radarr/radarr_context_clues_tests.rs @@ -240,6 +240,11 @@ mod tests { let (key_binding, description) = collection_details_context_clues_iter.next().unwrap(); + assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.edit); + assert_str_eq!(*description, "edit collection"); + + let (key_binding, description) = collection_details_context_clues_iter.next().unwrap(); + assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.esc); assert_str_eq!(*description, DEFAULT_KEYBINDINGS.esc.desc); assert_eq!(collection_details_context_clues_iter.next(), None); diff --git a/src/app/radarr/radarr_tests.rs b/src/app/radarr/radarr_tests.rs index e56493f..45648d7 100644 --- a/src/app/radarr/radarr_tests.rs +++ b/src/app/radarr/radarr_tests.rs @@ -38,17 +38,25 @@ mod tests { .await; assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetQualityProfiles.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), RadarrEvent::GetCollections.into() ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovies.into() + ); assert!(!app.data.radarr_data.prompt_confirm); assert_eq!(app.tick_count, 0); } #[tokio::test] async fn test_dispatch_by_collection_details_block() { - let (mut app, _) = construct_app_unit(); + let (mut app, mut sync_network_rx) = construct_app_unit(); app.data.radarr_data.collections.set_items(vec![Collection { movies: Some(vec![CollectionMovie::default()]), @@ -60,6 +68,14 @@ mod tests { .await; assert!(!app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetQualityProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetTags.into() + ); assert!(!app.data.radarr_data.collection_movies.items.is_empty()); assert_eq!(app.tick_count, 0); assert!(!app.data.radarr_data.prompt_confirm); @@ -80,6 +96,14 @@ mod tests { .await; assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetQualityProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetTags.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), RadarrEvent::AddMovie(None).into() @@ -132,6 +156,14 @@ mod tests { .await; assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetQualityProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetTags.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), RadarrEvent::GetMovies.into() @@ -153,6 +185,10 @@ mod tests { .await; assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetTags.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), RadarrEvent::GetIndexers.into() diff --git a/src/app/sonarr/mod.rs b/src/app/sonarr/mod.rs index 74dcd1e..6e16140 100644 --- a/src/app/sonarr/mod.rs +++ b/src/app/sonarr/mod.rs @@ -15,6 +15,15 @@ impl<'a> App<'a> { pub(super) async fn dispatch_by_sonarr_block(&mut self, active_sonarr_block: &ActiveSonarrBlock) { match active_sonarr_block { ActiveSonarrBlock::Series => { + self + .dispatch_network_event(SonarrEvent::GetQualityProfiles.into()) + .await; + self + .dispatch_network_event(SonarrEvent::GetLanguageProfiles.into()) + .await; + self + .dispatch_network_event(SonarrEvent::GetTags.into()) + .await; self .dispatch_network_event(SonarrEvent::ListSeries.into()) .await; @@ -89,6 +98,9 @@ impl<'a> App<'a> { .await; } ActiveSonarrBlock::Indexers => { + self + .dispatch_network_event(SonarrEvent::GetTags.into()) + .await; self .dispatch_network_event(SonarrEvent::GetIndexers.into()) .await; diff --git a/src/app/sonarr/sonarr_tests.rs b/src/app/sonarr/sonarr_tests.rs index 7e688e6..79b0ccc 100644 --- a/src/app/sonarr/sonarr_tests.rs +++ b/src/app/sonarr/sonarr_tests.rs @@ -257,6 +257,18 @@ mod tests { .await; assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + SonarrEvent::GetQualityProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + SonarrEvent::GetLanguageProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + SonarrEvent::GetTags.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), SonarrEvent::ListSeries.into() @@ -274,6 +286,10 @@ mod tests { .await; assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + SonarrEvent::GetTags.into() + ); assert_eq!( sync_network_rx.recv().await.unwrap(), SonarrEvent::GetIndexers.into() 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 b2cbf33..294fffc 100644 --- a/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs @@ -369,7 +369,7 @@ mod tests { test_edit_collection_key!( CollectionDetailsHandler, ActiveRadarrBlock::CollectionDetails, - ActiveRadarrBlock::CollectionDetails + Some(ActiveRadarrBlock::CollectionDetails) ); } diff --git a/src/handlers/radarr_handlers/collections/collections_handler_tests.rs b/src/handlers/radarr_handlers/collections/collections_handler_tests.rs index 6a4ff25..a62a6aa 100644 --- a/src/handlers/radarr_handlers/collections/collections_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/collections_handler_tests.rs @@ -449,7 +449,11 @@ mod tests { #[test] fn test_collection_search_box_left_right_keys() { let mut app = App::default(); - app.data.radarr_data.collections.set_items(vec![Collection::default()]); + app + .data + .radarr_data + .collections + .set_items(vec![Collection::default()]); app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); app.data.radarr_data.collections.search = Some("Test".into()); @@ -499,7 +503,11 @@ mod tests { #[test] fn test_collection_filter_box_left_right_keys() { let mut app = App::default(); - app.data.radarr_data.collections.set_items(vec![Collection::default()]); + app + .data + .radarr_data + .collections + .set_items(vec![Collection::default()]); app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into()); app.data.radarr_data.collections.filter = Some("Test".into()); @@ -938,7 +946,11 @@ mod tests { filtered_state: Some(TableState::default()), ..StatefulTable::default() }; - app.data.radarr_data.collections.set_items(vec![Collection::default()]); + app + .data + .radarr_data + .collections + .set_items(vec![Collection::default()]); CollectionsHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); @@ -977,7 +989,11 @@ mod tests { #[test] fn test_collections_sort_prompt_block_esc() { let mut app = App::default(); - app.data.radarr_data.collections.set_items(vec![Collection::default()]); + app + .data + .radarr_data + .collections + .set_items(vec![Collection::default()]); app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::CollectionsSortPrompt.into()); @@ -1174,11 +1190,7 @@ mod tests { #[test] fn test_collection_edit_key() { - test_edit_collection_key!( - CollectionsHandler, - ActiveRadarrBlock::Collections, - ActiveRadarrBlock::Collections - ); + test_edit_collection_key!(CollectionsHandler, ActiveRadarrBlock::Collections, None); } #[test] diff --git a/src/handlers/radarr_handlers/collections/mod.rs b/src/handlers/radarr_handlers/collections/mod.rs index 17f315e..f0ee1ef 100644 --- a/src/handlers/radarr_handlers/collections/mod.rs +++ b/src/handlers/radarr_handlers/collections/mod.rs @@ -151,13 +151,9 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<' match self.active_radarr_block { ActiveRadarrBlock::Collections => match self.key { _ if key == DEFAULT_KEYBINDINGS.edit.key => { - self.app.push_navigation_stack( - ( - ActiveRadarrBlock::EditCollectionPrompt, - Some(ActiveRadarrBlock::Collections), - ) - .into(), - ); + self + .app + .push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into()); self.app.data.radarr_data.edit_collection_modal = Some((&self.app.data.radarr_data).into()); self.app.data.radarr_data.selected_block = diff --git a/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs b/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs index 5911968..b0e9a43 100644 --- a/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs +++ b/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs @@ -424,14 +424,14 @@ mod tests { fn test_test_indexer_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); app.is_loading = is_ready; - app.data.radarr_data.indexer_test_error = Some("test result".to_owned()); + app.data.radarr_data.indexer_test_errors = Some("test result".to_owned()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::TestIndexer.into()); IndexersHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::TestIndexer, None).handle(); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into()); - assert_eq!(app.data.radarr_data.indexer_test_error, None); + assert_eq!(app.data.radarr_data.indexer_test_errors, None); } #[rstest] diff --git a/src/handlers/radarr_handlers/indexers/mod.rs b/src/handlers/radarr_handlers/indexers/mod.rs index 5fe6502..e239fc5 100644 --- a/src/handlers/radarr_handlers/indexers/mod.rs +++ b/src/handlers/radarr_handlers/indexers/mod.rs @@ -154,7 +154,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a, } ActiveRadarrBlock::TestIndexer => { self.app.pop_navigation_stack(); - self.app.data.radarr_data.indexer_test_error = None; + self.app.data.radarr_data.indexer_test_errors = None; } _ => handle_clear_errors(self.app), } diff --git a/src/handlers/radarr_handlers/radarr_handler_test_utils.rs b/src/handlers/radarr_handlers/radarr_handler_test_utils.rs index 849202f..b56730e 100644 --- a/src/handlers/radarr_handlers/radarr_handler_test_utils.rs +++ b/src/handlers/radarr_handlers/radarr_handler_test_utils.rs @@ -141,7 +141,7 @@ mod utils { assert_eq!( app.get_current_route(), - (ActiveRadarrBlock::EditCollectionPrompt, Some($context)).into() + (ActiveRadarrBlock::EditCollectionPrompt, $context).into() ); assert_eq!( app.data.radarr_data.selected_block.get_active_block(), diff --git a/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs b/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs index c21199f..826927e 100644 --- a/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs +++ b/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs @@ -432,14 +432,14 @@ mod tests { fn test_test_indexer_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); app.is_loading = is_ready; - app.data.sonarr_data.indexer_test_error = Some("test result".to_owned()); + app.data.sonarr_data.indexer_test_errors = Some("test result".to_owned()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::TestIndexer.into()); IndexersHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::TestIndexer, None).handle(); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Indexers.into()); - assert_eq!(app.data.sonarr_data.indexer_test_error, None); + assert_eq!(app.data.sonarr_data.indexer_test_errors, None); } #[rstest] diff --git a/src/handlers/sonarr_handlers/indexers/mod.rs b/src/handlers/sonarr_handlers/indexers/mod.rs index 6a5329b..78baf98 100644 --- a/src/handlers/sonarr_handlers/indexers/mod.rs +++ b/src/handlers/sonarr_handlers/indexers/mod.rs @@ -154,7 +154,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for IndexersHandler<'a, } ActiveSonarrBlock::TestIndexer => { self.app.pop_navigation_stack(); - self.app.data.sonarr_data.indexer_test_error = None; + self.app.data.sonarr_data.indexer_test_errors = None; } _ => handle_clear_errors(self.app), } diff --git a/src/handlers/table_handler.rs b/src/handlers/table_handler.rs index bd20cff..5a144ee 100644 --- a/src/handlers/table_handler.rs +++ b/src/handlers/table_handler.rs @@ -59,9 +59,12 @@ macro_rules! handle_table_events { { $self.[]() } - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.filter.key => $self.[](props), - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.search.key => $self.[](props), - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.sort.key => $self.[](props), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.filter.key + && props.filtering_block.is_some() => $self.[](props), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.search.key + && props.searching_block.is_some() => $self.[](props), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.sort.key + && props.sorting_block.is_some() => $self.[](props), _ => false, } } else { diff --git a/src/models/servarr_data/radarr/radarr_data.rs b/src/models/servarr_data/radarr/radarr_data.rs index 236b122..d5ae110 100644 --- a/src/models/servarr_data/radarr/radarr_data.rs +++ b/src/models/servarr_data/radarr/radarr_data.rs @@ -62,7 +62,7 @@ pub struct RadarrData<'a> { pub edit_indexer_modal: Option, pub edit_root_folder: Option, pub indexer_settings: Option, - pub indexer_test_error: Option, + pub indexer_test_errors: Option, pub indexer_test_all_results: Option>, pub movie_details_modal: Option, pub prompt_confirm: bool, @@ -112,7 +112,7 @@ impl<'a> Default for RadarrData<'a> { edit_indexer_modal: None, edit_root_folder: None, indexer_settings: None, - indexer_test_error: None, + indexer_test_errors: None, indexer_test_all_results: None, movie_details_modal: None, prompt_confirm: false, diff --git a/src/models/servarr_data/radarr/radarr_data_tests.rs b/src/models/servarr_data/radarr/radarr_data_tests.rs index 4222f59..04590c9 100644 --- a/src/models/servarr_data/radarr/radarr_data_tests.rs +++ b/src/models/servarr_data/radarr/radarr_data_tests.rs @@ -92,7 +92,7 @@ mod tests { assert!(radarr_data.edit_root_folder.is_none()); assert!(radarr_data.edit_indexer_modal.is_none()); assert!(radarr_data.indexer_settings.is_none()); - assert!(radarr_data.indexer_test_error.is_none()); + assert!(radarr_data.indexer_test_errors.is_none()); assert!(radarr_data.indexer_test_all_results.is_none()); assert!(radarr_data.movie_details_modal.is_none()); assert!(radarr_data.prompt_confirm_action.is_none()); diff --git a/src/models/servarr_data/sonarr/sonarr_data.rs b/src/models/servarr_data/sonarr/sonarr_data.rs index 1b5bcd2..21a2a8a 100644 --- a/src/models/servarr_data/sonarr/sonarr_data.rs +++ b/src/models/servarr_data/sonarr/sonarr_data.rs @@ -53,7 +53,7 @@ pub struct SonarrData<'a> { pub indexers: StatefulTable, pub indexer_settings: Option, pub indexer_test_all_results: Option>, - pub indexer_test_error: Option, + pub indexer_test_errors: Option, pub language_profiles_map: BiMap, pub logs: StatefulList, pub log_details: StatefulList, @@ -106,7 +106,7 @@ impl<'a> Default for SonarrData<'a> { history: StatefulTable::default(), indexers: StatefulTable::default(), indexer_settings: None, - indexer_test_error: None, + indexer_test_errors: None, indexer_test_all_results: None, language_profiles_map: BiMap::new(), logs: StatefulList::default(), diff --git a/src/models/servarr_data/sonarr/sonarr_data_tests.rs b/src/models/servarr_data/sonarr/sonarr_data_tests.rs index 5f65129..3e69b23 100644 --- a/src/models/servarr_data/sonarr/sonarr_data_tests.rs +++ b/src/models/servarr_data/sonarr/sonarr_data_tests.rs @@ -95,7 +95,7 @@ mod tests { assert!(sonarr_data.history.is_empty()); assert!(sonarr_data.indexers.is_empty()); assert!(sonarr_data.indexer_settings.is_none()); - assert!(sonarr_data.indexer_test_error.is_none()); + assert!(sonarr_data.indexer_test_errors.is_none()); assert!(sonarr_data.indexer_test_all_results.is_none()); assert!(sonarr_data.language_profiles_map.is_empty()); assert!(sonarr_data.logs.is_empty()); diff --git a/src/network/radarr_network.rs b/src/network/radarr_network.rs index 66be974..bd074b6 100644 --- a/src/network/radarr_network.rs +++ b/src/network/radarr_network.rs @@ -2102,12 +2102,16 @@ impl<'a, 'b> Network<'a, 'b> { self .handle_request::(request_props, |test_results, mut app| { if test_results.as_object().is_none() { - app.data.radarr_data.indexer_test_error = Some( - test_results.as_array().unwrap()[0] + app.data.radarr_data.indexer_test_errors = Some( + test_results + .as_array() + .unwrap()[0] .get("errorMessage") .unwrap() - .to_string(), + .to_string() ); + } else { + app.data.radarr_data.indexer_test_errors = Some(String::new()); }; }) .await diff --git a/src/network/radarr_network_tests.rs b/src/network/radarr_network_tests.rs index e3d3dd8..a8cf90f 100644 --- a/src/network/radarr_network_tests.rs +++ b/src/network/radarr_network_tests.rs @@ -931,7 +931,7 @@ mod test { async_details_server.assert_async().await; async_test_server.assert_async().await; assert_eq!( - app_arc.lock().await.data.radarr_data.indexer_test_error, + app_arc.lock().await.data.radarr_data.indexer_test_errors, Some("\"test failure\"".to_owned()) ); assert_eq!(value, response_json) @@ -1000,8 +1000,8 @@ mod test { async_details_server.assert_async().await; async_test_server.assert_async().await; assert_eq!( - app_arc.lock().await.data.radarr_data.indexer_test_error, - None + app_arc.lock().await.data.radarr_data.indexer_test_errors, + Some(String::new()) ); assert_eq!(value, json!({})); } diff --git a/src/network/sonarr_network.rs b/src/network/sonarr_network.rs index 2c8ad65..614b53c 100644 --- a/src/network/sonarr_network.rs +++ b/src/network/sonarr_network.rs @@ -2368,12 +2368,14 @@ impl<'a, 'b> Network<'a, 'b> { self .handle_request::(request_props, |test_results, mut app| { if test_results.as_object().is_none() { - app.data.sonarr_data.indexer_test_error = Some( + app.data.sonarr_data.indexer_test_errors = Some( test_results.as_array().unwrap()[0] .get("errorMessage") .unwrap() .to_string(), ); + } else { + app.data.sonarr_data.indexer_test_errors = Some(String::new()); }; }) .await diff --git a/src/network/sonarr_network_tests.rs b/src/network/sonarr_network_tests.rs index b87ebda..40f14e7 100644 --- a/src/network/sonarr_network_tests.rs +++ b/src/network/sonarr_network_tests.rs @@ -6302,7 +6302,7 @@ mod test { async_details_server.assert_async().await; async_test_server.assert_async().await; assert_eq!( - app_arc.lock().await.data.sonarr_data.indexer_test_error, + app_arc.lock().await.data.sonarr_data.indexer_test_errors, Some("\"test failure\"".to_owned()) ); assert_eq!(value, response_json) @@ -6371,8 +6371,8 @@ mod test { async_details_server.assert_async().await; async_test_server.assert_async().await; assert_eq!( - app_arc.lock().await.data.sonarr_data.indexer_test_error, - None + app_arc.lock().await.data.sonarr_data.indexer_test_errors, + Some(String::new()) ); assert_eq!(value, json!({})); } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index a91ae29..0459c86 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -128,39 +128,6 @@ pub fn draw_popup( popup_fn(f, app, popup_area); } -fn draw_popup_ui(f: &mut Frame<'_>, app: &mut App<'_>, size: Size) { - let (percent_x, percent_y) = size.to_percent(); - let popup_area = centered_rect(percent_x, percent_y, f.area()); - f.render_widget(Clear, popup_area); - f.render_widget(background_block(), popup_area); - T::draw(f, app, popup_area); -} - -pub fn draw_popup_over( - f: &mut Frame<'_>, - app: &mut App<'_>, - area: Rect, - background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - popup_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - size: Size, -) { - background_fn(f, app, area); - - draw_popup(f, app, popup_fn, size); -} - -pub fn draw_popup_over_ui( - f: &mut Frame<'_>, - app: &mut App<'_>, - area: Rect, - background_fn: impl Fn(&mut Frame<'_>, &mut App<'_>, Rect), - size: Size, -) { - background_fn(f, app, area); - - draw_popup_ui::(f, app, size); -} - fn draw_tabs(f: &mut Frame<'_>, area: Rect, title: &str, tab_state: &TabState) -> Rect { if title.is_empty() { f.render_widget(layout_block(), area); diff --git a/src/ui/radarr_ui/blocklist/mod.rs b/src/ui/radarr_ui/blocklist/mod.rs index 65bf10f..28165d8 100644 --- a/src/ui/radarr_ui/blocklist/mod.rs +++ b/src/ui/radarr_ui/blocklist/mod.rs @@ -32,12 +32,10 @@ impl DrawUi for BlocklistUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Radarr(active_radarr_block, _) = app.get_current_route() { + draw_blocklist_table(f, app, area); + match active_radarr_block { - ActiveRadarrBlock::Blocklist | ActiveRadarrBlock::BlocklistSortPrompt => { - draw_blocklist_table(f, app, area) - } ActiveRadarrBlock::BlocklistItemDetails => { - draw_blocklist_table(f, app, area); draw_blocklist_item_details_popup(f, app); } ActiveRadarrBlock::DeleteBlocklistItemPrompt => { @@ -55,7 +53,6 @@ impl DrawUi for BlocklistUi { .prompt(&prompt) .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_blocklist_table(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), @@ -67,7 +64,6 @@ impl DrawUi for BlocklistUi { .prompt("Do you want to clear your blocklist?") .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_blocklist_table(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::SmallPrompt), f.area(), diff --git a/src/ui/radarr_ui/collections/collection_details_ui.rs b/src/ui/radarr_ui/collections/collection_details_ui.rs index a19e6fd..5f5f3e1 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui.rs @@ -12,7 +12,6 @@ use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, }; use crate::models::{EnumDisplayStyle, Route}; -use crate::ui::radarr_ui::collections::draw_collections; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{ borderless_block, get_width_from_percentage, layout_block_top_border_with_title, title_block, @@ -20,7 +19,7 @@ use crate::ui::utils::{ }; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::Size; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use crate::utils::convert_runtime; #[cfg(test)] @@ -31,41 +30,25 @@ pub(super) struct CollectionDetailsUi; impl DrawUi for CollectionDetailsUi { fn accepts(route: Route) -> bool { - if let Route::Radarr(active_radarr_block, _) = route { + if let Route::Radarr(active_radarr_block, context_option) = route { + if let Some(context) = context_option { + return COLLECTION_DETAILS_BLOCKS.contains(&active_radarr_block) + && context == ActiveRadarrBlock::CollectionDetails; + } + return COLLECTION_DETAILS_BLOCKS.contains(&active_radarr_block); } false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Radarr(active_radarr_block, context_option) = app.get_current_route() { - let draw_collection_details_popup = - |f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| match context_option - .unwrap_or(active_radarr_block) - { - ActiveRadarrBlock::ViewMovieOverview => { - draw_popup_over( - f, - app, - popup_area, - draw_collection_details, - draw_movie_overview, - Size::Small, - ); - } - ActiveRadarrBlock::CollectionDetails => draw_collection_details(f, app, popup_area), - _ => (), - }; + draw_popup(f, app, draw_collection_details, Size::Large); - draw_popup_over( - f, - app, - area, - draw_collections, - draw_collection_details_popup, - Size::Large, - ); + if context_option.unwrap_or(active_radarr_block) == ActiveRadarrBlock::ViewMovieOverview { + draw_popup(f, app, draw_movie_overview, Size::Small); + } } } } 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 440fdf8..30f721b 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui_tests.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui_tests.rs @@ -17,5 +17,7 @@ mod tests { assert!(!CollectionDetailsUi::accepts(active_radarr_block.into())); } }); + + assert!(CollectionDetailsUi::accepts((ActiveRadarrBlock::CollectionDetails, Some(ActiveRadarrBlock::CollectionDetails)).into())); } } diff --git a/src/ui/radarr_ui/collections/edit_collection_ui.rs b/src/ui/radarr_ui/collections/edit_collection_ui.rs index decb857..e2e8197 100644 --- a/src/ui/radarr_ui/collections/edit_collection_ui.rs +++ b/src/ui/radarr_ui/collections/edit_collection_ui.rs @@ -1,9 +1,8 @@ -use std::sync::atomic::Ordering; - use ratatui::layout::{Constraint, Layout, Rect}; use ratatui::text::Text; use ratatui::widgets::{ListItem, Paragraph}; use ratatui::Frame; +use std::sync::atomic::Ordering; use crate::app::context_clues::{build_context_clue_string, CONFIRMATION_PROMPT_CONTEXT_CLUES}; use crate::app::App; @@ -14,7 +13,6 @@ use crate::models::servarr_data::radarr::radarr_data::{ use crate::models::{EnumDisplayStyle, Route}; use crate::render_selectable_input_box; use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi; -use crate::ui::radarr_ui::collections::draw_collections; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{layout_paragraph_borderless, title_block_centered}; use crate::ui::widgets::button::Button; @@ -22,7 +20,7 @@ use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_popup, draw_popup_over, draw_popup_over_ui, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; #[cfg(test)] #[path = "edit_collection_ui_tests.rs"] @@ -32,51 +30,42 @@ pub(super) struct EditCollectionUi; impl DrawUi for EditCollectionUi { fn accepts(route: Route) -> bool { - if let Route::Radarr(active_radarr_block, _) = route { + if let Route::Radarr(active_radarr_block, context_option) = route { + if let Some(context) = context_option { + return EDIT_COLLECTION_BLOCKS.contains(&active_radarr_block) + && context == ActiveRadarrBlock::CollectionDetails; + } + return EDIT_COLLECTION_BLOCKS.contains(&active_radarr_block); } false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Radarr(active_radarr_block, context_option) = app.get_current_route() { - let draw_edit_collection_prompt = - |f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| match active_radarr_block { - ActiveRadarrBlock::EditCollectionSelectMinimumAvailability => { - draw_edit_collection_confirmation_prompt(f, app, prompt_area); - draw_edit_collection_select_minimum_availability_popup(f, app); - } - ActiveRadarrBlock::EditCollectionSelectQualityProfile => { - draw_edit_collection_confirmation_prompt(f, app, prompt_area); - draw_edit_collection_select_quality_profile_popup(f, app); - } - ActiveRadarrBlock::EditCollectionPrompt - | ActiveRadarrBlock::EditCollectionToggleMonitored - | ActiveRadarrBlock::EditCollectionRootFolderPathInput - | ActiveRadarrBlock::EditCollectionToggleSearchOnAdd => { - draw_edit_collection_confirmation_prompt(f, app, prompt_area) - } - _ => (), - }; - if let Some(context) = context_option { - match context { - ActiveRadarrBlock::Collections => draw_popup_over( - f, - app, - area, - draw_collections, - draw_edit_collection_prompt, - Size::Medium, - ), - _ if COLLECTION_DETAILS_BLOCKS.contains(&context) => { - draw_popup_over_ui::(f, app, area, draw_collections, Size::Large); - draw_popup(f, app, draw_edit_collection_prompt, Size::Medium); - } - _ => (), + if COLLECTION_DETAILS_BLOCKS.contains(&context) { + draw_popup(f, app, CollectionDetailsUi::draw, Size::Large); } } + + draw_popup( + f, + app, + draw_edit_collection_confirmation_prompt, + Size::Medium, + ); + + match active_radarr_block { + ActiveRadarrBlock::EditCollectionSelectMinimumAvailability => { + draw_edit_collection_select_minimum_availability_popup(f, app); + } + ActiveRadarrBlock::EditCollectionSelectQualityProfile => { + draw_edit_collection_select_quality_profile_popup(f, app); + } + _ => (), + }; } } } 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 be9fbc4..842737d 100644 --- a/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs +++ b/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs @@ -16,6 +16,8 @@ mod tests { } else { assert!(!EditCollectionUi::accepts(active_radarr_block.into())); } - }) + }); + + assert!(EditCollectionUi::accepts((ActiveRadarrBlock::EditCollectionPrompt, Some(ActiveRadarrBlock::CollectionDetails)).into())); } } diff --git a/src/ui/radarr_ui/collections/mod.rs b/src/ui/radarr_ui/collections/mod.rs index f86b51f..37269f6 100644 --- a/src/ui/radarr_ui/collections/mod.rs +++ b/src/ui/radarr_ui/collections/mod.rs @@ -2,8 +2,6 @@ use ratatui::layout::{Constraint, Rect}; use ratatui::widgets::{Cell, Row}; use ratatui::Frame; -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::radarr_data::{ActiveRadarrBlock, COLLECTIONS_BLOCKS}; @@ -38,37 +36,23 @@ impl DrawUi for CollectionsUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let route = app.get_current_route(); - let mut collections_ui_matcher = |active_radarr_block| match active_radarr_block { - ActiveRadarrBlock::Collections - | ActiveRadarrBlock::CollectionsSortPrompt - | ActiveRadarrBlock::SearchCollection - | ActiveRadarrBlock::SearchCollectionError - | ActiveRadarrBlock::FilterCollections - | ActiveRadarrBlock::FilterCollectionsError => draw_collections(f, app, area), - ActiveRadarrBlock::UpdateAllCollectionsPrompt => { + draw_collections(f, app, area); + + match route { + _ if CollectionDetailsUi::accepts(route) => CollectionDetailsUi::draw(f, app, area), + _ if EditCollectionUi::accepts(route) => EditCollectionUi::draw(f, app, area), + Route::Radarr(ActiveRadarrBlock::UpdateAllCollectionsPrompt, _) => { let confirmation_prompt = ConfirmationPrompt::new() .title("Update All Collections") .prompt("Do you want to update all of your collections?") .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_collections(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), ); } _ => (), - }; - - match route { - _ if CollectionDetailsUi::accepts(route) => CollectionDetailsUi::draw(f, app, area), - _ if EditCollectionUi::accepts(route) => EditCollectionUi::draw(f, app, area), - Route::Radarr(active_radarr_block, _) - if COLLECTIONS_BLOCKS.contains(&active_radarr_block) => - { - collections_ui_matcher(active_radarr_block) - } - _ => (), } } } @@ -123,7 +107,11 @@ pub(super) fn draw_collections(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) .primary() }; let collections_table = ManagarrTable::new(content, collection_row_mapping) - .loading(app.is_loading) + .loading( + app.is_loading + || app.data.radarr_data.movies.is_empty() + || app.data.radarr_data.quality_profile_map.is_empty(), + ) .footer(collections_table_footer) .block(layout_block_top_border()) .sorting(active_radarr_block == ActiveRadarrBlock::CollectionsSortPrompt) diff --git a/src/ui/radarr_ui/downloads/mod.rs b/src/ui/radarr_ui/downloads/mod.rs index da8724b..48ab433 100644 --- a/src/ui/radarr_ui/downloads/mod.rs +++ b/src/ui/radarr_ui/downloads/mod.rs @@ -31,8 +31,9 @@ impl DrawUi for DownloadsUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Radarr(active_radarr_block, _) = app.get_current_route() { + draw_downloads(f, app, area); + match active_radarr_block { - ActiveRadarrBlock::Downloads => draw_downloads(f, app, area), ActiveRadarrBlock::DeleteDownloadPrompt => { let prompt = format!( "Do you really want to delete this download: \n{}?", @@ -43,7 +44,6 @@ impl DrawUi for DownloadsUi { .prompt(&prompt) .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_downloads(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), @@ -55,7 +55,6 @@ impl DrawUi for DownloadsUi { .prompt("Do you want to update your downloads?") .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_downloads(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), diff --git a/src/ui/radarr_ui/indexers/edit_indexer_ui.rs b/src/ui/radarr_ui/indexers/edit_indexer_ui.rs index d118a32..dc50d5e 100644 --- a/src/ui/radarr_ui/indexers/edit_indexer_ui.rs +++ b/src/ui/radarr_ui/indexers/edit_indexer_ui.rs @@ -5,7 +5,6 @@ use crate::app::App; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS}; use crate::models::Route; use crate::render_selectable_input_box; -use crate::ui::radarr_ui::indexers::draw_indexers; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::title_block_centered; use crate::ui::widgets::button::Button; @@ -13,7 +12,7 @@ use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::popup::Size; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use ratatui::layout::{Constraint, Flex, Layout, Rect}; use ratatui::text::Text; use ratatui::widgets::Paragraph; @@ -34,12 +33,10 @@ impl DrawUi for EditIndexerUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { - draw_popup_over( + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup( f, app, - area, - draw_indexers, draw_edit_indexer_prompt, Size::WideLargePrompt, ); diff --git a/src/ui/radarr_ui/indexers/indexer_settings_ui.rs b/src/ui/radarr_ui/indexers/indexer_settings_ui.rs index 642efde..3dd1972 100644 --- a/src/ui/radarr_ui/indexers/indexer_settings_ui.rs +++ b/src/ui/radarr_ui/indexers/indexer_settings_ui.rs @@ -12,7 +12,6 @@ use crate::models::servarr_data::radarr::radarr_data::{ }; use crate::models::Route; use crate::render_selectable_input_box; -use crate::ui::radarr_ui::indexers::draw_indexers; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::title_block_centered; use crate::ui::widgets::button::Button; @@ -20,7 +19,7 @@ use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::popup::Size; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; #[cfg(test)] #[path = "indexer_settings_ui_tests.rs"] @@ -37,12 +36,10 @@ impl DrawUi for IndexerSettingsUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { - draw_popup_over( + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup( f, app, - area, - draw_indexers, draw_edit_indexer_settings_prompt, Size::WideLargePrompt, ); diff --git a/src/ui/radarr_ui/indexers/mod.rs b/src/ui/radarr_ui/indexers/mod.rs index 9b1cbbf..63aaa81 100644 --- a/src/ui/radarr_ui/indexers/mod.rs +++ b/src/ui/radarr_ui/indexers/mod.rs @@ -44,63 +44,62 @@ impl DrawUi for IndexersUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let route = app.get_current_route(); - let mut indexers_matchers = |active_radarr_block| match active_radarr_block { - ActiveRadarrBlock::Indexers => draw_indexers(f, app, area), - ActiveRadarrBlock::TestIndexer => { - draw_indexers(f, app, area); - if app.is_loading { - let loading_popup = Popup::new(LoadingBlock::new( - app.is_loading, - title_block("Testing Indexer"), - )) - .size(Size::LargeMessage); - f.render_widget(loading_popup, f.area()); - } else { - let popup = if let Some(result) = app.data.radarr_data.indexer_test_error.as_ref() { - Popup::new(Message::new(result.clone())).size(Size::LargeMessage) - } else { - let message = Message::new("Indexer test succeeded!") - .title("Success") - .style(Style::new().success().bold()); - Popup::new(message).size(Size::Message) - }; - - f.render_widget(popup, f.area()); - } - } - ActiveRadarrBlock::DeleteIndexerPrompt => { - let prompt = format!( - "Do you really want to delete this indexer: \n{}?", - app - .data - .radarr_data - .indexers - .current_selection() - .name - .clone() - .unwrap_or_default() - ); - let confirmation_prompt = ConfirmationPrompt::new() - .title("Delete Indexer") - .prompt(&prompt) - .yes_no_value(app.data.radarr_data.prompt_confirm); - - draw_indexers(f, app, area); - f.render_widget( - Popup::new(confirmation_prompt).size(Size::MediumPrompt), - f.area(), - ); - } - _ => (), - }; + draw_indexers(f, app, area); match route { _ if EditIndexerUi::accepts(route) => EditIndexerUi::draw(f, app, area), _ if IndexerSettingsUi::accepts(route) => IndexerSettingsUi::draw(f, app, area), _ if TestAllIndexersUi::accepts(route) => TestAllIndexersUi::draw(f, app, area), - Route::Radarr(active_radarr_block, _) if INDEXERS_BLOCKS.contains(&active_radarr_block) => { - indexers_matchers(active_radarr_block) - } + Route::Radarr(active_radarr_block, _) => match active_radarr_block { + ActiveRadarrBlock::TestIndexer => { + if app.is_loading || app.data.radarr_data.indexer_test_errors.is_none() { + let loading_popup = Popup::new(LoadingBlock::new( + app.is_loading || app.data.radarr_data.indexer_test_errors.is_none(), + title_block("Testing Indexer"), + )) + .size(Size::LargeMessage); + f.render_widget(loading_popup, f.area()); + } else { + let popup = { + let result = app.data.radarr_data.indexer_test_errors.as_ref().expect("Test result is unpopulated"); + + if !result.is_empty() { + Popup::new(Message::new(result.clone())).size(Size::LargeMessage) + } else { + let message = Message::new("Indexer test succeeded!") + .title("Success") + .style(Style::new().success().bold()); + Popup::new(message).size(Size::Message) + } + }; + + f.render_widget(popup, f.area()); + } + } + ActiveRadarrBlock::DeleteIndexerPrompt => { + let prompt = format!( + "Do you really want to delete this indexer: \n{}?", + app + .data + .radarr_data + .indexers + .current_selection() + .name + .clone() + .unwrap_or_default() + ); + let confirmation_prompt = ConfirmationPrompt::new() + .title("Delete Indexer") + .prompt(&prompt) + .yes_no_value(app.data.radarr_data.prompt_confirm); + + f.render_widget( + Popup::new(confirmation_prompt).size(Size::MediumPrompt), + f.area(), + ); + } + _ => (), + }, _ => (), } } diff --git a/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs b/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs index 1b36a45..f7adc0d 100644 --- a/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs +++ b/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs @@ -3,12 +3,11 @@ use crate::app::App; use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::Route; -use crate::ui::radarr_ui::indexers::draw_indexers; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{borderless_block, get_width_from_percentage, title_block}; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::Size; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use ratatui::layout::{Alignment, Constraint, Rect}; use ratatui::widgets::{Cell, Row}; use ratatui::Frame; @@ -28,26 +27,22 @@ impl DrawUi for TestAllIndexersUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { - draw_popup_over( - f, - app, - area, - draw_indexers, - draw_test_all_indexers_test_results, - Size::Large, - ); + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup(f, app, draw_test_all_indexers_test_results, Size::Large); } } fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + let is_loading = app.is_loading || app.data.radarr_data.indexer_test_all_results.is_none(); + let block = title_block("Test All Indexers"); + let current_selection = if let Some(test_all_results) = app.data.radarr_data.indexer_test_all_results.as_ref() { test_all_results.current_selection().clone() } else { IndexerTestResultModalItem::default() }; - f.render_widget(title_block("Test All Indexers"), area); + f.render_widget(block, area); let help_footer = format!( "<↑↓> scroll | {}", build_context_clue_string(&BARE_POPUP_CONTEXT_CLUES) @@ -77,7 +72,7 @@ fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, are test_results_row_mapping, ) .block(borderless_block()) - .loading(app.is_loading) + .loading(is_loading) .footer(Some(help_footer)) .footer_alignment(Alignment::Center) .margin(1) diff --git a/src/ui/radarr_ui/library/add_movie_ui.rs b/src/ui/radarr_ui/library/add_movie_ui.rs index 11cd8a4..1070b16 100644 --- a/src/ui/radarr_ui/library/add_movie_ui.rs +++ b/src/ui/radarr_ui/library/add_movie_ui.rs @@ -13,8 +13,6 @@ use crate::models::radarr_models::AddMovieSearchResult; use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; use crate::models::{EnumDisplayStyle, Route}; -use crate::ui::radarr_ui::collections::{draw_collection_details, draw_collections}; -use crate::ui::radarr_ui::library::draw_library; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{ borderless_block, get_width_from_percentage, layout_block, layout_paragraph_borderless, @@ -26,9 +24,10 @@ use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::message::Message; use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use crate::utils::convert_runtime; use crate::{render_selectable_input_box, App}; +use crate::ui::radarr_ui::collections::CollectionsUi; #[cfg(test)] #[path = "add_movie_ui_tests.rs"] @@ -47,72 +46,34 @@ impl DrawUi for AddMovieUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Radarr(active_radarr_block, context_option) = app.get_current_route() { - let draw_add_movie_search_popup = - |f: &mut Frame<'_>, app: &mut App<'_>, area: Rect| match active_radarr_block { - ActiveRadarrBlock::AddMovieSearchInput - | ActiveRadarrBlock::AddMovieSearchResults - | ActiveRadarrBlock::AddMovieEmptySearchResults => { - draw_add_movie_search(f, app, area); - } + if context_option.is_some() { + CollectionsUi::draw(f, app, area); + draw_popup(f, app, draw_confirmation_popup, Size::Medium); + } else { + draw_popup(f, app, draw_add_movie_search, Size::Large); + + match active_radarr_block { ActiveRadarrBlock::AddMoviePrompt | ActiveRadarrBlock::AddMovieSelectMonitor | ActiveRadarrBlock::AddMovieSelectMinimumAvailability | ActiveRadarrBlock::AddMovieSelectQualityProfile | ActiveRadarrBlock::AddMovieSelectRootFolder | ActiveRadarrBlock::AddMovieTagsInput => { - if context_option.is_some() { - draw_popup_over( + draw_popup( f, app, - area, - draw_collection_details, draw_confirmation_popup, Size::Medium, ); - } else { - draw_popup_over( - f, - app, - area, - draw_add_movie_search, - draw_confirmation_popup, - Size::Medium, - ); - } } ActiveRadarrBlock::AddMovieAlreadyInLibrary => { - draw_add_movie_search(f, app, area); f.render_widget( Popup::new(Message::new("This film is already in your library")).size(Size::Message), f.area(), ); } _ => (), - }; - - match active_radarr_block { - _ if ADD_MOVIE_BLOCKS.contains(&active_radarr_block) => { - if context_option.is_some() { - draw_popup_over( - f, - app, - area, - draw_collections, - draw_add_movie_search_popup, - Size::Large, - ) - } else { - draw_popup_over( - f, - app, - area, - draw_library, - draw_add_movie_search_popup, - Size::Large, - ) - } } - _ => (), } } } @@ -285,26 +246,21 @@ fn draw_add_movie_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { fn draw_confirmation_popup(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Radarr(active_radarr_block, _) = app.get_current_route() { + draw_confirmation_prompt(f, app, area); + match active_radarr_block { ActiveRadarrBlock::AddMovieSelectMonitor => { - draw_confirmation_prompt(f, app, area); draw_add_movie_select_monitor_popup(f, app); } ActiveRadarrBlock::AddMovieSelectMinimumAvailability => { - draw_confirmation_prompt(f, app, area); draw_add_movie_select_minimum_availability_popup(f, app); } ActiveRadarrBlock::AddMovieSelectQualityProfile => { - draw_confirmation_prompt(f, app, area); draw_add_movie_select_quality_profile_popup(f, app); } ActiveRadarrBlock::AddMovieSelectRootFolder => { - draw_confirmation_prompt(f, app, area); draw_add_movie_select_root_folder_popup(f, app); } - ActiveRadarrBlock::AddMoviePrompt | ActiveRadarrBlock::AddMovieTagsInput => { - draw_confirmation_prompt(f, app, area) - } _ => (), } } diff --git a/src/ui/radarr_ui/library/delete_movie_ui.rs b/src/ui/radarr_ui/library/delete_movie_ui.rs index c5d1090..9a338da 100644 --- a/src/ui/radarr_ui/library/delete_movie_ui.rs +++ b/src/ui/radarr_ui/library/delete_movie_ui.rs @@ -4,7 +4,6 @@ use ratatui::Frame; use crate::app::App; 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::widgets::checkbox::Checkbox; use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt; use crate::ui::widgets::popup::{Popup, Size}; @@ -25,7 +24,7 @@ impl DrawUi for DeleteMovieUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if matches!( app.get_current_route(), Route::Radarr(ActiveRadarrBlock::DeleteMoviePrompt, _) @@ -50,7 +49,6 @@ impl DrawUi for DeleteMovieUi { .yes_no_highlighted(selected_block == ActiveRadarrBlock::DeleteMovieConfirmPrompt) .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_library(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), diff --git a/src/ui/radarr_ui/library/edit_movie_ui.rs b/src/ui/radarr_ui/library/edit_movie_ui.rs index 972fffe..f9458e8 100644 --- a/src/ui/radarr_ui/library/edit_movie_ui.rs +++ b/src/ui/radarr_ui/library/edit_movie_ui.rs @@ -14,7 +14,6 @@ use crate::models::servarr_data::radarr::radarr_data::{ }; use crate::models::{EnumDisplayStyle, Route}; use crate::render_selectable_input_box; -use crate::ui::radarr_ui::library::draw_library; use crate::ui::radarr_ui::library::movie_details_ui::MovieDetailsUi; use crate::ui::styles::ManagarrStyle; @@ -24,7 +23,7 @@ use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_popup, draw_popup_over, draw_popup_over_ui, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; #[cfg(test)] #[path = "edit_movie_ui_tests.rs"] @@ -41,46 +40,25 @@ impl DrawUi for EditMovieUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Radarr(active_radarr_block, context_option) = app.get_current_route() { - let draw_edit_movie_prompt = - |f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| match active_radarr_block { - ActiveRadarrBlock::EditMovieSelectMinimumAvailability => { - draw_edit_movie_confirmation_prompt(f, app, prompt_area); - draw_edit_movie_select_minimum_availability_popup(f, app); - } - ActiveRadarrBlock::EditMovieSelectQualityProfile => { - draw_edit_movie_confirmation_prompt(f, app, prompt_area); - draw_edit_movie_select_quality_profile_popup(f, app); - } - ActiveRadarrBlock::EditMoviePrompt - | ActiveRadarrBlock::EditMovieToggleMonitored - | ActiveRadarrBlock::EditMoviePathInput - | ActiveRadarrBlock::EditMovieTagsInput => { - draw_edit_movie_confirmation_prompt(f, app, prompt_area) - } - _ => (), - }; - if let Some(context) = context_option { - match context { - ActiveRadarrBlock::Movies => { - draw_popup_over( - f, - app, - area, - draw_library, - draw_edit_movie_prompt, - Size::Medium, - ); - } - _ if MOVIE_DETAILS_BLOCKS.contains(&context) => { - draw_popup_over_ui::(f, app, area, draw_library, Size::Large); - draw_popup(f, app, draw_edit_movie_prompt, Size::Medium); - } - _ => (), + if MOVIE_DETAILS_BLOCKS.contains(&context) { + draw_popup(f, app, MovieDetailsUi::draw, Size::Large); } } + + draw_popup(f, app, draw_edit_movie_confirmation_prompt, Size::Medium); + + match active_radarr_block { + ActiveRadarrBlock::EditMovieSelectMinimumAvailability => { + draw_edit_movie_select_minimum_availability_popup(f, app); + } + ActiveRadarrBlock::EditMovieSelectQualityProfile => { + draw_edit_movie_select_quality_profile_popup(f, app); + } + _ => (), + } } } } diff --git a/src/ui/radarr_ui/library/mod.rs b/src/ui/radarr_ui/library/mod.rs index 760f31b..3ed8db2 100644 --- a/src/ui/radarr_ui/library/mod.rs +++ b/src/ui/radarr_ui/library/mod.rs @@ -44,43 +44,32 @@ impl DrawUi for LibraryUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let route = app.get_current_route(); - let mut library_ui_matchers = |active_radarr_block: ActiveRadarrBlock| match active_radarr_block - { - ActiveRadarrBlock::Movies - | ActiveRadarrBlock::MoviesSortPrompt - | ActiveRadarrBlock::SearchMovie - | ActiveRadarrBlock::SearchMovieError - | ActiveRadarrBlock::FilterMovies - | ActiveRadarrBlock::FilterMoviesError => draw_library(f, app, area), - ActiveRadarrBlock::UpdateAllMoviesPrompt => { + if !matches!(route, Route::Radarr(_, Some(_))) { + draw_library(f, app, area); + } + + match route { + _ if MovieDetailsUi::accepts(route) => MovieDetailsUi::draw(f, app, area), + _ if AddMovieUi::accepts(route) => AddMovieUi::draw(f, app, area), + _ if EditMovieUi::accepts(route) => EditMovieUi::draw(f, app, area), + _ if DeleteMovieUi::accepts(route) => DeleteMovieUi::draw(f, app, area), + Route::Radarr(ActiveRadarrBlock::UpdateAllMoviesPrompt, _) => { let confirmation_prompt = ConfirmationPrompt::new() .title("Update All Movies") .prompt("Do you want to update info and scan your disks for all of your movies?") .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_library(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), ); } _ => (), - }; - - match route { - _ if MovieDetailsUi::accepts(route) => MovieDetailsUi::draw(f, app, area), - _ if AddMovieUi::accepts(route) => AddMovieUi::draw(f, app, area), - _ if EditMovieUi::accepts(route) => EditMovieUi::draw(f, app, area), - _ if DeleteMovieUi::accepts(route) => DeleteMovieUi::draw(f, app, area), - Route::Radarr(active_radarr_block, _) if LIBRARY_BLOCKS.contains(&active_radarr_block) => { - library_ui_matchers(active_radarr_block) - } - _ => (), } } } -pub(super) fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { +fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Radarr(active_radarr_block, _) = app.get_current_route() { let current_selection = if !app.data.radarr_data.movies.items.is_empty() { app.data.radarr_data.movies.current_selection().clone() diff --git a/src/ui/radarr_ui/library/movie_details_ui.rs b/src/ui/radarr_ui/library/movie_details_ui.rs index 7cfe147..74eff7e 100644 --- a/src/ui/radarr_ui/library/movie_details_ui.rs +++ b/src/ui/radarr_ui/library/movie_details_ui.rs @@ -11,14 +11,13 @@ use crate::models::radarr_models::{Credit, MovieHistoryItem, RadarrRelease}; use crate::models::servarr_data::radarr::modals::MovieDetailsModal; 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::styles::ManagarrStyle; use crate::ui::utils::{borderless_block, decorate_peer_style, get_width_from_percentage, layout_block_bottom_border, layout_block_top_border}; use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt; use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::{Popup, Size}; -use crate::ui::{draw_popup_over, draw_tabs, DrawUi}; +use crate::ui::{draw_popup, draw_tabs, DrawUi}; use crate::utils::convert_to_gb; #[cfg(test)] @@ -36,7 +35,7 @@ impl DrawUi for MovieDetailsUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Radarr(active_radarr_block, context_option) = app.get_current_route() { let draw_movie_info_popup = |f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| { let content_area = draw_tabs( @@ -85,11 +84,9 @@ impl DrawUi for MovieDetailsUi { } }; - draw_popup_over( + draw_popup( f, app, - area, - draw_library, draw_movie_info_popup, Size::Large, ); diff --git a/src/ui/radarr_ui/root_folders/mod.rs b/src/ui/radarr_ui/root_folders/mod.rs index 04a74d0..683570b 100644 --- a/src/ui/radarr_ui/root_folders/mod.rs +++ b/src/ui/radarr_ui/root_folders/mod.rs @@ -11,7 +11,7 @@ use crate::ui::utils::layout_block_top_border; use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::{Popup, Size}; -use crate::ui::{draw_input_box_popup, draw_popup_over, DrawUi}; +use crate::ui::{draw_input_box_popup, draw_popup, DrawUi}; use crate::utils::convert_to_gb; #[cfg(test)] @@ -31,13 +31,12 @@ impl DrawUi for RootFoldersUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Radarr(active_radarr_block, _) = app.get_current_route() { + draw_root_folders(f, app, area); + match active_radarr_block { - ActiveRadarrBlock::RootFolders => draw_root_folders(f, app, area), - ActiveRadarrBlock::AddRootFolderPrompt => draw_popup_over( + ActiveRadarrBlock::AddRootFolderPrompt => draw_popup( f, app, - area, - draw_root_folders, draw_add_root_folder_prompt_box, Size::InputBox, ), @@ -51,7 +50,6 @@ impl DrawUi for RootFoldersUi { .prompt(&prompt) .yes_no_value(app.data.radarr_data.prompt_confirm); - draw_root_folders(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), diff --git a/src/ui/radarr_ui/system/mod.rs b/src/ui/radarr_ui/system/mod.rs index db50e4b..3fbef36 100644 --- a/src/ui/radarr_ui/system/mod.rs +++ b/src/ui/radarr_ui/system/mod.rs @@ -63,18 +63,15 @@ impl DrawUi for SystemUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let route = app.get_current_route(); - - match route { - _ if SystemDetailsUi::accepts(route) => SystemDetailsUi::draw(f, app, area), - _ if matches!(route, Route::Radarr(ActiveRadarrBlock::System, _)) => { - draw_system_ui_layout(f, app, area) - } - _ => (), + draw_system_ui_layout(f, app, area); + + if SystemDetailsUi::accepts(route) { + SystemDetailsUi::draw(f, app, area); } } } -pub(super) fn draw_system_ui_layout(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { +fn draw_system_ui_layout(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let [activities_area, logs_area, help_area] = Layout::vertical([ Constraint::Ratio(1, 2), Constraint::Ratio(1, 2), diff --git a/src/ui/radarr_ui/system/system_details_ui.rs b/src/ui/radarr_ui/system/system_details_ui.rs index 41a5437..7eba677 100644 --- a/src/ui/radarr_ui/system/system_details_ui.rs +++ b/src/ui/radarr_ui/system/system_details_ui.rs @@ -10,7 +10,7 @@ use crate::models::radarr_models::RadarrTask; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; use crate::models::Route; use crate::ui::radarr_ui::system::{ - draw_queued_events, draw_system_ui_layout, extract_task_props, TASK_TABLE_CONSTRAINTS, + draw_queued_events, extract_task_props, TASK_TABLE_CONSTRAINTS, TASK_TABLE_HEADERS, }; use crate::ui::styles::ManagarrStyle; @@ -20,7 +20,7 @@ use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; #[cfg(test)] #[path = "system_details_ui_tests.rs"] @@ -37,33 +37,27 @@ impl DrawUi for SystemDetailsUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Radarr(active_radarr_block, _) = app.get_current_route() { match active_radarr_block { ActiveRadarrBlock::SystemLogs => { - draw_system_ui_layout(f, app, area); draw_logs_popup(f, app); } ActiveRadarrBlock::SystemTasks | ActiveRadarrBlock::SystemTaskStartConfirmPrompt => { - draw_popup_over( + draw_popup( f, app, - area, - draw_system_ui_layout, draw_tasks_popup, Size::Large, ) } - ActiveRadarrBlock::SystemQueuedEvents => draw_popup_over( + ActiveRadarrBlock::SystemQueuedEvents => draw_popup( f, app, - area, - draw_system_ui_layout, draw_queued_events, Size::Medium, ), ActiveRadarrBlock::SystemUpdates => { - draw_system_ui_layout(f, app, area); draw_updates_popup(f, app); } _ => (), diff --git a/src/ui/sonarr_ui/blocklist/mod.rs b/src/ui/sonarr_ui/blocklist/mod.rs index c382007..07f2efb 100644 --- a/src/ui/sonarr_ui/blocklist/mod.rs +++ b/src/ui/sonarr_ui/blocklist/mod.rs @@ -32,12 +32,10 @@ impl DrawUi for BlocklistUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() { + draw_blocklist_table(f, app, area); + match active_sonarr_block { - ActiveSonarrBlock::Blocklist | ActiveSonarrBlock::BlocklistSortPrompt => { - draw_blocklist_table(f, app, area) - } ActiveSonarrBlock::BlocklistItemDetails => { - draw_blocklist_table(f, app, area); draw_blocklist_item_details_popup(f, app); } ActiveSonarrBlock::DeleteBlocklistItemPrompt => { @@ -55,7 +53,6 @@ impl DrawUi for BlocklistUi { .prompt(&prompt) .yes_no_value(app.data.sonarr_data.prompt_confirm); - draw_blocklist_table(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), @@ -67,7 +64,6 @@ impl DrawUi for BlocklistUi { .prompt("Do you want to clear your blocklist?") .yes_no_value(app.data.sonarr_data.prompt_confirm); - draw_blocklist_table(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::SmallPrompt), f.area(), diff --git a/src/ui/sonarr_ui/downloads/mod.rs b/src/ui/sonarr_ui/downloads/mod.rs index d41c913..3ef77a3 100644 --- a/src/ui/sonarr_ui/downloads/mod.rs +++ b/src/ui/sonarr_ui/downloads/mod.rs @@ -31,8 +31,9 @@ impl DrawUi for DownloadsUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() { + draw_downloads(f, app, area); + match active_sonarr_block { - ActiveSonarrBlock::Downloads => draw_downloads(f, app, area), ActiveSonarrBlock::DeleteDownloadPrompt => { let prompt = format!( "Do you really want to delete this download: \n{}?", @@ -43,7 +44,6 @@ impl DrawUi for DownloadsUi { .prompt(&prompt) .yes_no_value(app.data.sonarr_data.prompt_confirm); - draw_downloads(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), @@ -55,7 +55,6 @@ impl DrawUi for DownloadsUi { .prompt("Do you want to update your downloads?") .yes_no_value(app.data.sonarr_data.prompt_confirm); - draw_downloads(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), diff --git a/src/ui/sonarr_ui/history/mod.rs b/src/ui/sonarr_ui/history/mod.rs index 70fe8a2..0ac32d1 100644 --- a/src/ui/sonarr_ui/history/mod.rs +++ b/src/ui/sonarr_ui/history/mod.rs @@ -39,18 +39,10 @@ impl DrawUi for HistoryUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() { - match active_sonarr_block { - ActiveSonarrBlock::History - | ActiveSonarrBlock::HistorySortPrompt - | ActiveSonarrBlock::SearchHistory - | ActiveSonarrBlock::SearchHistoryError - | ActiveSonarrBlock::FilterHistory - | ActiveSonarrBlock::FilterHistoryError => draw_history_table(f, app, area), - ActiveSonarrBlock::HistoryItemDetails => { - draw_history_table(f, app, area); - draw_history_item_details_popup(f, app); - } - _ => (), + draw_history_table(f, app, area); + + if active_sonarr_block == ActiveSonarrBlock::HistoryItemDetails { + draw_history_item_details_popup(f, app); } } } diff --git a/src/ui/sonarr_ui/indexers/edit_indexer_ui.rs b/src/ui/sonarr_ui/indexers/edit_indexer_ui.rs index 038a077..0bf48f1 100644 --- a/src/ui/sonarr_ui/indexers/edit_indexer_ui.rs +++ b/src/ui/sonarr_ui/indexers/edit_indexer_ui.rs @@ -5,7 +5,6 @@ use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS}; use crate::models::Route; use crate::render_selectable_input_box; -use crate::ui::sonarr_ui::indexers::draw_indexers; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::title_block_centered; use crate::ui::widgets::button::Button; @@ -13,7 +12,7 @@ use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::popup::Size; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use ratatui::layout::{Constraint, Flex, Layout, Rect}; use ratatui::text::Text; use ratatui::widgets::Paragraph; @@ -34,12 +33,10 @@ impl DrawUi for EditIndexerUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { - draw_popup_over( + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup( f, app, - area, - draw_indexers, draw_edit_indexer_prompt, Size::WideLargePrompt, ); diff --git a/src/ui/sonarr_ui/indexers/indexer_settings_ui.rs b/src/ui/sonarr_ui/indexers/indexer_settings_ui.rs index 684a15c..9f66133 100644 --- a/src/ui/sonarr_ui/indexers/indexer_settings_ui.rs +++ b/src/ui/sonarr_ui/indexers/indexer_settings_ui.rs @@ -10,14 +10,13 @@ use crate::models::servarr_data::sonarr::sonarr_data::{ }; use crate::models::Route; use crate::render_selectable_input_box; -use crate::ui::sonarr_ui::indexers::draw_indexers; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::title_block_centered; use crate::ui::widgets::button::Button; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::popup::Size; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; #[cfg(test)] #[path = "indexer_settings_ui_tests.rs"] @@ -34,12 +33,10 @@ impl DrawUi for IndexerSettingsUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { - draw_popup_over( + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup( f, app, - area, - draw_indexers, draw_edit_indexer_settings_prompt, Size::LargePrompt, ); diff --git a/src/ui/sonarr_ui/indexers/mod.rs b/src/ui/sonarr_ui/indexers/mod.rs index a560d9a..f5df36e 100644 --- a/src/ui/sonarr_ui/indexers/mod.rs +++ b/src/ui/sonarr_ui/indexers/mod.rs @@ -44,62 +44,61 @@ impl DrawUi for IndexersUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let route = app.get_current_route(); - let mut indexers_matchers = |active_sonarr_block| match active_sonarr_block { - ActiveSonarrBlock::Indexers => draw_indexers(f, app, area), - ActiveSonarrBlock::TestIndexer => { - draw_indexers(f, app, area); - if app.is_loading || app.is_routing { - let loading_popup = Popup::new(LoadingBlock::new( - app.is_loading, - title_block("Testing Indexer"), - )) - .size(Size::LargeMessage); - f.render_widget(loading_popup, f.area()); - } else { - let popup = if let Some(result) = app.data.sonarr_data.indexer_test_error.as_ref() { - Popup::new(Message::new(result.clone())).size(Size::LargeMessage) - } else { - let message = Message::new("Indexer test succeeded!") - .title("Success") - .style(Style::new().success().bold()); - Popup::new(message).size(Size::Message) - }; - - f.render_widget(popup, f.area()); - } - } - ActiveSonarrBlock::DeleteIndexerPrompt => { - let prompt = format!( - "Do you really want to delete this indexer: \n{}?", - app - .data - .sonarr_data - .indexers - .current_selection() - .name - .clone() - .unwrap_or_default() - ); - let confirmation_prompt = ConfirmationPrompt::new() - .title("Delete Indexer") - .prompt(&prompt) - .yes_no_value(app.data.sonarr_data.prompt_confirm); - - draw_indexers(f, app, area); - f.render_widget( - Popup::new(confirmation_prompt).size(Size::MediumPrompt), - f.area(), - ); - } - _ => (), - }; + draw_indexers(f, app, area); match route { _ if EditIndexerUi::accepts(route) => EditIndexerUi::draw(f, app, area), _ if IndexerSettingsUi::accepts(route) => IndexerSettingsUi::draw(f, app, area), _ if TestAllIndexersUi::accepts(route) => TestAllIndexersUi::draw(f, app, area), - Route::Sonarr(active_sonarr_block, _) if INDEXERS_BLOCKS.contains(&active_sonarr_block) => { - indexers_matchers(active_sonarr_block) + Route::Sonarr(active_sonarr_block, _) => match active_sonarr_block { + ActiveSonarrBlock::TestIndexer => { + if app.is_loading || app.data.sonarr_data.indexer_test_errors.is_none() { + let loading_popup = Popup::new(LoadingBlock::new( + app.is_loading || app.data.sonarr_data.indexer_test_errors.is_none(), + title_block("Testing Indexer"), + )) + .size(Size::LargeMessage); + f.render_widget(loading_popup, f.area()); + } else { + let popup = { + let result = app.data.sonarr_data.indexer_test_errors.as_ref().expect("Test result is unpopulated"); + + if !result.is_empty() { + Popup::new(Message::new(result.clone())).size(Size::LargeMessage) + } else { + let message = Message::new("Indexer test succeeded!") + .title("Success") + .style(Style::new().success().bold()); + Popup::new(message).size(Size::Message) + } + }; + + f.render_widget(popup, f.area()); + } + } + ActiveSonarrBlock::DeleteIndexerPrompt => { + let prompt = format!( + "Do you really want to delete this indexer: \n{}?", + app + .data + .sonarr_data + .indexers + .current_selection() + .name + .clone() + .unwrap_or_default() + ); + let confirmation_prompt = ConfirmationPrompt::new() + .title("Delete Indexer") + .prompt(&prompt) + .yes_no_value(app.data.sonarr_data.prompt_confirm); + + f.render_widget( + Popup::new(confirmation_prompt).size(Size::MediumPrompt), + f.area(), + ); + } + _ => (), } _ => (), } diff --git a/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs b/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs index 0962a20..22befdd 100644 --- a/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs +++ b/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs @@ -3,12 +3,11 @@ use crate::app::App; use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock; use crate::models::Route; -use crate::ui::sonarr_ui::indexers::draw_indexers; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{borderless_block, get_width_from_percentage, title_block}; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::Size; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use ratatui::layout::{Alignment, Constraint, Rect}; use ratatui::widgets::{Cell, Row}; use ratatui::Frame; @@ -28,12 +27,10 @@ impl DrawUi for TestAllIndexersUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { - draw_popup_over( + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup( f, app, - area, - draw_indexers, draw_test_all_indexers_test_results, Size::Large, ); @@ -41,6 +38,7 @@ impl DrawUi for TestAllIndexersUi { } fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + let is_loading = app.is_loading || app.data.sonarr_data.indexer_test_all_results.is_none(); let current_selection = if let Some(test_all_results) = app.data.sonarr_data.indexer_test_all_results.as_ref() { test_all_results.current_selection().clone() @@ -77,7 +75,7 @@ fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, are test_results_row_mapping, ) .block(borderless_block()) - .loading(app.is_loading) + .loading(is_loading) .footer(Some(help_footer)) .footer_alignment(Alignment::Center) .margin(1) diff --git a/src/ui/sonarr_ui/library/add_series_ui.rs b/src/ui/sonarr_ui/library/add_series_ui.rs index 0e78792..42b1266 100644 --- a/src/ui/sonarr_ui/library/add_series_ui.rs +++ b/src/ui/sonarr_ui/library/add_series_ui.rs @@ -13,7 +13,6 @@ use crate::models::servarr_data::sonarr::modals::AddSeriesModal; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ADD_SERIES_BLOCKS}; use crate::models::sonarr_models::AddSeriesSearchResult; use crate::models::{EnumDisplayStyle, Route}; -use crate::ui::sonarr_ui::library::draw_library; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{ borderless_block, get_width_from_percentage, layout_block, layout_paragraph_borderless, @@ -26,7 +25,7 @@ use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::message::Message; use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use crate::{render_selectable_input_box, App}; #[cfg(test)] @@ -44,50 +43,26 @@ impl DrawUi for AddSeriesUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() { - let draw_add_series_search_popup = - |f: &mut Frame<'_>, app: &mut App<'_>, area: Rect| match active_sonarr_block { - ActiveSonarrBlock::AddSeriesSearchInput - | ActiveSonarrBlock::AddSeriesSearchResults - | ActiveSonarrBlock::AddSeriesEmptySearchResults => { - draw_add_series_search(f, app, area); - } - ActiveSonarrBlock::AddSeriesPrompt - | ActiveSonarrBlock::AddSeriesSelectMonitor - | ActiveSonarrBlock::AddSeriesSelectSeriesType - | ActiveSonarrBlock::AddSeriesSelectQualityProfile - | ActiveSonarrBlock::AddSeriesSelectLanguageProfile - | ActiveSonarrBlock::AddSeriesSelectRootFolder - | ActiveSonarrBlock::AddSeriesTagsInput => { - draw_popup_over( - f, - app, - area, - draw_add_series_search, - draw_confirmation_popup, - Size::Long, - ); - } - ActiveSonarrBlock::AddSeriesAlreadyInLibrary => { - draw_add_series_search(f, app, area); - f.render_widget( - Popup::new(Message::new("This film is already in your library")).size(Size::Message), - f.area(), - ); - } - _ => (), - }; - + draw_popup(f, app, draw_add_series_search, Size::Large); + match active_sonarr_block { - _ if ADD_SERIES_BLOCKS.contains(&active_sonarr_block) => draw_popup_over( - f, - app, - area, - draw_library, - draw_add_series_search_popup, - Size::Large, - ), + ActiveSonarrBlock::AddSeriesPrompt + | ActiveSonarrBlock::AddSeriesSelectMonitor + | ActiveSonarrBlock::AddSeriesSelectSeriesType + | ActiveSonarrBlock::AddSeriesSelectQualityProfile + | ActiveSonarrBlock::AddSeriesSelectLanguageProfile + | ActiveSonarrBlock::AddSeriesSelectRootFolder + | ActiveSonarrBlock::AddSeriesTagsInput => { + draw_popup(f, app, draw_confirmation_popup, Size::Long); + } + ActiveSonarrBlock::AddSeriesAlreadyInLibrary => { + f.render_widget( + Popup::new(Message::new("This series is already in your library")).size(Size::Message), + f.area(), + ); + } _ => (), } } diff --git a/src/ui/sonarr_ui/library/delete_series_ui.rs b/src/ui/sonarr_ui/library/delete_series_ui.rs index c30c421..13e8ebb 100644 --- a/src/ui/sonarr_ui/library/delete_series_ui.rs +++ b/src/ui/sonarr_ui/library/delete_series_ui.rs @@ -4,7 +4,6 @@ use ratatui::Frame; use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DELETE_SERIES_BLOCKS}; use crate::models::Route; -use crate::ui::sonarr_ui::library::draw_library; use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt; use crate::ui::widgets::popup::{Popup, Size}; @@ -25,14 +24,14 @@ impl DrawUi for DeleteSeriesUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if matches!( app.get_current_route(), Route::Sonarr(ActiveSonarrBlock::DeleteSeriesPrompt, _) ) { let selected_block = app.data.sonarr_data.selected_block.get_active_block(); let prompt = format!( - "Do you really want to delete: \n{}?", + "Do you really want to delete the series: \n{}?", app.data.sonarr_data.series.current_selection().title.text ); let checkboxes = vec![ @@ -50,7 +49,6 @@ impl DrawUi for DeleteSeriesUi { .yes_no_highlighted(selected_block == ActiveSonarrBlock::DeleteSeriesConfirmPrompt) .yes_no_value(app.data.sonarr_data.prompt_confirm); - draw_library(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), diff --git a/src/ui/sonarr_ui/library/edit_series_ui.rs b/src/ui/sonarr_ui/library/edit_series_ui.rs index 93a500e..394df83 100644 --- a/src/ui/sonarr_ui/library/edit_series_ui.rs +++ b/src/ui/sonarr_ui/library/edit_series_ui.rs @@ -14,7 +14,6 @@ use crate::models::servarr_data::sonarr::sonarr_data::{ }; use crate::models::{EnumDisplayStyle, Route}; use crate::render_selectable_input_box; -use crate::ui::sonarr_ui::library::draw_library; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{layout_paragraph_borderless, title_block_centered}; @@ -23,7 +22,7 @@ use crate::ui::widgets::checkbox::Checkbox; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_popup, draw_popup_over, draw_popup_over_ui, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; use super::series_details_ui::SeriesDetailsUi; @@ -42,51 +41,33 @@ impl DrawUi for EditSeriesUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Sonarr(active_sonarr_block, context_option) = app.get_current_route() { - let draw_edit_series_prompt = - |f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| match active_sonarr_block { - ActiveSonarrBlock::EditSeriesSelectSeriesType => { - draw_edit_series_confirmation_prompt(f, app, prompt_area); - draw_edit_series_select_series_type_popup(f, app); - } - ActiveSonarrBlock::EditSeriesSelectQualityProfile => { - draw_edit_series_confirmation_prompt(f, app, prompt_area); - draw_edit_series_select_quality_profile_popup(f, app); - } - ActiveSonarrBlock::EditSeriesSelectLanguageProfile => { - draw_edit_series_confirmation_prompt(f, app, prompt_area); - draw_edit_series_select_language_profile_popup(f, app); - } - ActiveSonarrBlock::EditSeriesPrompt - | ActiveSonarrBlock::EditSeriesToggleMonitored - | ActiveSonarrBlock::EditSeriesToggleSeasonFolder - | ActiveSonarrBlock::EditSeriesPathInput - | ActiveSonarrBlock::EditSeriesTagsInput => { - draw_edit_series_confirmation_prompt(f, app, prompt_area) - } - _ => (), - }; - if let Some(context) = context_option { - match context { - ActiveSonarrBlock::Series => { - draw_popup_over( - f, - app, - area, - draw_library, - draw_edit_series_prompt, - Size::Long, - ); - } - _ if SERIES_DETAILS_BLOCKS.contains(&context) => { - draw_popup_over_ui::(f, app, area, draw_library, Size::Large); - draw_popup(f, app, draw_edit_series_prompt, Size::Long); - } - _ => (), + if SERIES_DETAILS_BLOCKS.contains(&context) { + draw_popup(f, app, SeriesDetailsUi::draw, Size::Large); } } + + let draw_edit_series_prompt = + |f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| { + draw_edit_series_confirmation_prompt(f, app, prompt_area); + + match active_sonarr_block { + ActiveSonarrBlock::EditSeriesSelectSeriesType => { + draw_edit_series_select_series_type_popup(f, app); + } + ActiveSonarrBlock::EditSeriesSelectQualityProfile => { + draw_edit_series_select_quality_profile_popup(f, app); + } + ActiveSonarrBlock::EditSeriesSelectLanguageProfile => { + draw_edit_series_select_language_profile_popup(f, app); + } + _ => (), + } + }; + + draw_popup(f, app, draw_edit_series_prompt, Size::Long); } } } diff --git a/src/ui/sonarr_ui/library/mod.rs b/src/ui/sonarr_ui/library/mod.rs index 3cfe084..7fb879d 100644 --- a/src/ui/sonarr_ui/library/mod.rs +++ b/src/ui/sonarr_ui/library/mod.rs @@ -54,46 +54,30 @@ impl DrawUi for LibraryUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let route = app.get_current_route(); - let mut series_ui_matchers = |active_sonarr_block: ActiveSonarrBlock| match active_sonarr_block - { - ActiveSonarrBlock::Series - | ActiveSonarrBlock::SeriesSortPrompt - | ActiveSonarrBlock::SearchSeries - | ActiveSonarrBlock::SearchSeriesError - | ActiveSonarrBlock::FilterSeries - | ActiveSonarrBlock::FilterSeriesError => draw_library(f, app, area), - ActiveSonarrBlock::UpdateAllSeriesPrompt => { + draw_library(f, app, area); + + match route { + _ if AddSeriesUi::accepts(route) => AddSeriesUi::draw(f, app, area), + _ if DeleteSeriesUi::accepts(route) => DeleteSeriesUi::draw(f, app, area), + _ if EditSeriesUi::accepts(route) => EditSeriesUi::draw(f, app, area), + _ if SeriesDetailsUi::accepts(route) => SeriesDetailsUi::draw(f, app, area), + Route::Sonarr(ActiveSonarrBlock::UpdateAllSeriesPrompt, _) => { let confirmation_prompt = ConfirmationPrompt::new() .title("Update All Series") .prompt("Do you want to update info and scan your disks for all of your series?") .yes_no_value(app.data.sonarr_data.prompt_confirm); - draw_library(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), ); } _ => (), - }; - - match route { - _ if AddSeriesUi::accepts(route) => AddSeriesUi::draw(f, app, area), - _ if DeleteSeriesUi::accepts(route) => DeleteSeriesUi::draw(f, app, area), - _ if EditSeriesUi::accepts(route) => EditSeriesUi::draw(f, app, area), - _ if SeriesDetailsUi::accepts(route) => { - draw_library(f, app, area); - SeriesDetailsUi::draw(f, app, area) - }, - Route::Sonarr(active_sonarr_block, _) if LIBRARY_BLOCKS.contains(&active_sonarr_block) => { - series_ui_matchers(active_sonarr_block) - } - _ => (), } } } -pub(super) fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { +fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() { let current_selection = if !app.data.sonarr_data.series.items.is_empty() { app.data.sonarr_data.series.current_selection().clone() diff --git a/src/ui/sonarr_ui/library/series_details_ui.rs b/src/ui/sonarr_ui/library/series_details_ui.rs index 40dc905..3e763f4 100644 --- a/src/ui/sonarr_ui/library/series_details_ui.rs +++ b/src/ui/sonarr_ui/library/series_details_ui.rs @@ -12,6 +12,7 @@ use crate::models::sonarr_models::{ Season, SeasonStatistics, SonarrHistoryEventType, SonarrHistoryItem, }; use crate::models::{EnumDisplayStyle, Route}; +use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi; use crate::ui::sonarr_ui::sonarr_ui_utils::{ create_download_failed_history_event_details, create_download_folder_imported_history_event_details, @@ -28,12 +29,9 @@ use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::message::Message; use crate::ui::widgets::popup::{Popup, Size}; -use crate::ui::{draw_popup, draw_popup_over, draw_tabs, DrawUi}; -use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi; +use crate::ui::{draw_popup, draw_tabs, DrawUi}; use crate::utils::convert_to_gb; -use super::draw_library; - #[cfg(test)] #[path = "series_details_ui_tests.rs"] mod series_details_ui_tests; @@ -107,28 +105,16 @@ impl DrawUi for SeriesDetailsUi { }; }; - match route { - _ if SeasonDetailsUi::accepts(route) => { - draw_popup(f, app, draw_series_details_popup, Size::XXLarge); - SeasonDetailsUi::draw(f, app, area); - }, - Route::Sonarr(active_sonarr_block, _) if SERIES_DETAILS_BLOCKS.contains(&active_sonarr_block) => { - draw_popup_over( - f, - app, - area, - draw_library, - draw_series_details_popup, - Size::XXLarge, - ); - } - _ => (), + draw_popup(f, app, draw_series_details_popup, Size::XXLarge); + + if SeasonDetailsUi::accepts(route) { + SeasonDetailsUi::draw(f, app, area); } } } } -pub fn draw_series_description(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { +fn draw_series_description(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let current_selection = app.data.sonarr_data.series.current_selection(); let monitored = if current_selection.monitored { "Yes" diff --git a/src/ui/sonarr_ui/root_folders/mod.rs b/src/ui/sonarr_ui/root_folders/mod.rs index d94b890..15a37a3 100644 --- a/src/ui/sonarr_ui/root_folders/mod.rs +++ b/src/ui/sonarr_ui/root_folders/mod.rs @@ -11,7 +11,7 @@ use crate::ui::utils::layout_block_top_border; use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::{Popup, Size}; -use crate::ui::{draw_input_box_popup, draw_popup_over, DrawUi}; +use crate::ui::{draw_input_box_popup, draw_popup, DrawUi}; use crate::utils::convert_to_gb; #[cfg(test)] @@ -31,13 +31,12 @@ impl DrawUi for RootFoldersUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() { + draw_root_folders(f, app, area); + match active_sonarr_block { - ActiveSonarrBlock::RootFolders => draw_root_folders(f, app, area), - ActiveSonarrBlock::AddRootFolderPrompt => draw_popup_over( + ActiveSonarrBlock::AddRootFolderPrompt => draw_popup( f, app, - area, - draw_root_folders, draw_add_root_folder_prompt_box, Size::InputBox, ), @@ -51,7 +50,6 @@ impl DrawUi for RootFoldersUi { .prompt(&prompt) .yes_no_value(app.data.sonarr_data.prompt_confirm); - draw_root_folders(f, app, area); f.render_widget( Popup::new(confirmation_prompt).size(Size::MediumPrompt), f.area(), diff --git a/src/ui/sonarr_ui/system/mod.rs b/src/ui/sonarr_ui/system/mod.rs index f9e6c88..2a5f9fb 100644 --- a/src/ui/sonarr_ui/system/mod.rs +++ b/src/ui/sonarr_ui/system/mod.rs @@ -57,18 +57,15 @@ impl DrawUi for SystemUi { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let route = app.get_current_route(); - - match route { - _ if SystemDetailsUi::accepts(route) => SystemDetailsUi::draw(f, app, area), - _ if matches!(route, Route::Sonarr(ActiveSonarrBlock::System, _)) => { - draw_system_ui_layout(f, app, area) - } - _ => (), + draw_system_ui_layout(f, app, area); + + if SystemDetailsUi::accepts(route) { + SystemDetailsUi::draw(f, app, area); } } } -pub(super) fn draw_system_ui_layout(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { +fn draw_system_ui_layout(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { let [activities_area, logs_area, help_area] = Layout::vertical([ Constraint::Ratio(1, 2), Constraint::Ratio(1, 2), diff --git a/src/ui/sonarr_ui/system/system_details_ui.rs b/src/ui/sonarr_ui/system/system_details_ui.rs index 7aa79a2..f2eb60e 100644 --- a/src/ui/sonarr_ui/system/system_details_ui.rs +++ b/src/ui/sonarr_ui/system/system_details_ui.rs @@ -10,7 +10,7 @@ use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SYSTEM use crate::models::sonarr_models::SonarrTask; use crate::models::Route; use crate::ui::sonarr_ui::system::{ - draw_queued_events, draw_system_ui_layout, extract_task_props, TASK_TABLE_CONSTRAINTS, + draw_queued_events, extract_task_props, TASK_TABLE_CONSTRAINTS, TASK_TABLE_HEADERS, }; use crate::ui::styles::ManagarrStyle; @@ -20,7 +20,7 @@ use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::{Popup, Size}; use crate::ui::widgets::selectable_list::SelectableList; -use crate::ui::{draw_popup_over, DrawUi}; +use crate::ui::{draw_popup, DrawUi}; #[cfg(test)] #[path = "system_details_ui_tests.rs"] @@ -37,33 +37,27 @@ impl DrawUi for SystemDetailsUi { false } - fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() { match active_sonarr_block { ActiveSonarrBlock::SystemLogs => { - draw_system_ui_layout(f, app, area); draw_logs_popup(f, app); } ActiveSonarrBlock::SystemTasks | ActiveSonarrBlock::SystemTaskStartConfirmPrompt => { - draw_popup_over( + draw_popup( f, app, - area, - draw_system_ui_layout, draw_tasks_popup, Size::Large, ) } - ActiveSonarrBlock::SystemQueuedEvents => draw_popup_over( + ActiveSonarrBlock::SystemQueuedEvents => draw_popup( f, app, - area, - draw_system_ui_layout, draw_queued_events, Size::Medium, ), ActiveSonarrBlock::SystemUpdates => { - draw_system_ui_layout(f, app, area); draw_updates_popup(f, app); } _ => (), @@ -158,7 +152,7 @@ fn draw_updates_popup(f: &mut Frame<'_>, app: &mut App<'_>) { let updates = app.data.sonarr_data.updates.get_text(); let block = title_block("Updates"); - if !updates.is_empty() { + if !updates.is_empty() && !app.is_loading { let updates_paragraph = Paragraph::new(Text::from(updates)) .block(borderless_block()) .scroll((app.data.sonarr_data.updates.offset, 0));