Refactored the filter and search logic to follow the established modal logic and added some refactored functions to the UI module as well to clean up the UI code too
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "managarr"
|
name = "managarr"
|
||||||
version = "0.0.26"
|
version = "0.0.27"
|
||||||
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
||||||
description = "A TUI for managing *arr servers"
|
description = "A TUI for managing *arr servers"
|
||||||
keywords = ["managarr", "tui-rs", "dashboard", "servarr", "tui", "terminal"]
|
keywords = ["managarr", "tui-rs", "dashboard", "servarr", "tui", "terminal"]
|
||||||
|
|||||||
@@ -370,6 +370,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_search_collections_submit() {
|
fn test_search_collections_submit() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -398,11 +400,56 @@ mod tests {
|
|||||||
.text,
|
.text,
|
||||||
"Test 2"
|
"Test 2"
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::Collections.into()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_search_collections_submit_error_on_no_search_hits() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into());
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.collections
|
||||||
|
.set_items(extended_stateful_iterable_vec!(
|
||||||
|
Collection,
|
||||||
|
HorizontallyScrollableText
|
||||||
|
));
|
||||||
|
app.data.radarr_data.search = Some("Test 5".into());
|
||||||
|
|
||||||
|
CollectionsHandler::with(
|
||||||
|
&SUBMIT_KEY,
|
||||||
|
&mut app,
|
||||||
|
&ActiveRadarrBlock::SearchCollection,
|
||||||
|
&None,
|
||||||
|
)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert_str_eq!(
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.collections
|
||||||
|
.current_selection()
|
||||||
|
.title
|
||||||
|
.text,
|
||||||
|
"Test 1"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::SearchCollectionError.into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_search_filtered_collections_submit() {
|
fn test_search_filtered_collections_submit() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -431,11 +478,17 @@ mod tests {
|
|||||||
.text,
|
.text,
|
||||||
"Test 2"
|
"Test 2"
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::Collections.into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filter_collections_submit() {
|
fn test_filter_collections_submit() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -465,6 +518,40 @@ mod tests {
|
|||||||
.text,
|
.text,
|
||||||
"Test 1"
|
"Test 1"
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::Collections.into()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_filter_collections_submit_error_on_no_filter_matches() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into());
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.collections
|
||||||
|
.set_items(extended_stateful_iterable_vec!(
|
||||||
|
Collection,
|
||||||
|
HorizontallyScrollableText
|
||||||
|
));
|
||||||
|
app.data.radarr_data.filter = Some("Test 5".into());
|
||||||
|
|
||||||
|
CollectionsHandler::with(
|
||||||
|
&SUBMIT_KEY,
|
||||||
|
&mut app,
|
||||||
|
&ActiveRadarrBlock::FilterCollections,
|
||||||
|
&None,
|
||||||
|
)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert!(app.data.radarr_data.filtered_collections.items.is_empty());
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::FilterCollectionsError.into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -526,21 +613,21 @@ mod tests {
|
|||||||
|
|
||||||
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
|
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
|
||||||
|
|
||||||
#[test]
|
#[rstest]
|
||||||
fn test_search_collection_block_esc() {
|
fn test_search_collection_block_esc(
|
||||||
|
#[values(
|
||||||
|
ActiveRadarrBlock::SearchCollection,
|
||||||
|
ActiveRadarrBlock::SearchCollectionError
|
||||||
|
)]
|
||||||
|
active_radarr_block: ActiveRadarrBlock,
|
||||||
|
) {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
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(active_radarr_block.into());
|
||||||
app.data.radarr_data = create_test_radarr_data();
|
app.data.radarr_data = create_test_radarr_data();
|
||||||
|
|
||||||
CollectionsHandler::with(
|
CollectionsHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
|
||||||
&ESC_KEY,
|
|
||||||
&mut app,
|
|
||||||
&ActiveRadarrBlock::SearchCollection,
|
|
||||||
&None,
|
|
||||||
)
|
|
||||||
.handle();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.get_current_route(),
|
app.get_current_route(),
|
||||||
@@ -550,21 +637,21 @@ mod tests {
|
|||||||
assert_search_reset!(app.data.radarr_data);
|
assert_search_reset!(app.data.radarr_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[rstest]
|
||||||
fn test_filter_collections_block_esc() {
|
fn test_filter_collections_block_esc(
|
||||||
|
#[values(
|
||||||
|
ActiveRadarrBlock::FilterCollections,
|
||||||
|
ActiveRadarrBlock::FilterCollectionsError
|
||||||
|
)]
|
||||||
|
active_radarr_block: ActiveRadarrBlock,
|
||||||
|
) {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into());
|
app.push_navigation_stack(active_radarr_block.into());
|
||||||
app.data.radarr_data = create_test_radarr_data();
|
app.data.radarr_data = create_test_radarr_data();
|
||||||
|
|
||||||
CollectionsHandler::with(
|
CollectionsHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
|
||||||
&ESC_KEY,
|
|
||||||
&mut app,
|
|
||||||
&ActiveRadarrBlock::FilterCollections,
|
|
||||||
&None,
|
|
||||||
)
|
|
||||||
.handle();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.get_current_route(),
|
app.get_current_route(),
|
||||||
@@ -675,6 +762,31 @@ mod tests {
|
|||||||
assert!(app.data.radarr_data.filter.is_some());
|
assert!(app.data.radarr_data.filter.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_filter_collections_key_resets_previous_filter() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.should_ignore_quit_key = true;
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
|
||||||
|
app.data.radarr_data = create_test_radarr_data();
|
||||||
|
|
||||||
|
CollectionsHandler::with(
|
||||||
|
&DEFAULT_KEYBINDINGS.filter.key,
|
||||||
|
&mut app,
|
||||||
|
&ActiveRadarrBlock::Collections,
|
||||||
|
&None,
|
||||||
|
)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::FilterCollections.into()
|
||||||
|
);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collection_edit_key() {
|
fn test_collection_edit_key() {
|
||||||
test_edit_collection_key!(
|
test_edit_collection_key!(
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ use crate::app::App;
|
|||||||
use crate::event::Key;
|
use crate::event::Key;
|
||||||
use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler;
|
use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler;
|
||||||
use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler;
|
use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler;
|
||||||
use crate::handlers::radarr_handlers::{
|
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||||
filter_table, handle_change_tab_left_right_keys, search_table,
|
|
||||||
};
|
|
||||||
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
|
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};
|
||||||
use crate::network::radarr_network::RadarrEvent;
|
use crate::network::radarr_network::RadarrEvent;
|
||||||
use crate::{handle_text_box_keys, handle_text_box_left_right_keys};
|
use crate::utils::strip_non_search_characters;
|
||||||
|
use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table};
|
||||||
|
|
||||||
mod collection_details_handler;
|
mod collection_details_handler;
|
||||||
mod edit_collection_handler;
|
mod edit_collection_handler;
|
||||||
@@ -221,46 +220,26 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
|
|||||||
.items
|
.items
|
||||||
.is_empty()
|
.is_empty()
|
||||||
{
|
{
|
||||||
let selected_index = search_table(
|
search_table!(
|
||||||
self.app,
|
self.app,
|
||||||
&self.app.data.radarr_data.collections.items.clone(),
|
collections,
|
||||||
|collection| &collection.title.text,
|
ActiveRadarrBlock::SearchCollectionError
|
||||||
);
|
);
|
||||||
self
|
|
||||||
.app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.collections
|
|
||||||
.select_index(selected_index);
|
|
||||||
} else {
|
} else {
|
||||||
let selected_index = search_table(
|
search_table!(
|
||||||
self.app,
|
self.app,
|
||||||
&self.app.data.radarr_data.filtered_collections.items.clone(),
|
filtered_collections,
|
||||||
|collection| &collection.title.text,
|
ActiveRadarrBlock::SearchCollectionError
|
||||||
);
|
);
|
||||||
self
|
|
||||||
.app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.filtered_collections
|
|
||||||
.select_index(selected_index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActiveRadarrBlock::FilterCollections => {
|
ActiveRadarrBlock::FilterCollections => {
|
||||||
let filtered_collections = filter_table(
|
filter_table!(
|
||||||
self.app,
|
self.app,
|
||||||
&self.app.data.radarr_data.collections.items.clone(),
|
collections,
|
||||||
|collection| &collection.title.text,
|
filtered_collections,
|
||||||
|
ActiveRadarrBlock::FilterCollectionsError
|
||||||
);
|
);
|
||||||
|
|
||||||
if !filtered_collections.is_empty() {
|
|
||||||
self
|
|
||||||
.app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.filtered_collections
|
|
||||||
.set_items(filtered_collections);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ActiveRadarrBlock::UpdateAllCollectionsPrompt => {
|
ActiveRadarrBlock::UpdateAllCollectionsPrompt => {
|
||||||
if self.app.data.radarr_data.prompt_confirm {
|
if self.app.data.radarr_data.prompt_confirm {
|
||||||
@@ -275,12 +254,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
|
|||||||
|
|
||||||
fn handle_esc(&mut self) {
|
fn handle_esc(&mut self) {
|
||||||
match self.active_radarr_block {
|
match self.active_radarr_block {
|
||||||
ActiveRadarrBlock::FilterCollections => {
|
ActiveRadarrBlock::FilterCollections | ActiveRadarrBlock::FilterCollectionsError => {
|
||||||
self.app.pop_navigation_stack();
|
self.app.pop_navigation_stack();
|
||||||
self.app.data.radarr_data.reset_filter();
|
self.app.data.radarr_data.reset_filter();
|
||||||
self.app.should_ignore_quit_key = false;
|
self.app.should_ignore_quit_key = false;
|
||||||
}
|
}
|
||||||
ActiveRadarrBlock::SearchCollection => {
|
ActiveRadarrBlock::SearchCollection | ActiveRadarrBlock::SearchCollectionError => {
|
||||||
self.app.pop_navigation_stack();
|
self.app.pop_navigation_stack();
|
||||||
self.app.data.radarr_data.reset_search();
|
self.app.data.radarr_data.reset_search();
|
||||||
self.app.should_ignore_quit_key = false;
|
self.app.should_ignore_quit_key = false;
|
||||||
@@ -313,6 +292,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
|
|||||||
self
|
self
|
||||||
.app
|
.app
|
||||||
.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into());
|
.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into());
|
||||||
|
self.app.data.radarr_data.reset_filter();
|
||||||
self.app.data.radarr_data.filter = Some(HorizontallyScrollableText::default());
|
self.app.data.radarr_data.filter = Some(HorizontallyScrollableText::default());
|
||||||
self.app.data.radarr_data.is_filtering = true;
|
self.app.data.radarr_data.is_filtering = true;
|
||||||
self.app.should_ignore_quit_key = true;
|
self.app.should_ignore_quit_key = true;
|
||||||
|
|||||||
@@ -388,6 +388,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_search_movie_submit() {
|
fn test_search_movie_submit() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -410,11 +412,47 @@ mod tests {
|
|||||||
app.data.radarr_data.movies.current_selection().title.text,
|
app.data.radarr_data.movies.current_selection().title.text,
|
||||||
"Test 2"
|
"Test 2"
|
||||||
);
|
);
|
||||||
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_search_movie_submit_error_on_no_search_hits() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.movies
|
||||||
|
.set_items(extended_stateful_iterable_vec!(
|
||||||
|
Movie,
|
||||||
|
HorizontallyScrollableText
|
||||||
|
));
|
||||||
|
app.data.radarr_data.search = Some("Test 5".into());
|
||||||
|
|
||||||
|
LibraryHandler::with(
|
||||||
|
&SUBMIT_KEY,
|
||||||
|
&mut app,
|
||||||
|
&ActiveRadarrBlock::SearchMovie,
|
||||||
|
&None,
|
||||||
|
)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert_str_eq!(
|
||||||
|
app.data.radarr_data.movies.current_selection().title.text,
|
||||||
|
"Test 1"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::SearchMovieError.into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_search_filtered_movies_submit() {
|
fn test_search_filtered_movies_submit() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -443,11 +481,14 @@ mod tests {
|
|||||||
.text,
|
.text,
|
||||||
"Test 2"
|
"Test 2"
|
||||||
);
|
);
|
||||||
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filter_movies_submit() {
|
fn test_filter_movies_submit() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -477,6 +518,37 @@ mod tests {
|
|||||||
.text,
|
.text,
|
||||||
"Test 1"
|
"Test 1"
|
||||||
);
|
);
|
||||||
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_filter_movies_submit_error_on_no_filter_matches() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.movies
|
||||||
|
.set_items(extended_stateful_iterable_vec!(
|
||||||
|
Movie,
|
||||||
|
HorizontallyScrollableText
|
||||||
|
));
|
||||||
|
app.data.radarr_data.filter = Some("Test 5".into());
|
||||||
|
|
||||||
|
LibraryHandler::with(
|
||||||
|
&SUBMIT_KEY,
|
||||||
|
&mut app,
|
||||||
|
&ActiveRadarrBlock::FilterMovies,
|
||||||
|
&None,
|
||||||
|
)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::FilterMoviesError.into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -532,30 +604,36 @@ mod tests {
|
|||||||
|
|
||||||
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
|
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
|
||||||
|
|
||||||
#[test]
|
#[rstest]
|
||||||
fn test_search_movie_block_esc() {
|
fn test_search_movie_block_esc(
|
||||||
|
#[values(ActiveRadarrBlock::SearchMovie, ActiveRadarrBlock::SearchMovieError)]
|
||||||
|
active_radarr_block: ActiveRadarrBlock,
|
||||||
|
) {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
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(active_radarr_block.into());
|
||||||
app.data.radarr_data = create_test_radarr_data();
|
app.data.radarr_data = create_test_radarr_data();
|
||||||
|
|
||||||
LibraryHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::SearchMovie, &None).handle();
|
LibraryHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
|
||||||
|
|
||||||
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
||||||
assert!(!app.should_ignore_quit_key);
|
assert!(!app.should_ignore_quit_key);
|
||||||
assert_search_reset!(app.data.radarr_data);
|
assert_search_reset!(app.data.radarr_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[rstest]
|
||||||
fn test_filter_movies_block_esc() {
|
fn test_filter_movies_block_esc(
|
||||||
|
#[values(ActiveRadarrBlock::FilterMovies, ActiveRadarrBlock::FilterMoviesError)]
|
||||||
|
active_radarr_block: ActiveRadarrBlock,
|
||||||
|
) {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
app.push_navigation_stack(active_radarr_block.into());
|
||||||
app.data.radarr_data = create_test_radarr_data();
|
app.data.radarr_data = create_test_radarr_data();
|
||||||
|
|
||||||
LibraryHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::FilterMovies, &None).handle();
|
LibraryHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
|
||||||
|
|
||||||
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
||||||
assert!(!app.should_ignore_quit_key);
|
assert!(!app.should_ignore_quit_key);
|
||||||
@@ -657,6 +735,31 @@ mod tests {
|
|||||||
assert!(app.data.radarr_data.filter.is_some());
|
assert!(app.data.radarr_data.filter.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_filter_movies_key_resets_previous_filter() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.should_ignore_quit_key = true;
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.data.radarr_data = create_test_radarr_data();
|
||||||
|
|
||||||
|
LibraryHandler::with(
|
||||||
|
&DEFAULT_KEYBINDINGS.filter.key,
|
||||||
|
&mut app,
|
||||||
|
&ActiveRadarrBlock::Movies,
|
||||||
|
&None,
|
||||||
|
)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::FilterMovies.into()
|
||||||
|
);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_movie_add_key() {
|
fn test_movie_add_key() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::event::Key;
|
use crate::event::Key;
|
||||||
|
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||||
use crate::handlers::radarr_handlers::library::add_movie_handler::AddMovieHandler;
|
use crate::handlers::radarr_handlers::library::add_movie_handler::AddMovieHandler;
|
||||||
use crate::handlers::radarr_handlers::library::delete_movie_handler::DeleteMovieHandler;
|
use crate::handlers::radarr_handlers::library::delete_movie_handler::DeleteMovieHandler;
|
||||||
use crate::handlers::radarr_handlers::library::edit_movie_handler::EditMovieHandler;
|
use crate::handlers::radarr_handlers::library::edit_movie_handler::EditMovieHandler;
|
||||||
use crate::handlers::radarr_handlers::library::movie_details_handler::MovieDetailsHandler;
|
use crate::handlers::radarr_handlers::library::movie_details_handler::MovieDetailsHandler;
|
||||||
use crate::handlers::radarr_handlers::{
|
|
||||||
filter_table, handle_change_tab_left_right_keys, search_table,
|
|
||||||
};
|
|
||||||
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
|
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};
|
||||||
use crate::network::radarr_network::RadarrEvent;
|
use crate::network::radarr_network::RadarrEvent;
|
||||||
use crate::{handle_text_box_keys, handle_text_box_left_right_keys};
|
use crate::utils::strip_non_search_characters;
|
||||||
|
use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table};
|
||||||
|
|
||||||
mod add_movie_handler;
|
mod add_movie_handler;
|
||||||
mod delete_movie_handler;
|
mod delete_movie_handler;
|
||||||
@@ -200,46 +200,22 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
|
|||||||
.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.items.is_empty() {
|
||||||
let selected_index = search_table(
|
search_table!(self.app, movies, ActiveRadarrBlock::SearchMovieError);
|
||||||
self.app,
|
|
||||||
&self.app.data.radarr_data.movies.items.clone(),
|
|
||||||
|movie| &movie.title.text,
|
|
||||||
);
|
|
||||||
self
|
|
||||||
.app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.movies
|
|
||||||
.select_index(selected_index);
|
|
||||||
} else {
|
} else {
|
||||||
let selected_index = search_table(
|
search_table!(
|
||||||
self.app,
|
self.app,
|
||||||
&self.app.data.radarr_data.filtered_movies.items.clone(),
|
filtered_movies,
|
||||||
|movie| &movie.title.text,
|
ActiveRadarrBlock::SearchMovieError
|
||||||
);
|
);
|
||||||
self
|
}
|
||||||
.app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.filtered_movies
|
|
||||||
.select_index(selected_index);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
ActiveRadarrBlock::FilterMovies => {
|
ActiveRadarrBlock::FilterMovies => {
|
||||||
let filtered_movies = filter_table(
|
filter_table!(
|
||||||
self.app,
|
self.app,
|
||||||
&self.app.data.radarr_data.movies.items.clone(),
|
movies,
|
||||||
|movie| &movie.title.text,
|
filtered_movies,
|
||||||
|
ActiveRadarrBlock::FilterMoviesError
|
||||||
);
|
);
|
||||||
|
|
||||||
if !filtered_movies.is_empty() {
|
|
||||||
self
|
|
||||||
.app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.filtered_movies
|
|
||||||
.set_items(filtered_movies);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ActiveRadarrBlock::UpdateAllMoviesPrompt => {
|
ActiveRadarrBlock::UpdateAllMoviesPrompt => {
|
||||||
if self.app.data.radarr_data.prompt_confirm {
|
if self.app.data.radarr_data.prompt_confirm {
|
||||||
@@ -254,12 +230,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
|
|||||||
|
|
||||||
fn handle_esc(&mut self) {
|
fn handle_esc(&mut self) {
|
||||||
match self.active_radarr_block {
|
match self.active_radarr_block {
|
||||||
ActiveRadarrBlock::FilterMovies => {
|
ActiveRadarrBlock::FilterMovies | ActiveRadarrBlock::FilterMoviesError => {
|
||||||
self.app.pop_navigation_stack();
|
self.app.pop_navigation_stack();
|
||||||
self.app.data.radarr_data.reset_filter();
|
self.app.data.radarr_data.reset_filter();
|
||||||
self.app.should_ignore_quit_key = false;
|
self.app.should_ignore_quit_key = false;
|
||||||
}
|
}
|
||||||
ActiveRadarrBlock::SearchMovie => {
|
ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchMovieError => {
|
||||||
self.app.pop_navigation_stack();
|
self.app.pop_navigation_stack();
|
||||||
self.app.data.radarr_data.reset_search();
|
self.app.data.radarr_data.reset_search();
|
||||||
self.app.should_ignore_quit_key = false;
|
self.app.should_ignore_quit_key = false;
|
||||||
@@ -292,6 +268,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
|
|||||||
self
|
self
|
||||||
.app
|
.app
|
||||||
.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
||||||
|
self.app.data.radarr_data.reset_filter();
|
||||||
self.app.data.radarr_data.filter = Some(HorizontallyScrollableText::default());
|
self.app.data.radarr_data.filter = Some(HorizontallyScrollableText::default());
|
||||||
self.app.data.radarr_data.is_filtering = true;
|
self.app.data.radarr_data.is_filtering = true;
|
||||||
self.app.should_ignore_quit_key = true;
|
self.app.should_ignore_quit_key = true;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use crate::handlers::radarr_handlers::root_folders::RootFoldersHandler;
|
|||||||
use crate::handlers::radarr_handlers::system::SystemHandler;
|
use crate::handlers::radarr_handlers::system::SystemHandler;
|
||||||
use crate::handlers::KeyEventHandler;
|
use crate::handlers::KeyEventHandler;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||||
use crate::utils::strip_non_search_characters;
|
|
||||||
use crate::{App, Key};
|
use crate::{App, Key};
|
||||||
|
|
||||||
mod collections;
|
mod collections;
|
||||||
@@ -100,87 +99,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
|
|||||||
fn handle_char_key_event(&mut self) {}
|
fn handle_char_key_event(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search_table<T, F>(app: &mut App<'_>, rows: &[T], field_selection_fn: F) -> Option<usize>
|
|
||||||
where
|
|
||||||
F: Fn(&T) -> &str,
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
|
|
||||||
app.data.radarr_data.search = None;
|
|
||||||
|
|
||||||
rows.iter().position(|item| {
|
|
||||||
strip_non_search_characters(field_selection_fn(item)).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();
|
|
||||||
}
|
|
||||||
|
|
||||||
search_index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn filter_table<T, F>(app: &mut App<'_>, rows: &[T], field_selection_fn: F) -> Vec<T>
|
|
||||||
where
|
|
||||||
F: Fn(&T) -> &str,
|
|
||||||
T: Clone,
|
|
||||||
{
|
|
||||||
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());
|
|
||||||
|
|
||||||
rows
|
|
||||||
.iter()
|
|
||||||
.filter(|&item| strip_non_search_characters(field_selection_fn(item)).contains(&filter))
|
|
||||||
.cloned()
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
app.data.radarr_data.filter = None;
|
|
||||||
app.data.radarr_data.is_filtering = false;
|
|
||||||
app.should_ignore_quit_key = false;
|
|
||||||
|
|
||||||
if !filter_matches.is_empty() || empty_filter {
|
|
||||||
app.pop_navigation_stack();
|
|
||||||
}
|
|
||||||
|
|
||||||
filter_matches
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: &Key) {
|
pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: &Key) {
|
||||||
let key_ref = key;
|
let key_ref = key;
|
||||||
match key_ref {
|
match key_ref {
|
||||||
@@ -195,3 +113,99 @@ 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();
|
||||||
|
|
||||||
|
$app.data.radarr_data.search = None;
|
||||||
|
|
||||||
|
$app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.$data_ref
|
||||||
|
.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.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());
|
||||||
|
|
||||||
|
$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.filter = None;
|
||||||
|
$app.data.radarr_data.is_filtering = false;
|
||||||
|
$app.should_ignore_quit_key = false;
|
||||||
|
|
||||||
|
if filter_matches.is_empty() && !empty_filter {
|
||||||
|
$app.pop_and_push_navigation_stack($error_block.into());
|
||||||
|
} else if empty_filter {
|
||||||
|
$app.pop_navigation_stack();
|
||||||
|
} else {
|
||||||
|
$app.pop_navigation_stack();
|
||||||
|
$app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.$filter_table_ref
|
||||||
|
.set_items(filter_matches);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,18 +6,21 @@ mod tests {
|
|||||||
|
|
||||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::handlers::radarr_handlers::{
|
use crate::handlers::radarr_handlers::{handle_change_tab_left_right_keys, RadarrHandler};
|
||||||
filter_table, handle_change_tab_left_right_keys, search_table, RadarrHandler,
|
|
||||||
};
|
|
||||||
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;
|
||||||
use crate::{extended_stateful_iterable_vec, test_handler_delegation};
|
use crate::utils::strip_non_search_characters;
|
||||||
|
use crate::{
|
||||||
|
extended_stateful_iterable_vec, filter_table, search_table, test_handler_delegation,
|
||||||
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_search_table() {
|
fn test_search_table_macro() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -29,13 +32,13 @@ mod tests {
|
|||||||
app.data.radarr_data.search = Some("Test 2".into());
|
app.data.radarr_data.search = Some("Test 2".into());
|
||||||
app.data.radarr_data.is_searching = true;
|
app.data.radarr_data.is_searching = true;
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
|
||||||
|
|
||||||
let movies = &app.data.radarr_data.movies.items.clone();
|
search_table!(app, movies, ActiveRadarrBlock::SearchMovieError);
|
||||||
|
|
||||||
let index = search_table(&mut app, movies, |movie| &movie.title.text);
|
assert_str_eq!(
|
||||||
|
app.data.radarr_data.movies.current_selection().title.text,
|
||||||
assert_eq!(index, Some(1));
|
"Test 2"
|
||||||
|
);
|
||||||
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
||||||
assert!(!app.data.radarr_data.is_searching);
|
assert!(!app.data.radarr_data.is_searching);
|
||||||
assert!(!app.should_ignore_quit_key);
|
assert!(!app.should_ignore_quit_key);
|
||||||
@@ -43,8 +46,39 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_search_table_no_search_hits() {
|
fn test_search_table_macro_empty_search() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.movies
|
||||||
|
.set_items(extended_stateful_iterable_vec!(
|
||||||
|
Movie,
|
||||||
|
HorizontallyScrollableText
|
||||||
|
));
|
||||||
|
app.data.radarr_data.search = Some("".into());
|
||||||
|
app.data.radarr_data.is_searching = true;
|
||||||
|
app.should_ignore_quit_key = true;
|
||||||
|
|
||||||
|
search_table!(app, movies, ActiveRadarrBlock::SearchMovieError);
|
||||||
|
|
||||||
|
assert_str_eq!(
|
||||||
|
app.data.radarr_data.movies.current_selection().title.text,
|
||||||
|
"Test 1"
|
||||||
|
);
|
||||||
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
|
||||||
|
assert!(!app.data.radarr_data.is_searching);
|
||||||
|
assert!(!app.should_ignore_quit_key);
|
||||||
|
assert!(app.data.radarr_data.search.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_search_table_macro_error_on_no_search_hits() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -56,16 +90,16 @@ mod tests {
|
|||||||
app.data.radarr_data.search = Some("Test 5".into());
|
app.data.radarr_data.search = Some("Test 5".into());
|
||||||
app.data.radarr_data.is_searching = true;
|
app.data.radarr_data.is_searching = true;
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
|
|
||||||
|
|
||||||
let movies = &app.data.radarr_data.movies.items.clone();
|
search_table!(app, movies, ActiveRadarrBlock::SearchMovieError);
|
||||||
|
|
||||||
let index = search_table(&mut app, movies, |movie| &movie.title.text);
|
assert_str_eq!(
|
||||||
|
app.data.radarr_data.movies.current_selection().title.text,
|
||||||
assert_eq!(index, None);
|
"Test 1"
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.get_current_route(),
|
app.get_current_route(),
|
||||||
&ActiveRadarrBlock::SearchMovie.into()
|
&ActiveRadarrBlock::SearchMovieError.into()
|
||||||
);
|
);
|
||||||
assert!(!app.data.radarr_data.is_searching);
|
assert!(!app.data.radarr_data.is_searching);
|
||||||
assert!(!app.should_ignore_quit_key);
|
assert!(!app.should_ignore_quit_key);
|
||||||
@@ -73,8 +107,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filter_table() {
|
fn test_filter_table_macro() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -86,14 +122,19 @@ mod tests {
|
|||||||
app.data.radarr_data.filter = Some("Test 2".into());
|
app.data.radarr_data.filter = Some("Test 2".into());
|
||||||
app.data.radarr_data.is_filtering = true;
|
app.data.radarr_data.is_filtering = true;
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
|
||||||
|
|
||||||
let movies = &app.data.radarr_data.movies.items.clone();
|
filter_table!(
|
||||||
|
app,
|
||||||
|
movies,
|
||||||
|
filtered_movies,
|
||||||
|
ActiveRadarrBlock::FilterMoviesError
|
||||||
|
);
|
||||||
|
|
||||||
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
|
assert_eq!(app.data.radarr_data.filtered_movies.items.len(), 1);
|
||||||
|
assert_str_eq!(
|
||||||
assert_eq!(filter_matches.len(), 1);
|
app.data.radarr_data.filtered_movies.items[0].title.text,
|
||||||
assert_str_eq!(filter_matches[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());
|
||||||
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);
|
||||||
@@ -101,38 +142,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filter_table_no_filter_matches() {
|
fn test_filter_table_macro_reset_and_pop_on_empty_filter() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
app
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.movies
|
|
||||||
.set_items(extended_stateful_iterable_vec!(
|
|
||||||
Movie,
|
|
||||||
HorizontallyScrollableText
|
|
||||||
));
|
|
||||||
app.data.radarr_data.filter = Some("Test 5".into());
|
|
||||||
app.data.radarr_data.is_filtering = true;
|
|
||||||
app.should_ignore_quit_key = true;
|
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
||||||
|
|
||||||
let movies = &app.data.radarr_data.movies.items.clone();
|
|
||||||
|
|
||||||
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
|
|
||||||
|
|
||||||
assert!(filter_matches.is_empty());
|
|
||||||
assert_eq!(
|
|
||||||
app.get_current_route(),
|
|
||||||
&ActiveRadarrBlock::FilterMovies.into()
|
|
||||||
);
|
|
||||||
assert!(!app.data.radarr_data.is_filtering);
|
|
||||||
assert!(!app.should_ignore_quit_key);
|
|
||||||
assert!(app.data.radarr_data.filter.is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_filter_table_reset_and_pop_navigation_on_empty_filter() {
|
|
||||||
let mut app = App::default();
|
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -144,13 +157,15 @@ mod tests {
|
|||||||
app.data.radarr_data.filter = Some("".into());
|
app.data.radarr_data.filter = Some("".into());
|
||||||
app.data.radarr_data.is_filtering = true;
|
app.data.radarr_data.is_filtering = true;
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
|
||||||
|
|
||||||
let movies = &app.data.radarr_data.movies.items.clone();
|
filter_table!(
|
||||||
|
app,
|
||||||
|
movies,
|
||||||
|
filtered_movies,
|
||||||
|
ActiveRadarrBlock::FilterMoviesError
|
||||||
|
);
|
||||||
|
|
||||||
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
|
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
|
||||||
|
|
||||||
assert!(filter_matches.is_empty());
|
|
||||||
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);
|
||||||
@@ -158,8 +173,44 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filter_table_noop_on_none_filter() {
|
fn test_filter_table_error_on_no_filter_matches() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.movies
|
||||||
|
.set_items(extended_stateful_iterable_vec!(
|
||||||
|
Movie,
|
||||||
|
HorizontallyScrollableText
|
||||||
|
));
|
||||||
|
app.data.radarr_data.filter = Some("Test 5".into());
|
||||||
|
app.data.radarr_data.is_filtering = true;
|
||||||
|
app.should_ignore_quit_key = true;
|
||||||
|
|
||||||
|
filter_table!(
|
||||||
|
app,
|
||||||
|
movies,
|
||||||
|
filtered_movies,
|
||||||
|
ActiveRadarrBlock::FilterMoviesError
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::FilterMoviesError.into()
|
||||||
|
);
|
||||||
|
assert!(!app.data.radarr_data.is_filtering);
|
||||||
|
assert!(!app.should_ignore_quit_key);
|
||||||
|
assert!(app.data.radarr_data.filter.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_filter_table_macro_error_on_none_filter() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
||||||
app
|
app
|
||||||
.data
|
.data
|
||||||
.radarr_data
|
.radarr_data
|
||||||
@@ -170,16 +221,18 @@ mod tests {
|
|||||||
));
|
));
|
||||||
app.data.radarr_data.is_filtering = true;
|
app.data.radarr_data.is_filtering = true;
|
||||||
app.should_ignore_quit_key = true;
|
app.should_ignore_quit_key = true;
|
||||||
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
|
|
||||||
|
|
||||||
let movies = &app.data.radarr_data.movies.items.clone();
|
filter_table!(
|
||||||
|
app,
|
||||||
|
movies,
|
||||||
|
filtered_movies,
|
||||||
|
ActiveRadarrBlock::FilterMoviesError
|
||||||
|
);
|
||||||
|
|
||||||
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
|
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
|
||||||
|
|
||||||
assert!(filter_matches.is_empty());
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.get_current_route(),
|
app.get_current_route(),
|
||||||
&ActiveRadarrBlock::FilterMovies.into()
|
&ActiveRadarrBlock::FilterMoviesError.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);
|
||||||
@@ -244,7 +297,9 @@ mod tests {
|
|||||||
#[values(
|
#[values(
|
||||||
ActiveRadarrBlock::Movies,
|
ActiveRadarrBlock::Movies,
|
||||||
ActiveRadarrBlock::SearchMovie,
|
ActiveRadarrBlock::SearchMovie,
|
||||||
|
ActiveRadarrBlock::SearchMovieError,
|
||||||
ActiveRadarrBlock::FilterMovies,
|
ActiveRadarrBlock::FilterMovies,
|
||||||
|
ActiveRadarrBlock::FilterMoviesError,
|
||||||
ActiveRadarrBlock::UpdateAllMoviesPrompt,
|
ActiveRadarrBlock::UpdateAllMoviesPrompt,
|
||||||
ActiveRadarrBlock::AddMovieSearchInput,
|
ActiveRadarrBlock::AddMovieSearchInput,
|
||||||
ActiveRadarrBlock::AddMovieSearchResults,
|
ActiveRadarrBlock::AddMovieSearchResults,
|
||||||
@@ -285,7 +340,9 @@ mod tests {
|
|||||||
#[values(
|
#[values(
|
||||||
ActiveRadarrBlock::Collections,
|
ActiveRadarrBlock::Collections,
|
||||||
ActiveRadarrBlock::SearchCollection,
|
ActiveRadarrBlock::SearchCollection,
|
||||||
|
ActiveRadarrBlock::SearchCollectionError,
|
||||||
ActiveRadarrBlock::FilterCollections,
|
ActiveRadarrBlock::FilterCollections,
|
||||||
|
ActiveRadarrBlock::FilterCollectionsError,
|
||||||
ActiveRadarrBlock::UpdateAllCollectionsPrompt,
|
ActiveRadarrBlock::UpdateAllCollectionsPrompt,
|
||||||
ActiveRadarrBlock::CollectionDetails,
|
ActiveRadarrBlock::CollectionDetails,
|
||||||
ActiveRadarrBlock::ViewMovieOverview,
|
ActiveRadarrBlock::ViewMovieOverview,
|
||||||
|
|||||||
@@ -287,7 +287,9 @@ pub enum ActiveRadarrBlock {
|
|||||||
EditMovieToggleMonitored,
|
EditMovieToggleMonitored,
|
||||||
FileInfo,
|
FileInfo,
|
||||||
FilterCollections,
|
FilterCollections,
|
||||||
|
FilterCollectionsError,
|
||||||
FilterMovies,
|
FilterMovies,
|
||||||
|
FilterMoviesError,
|
||||||
Indexers,
|
Indexers,
|
||||||
IndexerSettingsPrompt,
|
IndexerSettingsPrompt,
|
||||||
IndexerSettingsAvailabilityDelayInput,
|
IndexerSettingsAvailabilityDelayInput,
|
||||||
@@ -317,21 +319,27 @@ pub enum ActiveRadarrBlock {
|
|||||||
UpdateAllCollectionsPrompt,
|
UpdateAllCollectionsPrompt,
|
||||||
UpdateAllMoviesPrompt,
|
UpdateAllMoviesPrompt,
|
||||||
UpdateDownloadsPrompt,
|
UpdateDownloadsPrompt,
|
||||||
SearchMovie,
|
|
||||||
SearchCollection,
|
SearchCollection,
|
||||||
|
SearchCollectionError,
|
||||||
|
SearchMovie,
|
||||||
|
SearchMovieError,
|
||||||
ViewMovieOverview,
|
ViewMovieOverview,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static LIBRARY_BLOCKS: [ActiveRadarrBlock; 4] = [
|
pub static LIBRARY_BLOCKS: [ActiveRadarrBlock; 6] = [
|
||||||
ActiveRadarrBlock::Movies,
|
ActiveRadarrBlock::Movies,
|
||||||
ActiveRadarrBlock::SearchMovie,
|
ActiveRadarrBlock::SearchMovie,
|
||||||
|
ActiveRadarrBlock::SearchMovieError,
|
||||||
ActiveRadarrBlock::FilterMovies,
|
ActiveRadarrBlock::FilterMovies,
|
||||||
|
ActiveRadarrBlock::FilterMoviesError,
|
||||||
ActiveRadarrBlock::UpdateAllMoviesPrompt,
|
ActiveRadarrBlock::UpdateAllMoviesPrompt,
|
||||||
];
|
];
|
||||||
pub static COLLECTIONS_BLOCKS: [ActiveRadarrBlock; 4] = [
|
pub static COLLECTIONS_BLOCKS: [ActiveRadarrBlock; 6] = [
|
||||||
ActiveRadarrBlock::Collections,
|
ActiveRadarrBlock::Collections,
|
||||||
ActiveRadarrBlock::SearchCollection,
|
ActiveRadarrBlock::SearchCollection,
|
||||||
|
ActiveRadarrBlock::SearchCollectionError,
|
||||||
ActiveRadarrBlock::FilterCollections,
|
ActiveRadarrBlock::FilterCollections,
|
||||||
|
ActiveRadarrBlock::FilterCollectionsError,
|
||||||
ActiveRadarrBlock::UpdateAllCollectionsPrompt,
|
ActiveRadarrBlock::UpdateAllCollectionsPrompt,
|
||||||
];
|
];
|
||||||
pub static INDEXERS_BLOCKS: [ActiveRadarrBlock; 4] = [
|
pub static INDEXERS_BLOCKS: [ActiveRadarrBlock; 4] = [
|
||||||
@@ -420,14 +428,6 @@ pub static COLLECTION_DETAILS_BLOCKS: [ActiveRadarrBlock; 2] = [
|
|||||||
ActiveRadarrBlock::CollectionDetails,
|
ActiveRadarrBlock::CollectionDetails,
|
||||||
ActiveRadarrBlock::ViewMovieOverview,
|
ActiveRadarrBlock::ViewMovieOverview,
|
||||||
];
|
];
|
||||||
pub static SEARCH_BLOCKS: [ActiveRadarrBlock; 2] = [
|
|
||||||
ActiveRadarrBlock::SearchMovie,
|
|
||||||
ActiveRadarrBlock::SearchCollection,
|
|
||||||
];
|
|
||||||
pub static FILTER_BLOCKS: [ActiveRadarrBlock; 2] = [
|
|
||||||
ActiveRadarrBlock::FilterMovies,
|
|
||||||
ActiveRadarrBlock::FilterCollections,
|
|
||||||
];
|
|
||||||
pub static DELETE_MOVIE_BLOCKS: [ActiveRadarrBlock; 4] = [
|
pub static DELETE_MOVIE_BLOCKS: [ActiveRadarrBlock; 4] = [
|
||||||
ActiveRadarrBlock::DeleteMoviePrompt,
|
ActiveRadarrBlock::DeleteMoviePrompt,
|
||||||
ActiveRadarrBlock::DeleteMovieConfirmPrompt,
|
ActiveRadarrBlock::DeleteMovieConfirmPrompt,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
mod radarr_data_tests {
|
mod radarr_data_tests {
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||||
|
|
||||||
@@ -279,26 +278,30 @@ mod tests {
|
|||||||
ActiveRadarrBlock, ADD_MOVIE_BLOCKS, ADD_MOVIE_SELECTION_BLOCKS, COLLECTIONS_BLOCKS,
|
ActiveRadarrBlock, ADD_MOVIE_BLOCKS, ADD_MOVIE_SELECTION_BLOCKS, COLLECTIONS_BLOCKS,
|
||||||
COLLECTION_DETAILS_BLOCKS, DELETE_MOVIE_BLOCKS, DELETE_MOVIE_SELECTION_BLOCKS,
|
COLLECTION_DETAILS_BLOCKS, DELETE_MOVIE_BLOCKS, DELETE_MOVIE_SELECTION_BLOCKS,
|
||||||
DOWNLOADS_BLOCKS, EDIT_COLLECTION_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS,
|
DOWNLOADS_BLOCKS, EDIT_COLLECTION_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS,
|
||||||
EDIT_MOVIE_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, FILTER_BLOCKS, INDEXERS_BLOCKS,
|
EDIT_MOVIE_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, INDEXERS_BLOCKS, INDEXER_SETTINGS_BLOCKS,
|
||||||
INDEXER_SETTINGS_BLOCKS, INDEXER_SETTINGS_SELECTION_BLOCKS, LIBRARY_BLOCKS,
|
INDEXER_SETTINGS_SELECTION_BLOCKS, LIBRARY_BLOCKS, MOVIE_DETAILS_BLOCKS, ROOT_FOLDERS_BLOCKS,
|
||||||
MOVIE_DETAILS_BLOCKS, ROOT_FOLDERS_BLOCKS, SEARCH_BLOCKS, SYSTEM_DETAILS_BLOCKS,
|
SYSTEM_DETAILS_BLOCKS,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_library_blocks_contents() {
|
fn test_library_blocks_contents() {
|
||||||
assert_eq!(LIBRARY_BLOCKS.len(), 4);
|
assert_eq!(LIBRARY_BLOCKS.len(), 6);
|
||||||
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::Movies));
|
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::Movies));
|
||||||
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::SearchMovie));
|
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::SearchMovie));
|
||||||
|
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::SearchMovieError));
|
||||||
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::FilterMovies));
|
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::FilterMovies));
|
||||||
|
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::FilterMoviesError));
|
||||||
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::UpdateAllMoviesPrompt));
|
assert!(LIBRARY_BLOCKS.contains(&ActiveRadarrBlock::UpdateAllMoviesPrompt));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collections_blocks_contents() {
|
fn test_collections_blocks_contents() {
|
||||||
assert_eq!(COLLECTIONS_BLOCKS.len(), 4);
|
assert_eq!(COLLECTIONS_BLOCKS.len(), 6);
|
||||||
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::Collections));
|
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::Collections));
|
||||||
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::SearchCollection));
|
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::SearchCollection));
|
||||||
|
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::SearchCollectionError));
|
||||||
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::FilterCollections));
|
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::FilterCollections));
|
||||||
|
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::FilterCollectionsError));
|
||||||
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::UpdateAllCollectionsPrompt));
|
assert!(COLLECTIONS_BLOCKS.contains(&ActiveRadarrBlock::UpdateAllCollectionsPrompt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,20 +396,6 @@ mod tests {
|
|||||||
assert!(COLLECTION_DETAILS_BLOCKS.contains(&ActiveRadarrBlock::ViewMovieOverview));
|
assert!(COLLECTION_DETAILS_BLOCKS.contains(&ActiveRadarrBlock::ViewMovieOverview));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_search_blocks_contents() {
|
|
||||||
assert_eq!(SEARCH_BLOCKS.len(), 2);
|
|
||||||
assert!(SEARCH_BLOCKS.contains(&ActiveRadarrBlock::SearchMovie));
|
|
||||||
assert!(SEARCH_BLOCKS.contains(&ActiveRadarrBlock::SearchCollection));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_filter_blocks_contents() {
|
|
||||||
assert_eq!(FILTER_BLOCKS.len(), 2);
|
|
||||||
assert!(FILTER_BLOCKS.contains(&ActiveRadarrBlock::FilterMovies));
|
|
||||||
assert!(FILTER_BLOCKS.contains(&ActiveRadarrBlock::FilterCollections));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_delete_movie_blocks_contents() {
|
fn test_delete_movie_blocks_contents() {
|
||||||
assert_eq!(DELETE_MOVIE_BLOCKS.len(), 4);
|
assert_eq!(DELETE_MOVIE_BLOCKS.len(), 4);
|
||||||
|
|||||||
+51
-5
@@ -14,7 +14,7 @@ use tui::widgets::{Clear, List, ListItem};
|
|||||||
use tui::Frame;
|
use tui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::{Route, StatefulList, StatefulTable, TabState};
|
use crate::models::{HorizontallyScrollableText, Route, StatefulList, StatefulTable, TabState};
|
||||||
use crate::ui::radarr_ui::RadarrUi;
|
use crate::ui::radarr_ui::RadarrUi;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
background_block, borderless_block, centered_rect, horizontal_chunks,
|
background_block, borderless_block, centered_rect, horizontal_chunks,
|
||||||
@@ -659,8 +659,8 @@ pub fn draw_text_box<B: Backend>(
|
|||||||
should_show_cursor: bool,
|
should_show_cursor: bool,
|
||||||
is_selected: bool,
|
is_selected: bool,
|
||||||
) {
|
) {
|
||||||
let (block, style) = if let Some(..) = block_title {
|
let (block, style) = if let Some(title) = block_title {
|
||||||
(title_block_centered(block_title.unwrap()), style_default())
|
(title_block_centered(title), style_default())
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
layout_block(),
|
layout_block(),
|
||||||
@@ -671,10 +671,10 @@ pub fn draw_text_box<B: Backend>(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let search_paragraph = Paragraph::new(Text::from(block_content))
|
let paragraph = Paragraph::new(Text::from(block_content))
|
||||||
.style(style)
|
.style(style)
|
||||||
.block(block);
|
.block(block);
|
||||||
f.render_widget(search_paragraph, text_box_area);
|
f.render_widget(paragraph, text_box_area);
|
||||||
|
|
||||||
if should_show_cursor {
|
if should_show_cursor {
|
||||||
show_cursor(f, text_box_area, offset, block_content);
|
show_cursor(f, text_box_area, offset, block_content);
|
||||||
@@ -716,3 +716,49 @@ pub fn draw_text_box_with_label<B: Backend>(
|
|||||||
is_selected,
|
is_selected,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_input_box_popup<B: Backend>(
|
||||||
|
f: &mut Frame<'_, B>,
|
||||||
|
input_box_area: Rect,
|
||||||
|
box_title: &str,
|
||||||
|
box_content: &HorizontallyScrollableText,
|
||||||
|
) {
|
||||||
|
let chunks = vertical_chunks_with_margin(
|
||||||
|
vec![
|
||||||
|
Constraint::Length(3),
|
||||||
|
Constraint::Length(1),
|
||||||
|
Constraint::Min(0),
|
||||||
|
],
|
||||||
|
input_box_area,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
draw_text_box(
|
||||||
|
f,
|
||||||
|
chunks[0],
|
||||||
|
Some(box_title),
|
||||||
|
&box_content.text,
|
||||||
|
*box_content.offset.borrow(),
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
let help = Paragraph::new("<esc> cancel")
|
||||||
|
.style(style_help())
|
||||||
|
.alignment(Alignment::Center)
|
||||||
|
.block(borderless_block());
|
||||||
|
f.render_widget(help, chunks[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_error_message_popup<B: Backend>(
|
||||||
|
f: &mut Frame<'_, B>,
|
||||||
|
error_message_area: Rect,
|
||||||
|
error_msg: &str,
|
||||||
|
) {
|
||||||
|
let input = Paragraph::new(error_msg)
|
||||||
|
.style(style_failure())
|
||||||
|
.alignment(Alignment::Center)
|
||||||
|
.block(layout_block());
|
||||||
|
|
||||||
|
f.render_widget(input, error_message_area);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, COLLEC
|
|||||||
use crate::models::Route;
|
use crate::models::Route;
|
||||||
use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi;
|
use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi;
|
||||||
use crate::ui::radarr_ui::collections::edit_collection_ui::EditCollectionUi;
|
use crate::ui::radarr_ui::collections::edit_collection_ui::EditCollectionUi;
|
||||||
use crate::ui::radarr_ui::{draw_filter_box, draw_search_box};
|
|
||||||
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border, style_primary};
|
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border, style_primary};
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
draw_popup_over, draw_prompt_box, draw_prompt_popup_over, draw_table, DrawUi, TableProps,
|
draw_error_message_popup, draw_input_box_popup, draw_popup_over, draw_prompt_box,
|
||||||
|
draw_prompt_popup_over, draw_table, DrawUi, TableProps,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod collection_details_ui;
|
mod collection_details_ui;
|
||||||
@@ -45,19 +45,37 @@ impl DrawUi for CollectionsUi {
|
|||||||
app,
|
app,
|
||||||
content_rect,
|
content_rect,
|
||||||
draw_collections,
|
draw_collections,
|
||||||
draw_search_box,
|
draw_collection_search_box,
|
||||||
30,
|
30,
|
||||||
13,
|
13,
|
||||||
),
|
),
|
||||||
|
ActiveRadarrBlock::SearchCollectionError => draw_popup_over(
|
||||||
|
f,
|
||||||
|
app,
|
||||||
|
content_rect,
|
||||||
|
draw_collections,
|
||||||
|
draw_search_collection_error_box,
|
||||||
|
30,
|
||||||
|
8,
|
||||||
|
),
|
||||||
ActiveRadarrBlock::FilterCollections => draw_popup_over(
|
ActiveRadarrBlock::FilterCollections => draw_popup_over(
|
||||||
f,
|
f,
|
||||||
app,
|
app,
|
||||||
content_rect,
|
content_rect,
|
||||||
draw_collections,
|
draw_collections,
|
||||||
draw_filter_box,
|
draw_filter_collections_box,
|
||||||
30,
|
30,
|
||||||
13,
|
13,
|
||||||
),
|
),
|
||||||
|
ActiveRadarrBlock::FilterCollectionsError => draw_popup_over(
|
||||||
|
f,
|
||||||
|
app,
|
||||||
|
content_rect,
|
||||||
|
draw_collections,
|
||||||
|
draw_filter_collections_error_box,
|
||||||
|
30,
|
||||||
|
8,
|
||||||
|
),
|
||||||
ActiveRadarrBlock::UpdateAllCollectionsPrompt => draw_prompt_popup_over(
|
ActiveRadarrBlock::UpdateAllCollectionsPrompt => draw_prompt_popup_over(
|
||||||
f,
|
f,
|
||||||
app,
|
app,
|
||||||
@@ -177,3 +195,33 @@ fn draw_update_all_collections_prompt<B: Backend>(
|
|||||||
app.data.radarr_data.prompt_confirm,
|
app.data.radarr_data.prompt_confirm,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_collection_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
|
||||||
|
draw_input_box_popup(
|
||||||
|
f,
|
||||||
|
area,
|
||||||
|
"Search",
|
||||||
|
app.data.radarr_data.search.as_ref().unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_filter_collections_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
|
||||||
|
draw_input_box_popup(
|
||||||
|
f,
|
||||||
|
area,
|
||||||
|
"Filter",
|
||||||
|
app.data.radarr_data.filter.as_ref().unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_search_collection_error_box<B: Backend>(f: &mut Frame<'_, B>, _: &mut App<'_>, area: Rect) {
|
||||||
|
draw_error_message_popup(f, area, "Collection not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_filter_collections_error_box<B: Backend>(
|
||||||
|
f: &mut Frame<'_, B>,
|
||||||
|
_: &mut App<'_>,
|
||||||
|
area: Rect,
|
||||||
|
) {
|
||||||
|
draw_error_message_popup(f, area, "No collections found matching the given filter!");
|
||||||
|
}
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ fn draw_edit_indexer_settings_prompt<B: Backend>(
|
|||||||
|
|
||||||
let button_chunks = horizontal_chunks(
|
let button_chunks = horizontal_chunks(
|
||||||
iter::repeat(Constraint::Ratio(1, 4)).take(4).collect(),
|
iter::repeat(Constraint::Ratio(1, 4)).take(4).collect(),
|
||||||
// vec![Constraint::Percentage(50), Constraint::Percentage(50)],
|
|
||||||
chunks[1],
|
chunks[1],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,15 @@ use crate::app::App;
|
|||||||
use crate::models::radarr_models::Movie;
|
use crate::models::radarr_models::Movie;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, LIBRARY_BLOCKS};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, LIBRARY_BLOCKS};
|
||||||
use crate::models::Route;
|
use crate::models::Route;
|
||||||
|
use crate::ui::radarr_ui::determine_row_style;
|
||||||
use crate::ui::radarr_ui::library::add_movie_ui::AddMovieUi;
|
use crate::ui::radarr_ui::library::add_movie_ui::AddMovieUi;
|
||||||
use crate::ui::radarr_ui::library::delete_movie_ui::DeleteMovieUi;
|
use crate::ui::radarr_ui::library::delete_movie_ui::DeleteMovieUi;
|
||||||
use crate::ui::radarr_ui::library::edit_movie_ui::EditMovieUi;
|
use crate::ui::radarr_ui::library::edit_movie_ui::EditMovieUi;
|
||||||
use crate::ui::radarr_ui::library::movie_details_ui::MovieDetailsUi;
|
use crate::ui::radarr_ui::library::movie_details_ui::MovieDetailsUi;
|
||||||
use crate::ui::radarr_ui::{determine_row_style, draw_filter_box, draw_search_box};
|
|
||||||
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
draw_popup_over, draw_prompt_box, draw_prompt_popup_over, draw_table, DrawUi, TableProps,
|
draw_error_message_popup, draw_input_box_popup, draw_popup_over, draw_prompt_box,
|
||||||
|
draw_prompt_popup_over, draw_table, DrawUi, TableProps,
|
||||||
};
|
};
|
||||||
use crate::utils::{convert_runtime, convert_to_gb};
|
use crate::utils::{convert_runtime, convert_to_gb};
|
||||||
|
|
||||||
@@ -47,12 +48,42 @@ impl DrawUi for LibraryUi {
|
|||||||
let mut library_ui_matchers = |active_radarr_block: ActiveRadarrBlock| match active_radarr_block
|
let mut library_ui_matchers = |active_radarr_block: ActiveRadarrBlock| match active_radarr_block
|
||||||
{
|
{
|
||||||
ActiveRadarrBlock::Movies => draw_library(f, app, content_rect),
|
ActiveRadarrBlock::Movies => draw_library(f, app, content_rect),
|
||||||
ActiveRadarrBlock::SearchMovie => {
|
ActiveRadarrBlock::SearchMovie => draw_popup_over(
|
||||||
draw_popup_over(f, app, content_rect, draw_library, draw_search_box, 30, 13)
|
f,
|
||||||
}
|
app,
|
||||||
ActiveRadarrBlock::FilterMovies => {
|
content_rect,
|
||||||
draw_popup_over(f, app, content_rect, draw_library, draw_filter_box, 30, 13)
|
draw_library,
|
||||||
}
|
draw_movie_search_box,
|
||||||
|
30,
|
||||||
|
13,
|
||||||
|
),
|
||||||
|
ActiveRadarrBlock::SearchMovieError => draw_popup_over(
|
||||||
|
f,
|
||||||
|
app,
|
||||||
|
content_rect,
|
||||||
|
draw_library,
|
||||||
|
draw_search_movie_error_box,
|
||||||
|
30,
|
||||||
|
8,
|
||||||
|
),
|
||||||
|
ActiveRadarrBlock::FilterMovies => draw_popup_over(
|
||||||
|
f,
|
||||||
|
app,
|
||||||
|
content_rect,
|
||||||
|
draw_library,
|
||||||
|
draw_filter_movies_box,
|
||||||
|
30,
|
||||||
|
13,
|
||||||
|
),
|
||||||
|
ActiveRadarrBlock::FilterMoviesError => draw_popup_over(
|
||||||
|
f,
|
||||||
|
app,
|
||||||
|
content_rect,
|
||||||
|
draw_library,
|
||||||
|
draw_filter_movies_error_box,
|
||||||
|
30,
|
||||||
|
8,
|
||||||
|
),
|
||||||
ActiveRadarrBlock::UpdateAllMoviesPrompt => draw_prompt_popup_over(
|
ActiveRadarrBlock::UpdateAllMoviesPrompt => draw_prompt_popup_over(
|
||||||
f,
|
f,
|
||||||
app,
|
app,
|
||||||
@@ -194,3 +225,29 @@ fn draw_update_all_movies_prompt<B: Backend>(
|
|||||||
app.data.radarr_data.prompt_confirm,
|
app.data.radarr_data.prompt_confirm,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_movie_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
|
||||||
|
draw_input_box_popup(
|
||||||
|
f,
|
||||||
|
area,
|
||||||
|
"Search",
|
||||||
|
app.data.radarr_data.search.as_ref().unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_filter_movies_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
|
||||||
|
draw_input_box_popup(
|
||||||
|
f,
|
||||||
|
area,
|
||||||
|
"Filter",
|
||||||
|
app.data.radarr_data.filter.as_ref().unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_search_movie_error_box<B: Backend>(f: &mut Frame<'_, B>, _: &mut App<'_>, area: Rect) {
|
||||||
|
draw_error_message_popup(f, area, "Movie not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_filter_movies_error_box<B: Backend>(f: &mut Frame<'_, B>, _: &mut App<'_>, area: Rect) {
|
||||||
|
draw_error_message_popup(f, area, "No movies found matching the given filter!");
|
||||||
|
}
|
||||||
|
|||||||
+3
-126
@@ -11,9 +11,7 @@ use tui::Frame;
|
|||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::logos::RADARR_LOGO;
|
use crate::logos::RADARR_LOGO;
|
||||||
use crate::models::radarr_models::{DiskSpace, DownloadRecord, Movie, RootFolder};
|
use crate::models::radarr_models::{DiskSpace, DownloadRecord, Movie, RootFolder};
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{
|
use crate::models::servarr_data::radarr::radarr_data::RadarrData;
|
||||||
ActiveRadarrBlock, RadarrData, FILTER_BLOCKS, SEARCH_BLOCKS,
|
|
||||||
};
|
|
||||||
use crate::models::Route;
|
use crate::models::Route;
|
||||||
use crate::ui::draw_tabs;
|
use crate::ui::draw_tabs;
|
||||||
use crate::ui::loading;
|
use crate::ui::loading;
|
||||||
@@ -25,9 +23,8 @@ use crate::ui::radarr_ui::root_folders::RootFoldersUi;
|
|||||||
use crate::ui::radarr_ui::system::SystemUi;
|
use crate::ui::radarr_ui::system::SystemUi;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
borderless_block, horizontal_chunks, layout_block, line_gauge_with_label, line_gauge_with_title,
|
borderless_block, horizontal_chunks, layout_block, line_gauge_with_label, line_gauge_with_title,
|
||||||
show_cursor, style_awaiting_import, style_bold, style_default, style_failure, style_help,
|
style_awaiting_import, style_bold, style_default, style_failure, style_success,
|
||||||
style_success, style_unmonitored, style_warning, title_block, title_block_centered,
|
style_unmonitored, style_warning, title_block, vertical_chunks_with_margin,
|
||||||
vertical_chunks_with_margin,
|
|
||||||
};
|
};
|
||||||
use crate::ui::DrawUi;
|
use crate::ui::DrawUi;
|
||||||
use crate::utils::convert_to_gb;
|
use crate::utils::convert_to_gb;
|
||||||
@@ -231,126 +228,6 @@ fn determine_row_style(downloads_vec: &[DownloadRecord], movie: &Movie) -> Style
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
|
|
||||||
let chunks = vertical_chunks_with_margin(
|
|
||||||
vec![
|
|
||||||
Constraint::Length(3),
|
|
||||||
Constraint::Length(1),
|
|
||||||
Constraint::Min(0),
|
|
||||||
],
|
|
||||||
area,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
if !app.data.radarr_data.is_searching {
|
|
||||||
let error_msg = match app.get_current_route() {
|
|
||||||
Route::Radarr(active_radarr_block, _) => match active_radarr_block {
|
|
||||||
ActiveRadarrBlock::SearchMovie => "Movie not found!",
|
|
||||||
ActiveRadarrBlock::SearchCollection => "Collection not found!",
|
|
||||||
_ => "",
|
|
||||||
},
|
|
||||||
_ => "",
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = Paragraph::new(error_msg)
|
|
||||||
.style(style_failure())
|
|
||||||
.block(layout_block());
|
|
||||||
|
|
||||||
f.render_widget(input, chunks[0]);
|
|
||||||
} else {
|
|
||||||
let default_content = String::default();
|
|
||||||
let (block_title, offset, block_content) = match app.get_current_route() {
|
|
||||||
Route::Radarr(active_radarr_block, _) => match active_radarr_block {
|
|
||||||
_ if SEARCH_BLOCKS.contains(active_radarr_block) => (
|
|
||||||
"Search",
|
|
||||||
*app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.search
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.offset
|
|
||||||
.borrow(),
|
|
||||||
&app.data.radarr_data.search.as_ref().unwrap().text,
|
|
||||||
),
|
|
||||||
_ => ("", 0, &default_content),
|
|
||||||
},
|
|
||||||
_ => ("", 0, &default_content),
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = Paragraph::new(block_content.as_str())
|
|
||||||
.style(style_default())
|
|
||||||
.block(title_block_centered(block_title));
|
|
||||||
let help = Paragraph::new("<esc> cancel")
|
|
||||||
.style(style_help())
|
|
||||||
.alignment(Alignment::Center)
|
|
||||||
.block(borderless_block());
|
|
||||||
show_cursor(f, chunks[0], offset, block_content);
|
|
||||||
|
|
||||||
f.render_widget(input, chunks[0]);
|
|
||||||
f.render_widget(help, chunks[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_filter_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
|
|
||||||
let chunks = vertical_chunks_with_margin(
|
|
||||||
vec![
|
|
||||||
Constraint::Length(3),
|
|
||||||
Constraint::Length(1),
|
|
||||||
Constraint::Min(0),
|
|
||||||
],
|
|
||||||
area,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
if !app.data.radarr_data.is_filtering {
|
|
||||||
let error_msg = match app.get_current_route() {
|
|
||||||
Route::Radarr(active_radarr_block, _) => match active_radarr_block {
|
|
||||||
ActiveRadarrBlock::FilterMovies => "No movies found matching filter!",
|
|
||||||
ActiveRadarrBlock::FilterCollections => "No collections found matching filter!",
|
|
||||||
_ => "",
|
|
||||||
},
|
|
||||||
_ => "",
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = Paragraph::new(error_msg)
|
|
||||||
.style(style_failure())
|
|
||||||
.block(layout_block());
|
|
||||||
|
|
||||||
f.render_widget(input, chunks[0]);
|
|
||||||
} else {
|
|
||||||
let default_content = String::default();
|
|
||||||
let (block_title, offset, block_content) = match app.get_current_route() {
|
|
||||||
Route::Radarr(active_radarr_block, _) => match active_radarr_block {
|
|
||||||
_ if FILTER_BLOCKS.contains(active_radarr_block) => (
|
|
||||||
"Filter",
|
|
||||||
*app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.filter
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.offset
|
|
||||||
.borrow(),
|
|
||||||
&app.data.radarr_data.filter.as_ref().unwrap().text,
|
|
||||||
),
|
|
||||||
_ => ("", 0, &default_content),
|
|
||||||
},
|
|
||||||
_ => ("", 0, &default_content),
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = Paragraph::new(block_content.as_str())
|
|
||||||
.style(style_default())
|
|
||||||
.block(title_block_centered(block_title));
|
|
||||||
let help = Paragraph::new("<esc> cancel")
|
|
||||||
.style(style_help())
|
|
||||||
.alignment(Alignment::Center)
|
|
||||||
.block(borderless_block());
|
|
||||||
show_cursor(f, chunks[0], offset, block_content);
|
|
||||||
|
|
||||||
f.render_widget(input, chunks[0]);
|
|
||||||
f.render_widget(help, chunks[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_radarr_logo<B: Backend>(f: &mut Frame<'_, B>, area: Rect) {
|
fn draw_radarr_logo<B: Backend>(f: &mut Frame<'_, B>, area: Rect) {
|
||||||
let mut logo_text = Text::from(RADARR_LOGO);
|
let mut logo_text = Text::from(RADARR_LOGO);
|
||||||
logo_text.patch_style(Style::default().fg(Color::LightYellow));
|
logo_text.patch_style(Style::default().fg(Color::LightYellow));
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
use tui::backend::Backend;
|
use tui::backend::Backend;
|
||||||
use tui::layout::{Alignment, Constraint, Rect};
|
use tui::layout::{Constraint, Rect};
|
||||||
use tui::widgets::{Cell, Paragraph, Row};
|
use tui::widgets::{Cell, Row};
|
||||||
use tui::Frame;
|
use tui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::radarr_models::RootFolder;
|
use crate::models::radarr_models::RootFolder;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS};
|
||||||
use crate::models::Route;
|
use crate::models::Route;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{layout_block_top_border, style_primary};
|
||||||
borderless_block, layout_block_top_border, show_cursor, style_default, style_help, style_primary,
|
|
||||||
title_block_centered, vertical_chunks_with_margin,
|
|
||||||
};
|
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
draw_popup_over, draw_prompt_box, draw_prompt_popup_over, draw_table, DrawUi, TableProps,
|
draw_input_box_popup, draw_popup_over, draw_prompt_box, draw_prompt_popup_over, draw_table,
|
||||||
|
DrawUi, TableProps,
|
||||||
};
|
};
|
||||||
use crate::utils::convert_to_gb;
|
use crate::utils::convert_to_gb;
|
||||||
|
|
||||||
@@ -109,37 +107,12 @@ fn draw_add_root_folder_prompt_box<B: Backend>(
|
|||||||
app: &mut App<'_>,
|
app: &mut App<'_>,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
) {
|
) {
|
||||||
let chunks = vertical_chunks_with_margin(
|
draw_input_box_popup(
|
||||||
vec![
|
f,
|
||||||
Constraint::Length(3),
|
|
||||||
Constraint::Length(1),
|
|
||||||
Constraint::Min(0),
|
|
||||||
],
|
|
||||||
area,
|
area,
|
||||||
1,
|
"Add Root Folder",
|
||||||
|
app.data.radarr_data.edit_root_folder.as_ref().unwrap(),
|
||||||
);
|
);
|
||||||
let block_title = "Add Root Folder";
|
|
||||||
let offset = *app
|
|
||||||
.data
|
|
||||||
.radarr_data
|
|
||||||
.edit_root_folder
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.offset
|
|
||||||
.borrow();
|
|
||||||
let block_content = &app.data.radarr_data.edit_root_folder.as_ref().unwrap().text;
|
|
||||||
|
|
||||||
let input = Paragraph::new(block_content.as_str())
|
|
||||||
.style(style_default())
|
|
||||||
.block(title_block_centered(block_title));
|
|
||||||
let help = Paragraph::new("<esc> cancel")
|
|
||||||
.style(style_help())
|
|
||||||
.alignment(Alignment::Center)
|
|
||||||
.block(borderless_block());
|
|
||||||
show_cursor(f, chunks[0], offset, block_content);
|
|
||||||
|
|
||||||
f.render_widget(input, chunks[0]);
|
|
||||||
f.render_widget(help, chunks[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_delete_root_folder_prompt<B: Backend>(
|
fn draw_delete_root_folder_prompt<B: Backend>(
|
||||||
|
|||||||
Reference in New Issue
Block a user