Refactored unnecessary data fields into Options to make the code cleaner, and to reduce the memory usage of the application

This commit is contained in:
2023-08-14 13:02:50 -06:00
parent 23ad489b15
commit 907fa9a2ec
34 changed files with 932 additions and 545 deletions
+17 -19
View File
@@ -177,25 +177,23 @@ impl<'a> App<'a> {
} }
async fn populate_movie_collection_table(&mut self) { async fn populate_movie_collection_table(&mut self) {
let collection_movies = if !self.data.radarr_data.filtered_collections.items.is_empty() { let collection_movies =
self if let Some(filtered_collections) = self.data.radarr_data.filtered_collections.as_ref() {
.data filtered_collections
.radarr_data .current_selection()
.filtered_collections .clone()
.current_selection() .movies
.clone() .unwrap_or_default()
.movies } else {
.unwrap_or_default() self
} else { .data
self .radarr_data
.data .collections
.radarr_data .current_selection()
.collections .clone()
.current_selection() .movies
.clone() .unwrap_or_default()
.movies };
.unwrap_or_default()
};
self self
.data .data
.radarr_data .radarr_data
+7 -8
View File
@@ -8,6 +8,7 @@ mod tests {
use crate::app::App; use crate::app::App;
use crate::models::radarr_models::{Collection, CollectionMovie, Credit, Release}; use crate::models::radarr_models::{Collection, CollectionMovie, Credit, Release};
use crate::models::servarr_data::radarr::modals::MovieDetailsModal; use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
use crate::models::StatefulTable;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::network::NetworkEvent; use crate::network::NetworkEvent;
@@ -627,14 +628,12 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_populate_movie_collection_table_filtered() { async fn test_populate_movie_collection_table_filtered() {
let mut app = App::default(); let mut app = App::default();
app let mut filtered_collections = StatefulTable::default();
.data filtered_collections.set_items(vec![Collection {
.radarr_data movies: Some(vec![CollectionMovie::default()]),
.filtered_collections ..Collection::default()
.set_items(vec![Collection { }]);
movies: Some(vec![CollectionMovie::default()]), app.data.radarr_data.filtered_collections = Some(filtered_collections);
..Collection::default()
}]);
app.populate_movie_collection_table().await; app.populate_movie_collection_table().await;
@@ -234,7 +234,6 @@ mod tests {
RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS, RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS,
}; };
use crate::models::StatefulTable;
use crate::test_edit_collection_key; use crate::test_edit_collection_key;
use super::*; use super::*;
@@ -19,6 +19,7 @@ mod tests {
mod test_handle_scroll_up_and_down { mod test_handle_scroll_up_and_down {
use rstest::rstest; use rstest::rstest;
use crate::models::StatefulTable;
use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
use super::*; use super::*;
@@ -34,21 +35,54 @@ mod tests {
to_string to_string
); );
test_iterable_scroll!( #[rstest]
test_filtered_collections_scroll, fn test_filtered_collections_scroll(
CollectionsHandler, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
filtered_collections, ) {
simple_stateful_iterable_vec!(Collection, HorizontallyScrollableText), let mut app = App::default();
ActiveRadarrBlock::Collections, let mut filtered_collections = StatefulTable::default();
None, filtered_collections.set_items(simple_stateful_iterable_vec!(
title, Collection,
to_string HorizontallyScrollableText
); ));
app.data.radarr_data.filtered_collections = Some(filtered_collections);
CollectionsHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 2"
);
CollectionsHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
} }
mod test_handle_home_end { mod test_handle_home_end {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use crate::models::StatefulTable;
use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end};
use super::*; use super::*;
@@ -64,16 +98,58 @@ mod tests {
to_string to_string
); );
test_iterable_home_and_end!( #[test]
test_filtered_collections_home_end, fn test_filtered_collections_home_end() {
CollectionsHandler, let mut app = App::default();
filtered_collections, let mut filtered_collections = StatefulTable::default();
extended_stateful_iterable_vec!(Collection, HorizontallyScrollableText), filtered_collections.set_items(extended_stateful_iterable_vec!(
ActiveRadarrBlock::Collections, Collection,
None, HorizontallyScrollableText
title, ));
to_string app.data.radarr_data.filtered_collections = Some(filtered_collections);
);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 3"
);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[test] #[test]
fn test_collection_search_box_home_end_keys() { fn test_collection_search_box_home_end_keys() {
@@ -341,6 +417,7 @@ mod tests {
} }
mod test_handle_submit { mod test_handle_submit {
use crate::models::StatefulTable;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
@@ -450,14 +527,12 @@ mod tests {
let mut app = App::default(); let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into());
app let mut filtered_collections = StatefulTable::default();
.data filtered_collections.set_items(extended_stateful_iterable_vec!(
.radarr_data Collection,
.filtered_collections HorizontallyScrollableText
.set_items(extended_stateful_iterable_vec!( ));
Collection, app.data.radarr_data.filtered_collections = Some(filtered_collections);
HorizontallyScrollableText
));
app.data.radarr_data.search = Some("Test 2".into()); app.data.radarr_data.search = Some("Test 2".into());
CollectionsHandler::with( CollectionsHandler::with(
@@ -473,6 +548,8 @@ mod tests {
.data .data
.radarr_data .radarr_data
.filtered_collections .filtered_collections
.as_ref()
.unwrap()
.current_selection() .current_selection()
.title .title
.text, .text,
@@ -507,12 +584,25 @@ mod tests {
) )
.handle(); .handle();
assert_eq!(app.data.radarr_data.filtered_collections.items.len(), 3); assert!(app.data.radarr_data.filtered_collections.is_some());
assert_eq!(
app
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.items
.len(),
3
);
assert_str_eq!( assert_str_eq!(
app app
.data .data
.radarr_data .radarr_data
.filtered_collections .filtered_collections
.as_ref()
.unwrap()
.current_selection() .current_selection()
.title .title
.text, .text,
@@ -547,7 +637,7 @@ mod tests {
) )
.handle(); .handle();
assert!(app.data.radarr_data.filtered_collections.items.is_empty()); assert!(app.data.radarr_data.filtered_collections.is_none());
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
&ActiveRadarrBlock::FilterCollectionsError.into() &ActiveRadarrBlock::FilterCollectionsError.into()
@@ -715,7 +805,6 @@ mod tests {
RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS, RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS,
}; };
use crate::models::StatefulTable;
use crate::{assert_refresh_key, test_edit_collection_key}; use crate::{assert_refresh_key, test_edit_collection_key};
use super::*; use super::*;
@@ -784,7 +873,7 @@ mod tests {
assert!(app.data.radarr_data.is_filtering); assert!(app.data.radarr_data.is_filtering);
assert!(app.should_ignore_quit_key); assert!(app.should_ignore_quit_key);
assert!(app.data.radarr_data.filter.is_some()); assert!(app.data.radarr_data.filter.is_some());
assert!(app.data.radarr_data.filtered_collections.items.is_empty()); assert!(app.data.radarr_data.filtered_collections.is_none());
} }
#[test] #[test]
+14 -56
View File
@@ -8,7 +8,7 @@ use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler
use crate::models::servarr_data::radarr::radarr_data::{ use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, COLLECTIONS_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS, ActiveRadarrBlock, COLLECTIONS_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS,
}; };
use crate::models::{BlockSelectionState, HorizontallyScrollableText, Scrollable}; use crate::models::{BlockSelectionState, HorizontallyScrollableText, Scrollable, StatefulTable};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::utils::strip_non_search_characters; use crate::utils::strip_non_search_characters;
use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table}; use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table};
@@ -68,15 +68,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
fn handle_scroll_up(&mut self) { fn handle_scroll_up(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::Collections { if self.active_radarr_block == &ActiveRadarrBlock::Collections {
if !self if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut() {
.app filtered_collections.scroll_up();
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{
self.app.data.radarr_data.filtered_collections.scroll_up();
} else { } else {
self.app.data.radarr_data.collections.scroll_up() self.app.data.radarr_data.collections.scroll_up()
} }
@@ -85,15 +78,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
fn handle_scroll_down(&mut self) { fn handle_scroll_down(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::Collections { if self.active_radarr_block == &ActiveRadarrBlock::Collections {
if !self if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut() {
.app filtered_collections.scroll_down();
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{
self.app.data.radarr_data.filtered_collections.scroll_down();
} else { } else {
self.app.data.radarr_data.collections.scroll_down() self.app.data.radarr_data.collections.scroll_down()
} }
@@ -103,20 +89,9 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
fn handle_home(&mut self) { fn handle_home(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Collections => { ActiveRadarrBlock::Collections => {
if !self if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut()
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{ {
self filtered_collections.scroll_to_top();
.app
.data
.radarr_data
.filtered_collections
.scroll_to_top();
} else { } else {
self.app.data.radarr_data.collections.scroll_to_top() self.app.data.radarr_data.collections.scroll_to_top()
} }
@@ -144,20 +119,9 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
fn handle_end(&mut self) { fn handle_end(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Collections => { ActiveRadarrBlock::Collections => {
if !self if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut()
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{ {
self filtered_collections.scroll_to_bottom();
.app
.data
.radarr_data
.filtered_collections
.scroll_to_bottom();
} else { } else {
self.app.data.radarr_data.collections.scroll_to_bottom() self.app.data.radarr_data.collections.scroll_to_bottom()
} }
@@ -212,23 +176,17 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
.app .app
.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()), .push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()),
ActiveRadarrBlock::SearchCollection => { ActiveRadarrBlock::SearchCollection => {
if self if self.app.data.radarr_data.filtered_collections.is_some() {
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{
search_table!( search_table!(
self.app, self.app,
collections, filtered_collections,
ActiveRadarrBlock::SearchCollectionError ActiveRadarrBlock::SearchCollectionError,
true
); );
} else { } else {
search_table!( search_table!(
self.app, self.app,
filtered_collections, collections,
ActiveRadarrBlock::SearchCollectionError ActiveRadarrBlock::SearchCollectionError
); );
} }
@@ -3,7 +3,7 @@ use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::models::servarr_data::radarr::radarr_data::{ use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, ADD_MOVIE_BLOCKS, ADD_MOVIE_SELECTION_BLOCKS, ActiveRadarrBlock, ADD_MOVIE_BLOCKS, ADD_MOVIE_SELECTION_BLOCKS,
}; };
use crate::models::{BlockSelectionState, Scrollable, StatefulTable}; use crate::models::{BlockSelectionState, Scrollable};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_text_box_keys, handle_text_box_left_right_keys, App, Key}; use crate::{handle_text_box_keys, handle_text_box_left_right_keys, App, Key};
@@ -43,9 +43,14 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
fn handle_scroll_up(&mut self) { fn handle_scroll_up(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::AddMovieSearchResults => { ActiveRadarrBlock::AddMovieSearchResults => self
self.app.data.radarr_data.add_searched_movies.scroll_up() .app
} .data
.radarr_data
.add_searched_movies
.as_mut()
.unwrap()
.scroll_up(),
ActiveRadarrBlock::AddMovieSelectMonitor => self ActiveRadarrBlock::AddMovieSelectMonitor => self
.app .app
.data .data
@@ -89,9 +94,14 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
fn handle_scroll_down(&mut self) { fn handle_scroll_down(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::AddMovieSearchResults => { ActiveRadarrBlock::AddMovieSearchResults => self
self.app.data.radarr_data.add_searched_movies.scroll_down() .app
} .data
.radarr_data
.add_searched_movies
.as_mut()
.unwrap()
.scroll_down(),
ActiveRadarrBlock::AddMovieSelectMonitor => self ActiveRadarrBlock::AddMovieSelectMonitor => self
.app .app
.data .data
@@ -140,6 +150,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_mut()
.unwrap()
.scroll_to_top(), .scroll_to_top(),
ActiveRadarrBlock::AddMovieSelectMonitor => self ActiveRadarrBlock::AddMovieSelectMonitor => self
.app .app
@@ -205,6 +217,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_mut()
.unwrap()
.scroll_to_bottom(), .scroll_to_bottom(),
ActiveRadarrBlock::AddMovieSelectMonitor => self ActiveRadarrBlock::AddMovieSelectMonitor => self
.app .app
@@ -312,19 +326,15 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
self.app.should_ignore_quit_key = false; self.app.should_ignore_quit_key = false;
} }
_ if *self.active_radarr_block == ActiveRadarrBlock::AddMovieSearchResults _ if *self.active_radarr_block == ActiveRadarrBlock::AddMovieSearchResults
&& !self && self.app.data.radarr_data.add_searched_movies.is_some() =>
.app
.data
.radarr_data
.add_searched_movies
.items
.is_empty() =>
{ {
let tmdb_id = self let tmdb_id = self
.app .app
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.tmdb_id .tmdb_id
.clone(); .clone();
@@ -403,7 +413,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
} }
ActiveRadarrBlock::AddMovieSearchResults | ActiveRadarrBlock::AddMovieEmptySearchResults => { ActiveRadarrBlock::AddMovieSearchResults | ActiveRadarrBlock::AddMovieEmptySearchResults => {
self.app.pop_navigation_stack(); self.app.pop_navigation_stack();
self.app.data.radarr_data.add_searched_movies = StatefulTable::default(); self.app.data.radarr_data.add_searched_movies = None;
self.app.should_ignore_quit_key = true; self.app.should_ignore_quit_key = true;
} }
ActiveRadarrBlock::AddMoviePrompt => { ActiveRadarrBlock::AddMoviePrompt => {
@@ -21,21 +21,65 @@ mod tests {
use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::models::servarr_data::radarr::modals::AddMovieModal;
use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS;
use crate::models::BlockSelectionState; use crate::models::{BlockSelectionState, StatefulTable};
use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; use crate::simple_stateful_iterable_vec;
use super::*; use super::*;
test_iterable_scroll!( #[rstest]
test_add_movie_search_results_scroll, fn test_add_movie_search_results_scroll(
AddMovieHandler, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
add_searched_movies, ) {
simple_stateful_iterable_vec!(AddMovieSearchResult, HorizontallyScrollableText), let mut app = App::default();
ActiveRadarrBlock::AddMovieSearchResults, let mut add_searched_movies = StatefulTable::default();
None, add_searched_movies.set_items(simple_stateful_iterable_vec!(
title, AddMovieSearchResult,
to_string HorizontallyScrollableText
); ));
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
AddMovieHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 2"
);
AddMovieHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[rstest] #[rstest]
fn test_add_movie_select_monitor_scroll( fn test_add_movie_select_monitor_scroll(
@@ -302,21 +346,64 @@ mod tests {
mod test_handle_home_end { mod test_handle_home_end {
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::extended_stateful_iterable_vec;
use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::models::servarr_data::radarr::modals::AddMovieModal;
use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; use crate::models::StatefulTable;
use super::*; use super::*;
test_iterable_home_and_end!( #[test]
test_add_movie_search_results_home_end, fn test_add_movie_search_results_home_end() {
AddMovieHandler, let mut app = App::default();
add_searched_movies, let mut add_searched_movies = StatefulTable::default();
extended_stateful_iterable_vec!(AddMovieSearchResult, HorizontallyScrollableText), add_searched_movies.set_items(extended_stateful_iterable_vec!(
ActiveRadarrBlock::AddMovieSearchResults, AddMovieSearchResult,
None, HorizontallyScrollableText
title, ));
to_string app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
);
AddMovieHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 3"
);
AddMovieHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[test] #[test]
fn test_add_movie_select_monitor_home_end() { fn test_add_movie_select_monitor_home_end() {
@@ -765,7 +852,7 @@ mod tests {
use crate::models::radarr_models::Movie; use crate::models::radarr_models::Movie;
use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::models::servarr_data::radarr::modals::AddMovieModal;
use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS;
use crate::models::BlockSelectionState; use crate::models::{BlockSelectionState, StatefulTable};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use super::*; use super::*;
@@ -818,11 +905,9 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_results_submit() { fn test_add_movie_search_results_submit() {
let mut app = App::default(); let mut app = App::default();
app let mut add_searched_movies = StatefulTable::default();
.data add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
.radarr_data app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
.add_searched_movies
.set_items(vec![AddMovieSearchResult::default()]);
app.data.radarr_data.quality_profile_map = app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(1, "B - Test 2".to_owned()), (0, "A - Test 1".to_owned())]); BiMap::from_iter([(1, "B - Test 2".to_owned()), (0, "A - Test 1".to_owned())]);
@@ -904,11 +989,9 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_results_submit_movie_already_in_library() { fn test_add_movie_search_results_submit_movie_already_in_library() {
let mut app = App::default(); let mut app = App::default();
app let mut add_searched_movies = StatefulTable::default();
.data add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
.radarr_data app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
.add_searched_movies
.set_items(vec![AddMovieSearchResult::default()]);
app app
.data .data
.radarr_data .radarr_data
@@ -1063,6 +1146,7 @@ mod tests {
use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::models::servarr_data::radarr::modals::AddMovieModal;
use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data;
use crate::models::StatefulTable;
use crate::{assert_search_reset, simple_stateful_iterable_vec}; use crate::{assert_search_reset, simple_stateful_iterable_vec};
use super::*; use super::*;
@@ -1123,14 +1207,12 @@ mod tests {
let mut app = App::default(); let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
app let mut add_searched_movies = StatefulTable::default();
.data add_searched_movies.set_items(simple_stateful_iterable_vec!(
.radarr_data AddMovieSearchResult,
.add_searched_movies HorizontallyScrollableText
.set_items(simple_stateful_iterable_vec!( ));
AddMovieSearchResult, app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
HorizontallyScrollableText
));
AddMovieHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle(); AddMovieHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
@@ -1138,7 +1220,7 @@ mod tests {
app.get_current_route(), app.get_current_route(),
&ActiveRadarrBlock::AddMovieSearchInput.into() &ActiveRadarrBlock::AddMovieSearchInput.into()
); );
assert!(app.data.radarr_data.add_searched_movies.items.is_empty()); assert!(app.data.radarr_data.add_searched_movies.is_none());
assert!(app.should_ignore_quit_key); assert!(app.should_ignore_quit_key);
} }
@@ -18,6 +18,7 @@ mod tests {
use crate::test_handler_delegation; use crate::test_handler_delegation;
mod test_handle_scroll_up_and_down { mod test_handle_scroll_up_and_down {
use crate::models::StatefulTable;
use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
use super::*; use super::*;
@@ -33,21 +34,54 @@ mod tests {
to_string to_string
); );
test_iterable_scroll!( #[rstest]
test_filtered_movies_scroll, fn test_filtered_movies_scroll(
LibraryHandler, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
filtered_movies, ) {
simple_stateful_iterable_vec!(Movie, HorizontallyScrollableText), let mut app = App::default();
ActiveRadarrBlock::Movies, let mut filtered_movies = StatefulTable::default();
None, filtered_movies.set_items(simple_stateful_iterable_vec!(
title, Movie,
to_string HorizontallyScrollableText
); ));
app.data.radarr_data.filtered_movies = Some(filtered_movies);
LibraryHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 2"
);
LibraryHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
} }
mod test_handle_home_end { mod test_handle_home_end {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use crate::models::StatefulTable;
use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end};
use super::*; use super::*;
@@ -63,16 +97,58 @@ mod tests {
to_string to_string
); );
test_iterable_home_and_end!( #[test]
test_filtered_movies_home_end, fn test_filtered_movies_home_end() {
LibraryHandler, let mut app = App::default();
filtered_movies, let mut filtered_movies = StatefulTable::default();
extended_stateful_iterable_vec!(Movie, HorizontallyScrollableText), filtered_movies.set_items(extended_stateful_iterable_vec!(
ActiveRadarrBlock::Movies, Movie,
None, HorizontallyScrollableText
title, ));
to_string app.data.radarr_data.filtered_movies = Some(filtered_movies);
);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 3"
);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[test] #[test]
fn test_movie_search_box_home_end_keys() { fn test_movie_search_box_home_end_keys() {
@@ -367,6 +443,7 @@ mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use crate::extended_stateful_iterable_vec; use crate::extended_stateful_iterable_vec;
use crate::models::StatefulTable;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use super::*; use super::*;
@@ -453,14 +530,12 @@ mod tests {
let mut app = App::default(); let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
app let mut filtered_movies = StatefulTable::default();
.data filtered_movies.set_items(extended_stateful_iterable_vec!(
.radarr_data Movie,
.filtered_movies HorizontallyScrollableText
.set_items(extended_stateful_iterable_vec!( ));
Movie, app.data.radarr_data.filtered_movies = Some(filtered_movies);
HorizontallyScrollableText
));
app.data.radarr_data.search = Some("Test 2".into()); app.data.radarr_data.search = Some("Test 2".into());
LibraryHandler::with( LibraryHandler::with(
@@ -476,6 +551,8 @@ mod tests {
.data .data
.radarr_data .radarr_data
.filtered_movies .filtered_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.title .title
.text, .text,
@@ -507,12 +584,25 @@ mod tests {
) )
.handle(); .handle();
assert_eq!(app.data.radarr_data.filtered_movies.items.len(), 3); assert!(app.data.radarr_data.filtered_movies.is_some());
assert_eq!(
app
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.items
.len(),
3
);
assert_str_eq!( assert_str_eq!(
app app
.data .data
.radarr_data .radarr_data
.filtered_movies .filtered_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.title .title
.text, .text,
@@ -544,7 +634,7 @@ mod tests {
) )
.handle(); .handle();
assert!(app.data.radarr_data.filtered_movies.items.is_empty()); assert!(app.data.radarr_data.filtered_movies.is_none());
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
&ActiveRadarrBlock::FilterMoviesError.into() &ActiveRadarrBlock::FilterMoviesError.into()
@@ -688,7 +778,6 @@ mod tests {
RadarrData, EDIT_MOVIE_SELECTION_BLOCKS, RadarrData, EDIT_MOVIE_SELECTION_BLOCKS,
}; };
use crate::models::StatefulTable;
use crate::{assert_refresh_key, test_edit_movie_key}; use crate::{assert_refresh_key, test_edit_movie_key};
use super::*; use super::*;
@@ -757,7 +846,7 @@ mod tests {
assert!(app.data.radarr_data.is_filtering); assert!(app.data.radarr_data.is_filtering);
assert!(app.should_ignore_quit_key); assert!(app.should_ignore_quit_key);
assert!(app.data.radarr_data.filter.is_some()); assert!(app.data.radarr_data.filter.is_some());
assert!(app.data.radarr_data.filtered_movies.items.is_empty()); assert!(app.data.radarr_data.filtered_movies.is_none());
} }
#[test] #[test]
+14 -13
View File
@@ -11,7 +11,7 @@ use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler
use crate::models::servarr_data::radarr::radarr_data::{ use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, DELETE_MOVIE_SELECTION_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, LIBRARY_BLOCKS, ActiveRadarrBlock, DELETE_MOVIE_SELECTION_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, LIBRARY_BLOCKS,
}; };
use crate::models::{BlockSelectionState, HorizontallyScrollableText, Scrollable}; use crate::models::{BlockSelectionState, HorizontallyScrollableText, Scrollable, StatefulTable};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::utils::strip_non_search_characters; use crate::utils::strip_non_search_characters;
use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table}; use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table};
@@ -81,8 +81,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
fn handle_scroll_up(&mut self) { fn handle_scroll_up(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::Movies { if self.active_radarr_block == &ActiveRadarrBlock::Movies {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() { if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
self.app.data.radarr_data.filtered_movies.scroll_up(); filtered_movies.scroll_up();
} else { } else {
self.app.data.radarr_data.movies.scroll_up() self.app.data.radarr_data.movies.scroll_up()
} }
@@ -91,8 +91,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
fn handle_scroll_down(&mut self) { fn handle_scroll_down(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::Movies { if self.active_radarr_block == &ActiveRadarrBlock::Movies {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() { if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
self.app.data.radarr_data.filtered_movies.scroll_down(); filtered_movies.scroll_down();
} else { } else {
self.app.data.radarr_data.movies.scroll_down() self.app.data.radarr_data.movies.scroll_down()
} }
@@ -102,8 +102,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
fn handle_home(&mut self) { fn handle_home(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Movies => { ActiveRadarrBlock::Movies => {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() { if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
self.app.data.radarr_data.filtered_movies.scroll_to_top(); filtered_movies.scroll_to_top();
} else { } else {
self.app.data.radarr_data.movies.scroll_to_top() self.app.data.radarr_data.movies.scroll_to_top()
} }
@@ -135,8 +135,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
fn handle_end(&mut self) { fn handle_end(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Movies => { ActiveRadarrBlock::Movies => {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() { if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
self.app.data.radarr_data.filtered_movies.scroll_to_bottom(); filtered_movies.scroll_to_bottom();
} else { } else {
self.app.data.radarr_data.movies.scroll_to_bottom() self.app.data.radarr_data.movies.scroll_to_bottom()
} }
@@ -199,14 +199,15 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
.app .app
.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()), .push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()),
ActiveRadarrBlock::SearchMovie => { ActiveRadarrBlock::SearchMovie => {
if self.app.data.radarr_data.filtered_movies.items.is_empty() { if self.app.data.radarr_data.filtered_movies.is_some() {
search_table!(self.app, movies, ActiveRadarrBlock::SearchMovieError);
} else {
search_table!( search_table!(
self.app, self.app,
filtered_movies, filtered_movies,
ActiveRadarrBlock::SearchMovieError ActiveRadarrBlock::SearchMovieError,
true
); );
} else {
search_table!(self.app, movies, ActiveRadarrBlock::SearchMovieError);
} }
} }
ActiveRadarrBlock::FilterMovies => { ActiveRadarrBlock::FilterMovies => {
@@ -477,7 +477,7 @@ fn sort_releases_by_selected_field(
.cmp(release_b.size.as_u64().as_ref().unwrap()) .cmp(release_b.size.as_u64().as_ref().unwrap())
}, },
ReleaseField::Peers => |release_a, release_b| { ReleaseField::Peers => |release_a, release_b| {
let default_number = Number::from(i64::max_value()); let default_number = Number::from(i64::MAX);
let seeder_a = release_a let seeder_a = release_a
.seeders .seeders
.as_ref() .as_ref()
@@ -914,7 +914,7 @@ mod tests {
use crate::models::servarr_data::radarr::radarr_data::{ use crate::models::servarr_data::radarr::radarr_data::{
RadarrData, EDIT_MOVIE_SELECTION_BLOCKS, RadarrData, EDIT_MOVIE_SELECTION_BLOCKS,
}; };
use crate::models::StatefulTable;
use crate::test_edit_movie_key; use crate::test_edit_movie_key;
use super::*; use super::*;
+58 -47
View File
@@ -117,16 +117,8 @@ pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: &Key) {
#[macro_export] #[macro_export]
macro_rules! search_table { macro_rules! search_table {
($app:expr, $data_ref:ident, $error_block:expr) => { ($app:expr, $data_ref:ident, $error_block:expr) => {
let search_index = if $app.data.radarr_data.search.is_some() { let search_index = if let Some(search_str) = $app.data.radarr_data.search.as_ref() {
let search_string = $app let search_string = search_str.text.clone().to_lowercase();
.data
.radarr_data
.search
.as_ref()
.unwrap()
.text
.clone()
.to_lowercase();
$app.data.radarr_data.search = None; $app.data.radarr_data.search = None;
@@ -151,44 +143,65 @@ macro_rules! search_table {
$app.pop_and_push_navigation_stack($error_block.into()); $app.pop_and_push_navigation_stack($error_block.into());
} }
}; };
($app:expr, $data_ref:ident, $error_block:expr, $option:ident) => {
let search_index = if let Some(search_str) = $app.data.radarr_data.search.as_ref() {
let search_string = search_str.text.clone().to_lowercase();
$app.data.radarr_data.search = None;
$app
.data
.radarr_data
.$data_ref
.as_ref()
.unwrap()
.items
.iter()
.position(|item| strip_non_search_characters(&item.title.text).contains(&search_string))
} else {
None
};
$app.data.radarr_data.is_searching = false;
$app.should_ignore_quit_key = false;
if search_index.is_some() {
$app.pop_navigation_stack();
$app
.data
.radarr_data
.$data_ref
.as_mut()
.unwrap()
.select_index(search_index);
} else {
$app.pop_and_push_navigation_stack($error_block.into());
}
};
} }
#[macro_export] #[macro_export]
macro_rules! filter_table { macro_rules! filter_table {
($app:expr, $source_table_ref:ident, $filter_table_ref:ident, $error_block:expr) => { ($app:expr, $source_table_ref:ident, $filter_table_ref:ident, $error_block:expr) => {
let empty_filter = $app.data.radarr_data.filter.is_some() let empty_filter = match $app.data.radarr_data.filter.as_ref() {
&& $app Some(filter) if filter.text.is_empty() => true,
.data _ => false,
.radarr_data };
.filter let filter_matches = match $app.data.radarr_data.filter.as_ref() {
.as_ref() Some(filter) if !filter.text.is_empty() => {
.unwrap() let scrubbed_filter = strip_non_search_characters(&filter.text.clone());
.text
.is_empty();
let filter_matches = if $app.data.radarr_data.filter.is_some()
&& !$app
.data
.radarr_data
.filter
.as_ref()
.unwrap()
.text
.is_empty()
{
let filter =
strip_non_search_characters(&$app.data.radarr_data.filter.as_ref().unwrap().text.clone());
$app $app
.data .data
.radarr_data .radarr_data
.$source_table_ref .$source_table_ref
.items .items
.iter() .iter()
.filter(|item| strip_non_search_characters(&item.title.text).contains(&filter)) .filter(|item| strip_non_search_characters(&item.title.text).contains(&scrubbed_filter))
.cloned() .cloned()
.collect() .collect()
} else { }
Vec::new() _ => Vec::new(),
}; };
$app.data.radarr_data.filter = None; $app.data.radarr_data.filter = None;
@@ -201,11 +214,9 @@ macro_rules! filter_table {
$app.pop_navigation_stack(); $app.pop_navigation_stack();
} else { } else {
$app.pop_navigation_stack(); $app.pop_navigation_stack();
$app let mut filter_table = StatefulTable::default();
.data filter_table.set_items(filter_matches);
.radarr_data $app.data.radarr_data.$filter_table_ref = Some(filter_table);
.$filter_table_ref
.set_items(filter_matches);
} }
}; };
} }
@@ -11,7 +11,7 @@ mod utils {
(1111, "Any".to_owned()), (1111, "Any".to_owned()),
]), ]),
tags_map: BiMap::from_iter([(1, "test".to_owned())]), tags_map: BiMap::from_iter([(1, "test".to_owned())]),
filtered_movies: StatefulTable::default(), filtered_movies: None,
..create_test_radarr_data() ..create_test_radarr_data()
}; };
radarr_data.movies.set_items(vec![Movie { radarr_data.movies.set_items(vec![Movie {
@@ -126,7 +126,7 @@ mod utils {
(2222, "HD - 1080p".to_owned()), (2222, "HD - 1080p".to_owned()),
(1111, "Any".to_owned()), (1111, "Any".to_owned()),
]), ]),
filtered_collections: StatefulTable::default(), filtered_collections: None,
..create_test_radarr_data() ..create_test_radarr_data()
}; };
radarr_data.collections.set_items(vec![Collection { radarr_data.collections.set_items(vec![Collection {
@@ -10,7 +10,7 @@ mod tests {
use crate::handlers::KeyEventHandler; use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::Movie; use crate::models::radarr_models::Movie;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::HorizontallyScrollableText; use crate::models::{HorizontallyScrollableText, StatefulTable};
use crate::utils::strip_non_search_characters; use crate::utils::strip_non_search_characters;
use crate::{ use crate::{
extended_stateful_iterable_vec, filter_table, search_table, test_handler_delegation, extended_stateful_iterable_vec, filter_table, search_table, test_handler_delegation,
@@ -130,9 +130,22 @@ mod tests {
ActiveRadarrBlock::FilterMoviesError ActiveRadarrBlock::FilterMoviesError
); );
assert_eq!(app.data.radarr_data.filtered_movies.items.len(), 1); assert!(app.data.radarr_data.filtered_movies.is_some());
assert_eq!(
app
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.items
.len(),
1
);
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.filtered_movies.items[0].title.text, app.data.radarr_data.filtered_movies.as_ref().unwrap().items[0]
.title
.text,
"Test 2" "Test 2"
); );
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
@@ -165,7 +178,7 @@ mod tests {
ActiveRadarrBlock::FilterMoviesError ActiveRadarrBlock::FilterMoviesError
); );
assert!(app.data.radarr_data.filtered_movies.items.is_empty()); assert!(app.data.radarr_data.filtered_movies.is_none());
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.is_filtering); assert!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key); assert!(!app.should_ignore_quit_key);
@@ -196,7 +209,7 @@ mod tests {
ActiveRadarrBlock::FilterMoviesError ActiveRadarrBlock::FilterMoviesError
); );
assert!(app.data.radarr_data.filtered_movies.items.is_empty()); assert!(app.data.radarr_data.filtered_movies.is_none());
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
&ActiveRadarrBlock::FilterMoviesError.into() &ActiveRadarrBlock::FilterMoviesError.into()
@@ -229,7 +242,7 @@ mod tests {
ActiveRadarrBlock::FilterMoviesError ActiveRadarrBlock::FilterMoviesError
); );
assert!(app.data.radarr_data.filtered_movies.items.is_empty()); assert!(app.data.radarr_data.filtered_movies.is_none());
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
&ActiveRadarrBlock::FilterMoviesError.into() &ActiveRadarrBlock::FilterMoviesError.into()
+6 -6
View File
@@ -43,10 +43,10 @@ impl From<&RadarrData<'_>> for EditMovieModal {
minimum_availability, minimum_availability,
quality_profile_id, quality_profile_id,
.. ..
} = if radarr_data.filtered_movies.items.is_empty() { } = if let Some(filtered_movies) = radarr_data.filtered_movies.as_ref() {
radarr_data.movies.current_selection() filtered_movies.current_selection()
} else { } else {
radarr_data.filtered_movies.current_selection() radarr_data.movies.current_selection()
}; };
edit_movie_modal edit_movie_modal
@@ -159,10 +159,10 @@ impl From<&RadarrData<'_>> for EditCollectionModal {
minimum_availability, minimum_availability,
quality_profile_id, quality_profile_id,
.. ..
} = if radarr_data.filtered_collections.items.is_empty() { } = if let Some(filtered_collections) = radarr_data.filtered_collections.as_ref() {
radarr_data.collections.current_selection() filtered_collections.current_selection()
} else { } else {
radarr_data.filtered_collections.current_selection() radarr_data.collections.current_selection()
}; };
edit_collection_modal.path = root_folder_path.clone().unwrap_or_default().into(); edit_collection_modal.path = root_folder_path.clone().unwrap_or_default().into();
@@ -21,7 +21,7 @@ mod test {
(1111, "Any".to_owned()), (1111, "Any".to_owned()),
]), ]),
tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]), tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]),
filtered_movies: StatefulTable::default(), filtered_movies: None,
..create_test_radarr_data() ..create_test_radarr_data()
}; };
let movie = Movie { let movie = Movie {
@@ -34,7 +34,9 @@ mod test {
}; };
if test_filtered_movies { if test_filtered_movies {
radarr_data.filtered_movies.set_items(vec![movie]); let mut filtered_movies = StatefulTable::default();
filtered_movies.set_items(vec![movie]);
radarr_data.filtered_movies = Some(filtered_movies);
} else { } else {
radarr_data.movies.set_items(vec![movie]); radarr_data.movies.set_items(vec![movie]);
} }
@@ -111,7 +113,7 @@ mod test {
(2222, "HD - 1080p".to_owned()), (2222, "HD - 1080p".to_owned()),
(1111, "Any".to_owned()), (1111, "Any".to_owned()),
]), ]),
filtered_collections: StatefulTable::default(), filtered_collections: None,
..create_test_radarr_data() ..create_test_radarr_data()
}; };
let collection = Collection { let collection = Collection {
@@ -124,7 +126,9 @@ mod test {
}; };
if test_filtered_collections { if test_filtered_collections {
radarr_data.filtered_collections.set_items(vec![collection]); let mut filtered_collections = StatefulTable::default();
filtered_collections.set_items(vec![collection]);
radarr_data.filtered_collections = Some(filtered_collections);
} else { } else {
radarr_data.collections.set_items(vec![collection]); radarr_data.collections.set_items(vec![collection]);
} }
+15 -15
View File
@@ -35,33 +35,33 @@ pub struct RadarrData<'a> {
pub version: String, pub version: String,
pub start_time: DateTime<Utc>, pub start_time: DateTime<Utc>,
pub movies: StatefulTable<Movie>, pub movies: StatefulTable<Movie>,
pub filtered_movies: StatefulTable<Movie>,
pub add_searched_movies: StatefulTable<AddMovieSearchResult>,
pub selected_block: BlockSelectionState<'a, ActiveRadarrBlock>, pub selected_block: BlockSelectionState<'a, ActiveRadarrBlock>,
pub downloads: StatefulTable<DownloadRecord>, pub downloads: StatefulTable<DownloadRecord>,
pub indexers: StatefulTable<Indexer>, pub indexers: StatefulTable<Indexer>,
pub indexer_settings: Option<IndexerSettings>,
pub quality_profile_map: BiMap<u64, String>, pub quality_profile_map: BiMap<u64, String>,
pub tags_map: BiMap<u64, String>, pub tags_map: BiMap<u64, String>,
pub collections: StatefulTable<Collection>, pub collections: StatefulTable<Collection>,
pub filtered_collections: StatefulTable<Collection>,
pub collection_movies: StatefulTable<CollectionMovie>, pub collection_movies: StatefulTable<CollectionMovie>,
pub logs: StatefulList<HorizontallyScrollableText>, pub logs: StatefulList<HorizontallyScrollableText>,
pub log_details: StatefulList<HorizontallyScrollableText>, pub log_details: StatefulList<HorizontallyScrollableText>,
pub tasks: StatefulTable<Task>, pub tasks: StatefulTable<Task>,
pub queued_events: StatefulTable<QueueEvent>, pub queued_events: StatefulTable<QueueEvent>,
pub updates: ScrollableText, pub updates: ScrollableText,
pub prompt_confirm_action: Option<RadarrEvent>,
pub main_tabs: TabState, pub main_tabs: TabState,
pub movie_info_tabs: TabState, pub movie_info_tabs: TabState,
pub search: Option<HorizontallyScrollableText>, pub search: Option<HorizontallyScrollableText>,
pub filter: Option<HorizontallyScrollableText>, pub filter: Option<HorizontallyScrollableText>,
pub add_movie_modal: Option<AddMovieModal>, pub add_movie_modal: Option<AddMovieModal>,
pub add_searched_movies: Option<StatefulTable<AddMovieSearchResult>>,
pub edit_movie_modal: Option<EditMovieModal>, pub edit_movie_modal: Option<EditMovieModal>,
pub edit_collection_modal: Option<EditCollectionModal>, pub edit_collection_modal: Option<EditCollectionModal>,
pub edit_root_folder: Option<HorizontallyScrollableText>, pub edit_root_folder: Option<HorizontallyScrollableText>,
pub filtered_collections: Option<StatefulTable<Collection>>,
pub filtered_movies: Option<StatefulTable<Movie>>,
pub indexer_settings: Option<IndexerSettings>,
pub movie_details_modal: Option<MovieDetailsModal>, pub movie_details_modal: Option<MovieDetailsModal>,
pub prompt_confirm: bool, pub prompt_confirm: bool,
pub prompt_confirm_action: Option<RadarrEvent>,
pub delete_movie_files: bool, pub delete_movie_files: bool,
pub add_list_exclusion: bool, pub add_list_exclusion: bool,
pub is_searching: bool, pub is_searching: bool,
@@ -78,16 +78,16 @@ impl<'a> RadarrData<'a> {
self.is_searching = false; self.is_searching = false;
self.search = None; self.search = None;
self.filter = None; self.filter = None;
self.filtered_movies = StatefulTable::default(); self.filtered_movies = None;
self.filtered_collections = StatefulTable::default(); self.filtered_collections = None;
self.add_searched_movies = StatefulTable::default(); self.add_searched_movies = None;
} }
pub fn reset_filter(&mut self) { pub fn reset_filter(&mut self) {
self.is_filtering = false; self.is_filtering = false;
self.filter = None; self.filter = None;
self.filtered_movies = StatefulTable::default(); self.filtered_movies = None;
self.filtered_collections = StatefulTable::default(); self.filtered_collections = None;
} }
pub fn reset_movie_info_tabs(&mut self) { pub fn reset_movie_info_tabs(&mut self) {
@@ -104,33 +104,33 @@ impl<'a> Default for RadarrData<'a> {
version: String::default(), version: String::default(),
start_time: DateTime::default(), start_time: DateTime::default(),
movies: StatefulTable::default(), movies: StatefulTable::default(),
add_searched_movies: StatefulTable::default(),
selected_block: BlockSelectionState::default(), selected_block: BlockSelectionState::default(),
filtered_movies: StatefulTable::default(),
downloads: StatefulTable::default(), downloads: StatefulTable::default(),
indexers: StatefulTable::default(), indexers: StatefulTable::default(),
indexer_settings: None,
quality_profile_map: BiMap::default(), quality_profile_map: BiMap::default(),
tags_map: BiMap::default(), tags_map: BiMap::default(),
collections: StatefulTable::default(), collections: StatefulTable::default(),
filtered_collections: StatefulTable::default(),
collection_movies: StatefulTable::default(), collection_movies: StatefulTable::default(),
logs: StatefulList::default(), logs: StatefulList::default(),
log_details: StatefulList::default(), log_details: StatefulList::default(),
tasks: StatefulTable::default(), tasks: StatefulTable::default(),
queued_events: StatefulTable::default(), queued_events: StatefulTable::default(),
updates: ScrollableText::default(), updates: ScrollableText::default(),
prompt_confirm_action: None,
search: None, search: None,
filter: None, filter: None,
add_movie_modal: None, add_movie_modal: None,
add_searched_movies: None,
edit_movie_modal: None, edit_movie_modal: None,
edit_collection_modal: None, edit_collection_modal: None,
edit_root_folder: None, edit_root_folder: None,
filtered_collections: None,
filtered_movies: None,
indexer_settings: None,
movie_details_modal: None, movie_details_modal: None,
is_searching: false, is_searching: false,
is_filtering: false, is_filtering: false,
prompt_confirm: false, prompt_confirm: false,
prompt_confirm_action: None,
delete_movie_files: false, delete_movie_files: false,
add_list_exclusion: false, add_list_exclusion: false,
main_tabs: TabState::new(vec![ main_tabs: TabState::new(vec![
@@ -79,32 +79,32 @@ mod tests {
assert!(radarr_data.version.is_empty()); assert!(radarr_data.version.is_empty());
assert_eq!(radarr_data.start_time, <DateTime<Utc>>::default()); assert_eq!(radarr_data.start_time, <DateTime<Utc>>::default());
assert!(radarr_data.movies.items.is_empty()); assert!(radarr_data.movies.items.is_empty());
assert!(radarr_data.add_searched_movies.items.is_empty());
assert_eq!(radarr_data.selected_block, BlockSelectionState::default()); assert_eq!(radarr_data.selected_block, BlockSelectionState::default());
assert!(radarr_data.filtered_movies.items.is_empty());
assert!(radarr_data.downloads.items.is_empty()); assert!(radarr_data.downloads.items.is_empty());
assert!(radarr_data.indexers.items.is_empty()); assert!(radarr_data.indexers.items.is_empty());
assert!(radarr_data.indexer_settings.is_none());
assert!(radarr_data.quality_profile_map.is_empty()); assert!(radarr_data.quality_profile_map.is_empty());
assert!(radarr_data.tags_map.is_empty()); assert!(radarr_data.tags_map.is_empty());
assert!(radarr_data.collections.items.is_empty()); assert!(radarr_data.collections.items.is_empty());
assert!(radarr_data.filtered_collections.items.is_empty());
assert!(radarr_data.collection_movies.items.is_empty()); assert!(radarr_data.collection_movies.items.is_empty());
assert!(radarr_data.logs.items.is_empty()); assert!(radarr_data.logs.items.is_empty());
assert!(radarr_data.log_details.items.is_empty()); assert!(radarr_data.log_details.items.is_empty());
assert!(radarr_data.tasks.items.is_empty()); assert!(radarr_data.tasks.items.is_empty());
assert!(radarr_data.queued_events.items.is_empty()); assert!(radarr_data.queued_events.items.is_empty());
assert!(radarr_data.updates.get_text().is_empty()); assert!(radarr_data.updates.get_text().is_empty());
assert!(radarr_data.prompt_confirm_action.is_none());
assert!(radarr_data.search.is_none()); assert!(radarr_data.search.is_none());
assert!(radarr_data.filter.is_none()); assert!(radarr_data.filter.is_none());
assert!(radarr_data.add_movie_modal.is_none()); assert!(radarr_data.add_movie_modal.is_none());
assert!(radarr_data.add_searched_movies.is_none());
assert!(radarr_data.edit_movie_modal.is_none()); assert!(radarr_data.edit_movie_modal.is_none());
assert!(radarr_data.edit_collection_modal.is_none()); assert!(radarr_data.edit_collection_modal.is_none());
assert!(radarr_data.edit_root_folder.is_none()); assert!(radarr_data.edit_root_folder.is_none());
assert!(radarr_data.filtered_collections.is_none());
assert!(radarr_data.filtered_movies.is_none());
assert!(radarr_data.indexer_settings.is_none());
assert!(radarr_data.movie_details_modal.is_none()); assert!(radarr_data.movie_details_modal.is_none());
assert!(!radarr_data.is_searching); assert!(!radarr_data.is_searching);
assert!(!radarr_data.is_filtering); assert!(!radarr_data.is_filtering);
assert!(radarr_data.prompt_confirm_action.is_none());
assert!(!radarr_data.prompt_confirm); assert!(!radarr_data.prompt_confirm);
assert!(!radarr_data.delete_movie_files); assert!(!radarr_data.delete_movie_files);
assert!(!radarr_data.add_list_exclusion); assert!(!radarr_data.add_list_exclusion);
@@ -6,7 +6,7 @@ pub mod utils {
}; };
use crate::models::servarr_data::radarr::modals::MovieDetailsModal; use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
use crate::models::servarr_data::radarr::radarr_data::RadarrData; use crate::models::servarr_data::radarr::radarr_data::RadarrData;
use crate::models::{HorizontallyScrollableText, ScrollableText}; use crate::models::{HorizontallyScrollableText, ScrollableText, StatefulTable};
pub fn create_test_radarr_data<'a>() -> RadarrData<'a> { pub fn create_test_radarr_data<'a>() -> RadarrData<'a> {
let mut movie_details_modal = MovieDetailsModal { let mut movie_details_modal = MovieDetailsModal {
@@ -39,17 +39,26 @@ pub mod utils {
filter: Some("test filter".into()), filter: Some("test filter".into()),
edit_root_folder: Some("test path".into()), edit_root_folder: Some("test path".into()),
movie_details_modal: Some(movie_details_modal), movie_details_modal: Some(movie_details_modal),
filtered_movies: Some(StatefulTable::default()),
filtered_collections: Some(StatefulTable::default()),
add_searched_movies: Some(StatefulTable::default()),
..RadarrData::default() ..RadarrData::default()
}; };
radarr_data.movie_info_tabs.index = 1; radarr_data.movie_info_tabs.index = 1;
radarr_data radarr_data
.filtered_movies .filtered_movies
.as_mut()
.unwrap()
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
radarr_data radarr_data
.filtered_collections .filtered_collections
.as_mut()
.unwrap()
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
radarr_data radarr_data
.add_searched_movies .add_searched_movies
.as_mut()
.unwrap()
.set_items(vec![AddMovieSearchResult::default()]); .set_items(vec![AddMovieSearchResult::default()]);
radarr_data radarr_data
.collection_movies .collection_movies
@@ -67,9 +76,9 @@ pub mod utils {
assert!(!$radarr_data.is_searching); assert!(!$radarr_data.is_searching);
assert!($radarr_data.search.is_none()); assert!($radarr_data.search.is_none());
assert!($radarr_data.filter.is_none()); assert!($radarr_data.filter.is_none());
assert!($radarr_data.filtered_movies.items.is_empty()); assert!($radarr_data.filtered_movies.is_none());
assert!($radarr_data.filtered_collections.items.is_empty()); assert!($radarr_data.filtered_collections.is_none());
assert!($radarr_data.add_searched_movies.items.is_empty()); assert!($radarr_data.add_searched_movies.is_none());
}; };
} }
@@ -78,8 +87,8 @@ pub mod utils {
($radarr_data:expr) => { ($radarr_data:expr) => {
assert!(!$radarr_data.is_filtering); assert!(!$radarr_data.is_filtering);
assert!($radarr_data.filter.is_none()); assert!($radarr_data.filter.is_none());
assert!($radarr_data.filtered_movies.items.is_empty()); assert!($radarr_data.filtered_movies.is_none());
assert!($radarr_data.filtered_collections.items.is_empty()); assert!($radarr_data.filtered_collections.is_none());
}; };
} }
+56 -45
View File
@@ -18,7 +18,7 @@ use crate::models::servarr_data::radarr::modals::{
AddMovieModal, EditCollectionModal, EditMovieModal, MovieDetailsModal, AddMovieModal, EditCollectionModal, EditMovieModal, MovieDetailsModal,
}; };
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText}; use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText, StatefulTable};
use crate::network::{Network, NetworkEvent, RequestMethod, RequestProps}; use crate::network::{Network, NetworkEvent, RequestMethod, RequestProps};
use crate::utils::{convert_runtime, convert_to_gb}; use crate::utils::{convert_runtime, convert_to_gb};
@@ -191,6 +191,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.clone(); .clone();
(tmdb_id, title.text) (tmdb_id, title.text)
@@ -200,6 +202,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.clone(); .clone();
(tmdb_id, title.text) (tmdb_id, title.text)
@@ -688,24 +692,24 @@ impl<'a, 'b> Network<'a, 'b> {
.await; .await;
self self
.handle_request::<(), Vec<Credit>>(request_props, |credit_vec, mut app| { .handle_request::<(), Vec<Credit>>(request_props, |credit_vec, mut app| {
let cast_vec: Vec<Credit> = credit_vec let cast_vec: Vec<Credit> = credit_vec
.iter() .iter()
.cloned() .cloned()
.filter(|credit| credit.credit_type == CreditType::Cast) .filter(|credit| credit.credit_type == CreditType::Cast)
.collect(); .collect();
let crew_vec: Vec<Credit> = credit_vec let crew_vec: Vec<Credit> = credit_vec
.iter() .iter()
.cloned() .cloned()
.filter(|credit| credit.credit_type == CreditType::Crew) .filter(|credit| credit.credit_type == CreditType::Crew)
.collect(); .collect();
debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request"); debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request");
app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_cast.set_items(cast_vec); app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_cast.set_items(cast_vec);
app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_crew.set_items(crew_vec); app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_crew.set_items(crew_vec);
}) })
.await; .await;
} }
async fn get_diskspace(&mut self) { async fn get_diskspace(&mut self) {
@@ -1020,20 +1024,20 @@ impl<'a, 'b> Network<'a, 'b> {
.await; .await;
self self
.handle_request::<(), Vec<MovieHistoryItem>>(request_props, |movie_history_vec, mut app| { .handle_request::<(), Vec<MovieHistoryItem>>(request_props, |movie_history_vec, mut app| {
debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request"); debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request");
let mut reversed_movie_history_vec = movie_history_vec.to_vec(); let mut reversed_movie_history_vec = movie_history_vec.to_vec();
reversed_movie_history_vec.reverse(); reversed_movie_history_vec.reverse();
app app
.data .data
.radarr_data .radarr_data
.movie_details_modal .movie_details_modal
.as_mut() .as_mut()
.unwrap() .unwrap()
.movie_history .movie_history
.set_items(reversed_movie_history_vec) .set_items(reversed_movie_history_vec)
}) })
.await; .await;
} }
async fn get_movies(&mut self) { async fn get_movies(&mut self) {
@@ -1118,11 +1122,11 @@ impl<'a, 'b> Network<'a, 'b> {
.await; .await;
self self
.handle_request::<(), Vec<Release>>(request_props, |release_vec, mut app| { .handle_request::<(), Vec<Release>>(request_props, |release_vec, mut app| {
debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request"); debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request");
app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_releases.set_items(release_vec); app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_releases.set_items(release_vec);
}) })
.await; .await;
} }
async fn get_root_folders(&mut self) { async fn get_root_folders(&mut self) {
@@ -1325,12 +1329,14 @@ impl<'a, 'b> Network<'a, 'b> {
app.pop_and_push_navigation_stack( app.pop_and_push_navigation_stack(
ActiveRadarrBlock::AddMovieEmptySearchResults.into(), ActiveRadarrBlock::AddMovieEmptySearchResults.into(),
); );
} else if let Some(add_searched_movies) =
app.data.radarr_data.add_searched_movies.as_mut()
{
add_searched_movies.set_items(movie_vec);
} else { } else {
app let mut add_searched_movies = StatefulTable::default();
.data add_searched_movies.set_items(movie_vec);
.radarr_data app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
.add_searched_movies
.set_items(movie_vec);
} }
}) })
.await; .await;
@@ -1568,12 +1574,14 @@ impl<'a, 'b> Network<'a, 'b> {
async fn extract_movie_id(&mut self) -> (u64, u64) { async fn extract_movie_id(&mut self) -> (u64, u64) {
let app = self.app.lock().await; let app = self.app.lock().await;
if !app.data.radarr_data.filtered_movies.items.is_empty() { if app.data.radarr_data.filtered_movies.is_some() {
( (
app app
.data .data
.radarr_data .radarr_data
.filtered_movies .filtered_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.id .id
.as_u64() .as_u64()
@@ -1582,6 +1590,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data .data
.radarr_data .radarr_data
.filtered_movies .filtered_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.tmdb_id .tmdb_id
.as_u64() .as_u64()
@@ -1610,15 +1620,14 @@ impl<'a, 'b> Network<'a, 'b> {
} }
async fn extract_collection_id(&mut self) -> u64 { async fn extract_collection_id(&mut self) -> u64 {
if !self if self
.app .app
.lock() .lock()
.await .await
.data .data
.radarr_data .radarr_data
.filtered_collections .filtered_collections
.items .is_some()
.is_empty()
{ {
self self
.app .app
@@ -1627,6 +1636,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data .data
.radarr_data .radarr_data
.filtered_collections .filtered_collections
.as_ref()
.unwrap()
.current_selection() .current_selection()
.id .id
.as_u64() .as_u64()
+125 -31
View File
@@ -17,7 +17,7 @@ mod test {
Monitor, MovieFile, Quality, QualityWrapper, Rating, RatingsList, Monitor, MovieFile, Quality, QualityWrapper, Rating, RatingsList,
}; };
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::HorizontallyScrollableText; use crate::models::{HorizontallyScrollableText, StatefulTable};
use crate::App; use crate::App;
use super::super::*; use super::super::*;
@@ -375,6 +375,13 @@ mod test {
.await; .await;
async_server.assert_async().await; async_server.assert_async().await;
assert!(app_arc
.lock()
.await
.data
.radarr_data
.add_searched_movies
.is_some());
assert_eq!( assert_eq!(
app_arc app_arc
.lock() .lock()
@@ -382,6 +389,8 @@ mod test {
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_ref()
.unwrap()
.items, .items,
vec![add_movie_search_result()] vec![add_movie_search_result()]
); );
@@ -437,8 +446,7 @@ mod test {
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.items .is_none());
.is_empty());
assert_eq!( assert_eq!(
app_arc.lock().await.get_current_route(), app_arc.lock().await.get_current_route(),
&ActiveRadarrBlock::AddMovieEmptySearchResults.into() &ActiveRadarrBlock::AddMovieEmptySearchResults.into()
@@ -487,8 +495,7 @@ mod test {
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.items .is_none());
.is_empty());
assert_eq!( assert_eq!(
app_arc.lock().await.get_current_route(), app_arc.lock().await.get_current_route(),
&ActiveRadarrBlock::Movies.into() &ActiveRadarrBlock::Movies.into()
@@ -1599,11 +1606,9 @@ mod test {
.set_items(vec![collection_movie()]); .set_items(vec![collection_movie()]);
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
} else { } else {
app let mut add_searched_movies = StatefulTable::default();
.data add_searched_movies.set_items(vec![add_movie_search_result()]);
.radarr_data app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
.add_searched_movies
.set_items(vec![add_movie_search_result()]);
} }
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new());
@@ -1620,6 +1625,103 @@ mod test {
.is_none()); .is_none());
} }
#[tokio::test]
async fn test_handle_add_movie_event_reuse_existing_table_if_search_already_performed() {
let (async_server, app_arc, _server) = mock_radarr_api(
RequestMethod::Post,
Some(json!({
"tmdbId": 5678,
"title": "Test",
"rootFolderPath": "/nfs2",
"minimumAvailability": "announced",
"monitored": true,
"qualityProfileId": 2222,
"tags": [1, 2],
"addOptions": {
"monitor": "movieOnly",
"searchForMovie": true
}
})),
None,
RadarrEvent::AddMovie.resource(),
)
.await;
{
let mut app = app_arc.lock().await;
let mut add_movie_modal = AddMovieModal {
tags: "usenet, testing".into(),
..AddMovieModal::default()
};
add_movie_modal.root_folder_list.set_items(vec![
RootFolder {
id: Number::from(1),
path: "/nfs".to_owned(),
accessible: true,
free_space: Number::from(219902325555200u64),
unmapped_folders: None,
},
RootFolder {
id: Number::from(2),
path: "/nfs2".to_owned(),
accessible: true,
free_space: Number::from(21990232555520u64),
unmapped_folders: None,
},
]);
add_movie_modal.root_folder_list.state.select(Some(1));
add_movie_modal
.quality_profile_list
.set_items(vec!["HD - 1080p".to_owned()]);
add_movie_modal
.monitor_list
.set_items(Vec::from_iter(Monitor::iter()));
add_movie_modal
.minimum_availability_list
.set_items(Vec::from_iter(MinimumAvailability::iter()));
app.data.radarr_data.add_movie_modal = Some(add_movie_modal);
app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(2222, "HD - 1080p".to_owned())]);
app.data.radarr_data.tags_map =
BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]);
let secondary_search_result = AddMovieSearchResult {
tmdb_id: Number::from(5678),
..add_movie_search_result()
};
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![add_movie_search_result(), secondary_search_result]);
add_searched_movies.scroll_to_bottom();
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
}
let mut network = Network::new(&app_arc, CancellationToken::new());
network.handle_radarr_event(RadarrEvent::AddMovie).await;
async_server.assert_async().await;
assert!(app_arc
.lock()
.await
.data
.radarr_data
.add_movie_modal
.is_none());
assert_eq!(
app_arc
.lock()
.await
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.tmdb_id
.as_u64()
.unwrap(),
5678
);
}
#[tokio::test] #[tokio::test]
async fn test_handle_add_root_folder_event() { async fn test_handle_add_root_folder_event() {
let (async_server, app_arc, _server) = mock_radarr_api( let (async_server, app_arc, _server) = mock_radarr_api(
@@ -1916,17 +2018,13 @@ mod test {
#[tokio::test] #[tokio::test]
async fn test_extract_movie_id_filtered_movies() { async fn test_extract_movie_id_filtered_movies() {
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
app_arc let mut filtered_movies = StatefulTable::default();
.lock() filtered_movies.set_items(vec![Movie {
.await id: Number::from(1),
.data tmdb_id: Number::from(2),
.radarr_data ..Movie::default()
.filtered_movies }]);
.set_items(vec![Movie { app_arc.lock().await.data.radarr_data.filtered_movies = Some(filtered_movies);
id: Number::from(1),
tmdb_id: Number::from(2),
..Movie::default()
}]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new());
assert_eq!(network.extract_movie_id().await, (1, 2)); assert_eq!(network.extract_movie_id().await, (1, 2));
@@ -1953,16 +2051,12 @@ mod test {
#[tokio::test] #[tokio::test]
async fn test_extract_collection_id_filtered_collection() { async fn test_extract_collection_id_filtered_collection() {
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
app_arc let mut filtered_collections = StatefulTable::default();
.lock() filtered_collections.set_items(vec![Collection {
.await id: Number::from(1),
.data ..Collection::default()
.radarr_data }]);
.filtered_collections app_arc.lock().await.data.radarr_data.filtered_collections = Some(filtered_collections);
.set_items(vec![Collection {
id: Number::from(1),
..Collection::default()
}]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new());
assert_eq!(network.extract_collection_id().await, 1); assert_eq!(network.extract_collection_id().await, 1);
+57 -19
View File
@@ -291,7 +291,8 @@ fn draw_tabs<'a, B: Backend>(
} }
pub struct TableProps<'a, T> { pub struct TableProps<'a, T> {
pub content: &'a mut StatefulTable<T>, pub content: Option<&'a mut StatefulTable<T>>,
pub wrapped_content: Option<Option<&'a mut StatefulTable<T>>>,
pub table_headers: Vec<&'a str>, pub table_headers: Vec<&'a str>,
pub constraints: Vec<Constraint>, pub constraints: Vec<Constraint>,
pub help: Option<String>, pub help: Option<String>,
@@ -319,6 +320,7 @@ fn draw_table<'a, B, T, F>(
{ {
let TableProps { let TableProps {
content, content,
wrapped_content,
table_headers, table_headers,
constraints, constraints,
help, help,
@@ -326,29 +328,65 @@ fn draw_table<'a, B, T, F>(
let content_area = draw_help_and_get_content_rect(f, content_area, help); let content_area = draw_help_and_get_content_rect(f, content_area, help);
if !content.items.is_empty() { if wrapped_content.is_some() && wrapped_content.as_ref().unwrap().is_some() {
let rows = content.items.iter().map(row_mapper); draw_table_contents(
f,
let headers = Row::new(table_headers) block,
.style(style_default_bold()) row_mapper,
.bottom_margin(0); highlight,
wrapped_content.unwrap().as_mut().unwrap(),
let mut table = Table::new(rows).header(headers).block(block); table_headers,
&constraints,
if highlight { content_area,
table = table );
.highlight_style(style_highlight()) } else if content.is_some() && !content.as_ref().unwrap().items.is_empty() {
.highlight_symbol(HIGHLIGHT_SYMBOL); draw_table_contents(
} f,
block,
table = table.widths(&constraints); row_mapper,
highlight,
f.render_stateful_widget(table, content_area, &mut content.state); content.unwrap(),
table_headers,
&constraints,
content_area,
);
} else { } else {
loading(f, block, content_area, is_loading); loading(f, block, content_area, is_loading);
} }
} }
fn draw_table_contents<'a, B, T, F>(
f: &mut Frame<'_, B>,
block: Block<'_>,
row_mapper: F,
highlight: bool,
content: &mut StatefulTable<T>,
table_headers: Vec<&str>,
constraints: &Vec<Constraint>,
content_area: Rect,
) where
B: Backend,
F: Fn(&T) -> Row<'a>,
{
let rows = content.items.iter().map(row_mapper);
let headers = Row::new(table_headers)
.style(style_default_bold())
.bottom_margin(0);
let mut table = Table::new(rows).header(headers).block(block);
if highlight {
table = table
.highlight_style(style_highlight())
.highlight_symbol(HIGHLIGHT_SYMBOL);
}
table = table.widths(&constraints);
f.render_stateful_widget(table, content_area, &mut content.state);
}
pub fn loading<B: Backend>(f: &mut Frame<'_, B>, block: Block<'_>, area: Rect, is_loading: bool) { pub fn loading<B: Backend>(f: &mut Frame<'_, B>, block: Block<'_>, area: Rect, is_loading: bool) {
if is_loading { if is_loading {
let text = "\n\n Loading ...\n\n".to_owned(); let text = "\n\n Loading ...\n\n".to_owned();
@@ -80,15 +80,12 @@ pub fn draw_collection_details<B: Backend>(
content_area, content_area,
1, 1,
); );
let collection_selection = if !app.data.radarr_data.filtered_collections.items.is_empty() { let collection_selection =
app if let Some(filtered_collections) = app.data.radarr_data.filtered_collections.as_ref() {
.data filtered_collections.current_selection()
.radarr_data } else {
.filtered_collections app.data.radarr_data.collections.current_selection()
.current_selection() };
} else {
app.data.radarr_data.collections.current_selection()
};
let quality_profile = app let quality_profile = app
.data .data
.radarr_data .radarr_data
@@ -161,7 +158,8 @@ pub fn draw_collection_details<B: Backend>(
chunks[1], chunks[1],
layout_block_top_border_with_title(title_style("Movies")), layout_block_top_border_with_title(title_style("Movies")),
TableProps { TableProps {
content: &mut app.data.radarr_data.collection_movies, content: Some(&mut app.data.radarr_data.collection_movies),
wrapped_content: None,
table_headers: vec![ table_headers: vec![
"", "",
"Title", "Title",
@@ -97,20 +97,10 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
prompt_area: Rect, prompt_area: Rect,
) { ) {
let (collection_title, collection_overview) = let (collection_title, collection_overview) =
if app.data.radarr_data.filtered_collections.items.is_empty() { if let Some(filtered_collections) = app.data.radarr_data.filtered_collections.as_ref() {
( (
app filtered_collections.current_selection().title.text.clone(),
.data filtered_collections
.radarr_data
.collections
.current_selection()
.title
.text
.clone(),
app
.data
.radarr_data
.collections
.current_selection() .current_selection()
.overview .overview
.clone() .clone()
@@ -121,7 +111,7 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
app app
.data .data
.radarr_data .radarr_data
.filtered_collections .collections
.current_selection() .current_selection()
.title .title
.text .text
@@ -129,7 +119,7 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
app app
.data .data
.radarr_data .radarr_data
.filtered_collections .collections
.current_selection() .current_selection()
.overview .overview
.clone() .clone()
+12 -18
View File
@@ -100,25 +100,18 @@ impl DrawUi for CollectionsUi {
} }
pub(super) fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) { pub(super) fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
let current_selection = if !app.data.radarr_data.filtered_collections.items.is_empty() { let current_selection =
app if let Some(filtered_collections) = app.data.radarr_data.filtered_collections.as_ref() {
.data filtered_collections.current_selection().clone()
.radarr_data } else if !app.data.radarr_data.collections.items.is_empty() {
.filtered_collections app.data.radarr_data.collections.current_selection().clone()
.current_selection() } else {
.clone() Collection::default()
} else if !app.data.radarr_data.collections.items.is_empty() { };
app.data.radarr_data.collections.current_selection().clone()
} else {
Collection::default()
};
let quality_profile_map = &app.data.radarr_data.quality_profile_map; let quality_profile_map = &app.data.radarr_data.quality_profile_map;
let content = if !app.data.radarr_data.filtered_collections.items.is_empty() let content = match app.data.radarr_data.filtered_collections.as_mut() {
&& !app.data.radarr_data.is_filtering Some(filtered_collections) if !app.data.radarr_data.is_filtering => Some(filtered_collections),
{ _ => Some(&mut app.data.radarr_data.collections),
&mut app.data.radarr_data.filtered_collections
} else {
&mut app.data.radarr_data.collections
}; };
draw_table( draw_table(
f, f,
@@ -126,6 +119,7 @@ pub(super) fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content, content,
wrapped_content: None,
table_headers: vec![ table_headers: vec![
"Collection", "Collection",
"Number of Movies", "Number of Movies",
+2 -1
View File
@@ -62,7 +62,8 @@ fn draw_downloads<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rec
area, area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app.data.radarr_data.downloads, content: Some(&mut app.data.radarr_data.downloads),
wrapped_content: None,
table_headers: vec![ table_headers: vec![
"Title", "Title",
"Percent Complete", "Percent Complete",
+2 -1
View File
@@ -59,7 +59,8 @@ fn draw_indexers<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect
area, area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app.data.radarr_data.indexers, content: Some(&mut app.data.radarr_data.indexers),
wrapped_content: None,
table_headers: vec![ table_headers: vec![
"Indexer", "Indexer",
"RSS", "RSS",
+14 -12
View File
@@ -104,16 +104,13 @@ impl DrawUi for AddMovieUi {
} }
fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) { fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
let current_selection = if app.data.radarr_data.add_searched_movies.items.is_empty() { let is_loading = app.is_loading || app.data.radarr_data.add_searched_movies.is_none();
AddMovieSearchResult::default() let current_selection =
} else { if let Some(add_searched_movies) = app.data.radarr_data.add_searched_movies.as_ref() {
app add_searched_movies.current_selection().clone()
.data } else {
.radarr_data AddMovieSearchResult::default()
.add_searched_movies };
.current_selection()
.clone()
};
let chunks = vertical_chunks_with_margin( let chunks = vertical_chunks_with_margin(
vec![ vec![
@@ -181,7 +178,8 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, ar
chunks[1], chunks[1],
layout_block(), layout_block(),
TableProps { TableProps {
content: &mut app.data.radarr_data.add_searched_movies, content: None,
wrapped_content: Some(app.data.radarr_data.add_searched_movies.as_mut()),
table_headers: vec![ table_headers: vec![
"", "",
"Title", "Title",
@@ -260,7 +258,7 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, ar
]) ])
.style(style_primary()) .style(style_primary())
}, },
app.is_loading, is_loading,
true, true,
); );
} }
@@ -354,6 +352,8 @@ fn draw_confirmation_prompt<B: Backend>(
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.title .title
.text, .text,
@@ -361,6 +361,8 @@ fn draw_confirmation_prompt<B: Backend>(
.data .data
.radarr_data .radarr_data
.add_searched_movies .add_searched_movies
.as_ref()
.unwrap()
.current_selection() .current_selection()
.overview .overview
.clone(), .clone(),
+25 -37
View File
@@ -93,43 +93,31 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
app: &mut App<'_>, app: &mut App<'_>,
prompt_area: Rect, prompt_area: Rect,
) { ) {
let (movie_title, movie_overview) = if app.data.radarr_data.filtered_movies.items.is_empty() { let (movie_title, movie_overview) =
( if let Some(filtered_movies) = app.data.radarr_data.filtered_movies.as_ref() {
app (
.data filtered_movies.current_selection().title.text.clone(),
.radarr_data filtered_movies.current_selection().overview.clone(),
.movies )
.current_selection() } else {
.title (
.text app
.clone(), .data
app .radarr_data
.data .movies
.radarr_data .current_selection()
.movies .title
.current_selection() .text
.overview .clone(),
.clone(), app
) .data
} else { .radarr_data
( .movies
app .current_selection()
.data .overview
.radarr_data .clone(),
.filtered_movies )
.current_selection() };
.title
.text
.clone(),
app
.data
.radarr_data
.filtered_movies
.current_selection()
.overview
.clone(),
)
};
let title = format!("Edit - {}", movie_title); let title = format!("Edit - {}", movie_title);
let yes_no_value = app.data.radarr_data.prompt_confirm; let yes_no_value = app.data.radarr_data.prompt_confirm;
let selected_block = app.data.radarr_data.selected_block.get_active_block(); let selected_block = app.data.radarr_data.selected_block.get_active_block();
+12 -18
View File
@@ -108,27 +108,20 @@ impl DrawUi for LibraryUi {
} }
pub(super) fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) { pub(super) fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
let current_selection = if !app.data.radarr_data.filtered_movies.items.is_empty() { let current_selection =
app if let Some(filtered_movies) = app.data.radarr_data.filtered_movies.as_ref() {
.data filtered_movies.current_selection().clone()
.radarr_data } else if !app.data.radarr_data.movies.items.is_empty() {
.filtered_movies app.data.radarr_data.movies.current_selection().clone()
.current_selection() } else {
.clone() Movie::default()
} else if !app.data.radarr_data.movies.items.is_empty() { };
app.data.radarr_data.movies.current_selection().clone()
} else {
Movie::default()
};
let quality_profile_map = &app.data.radarr_data.quality_profile_map; let quality_profile_map = &app.data.radarr_data.quality_profile_map;
let tags_map = &app.data.radarr_data.tags_map; let tags_map = &app.data.radarr_data.tags_map;
let downloads_vec = &app.data.radarr_data.downloads.items; let downloads_vec = &app.data.radarr_data.downloads.items;
let content = if !app.data.radarr_data.filtered_movies.items.is_empty() let content = match app.data.radarr_data.filtered_movies.as_mut() {
&& !app.data.radarr_data.is_filtering Some(filtered_movies) if !app.data.radarr_data.is_filtering => Some(filtered_movies),
{ _ => Some(&mut app.data.radarr_data.movies),
&mut app.data.radarr_data.filtered_movies
} else {
&mut app.data.radarr_data.movies
}; };
draw_table( draw_table(
@@ -137,6 +130,7 @@ pub(super) fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content, content,
wrapped_content: None,
table_headers: vec![ table_headers: vec![
"Title", "Title",
"Year", "Year",
+32 -22
View File
@@ -269,7 +269,8 @@ fn draw_movie_history<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, conte
content_area, content_area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut movie_details_modal.movie_history, content: Some(&mut movie_details_modal.movie_history),
wrapped_content: None,
table_headers: vec!["Source Title", "Event Type", "Languages", "Quality", "Date"], table_headers: vec!["Source Title", "Event Type", "Languages", "Quality", "Date"],
constraints: vec![ constraints: vec![
Constraint::Percentage(34), Constraint::Percentage(34),
@@ -326,13 +327,16 @@ fn draw_movie_cast<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_
content_area, content_area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app content: Some(
.data &mut app
.radarr_data .data
.movie_details_modal .radarr_data
.as_mut() .movie_details_modal
.unwrap() .as_mut()
.movie_cast, .unwrap()
.movie_cast,
),
wrapped_content: None,
constraints: iter::repeat(Constraint::Ratio(1, 2)).take(2).collect(), constraints: iter::repeat(Constraint::Ratio(1, 2)).take(2).collect(),
table_headers: vec!["Cast Member", "Character"], table_headers: vec!["Cast Member", "Character"],
help: app help: app
@@ -365,13 +369,16 @@ fn draw_movie_crew<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_
content_area, content_area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app content: Some(
.data &mut app
.radarr_data .data
.movie_details_modal .radarr_data
.as_mut() .movie_details_modal
.unwrap() .as_mut()
.movie_crew, .unwrap()
.movie_crew,
),
wrapped_content: None,
constraints: iter::repeat(Constraint::Ratio(1, 3)).take(3).collect(), constraints: iter::repeat(Constraint::Ratio(1, 3)).take(3).collect(),
table_headers: vec!["Crew Member", "Job", "Department"], table_headers: vec!["Crew Member", "Job", "Department"],
help: app help: app
@@ -455,13 +462,16 @@ fn draw_movie_releases<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, cont
content_area, content_area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app content: Some(
.data &mut app
.radarr_data .data
.movie_details_modal .radarr_data
.as_mut() .movie_details_modal
.unwrap() .as_mut()
.movie_releases, .unwrap()
.movie_releases,
),
wrapped_content: None,
constraints: vec![ constraints: vec![
Constraint::Length(9), Constraint::Length(9),
Constraint::Length(10), Constraint::Length(10),
+2 -1
View File
@@ -61,7 +61,8 @@ fn draw_root_folders<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area:
area, area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app.data.radarr_data.root_folders, content: Some(&mut app.data.radarr_data.root_folders),
wrapped_content: None,
table_headers: vec!["Path", "Free Space", "Unmapped Folders"], table_headers: vec!["Path", "Free Space", "Unmapped Folders"],
constraints: vec![ constraints: vec![
Constraint::Percentage(60), Constraint::Percentage(60),
+4 -2
View File
@@ -106,7 +106,8 @@ fn draw_tasks<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
area, area,
title_block("Tasks"), title_block("Tasks"),
TableProps { TableProps {
content: &mut app.data.radarr_data.tasks, content: Some(&mut app.data.radarr_data.tasks),
wrapped_content: None,
table_headers: TASK_TABLE_HEADERS.to_vec(), table_headers: TASK_TABLE_HEADERS.to_vec(),
constraints: TASK_TABLE_CONSTRAINTS.to_vec(), constraints: TASK_TABLE_CONSTRAINTS.to_vec(),
help: None, help: None,
@@ -134,7 +135,8 @@ pub(super) fn draw_queued_events<B: Backend>(f: &mut Frame<'_, B>, app: &mut App
area, area,
title_block("Queued Events"), title_block("Queued Events"),
TableProps { TableProps {
content: &mut app.data.radarr_data.queued_events, content: Some(&mut app.data.radarr_data.queued_events),
wrapped_content: None,
table_headers: vec!["Trigger", "Status", "Name", "Queued", "Started", "Duration"], table_headers: vec!["Trigger", "Status", "Name", "Queued", "Started", "Duration"],
constraints: vec![ constraints: vec![
Constraint::Percentage(13), Constraint::Percentage(13),
+2 -1
View File
@@ -109,7 +109,8 @@ fn draw_tasks_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: R
context_area, context_area,
borderless_block(), borderless_block(),
TableProps { TableProps {
content: &mut app.data.radarr_data.tasks, content: Some(&mut app.data.radarr_data.tasks),
wrapped_content: None,
table_headers: TASK_TABLE_HEADERS.to_vec(), table_headers: TASK_TABLE_HEADERS.to_vec(),
constraints: TASK_TABLE_CONSTRAINTS.to_vec(), constraints: TASK_TABLE_CONSTRAINTS.to_vec(),
help: None, help: None,