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) {
let collection_movies = if !self.data.radarr_data.filtered_collections.items.is_empty() {
self
.data
.radarr_data
.filtered_collections
.current_selection()
.clone()
.movies
.unwrap_or_default()
} else {
self
.data
.radarr_data
.collections
.current_selection()
.clone()
.movies
.unwrap_or_default()
};
let collection_movies =
if let Some(filtered_collections) = self.data.radarr_data.filtered_collections.as_ref() {
filtered_collections
.current_selection()
.clone()
.movies
.unwrap_or_default()
} else {
self
.data
.radarr_data
.collections
.current_selection()
.clone()
.movies
.unwrap_or_default()
};
self
.data
.radarr_data
+7 -8
View File
@@ -8,6 +8,7 @@ mod tests {
use crate::app::App;
use crate::models::radarr_models::{Collection, CollectionMovie, Credit, Release};
use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
use crate::models::StatefulTable;
use crate::network::radarr_network::RadarrEvent;
use crate::network::NetworkEvent;
@@ -627,14 +628,12 @@ mod tests {
#[tokio::test]
async fn test_populate_movie_collection_table_filtered() {
let mut app = App::default();
app
.data
.radarr_data
.filtered_collections
.set_items(vec![Collection {
movies: Some(vec![CollectionMovie::default()]),
..Collection::default()
}]);
let mut filtered_collections = StatefulTable::default();
filtered_collections.set_items(vec![Collection {
movies: Some(vec![CollectionMovie::default()]),
..Collection::default()
}]);
app.data.radarr_data.filtered_collections = Some(filtered_collections);
app.populate_movie_collection_table().await;
@@ -234,7 +234,6 @@ mod tests {
RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS,
};
use crate::models::StatefulTable;
use crate::test_edit_collection_key;
use super::*;
@@ -19,6 +19,7 @@ mod tests {
mod test_handle_scroll_up_and_down {
use rstest::rstest;
use crate::models::StatefulTable;
use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
use super::*;
@@ -34,21 +35,54 @@ mod tests {
to_string
);
test_iterable_scroll!(
test_filtered_collections_scroll,
CollectionsHandler,
filtered_collections,
simple_stateful_iterable_vec!(Collection, HorizontallyScrollableText),
ActiveRadarrBlock::Collections,
None,
title,
to_string
);
#[rstest]
fn test_filtered_collections_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
let mut filtered_collections = StatefulTable::default();
filtered_collections.set_items(simple_stateful_iterable_vec!(
Collection,
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 {
use pretty_assertions::assert_eq;
use crate::models::StatefulTable;
use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end};
use super::*;
@@ -64,16 +98,58 @@ mod tests {
to_string
);
test_iterable_home_and_end!(
test_filtered_collections_home_end,
CollectionsHandler,
filtered_collections,
extended_stateful_iterable_vec!(Collection, HorizontallyScrollableText),
ActiveRadarrBlock::Collections,
None,
title,
to_string
);
#[test]
fn test_filtered_collections_home_end() {
let mut app = App::default();
let mut filtered_collections = StatefulTable::default();
filtered_collections.set_items(extended_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
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]
fn test_collection_search_box_home_end_keys() {
@@ -341,6 +417,7 @@ mod tests {
}
mod test_handle_submit {
use crate::models::StatefulTable;
use pretty_assertions::assert_eq;
use crate::network::radarr_network::RadarrEvent;
@@ -450,14 +527,12 @@ mod tests {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into());
app
.data
.radarr_data
.filtered_collections
.set_items(extended_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
let mut filtered_collections = StatefulTable::default();
filtered_collections.set_items(extended_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
app.data.radarr_data.filtered_collections = Some(filtered_collections);
app.data.radarr_data.search = Some("Test 2".into());
CollectionsHandler::with(
@@ -473,6 +548,8 @@ mod tests {
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.current_selection()
.title
.text,
@@ -507,12 +584,25 @@ mod tests {
)
.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!(
app
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.current_selection()
.title
.text,
@@ -547,7 +637,7 @@ mod tests {
)
.handle();
assert!(app.data.radarr_data.filtered_collections.items.is_empty());
assert!(app.data.radarr_data.filtered_collections.is_none());
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterCollectionsError.into()
@@ -715,7 +805,6 @@ mod tests {
RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS,
};
use crate::models::StatefulTable;
use crate::{assert_refresh_key, test_edit_collection_key};
use super::*;
@@ -784,7 +873,7 @@ mod tests {
assert!(app.data.radarr_data.is_filtering);
assert!(app.should_ignore_quit_key);
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]
+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::{
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::utils::strip_non_search_characters;
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) {
if self.active_radarr_block == &ActiveRadarrBlock::Collections {
if !self
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{
self.app.data.radarr_data.filtered_collections.scroll_up();
if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut() {
filtered_collections.scroll_up();
} else {
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) {
if self.active_radarr_block == &ActiveRadarrBlock::Collections {
if !self
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{
self.app.data.radarr_data.filtered_collections.scroll_down();
if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut() {
filtered_collections.scroll_down();
} else {
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) {
match self.active_radarr_block {
ActiveRadarrBlock::Collections => {
if !self
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut()
{
self
.app
.data
.radarr_data
.filtered_collections
.scroll_to_top();
filtered_collections.scroll_to_top();
} else {
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) {
match self.active_radarr_block {
ActiveRadarrBlock::Collections => {
if !self
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
if let Some(filtered_collections) = self.app.data.radarr_data.filtered_collections.as_mut()
{
self
.app
.data
.radarr_data
.filtered_collections
.scroll_to_bottom();
filtered_collections.scroll_to_bottom();
} else {
self.app.data.radarr_data.collections.scroll_to_bottom()
}
@@ -212,23 +176,17 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
.app
.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()),
ActiveRadarrBlock::SearchCollection => {
if self
.app
.data
.radarr_data
.filtered_collections
.items
.is_empty()
{
if self.app.data.radarr_data.filtered_collections.is_some() {
search_table!(
self.app,
collections,
ActiveRadarrBlock::SearchCollectionError
filtered_collections,
ActiveRadarrBlock::SearchCollectionError,
true
);
} else {
search_table!(
self.app,
filtered_collections,
collections,
ActiveRadarrBlock::SearchCollectionError
);
}
@@ -3,7 +3,7 @@ use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::models::servarr_data::radarr::radarr_data::{
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::{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) {
match self.active_radarr_block {
ActiveRadarrBlock::AddMovieSearchResults => {
self.app.data.radarr_data.add_searched_movies.scroll_up()
}
ActiveRadarrBlock::AddMovieSearchResults => self
.app
.data
.radarr_data
.add_searched_movies
.as_mut()
.unwrap()
.scroll_up(),
ActiveRadarrBlock::AddMovieSelectMonitor => self
.app
.data
@@ -89,9 +94,14 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
fn handle_scroll_down(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::AddMovieSearchResults => {
self.app.data.radarr_data.add_searched_movies.scroll_down()
}
ActiveRadarrBlock::AddMovieSearchResults => self
.app
.data
.radarr_data
.add_searched_movies
.as_mut()
.unwrap()
.scroll_down(),
ActiveRadarrBlock::AddMovieSelectMonitor => self
.app
.data
@@ -140,6 +150,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
.data
.radarr_data
.add_searched_movies
.as_mut()
.unwrap()
.scroll_to_top(),
ActiveRadarrBlock::AddMovieSelectMonitor => self
.app
@@ -205,6 +217,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
.data
.radarr_data
.add_searched_movies
.as_mut()
.unwrap()
.scroll_to_bottom(),
ActiveRadarrBlock::AddMovieSelectMonitor => self
.app
@@ -312,19 +326,15 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
self.app.should_ignore_quit_key = false;
}
_ if *self.active_radarr_block == ActiveRadarrBlock::AddMovieSearchResults
&& !self
.app
.data
.radarr_data
.add_searched_movies
.items
.is_empty() =>
&& self.app.data.radarr_data.add_searched_movies.is_some() =>
{
let tmdb_id = self
.app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.tmdb_id
.clone();
@@ -403,7 +413,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
}
ActiveRadarrBlock::AddMovieSearchResults | ActiveRadarrBlock::AddMovieEmptySearchResults => {
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;
}
ActiveRadarrBlock::AddMoviePrompt => {
@@ -21,21 +21,65 @@ mod tests {
use crate::models::servarr_data::radarr::modals::AddMovieModal;
use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS;
use crate::models::BlockSelectionState;
use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
use crate::models::{BlockSelectionState, StatefulTable};
use crate::simple_stateful_iterable_vec;
use super::*;
test_iterable_scroll!(
test_add_movie_search_results_scroll,
AddMovieHandler,
add_searched_movies,
simple_stateful_iterable_vec!(AddMovieSearchResult, HorizontallyScrollableText),
ActiveRadarrBlock::AddMovieSearchResults,
None,
title,
to_string
);
#[rstest]
fn test_add_movie_search_results_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(simple_stateful_iterable_vec!(
AddMovieSearchResult,
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]
fn test_add_movie_select_monitor_scroll(
@@ -302,21 +346,64 @@ mod tests {
mod test_handle_home_end {
use strum::IntoEnumIterator;
use crate::extended_stateful_iterable_vec;
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::*;
test_iterable_home_and_end!(
test_add_movie_search_results_home_end,
AddMovieHandler,
add_searched_movies,
extended_stateful_iterable_vec!(AddMovieSearchResult, HorizontallyScrollableText),
ActiveRadarrBlock::AddMovieSearchResults,
None,
title,
to_string
);
#[test]
fn test_add_movie_search_results_home_end() {
let mut app = App::default();
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(extended_stateful_iterable_vec!(
AddMovieSearchResult,
HorizontallyScrollableText
));
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]
fn test_add_movie_select_monitor_home_end() {
@@ -765,7 +852,7 @@ mod tests {
use crate::models::radarr_models::Movie;
use crate::models::servarr_data::radarr::modals::AddMovieModal;
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 super::*;
@@ -818,11 +905,9 @@ mod tests {
#[test]
fn test_add_movie_search_results_submit() {
let mut app = App::default();
app
.data
.radarr_data
.add_searched_movies
.set_items(vec![AddMovieSearchResult::default()]);
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(1, "B - Test 2".to_owned()), (0, "A - Test 1".to_owned())]);
@@ -904,11 +989,9 @@ mod tests {
#[test]
fn test_add_movie_search_results_submit_movie_already_in_library() {
let mut app = App::default();
app
.data
.radarr_data
.add_searched_movies
.set_items(vec![AddMovieSearchResult::default()]);
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
app
.data
.radarr_data
@@ -1063,6 +1146,7 @@ mod tests {
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::StatefulTable;
use crate::{assert_search_reset, simple_stateful_iterable_vec};
use super::*;
@@ -1123,14 +1207,12 @@ mod tests {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
app.push_navigation_stack(active_radarr_block.into());
app
.data
.radarr_data
.add_searched_movies
.set_items(simple_stateful_iterable_vec!(
AddMovieSearchResult,
HorizontallyScrollableText
));
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(simple_stateful_iterable_vec!(
AddMovieSearchResult,
HorizontallyScrollableText
));
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
AddMovieHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
@@ -1138,7 +1220,7 @@ mod tests {
app.get_current_route(),
&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);
}
@@ -18,6 +18,7 @@ mod tests {
use crate::test_handler_delegation;
mod test_handle_scroll_up_and_down {
use crate::models::StatefulTable;
use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
use super::*;
@@ -33,21 +34,54 @@ mod tests {
to_string
);
test_iterable_scroll!(
test_filtered_movies_scroll,
LibraryHandler,
filtered_movies,
simple_stateful_iterable_vec!(Movie, HorizontallyScrollableText),
ActiveRadarrBlock::Movies,
None,
title,
to_string
);
#[rstest]
fn test_filtered_movies_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
let mut filtered_movies = StatefulTable::default();
filtered_movies.set_items(simple_stateful_iterable_vec!(
Movie,
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 {
use pretty_assertions::assert_eq;
use crate::models::StatefulTable;
use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end};
use super::*;
@@ -63,16 +97,58 @@ mod tests {
to_string
);
test_iterable_home_and_end!(
test_filtered_movies_home_end,
LibraryHandler,
filtered_movies,
extended_stateful_iterable_vec!(Movie, HorizontallyScrollableText),
ActiveRadarrBlock::Movies,
None,
title,
to_string
);
#[test]
fn test_filtered_movies_home_end() {
let mut app = App::default();
let mut filtered_movies = StatefulTable::default();
filtered_movies.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
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]
fn test_movie_search_box_home_end_keys() {
@@ -367,6 +443,7 @@ mod tests {
use pretty_assertions::assert_eq;
use crate::extended_stateful_iterable_vec;
use crate::models::StatefulTable;
use crate::network::radarr_network::RadarrEvent;
use super::*;
@@ -453,14 +530,12 @@ mod tests {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
app
.data
.radarr_data
.filtered_movies
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
let mut filtered_movies = StatefulTable::default();
filtered_movies.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.filtered_movies = Some(filtered_movies);
app.data.radarr_data.search = Some("Test 2".into());
LibraryHandler::with(
@@ -476,6 +551,8 @@ mod tests {
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.title
.text,
@@ -507,12 +584,25 @@ mod tests {
)
.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!(
app
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.title
.text,
@@ -544,7 +634,7 @@ mod tests {
)
.handle();
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::FilterMoviesError.into()
@@ -688,7 +778,6 @@ mod tests {
RadarrData, EDIT_MOVIE_SELECTION_BLOCKS,
};
use crate::models::StatefulTable;
use crate::{assert_refresh_key, test_edit_movie_key};
use super::*;
@@ -757,7 +846,7 @@ mod tests {
assert!(app.data.radarr_data.is_filtering);
assert!(app.should_ignore_quit_key);
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]
+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::{
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::utils::strip_non_search_characters;
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) {
if self.active_radarr_block == &ActiveRadarrBlock::Movies {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() {
self.app.data.radarr_data.filtered_movies.scroll_up();
if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
filtered_movies.scroll_up();
} else {
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) {
if self.active_radarr_block == &ActiveRadarrBlock::Movies {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() {
self.app.data.radarr_data.filtered_movies.scroll_down();
if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
filtered_movies.scroll_down();
} else {
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) {
match self.active_radarr_block {
ActiveRadarrBlock::Movies => {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() {
self.app.data.radarr_data.filtered_movies.scroll_to_top();
if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
filtered_movies.scroll_to_top();
} else {
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) {
match self.active_radarr_block {
ActiveRadarrBlock::Movies => {
if !self.app.data.radarr_data.filtered_movies.items.is_empty() {
self.app.data.radarr_data.filtered_movies.scroll_to_bottom();
if let Some(filtered_movies) = self.app.data.radarr_data.filtered_movies.as_mut() {
filtered_movies.scroll_to_bottom();
} else {
self.app.data.radarr_data.movies.scroll_to_bottom()
}
@@ -199,14 +199,15 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
.app
.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()),
ActiveRadarrBlock::SearchMovie => {
if self.app.data.radarr_data.filtered_movies.items.is_empty() {
search_table!(self.app, movies, ActiveRadarrBlock::SearchMovieError);
} else {
if self.app.data.radarr_data.filtered_movies.is_some() {
search_table!(
self.app,
filtered_movies,
ActiveRadarrBlock::SearchMovieError
ActiveRadarrBlock::SearchMovieError,
true
);
} else {
search_table!(self.app, movies, ActiveRadarrBlock::SearchMovieError);
}
}
ActiveRadarrBlock::FilterMovies => {
@@ -477,7 +477,7 @@ fn sort_releases_by_selected_field(
.cmp(release_b.size.as_u64().as_ref().unwrap())
},
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
.seeders
.as_ref()
@@ -914,7 +914,7 @@ mod tests {
use crate::models::servarr_data::radarr::radarr_data::{
RadarrData, EDIT_MOVIE_SELECTION_BLOCKS,
};
use crate::models::StatefulTable;
use crate::test_edit_movie_key;
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_rules! search_table {
($app:expr, $data_ref:ident, $error_block:expr) => {
let search_index = if $app.data.radarr_data.search.is_some() {
let search_string = $app
.data
.radarr_data
.search
.as_ref()
.unwrap()
.text
.clone()
.to_lowercase();
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;
@@ -151,44 +143,65 @@ macro_rules! search_table {
$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_rules! filter_table {
($app:expr, $source_table_ref:ident, $filter_table_ref:ident, $error_block:expr) => {
let empty_filter = $app.data.radarr_data.filter.is_some()
&& $app
.data
.radarr_data
.filter
.as_ref()
.unwrap()
.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());
let empty_filter = match $app.data.radarr_data.filter.as_ref() {
Some(filter) if filter.text.is_empty() => true,
_ => false,
};
let filter_matches = match $app.data.radarr_data.filter.as_ref() {
Some(filter) if !filter.text.is_empty() => {
let scrubbed_filter = strip_non_search_characters(&filter.text.clone());
$app
.data
.radarr_data
.$source_table_ref
.items
.iter()
.filter(|item| strip_non_search_characters(&item.title.text).contains(&filter))
.cloned()
.collect()
} else {
Vec::new()
$app
.data
.radarr_data
.$source_table_ref
.items
.iter()
.filter(|item| strip_non_search_characters(&item.title.text).contains(&scrubbed_filter))
.cloned()
.collect()
}
_ => Vec::new(),
};
$app.data.radarr_data.filter = None;
@@ -201,11 +214,9 @@ macro_rules! filter_table {
$app.pop_navigation_stack();
} else {
$app.pop_navigation_stack();
$app
.data
.radarr_data
.$filter_table_ref
.set_items(filter_matches);
let mut filter_table = StatefulTable::default();
filter_table.set_items(filter_matches);
$app.data.radarr_data.$filter_table_ref = Some(filter_table);
}
};
}
@@ -11,7 +11,7 @@ mod utils {
(1111, "Any".to_owned()),
]),
tags_map: BiMap::from_iter([(1, "test".to_owned())]),
filtered_movies: StatefulTable::default(),
filtered_movies: None,
..create_test_radarr_data()
};
radarr_data.movies.set_items(vec![Movie {
@@ -126,7 +126,7 @@ mod utils {
(2222, "HD - 1080p".to_owned()),
(1111, "Any".to_owned()),
]),
filtered_collections: StatefulTable::default(),
filtered_collections: None,
..create_test_radarr_data()
};
radarr_data.collections.set_items(vec![Collection {
@@ -10,7 +10,7 @@ mod tests {
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::Movie;
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::{
extended_stateful_iterable_vec, filter_table, search_table, test_handler_delegation,
@@ -130,9 +130,22 @@ mod tests {
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!(
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"
);
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
@@ -165,7 +178,7 @@ mod tests {
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!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key);
@@ -196,7 +209,7 @@ mod tests {
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::FilterMoviesError.into()
@@ -229,7 +242,7 @@ mod tests {
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::FilterMoviesError.into()
+6 -6
View File
@@ -43,10 +43,10 @@ impl From<&RadarrData<'_>> for EditMovieModal {
minimum_availability,
quality_profile_id,
..
} = if radarr_data.filtered_movies.items.is_empty() {
radarr_data.movies.current_selection()
} = if let Some(filtered_movies) = radarr_data.filtered_movies.as_ref() {
filtered_movies.current_selection()
} else {
radarr_data.filtered_movies.current_selection()
radarr_data.movies.current_selection()
};
edit_movie_modal
@@ -159,10 +159,10 @@ impl From<&RadarrData<'_>> for EditCollectionModal {
minimum_availability,
quality_profile_id,
..
} = if radarr_data.filtered_collections.items.is_empty() {
radarr_data.collections.current_selection()
} = if let Some(filtered_collections) = radarr_data.filtered_collections.as_ref() {
filtered_collections.current_selection()
} else {
radarr_data.filtered_collections.current_selection()
radarr_data.collections.current_selection()
};
edit_collection_modal.path = root_folder_path.clone().unwrap_or_default().into();
@@ -21,7 +21,7 @@ mod test {
(1111, "Any".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()
};
let movie = Movie {
@@ -34,7 +34,9 @@ mod test {
};
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 {
radarr_data.movies.set_items(vec![movie]);
}
@@ -111,7 +113,7 @@ mod test {
(2222, "HD - 1080p".to_owned()),
(1111, "Any".to_owned()),
]),
filtered_collections: StatefulTable::default(),
filtered_collections: None,
..create_test_radarr_data()
};
let collection = Collection {
@@ -124,7 +126,9 @@ mod test {
};
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 {
radarr_data.collections.set_items(vec![collection]);
}
+15 -15
View File
@@ -35,33 +35,33 @@ pub struct RadarrData<'a> {
pub version: String,
pub start_time: DateTime<Utc>,
pub movies: StatefulTable<Movie>,
pub filtered_movies: StatefulTable<Movie>,
pub add_searched_movies: StatefulTable<AddMovieSearchResult>,
pub selected_block: BlockSelectionState<'a, ActiveRadarrBlock>,
pub downloads: StatefulTable<DownloadRecord>,
pub indexers: StatefulTable<Indexer>,
pub indexer_settings: Option<IndexerSettings>,
pub quality_profile_map: BiMap<u64, String>,
pub tags_map: BiMap<u64, String>,
pub collections: StatefulTable<Collection>,
pub filtered_collections: StatefulTable<Collection>,
pub collection_movies: StatefulTable<CollectionMovie>,
pub logs: StatefulList<HorizontallyScrollableText>,
pub log_details: StatefulList<HorizontallyScrollableText>,
pub tasks: StatefulTable<Task>,
pub queued_events: StatefulTable<QueueEvent>,
pub updates: ScrollableText,
pub prompt_confirm_action: Option<RadarrEvent>,
pub main_tabs: TabState,
pub movie_info_tabs: TabState,
pub search: Option<HorizontallyScrollableText>,
pub filter: Option<HorizontallyScrollableText>,
pub add_movie_modal: Option<AddMovieModal>,
pub add_searched_movies: Option<StatefulTable<AddMovieSearchResult>>,
pub edit_movie_modal: Option<EditMovieModal>,
pub edit_collection_modal: Option<EditCollectionModal>,
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 prompt_confirm: bool,
pub prompt_confirm_action: Option<RadarrEvent>,
pub delete_movie_files: bool,
pub add_list_exclusion: bool,
pub is_searching: bool,
@@ -78,16 +78,16 @@ impl<'a> RadarrData<'a> {
self.is_searching = false;
self.search = None;
self.filter = None;
self.filtered_movies = StatefulTable::default();
self.filtered_collections = StatefulTable::default();
self.add_searched_movies = StatefulTable::default();
self.filtered_movies = None;
self.filtered_collections = None;
self.add_searched_movies = None;
}
pub fn reset_filter(&mut self) {
self.is_filtering = false;
self.filter = None;
self.filtered_movies = StatefulTable::default();
self.filtered_collections = StatefulTable::default();
self.filtered_movies = None;
self.filtered_collections = None;
}
pub fn reset_movie_info_tabs(&mut self) {
@@ -104,33 +104,33 @@ impl<'a> Default for RadarrData<'a> {
version: String::default(),
start_time: DateTime::default(),
movies: StatefulTable::default(),
add_searched_movies: StatefulTable::default(),
selected_block: BlockSelectionState::default(),
filtered_movies: StatefulTable::default(),
downloads: StatefulTable::default(),
indexers: StatefulTable::default(),
indexer_settings: None,
quality_profile_map: BiMap::default(),
tags_map: BiMap::default(),
collections: StatefulTable::default(),
filtered_collections: StatefulTable::default(),
collection_movies: StatefulTable::default(),
logs: StatefulList::default(),
log_details: StatefulList::default(),
tasks: StatefulTable::default(),
queued_events: StatefulTable::default(),
updates: ScrollableText::default(),
prompt_confirm_action: None,
search: None,
filter: None,
add_movie_modal: None,
add_searched_movies: None,
edit_movie_modal: None,
edit_collection_modal: None,
edit_root_folder: None,
filtered_collections: None,
filtered_movies: None,
indexer_settings: None,
movie_details_modal: None,
is_searching: false,
is_filtering: false,
prompt_confirm: false,
prompt_confirm_action: None,
delete_movie_files: false,
add_list_exclusion: false,
main_tabs: TabState::new(vec![
@@ -79,32 +79,32 @@ mod tests {
assert!(radarr_data.version.is_empty());
assert_eq!(radarr_data.start_time, <DateTime<Utc>>::default());
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!(radarr_data.filtered_movies.items.is_empty());
assert!(radarr_data.downloads.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.tags_map.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.logs.items.is_empty());
assert!(radarr_data.log_details.items.is_empty());
assert!(radarr_data.tasks.items.is_empty());
assert!(radarr_data.queued_events.items.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.filter.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_collection_modal.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.is_searching);
assert!(!radarr_data.is_filtering);
assert!(radarr_data.prompt_confirm_action.is_none());
assert!(!radarr_data.prompt_confirm);
assert!(!radarr_data.delete_movie_files);
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::radarr_data::RadarrData;
use crate::models::{HorizontallyScrollableText, ScrollableText};
use crate::models::{HorizontallyScrollableText, ScrollableText, StatefulTable};
pub fn create_test_radarr_data<'a>() -> RadarrData<'a> {
let mut movie_details_modal = MovieDetailsModal {
@@ -39,17 +39,26 @@ pub mod utils {
filter: Some("test filter".into()),
edit_root_folder: Some("test path".into()),
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()
};
radarr_data.movie_info_tabs.index = 1;
radarr_data
.filtered_movies
.as_mut()
.unwrap()
.set_items(vec![Movie::default()]);
radarr_data
.filtered_collections
.as_mut()
.unwrap()
.set_items(vec![Collection::default()]);
radarr_data
.add_searched_movies
.as_mut()
.unwrap()
.set_items(vec![AddMovieSearchResult::default()]);
radarr_data
.collection_movies
@@ -67,9 +76,9 @@ pub mod utils {
assert!(!$radarr_data.is_searching);
assert!($radarr_data.search.is_none());
assert!($radarr_data.filter.is_none());
assert!($radarr_data.filtered_movies.items.is_empty());
assert!($radarr_data.filtered_collections.items.is_empty());
assert!($radarr_data.add_searched_movies.items.is_empty());
assert!($radarr_data.filtered_movies.is_none());
assert!($radarr_data.filtered_collections.is_none());
assert!($radarr_data.add_searched_movies.is_none());
};
}
@@ -78,8 +87,8 @@ pub mod utils {
($radarr_data:expr) => {
assert!(!$radarr_data.is_filtering);
assert!($radarr_data.filter.is_none());
assert!($radarr_data.filtered_movies.items.is_empty());
assert!($radarr_data.filtered_collections.items.is_empty());
assert!($radarr_data.filtered_movies.is_none());
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,
};
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::utils::{convert_runtime, convert_to_gb};
@@ -191,6 +191,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.clone();
(tmdb_id, title.text)
@@ -200,6 +202,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.clone();
(tmdb_id, title.text)
@@ -688,24 +692,24 @@ impl<'a, 'b> Network<'a, 'b> {
.await;
self
.handle_request::<(), Vec<Credit>>(request_props, |credit_vec, mut app| {
let cast_vec: Vec<Credit> = credit_vec
.iter()
.cloned()
.filter(|credit| credit.credit_type == CreditType::Cast)
.collect();
let crew_vec: Vec<Credit> = credit_vec
.iter()
.cloned()
.filter(|credit| credit.credit_type == CreditType::Crew)
.collect();
.handle_request::<(), Vec<Credit>>(request_props, |credit_vec, mut app| {
let cast_vec: Vec<Credit> = credit_vec
.iter()
.cloned()
.filter(|credit| credit.credit_type == CreditType::Cast)
.collect();
let crew_vec: Vec<Credit> = credit_vec
.iter()
.cloned()
.filter(|credit| credit.credit_type == CreditType::Crew)
.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_crew.set_items(crew_vec);
})
.await;
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);
})
.await;
}
async fn get_diskspace(&mut self) {
@@ -1020,20 +1024,20 @@ impl<'a, 'b> Network<'a, 'b> {
.await;
self
.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");
let mut reversed_movie_history_vec = movie_history_vec.to_vec();
reversed_movie_history_vec.reverse();
app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_history
.set_items(reversed_movie_history_vec)
})
.await;
.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");
let mut reversed_movie_history_vec = movie_history_vec.to_vec();
reversed_movie_history_vec.reverse();
app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_history
.set_items(reversed_movie_history_vec)
})
.await;
}
async fn get_movies(&mut self) {
@@ -1118,11 +1122,11 @@ impl<'a, 'b> Network<'a, 'b> {
.await;
self
.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");
app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_releases.set_items(release_vec);
})
.await;
.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");
app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_releases.set_items(release_vec);
})
.await;
}
async fn get_root_folders(&mut self) {
@@ -1325,12 +1329,14 @@ impl<'a, 'b> Network<'a, 'b> {
app.pop_and_push_navigation_stack(
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 {
app
.data
.radarr_data
.add_searched_movies
.set_items(movie_vec);
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(movie_vec);
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
}
})
.await;
@@ -1568,12 +1574,14 @@ impl<'a, 'b> Network<'a, 'b> {
async fn extract_movie_id(&mut self) -> (u64, u64) {
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
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.id
.as_u64()
@@ -1582,6 +1590,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data
.radarr_data
.filtered_movies
.as_ref()
.unwrap()
.current_selection()
.tmdb_id
.as_u64()
@@ -1610,15 +1620,14 @@ impl<'a, 'b> Network<'a, 'b> {
}
async fn extract_collection_id(&mut self) -> u64 {
if !self
if self
.app
.lock()
.await
.data
.radarr_data
.filtered_collections
.items
.is_empty()
.is_some()
{
self
.app
@@ -1627,6 +1636,8 @@ impl<'a, 'b> Network<'a, 'b> {
.data
.radarr_data
.filtered_collections
.as_ref()
.unwrap()
.current_selection()
.id
.as_u64()
+125 -31
View File
@@ -17,7 +17,7 @@ mod test {
Monitor, MovieFile, Quality, QualityWrapper, Rating, RatingsList,
};
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::HorizontallyScrollableText;
use crate::models::{HorizontallyScrollableText, StatefulTable};
use crate::App;
use super::super::*;
@@ -375,6 +375,13 @@ mod test {
.await;
async_server.assert_async().await;
assert!(app_arc
.lock()
.await
.data
.radarr_data
.add_searched_movies
.is_some());
assert_eq!(
app_arc
.lock()
@@ -382,6 +389,8 @@ mod test {
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.items,
vec![add_movie_search_result()]
);
@@ -437,8 +446,7 @@ mod test {
.data
.radarr_data
.add_searched_movies
.items
.is_empty());
.is_none());
assert_eq!(
app_arc.lock().await.get_current_route(),
&ActiveRadarrBlock::AddMovieEmptySearchResults.into()
@@ -487,8 +495,7 @@ mod test {
.data
.radarr_data
.add_searched_movies
.items
.is_empty());
.is_none());
assert_eq!(
app_arc.lock().await.get_current_route(),
&ActiveRadarrBlock::Movies.into()
@@ -1599,11 +1606,9 @@ mod test {
.set_items(vec![collection_movie()]);
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
} else {
app
.data
.radarr_data
.add_searched_movies
.set_items(vec![add_movie_search_result()]);
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![add_movie_search_result()]);
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
}
}
let mut network = Network::new(&app_arc, CancellationToken::new());
@@ -1620,6 +1625,103 @@ mod test {
.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]
async fn test_handle_add_root_folder_event() {
let (async_server, app_arc, _server) = mock_radarr_api(
@@ -1916,17 +2018,13 @@ mod test {
#[tokio::test]
async fn test_extract_movie_id_filtered_movies() {
let app_arc = Arc::new(Mutex::new(App::default()));
app_arc
.lock()
.await
.data
.radarr_data
.filtered_movies
.set_items(vec![Movie {
id: Number::from(1),
tmdb_id: Number::from(2),
..Movie::default()
}]);
let mut filtered_movies = StatefulTable::default();
filtered_movies.set_items(vec![Movie {
id: Number::from(1),
tmdb_id: Number::from(2),
..Movie::default()
}]);
app_arc.lock().await.data.radarr_data.filtered_movies = Some(filtered_movies);
let mut network = Network::new(&app_arc, CancellationToken::new());
assert_eq!(network.extract_movie_id().await, (1, 2));
@@ -1953,16 +2051,12 @@ mod test {
#[tokio::test]
async fn test_extract_collection_id_filtered_collection() {
let app_arc = Arc::new(Mutex::new(App::default()));
app_arc
.lock()
.await
.data
.radarr_data
.filtered_collections
.set_items(vec![Collection {
id: Number::from(1),
..Collection::default()
}]);
let mut filtered_collections = StatefulTable::default();
filtered_collections.set_items(vec![Collection {
id: Number::from(1),
..Collection::default()
}]);
app_arc.lock().await.data.radarr_data.filtered_collections = Some(filtered_collections);
let mut network = Network::new(&app_arc, CancellationToken::new());
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 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 constraints: Vec<Constraint>,
pub help: Option<String>,
@@ -319,6 +320,7 @@ fn draw_table<'a, B, T, F>(
{
let TableProps {
content,
wrapped_content,
table_headers,
constraints,
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);
if !content.items.is_empty() {
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);
if wrapped_content.is_some() && wrapped_content.as_ref().unwrap().is_some() {
draw_table_contents(
f,
block,
row_mapper,
highlight,
wrapped_content.unwrap().as_mut().unwrap(),
table_headers,
&constraints,
content_area,
);
} else if content.is_some() && !content.as_ref().unwrap().items.is_empty() {
draw_table_contents(
f,
block,
row_mapper,
highlight,
content.unwrap(),
table_headers,
&constraints,
content_area,
);
} else {
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) {
if is_loading {
let text = "\n\n Loading ...\n\n".to_owned();
@@ -80,15 +80,12 @@ pub fn draw_collection_details<B: Backend>(
content_area,
1,
);
let collection_selection = if !app.data.radarr_data.filtered_collections.items.is_empty() {
app
.data
.radarr_data
.filtered_collections
.current_selection()
} else {
app.data.radarr_data.collections.current_selection()
};
let collection_selection =
if let Some(filtered_collections) = app.data.radarr_data.filtered_collections.as_ref() {
filtered_collections.current_selection()
} else {
app.data.radarr_data.collections.current_selection()
};
let quality_profile = app
.data
.radarr_data
@@ -161,7 +158,8 @@ pub fn draw_collection_details<B: Backend>(
chunks[1],
layout_block_top_border_with_title(title_style("Movies")),
TableProps {
content: &mut app.data.radarr_data.collection_movies,
content: Some(&mut app.data.radarr_data.collection_movies),
wrapped_content: None,
table_headers: vec![
"",
"Title",
@@ -97,20 +97,10 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
prompt_area: Rect,
) {
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
.data
.radarr_data
.collections
.current_selection()
.title
.text
.clone(),
app
.data
.radarr_data
.collections
filtered_collections.current_selection().title.text.clone(),
filtered_collections
.current_selection()
.overview
.clone()
@@ -121,7 +111,7 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
app
.data
.radarr_data
.filtered_collections
.collections
.current_selection()
.title
.text
@@ -129,7 +119,7 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
app
.data
.radarr_data
.filtered_collections
.collections
.current_selection()
.overview
.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) {
let current_selection = if !app.data.radarr_data.filtered_collections.items.is_empty() {
app
.data
.radarr_data
.filtered_collections
.current_selection()
.clone()
} else if !app.data.radarr_data.collections.items.is_empty() {
app.data.radarr_data.collections.current_selection().clone()
} else {
Collection::default()
};
let current_selection =
if let Some(filtered_collections) = app.data.radarr_data.filtered_collections.as_ref() {
filtered_collections.current_selection().clone()
} 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 content = if !app.data.radarr_data.filtered_collections.items.is_empty()
&& !app.data.radarr_data.is_filtering
{
&mut app.data.radarr_data.filtered_collections
} else {
&mut app.data.radarr_data.collections
let content = match app.data.radarr_data.filtered_collections.as_mut() {
Some(filtered_collections) if !app.data.radarr_data.is_filtering => Some(filtered_collections),
_ => Some(&mut app.data.radarr_data.collections),
};
draw_table(
f,
@@ -126,6 +119,7 @@ pub(super) fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'
layout_block_top_border(),
TableProps {
content,
wrapped_content: None,
table_headers: vec![
"Collection",
"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,
layout_block_top_border(),
TableProps {
content: &mut app.data.radarr_data.downloads,
content: Some(&mut app.data.radarr_data.downloads),
wrapped_content: None,
table_headers: vec![
"Title",
"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,
layout_block_top_border(),
TableProps {
content: &mut app.data.radarr_data.indexers,
content: Some(&mut app.data.radarr_data.indexers),
wrapped_content: None,
table_headers: vec![
"Indexer",
"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) {
let current_selection = if app.data.radarr_data.add_searched_movies.items.is_empty() {
AddMovieSearchResult::default()
} else {
app
.data
.radarr_data
.add_searched_movies
.current_selection()
.clone()
};
let is_loading = app.is_loading || app.data.radarr_data.add_searched_movies.is_none();
let current_selection =
if let Some(add_searched_movies) = app.data.radarr_data.add_searched_movies.as_ref() {
add_searched_movies.current_selection().clone()
} else {
AddMovieSearchResult::default()
};
let chunks = vertical_chunks_with_margin(
vec![
@@ -181,7 +178,8 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, ar
chunks[1],
layout_block(),
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![
"",
"Title",
@@ -260,7 +258,7 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, ar
])
.style(style_primary())
},
app.is_loading,
is_loading,
true,
);
}
@@ -354,6 +352,8 @@ fn draw_confirmation_prompt<B: Backend>(
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.text,
@@ -361,6 +361,8 @@ fn draw_confirmation_prompt<B: Backend>(
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.overview
.clone(),
+25 -37
View File
@@ -93,43 +93,31 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
app: &mut App<'_>,
prompt_area: Rect,
) {
let (movie_title, movie_overview) = if app.data.radarr_data.filtered_movies.items.is_empty() {
(
app
.data
.radarr_data
.movies
.current_selection()
.title
.text
.clone(),
app
.data
.radarr_data
.movies
.current_selection()
.overview
.clone(),
)
} else {
(
app
.data
.radarr_data
.filtered_movies
.current_selection()
.title
.text
.clone(),
app
.data
.radarr_data
.filtered_movies
.current_selection()
.overview
.clone(),
)
};
let (movie_title, movie_overview) =
if let Some(filtered_movies) = app.data.radarr_data.filtered_movies.as_ref() {
(
filtered_movies.current_selection().title.text.clone(),
filtered_movies.current_selection().overview.clone(),
)
} else {
(
app
.data
.radarr_data
.movies
.current_selection()
.title
.text
.clone(),
app
.data
.radarr_data
.movies
.current_selection()
.overview
.clone(),
)
};
let title = format!("Edit - {}", movie_title);
let yes_no_value = app.data.radarr_data.prompt_confirm;
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) {
let current_selection = if !app.data.radarr_data.filtered_movies.items.is_empty() {
app
.data
.radarr_data
.filtered_movies
.current_selection()
.clone()
} else if !app.data.radarr_data.movies.items.is_empty() {
app.data.radarr_data.movies.current_selection().clone()
} else {
Movie::default()
};
let current_selection =
if let Some(filtered_movies) = app.data.radarr_data.filtered_movies.as_ref() {
filtered_movies.current_selection().clone()
} 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 tags_map = &app.data.radarr_data.tags_map;
let downloads_vec = &app.data.radarr_data.downloads.items;
let content = if !app.data.radarr_data.filtered_movies.items.is_empty()
&& !app.data.radarr_data.is_filtering
{
&mut app.data.radarr_data.filtered_movies
} else {
&mut app.data.radarr_data.movies
let content = match app.data.radarr_data.filtered_movies.as_mut() {
Some(filtered_movies) if !app.data.radarr_data.is_filtering => Some(filtered_movies),
_ => Some(&mut app.data.radarr_data.movies),
};
draw_table(
@@ -137,6 +130,7 @@ pub(super) fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>,
layout_block_top_border(),
TableProps {
content,
wrapped_content: None,
table_headers: vec![
"Title",
"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,
layout_block_top_border(),
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"],
constraints: vec![
Constraint::Percentage(34),
@@ -326,13 +327,16 @@ fn draw_movie_cast<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_
content_area,
layout_block_top_border(),
TableProps {
content: &mut app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_cast,
content: Some(
&mut app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_cast,
),
wrapped_content: None,
constraints: iter::repeat(Constraint::Ratio(1, 2)).take(2).collect(),
table_headers: vec!["Cast Member", "Character"],
help: app
@@ -365,13 +369,16 @@ fn draw_movie_crew<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_
content_area,
layout_block_top_border(),
TableProps {
content: &mut app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_crew,
content: Some(
&mut app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_crew,
),
wrapped_content: None,
constraints: iter::repeat(Constraint::Ratio(1, 3)).take(3).collect(),
table_headers: vec!["Crew Member", "Job", "Department"],
help: app
@@ -455,13 +462,16 @@ fn draw_movie_releases<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, cont
content_area,
layout_block_top_border(),
TableProps {
content: &mut app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_releases,
content: Some(
&mut app
.data
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.movie_releases,
),
wrapped_content: None,
constraints: vec![
Constraint::Length(9),
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,
layout_block_top_border(),
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"],
constraints: vec![
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,
title_block("Tasks"),
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(),
constraints: TASK_TABLE_CONSTRAINTS.to_vec(),
help: None,
@@ -134,7 +135,8 @@ pub(super) fn draw_queued_events<B: Backend>(f: &mut Frame<'_, B>, app: &mut App
area,
title_block("Queued Events"),
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"],
constraints: vec![
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,
borderless_block(),
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(),
constraints: TASK_TABLE_CONSTRAINTS.to_vec(),
help: None,