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:
+51
-5
@@ -14,7 +14,7 @@ use tui::widgets::{Clear, List, ListItem};
|
||||
use tui::Frame;
|
||||
|
||||
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::utils::{
|
||||
background_block, borderless_block, centered_rect, horizontal_chunks,
|
||||
@@ -659,8 +659,8 @@ pub fn draw_text_box<B: Backend>(
|
||||
should_show_cursor: bool,
|
||||
is_selected: bool,
|
||||
) {
|
||||
let (block, style) = if let Some(..) = block_title {
|
||||
(title_block_centered(block_title.unwrap()), style_default())
|
||||
let (block, style) = if let Some(title) = block_title {
|
||||
(title_block_centered(title), style_default())
|
||||
} else {
|
||||
(
|
||||
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)
|
||||
.block(block);
|
||||
f.render_widget(search_paragraph, text_box_area);
|
||||
f.render_widget(paragraph, text_box_area);
|
||||
|
||||
if should_show_cursor {
|
||||
show_cursor(f, text_box_area, offset, block_content);
|
||||
@@ -716,3 +716,49 @@ pub fn draw_text_box_with_label<B: Backend>(
|
||||
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::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi;
|
||||
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::{
|
||||
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;
|
||||
@@ -45,19 +45,37 @@ impl DrawUi for CollectionsUi {
|
||||
app,
|
||||
content_rect,
|
||||
draw_collections,
|
||||
draw_search_box,
|
||||
draw_collection_search_box,
|
||||
30,
|
||||
13,
|
||||
),
|
||||
ActiveRadarrBlock::SearchCollectionError => draw_popup_over(
|
||||
f,
|
||||
app,
|
||||
content_rect,
|
||||
draw_collections,
|
||||
draw_search_collection_error_box,
|
||||
30,
|
||||
8,
|
||||
),
|
||||
ActiveRadarrBlock::FilterCollections => draw_popup_over(
|
||||
f,
|
||||
app,
|
||||
content_rect,
|
||||
draw_collections,
|
||||
draw_filter_box,
|
||||
draw_filter_collections_box,
|
||||
30,
|
||||
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(
|
||||
f,
|
||||
app,
|
||||
@@ -177,3 +195,33 @@ fn draw_update_all_collections_prompt<B: Backend>(
|
||||
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(
|
||||
iter::repeat(Constraint::Ratio(1, 4)).take(4).collect(),
|
||||
// vec![Constraint::Percentage(50), Constraint::Percentage(50)],
|
||||
chunks[1],
|
||||
);
|
||||
|
||||
|
||||
@@ -7,14 +7,15 @@ use crate::app::App;
|
||||
use crate::models::radarr_models::Movie;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, LIBRARY_BLOCKS};
|
||||
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::delete_movie_ui::DeleteMovieUi;
|
||||
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::{determine_row_style, draw_filter_box, draw_search_box};
|
||||
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
||||
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};
|
||||
|
||||
@@ -47,12 +48,42 @@ impl DrawUi for LibraryUi {
|
||||
let mut library_ui_matchers = |active_radarr_block: ActiveRadarrBlock| match active_radarr_block
|
||||
{
|
||||
ActiveRadarrBlock::Movies => draw_library(f, app, content_rect),
|
||||
ActiveRadarrBlock::SearchMovie => {
|
||||
draw_popup_over(f, app, content_rect, draw_library, draw_search_box, 30, 13)
|
||||
}
|
||||
ActiveRadarrBlock::FilterMovies => {
|
||||
draw_popup_over(f, app, content_rect, draw_library, draw_filter_box, 30, 13)
|
||||
}
|
||||
ActiveRadarrBlock::SearchMovie => draw_popup_over(
|
||||
f,
|
||||
app,
|
||||
content_rect,
|
||||
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(
|
||||
f,
|
||||
app,
|
||||
@@ -194,3 +225,29 @@ fn draw_update_all_movies_prompt<B: Backend>(
|
||||
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::logos::RADARR_LOGO;
|
||||
use crate::models::radarr_models::{DiskSpace, DownloadRecord, Movie, RootFolder};
|
||||
use crate::models::servarr_data::radarr::radarr_data::{
|
||||
ActiveRadarrBlock, RadarrData, FILTER_BLOCKS, SEARCH_BLOCKS,
|
||||
};
|
||||
use crate::models::servarr_data::radarr::radarr_data::RadarrData;
|
||||
use crate::models::Route;
|
||||
use crate::ui::draw_tabs;
|
||||
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::utils::{
|
||||
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_success, style_unmonitored, style_warning, title_block, title_block_centered,
|
||||
vertical_chunks_with_margin,
|
||||
style_awaiting_import, style_bold, style_default, style_failure, style_success,
|
||||
style_unmonitored, style_warning, title_block, vertical_chunks_with_margin,
|
||||
};
|
||||
use crate::ui::DrawUi;
|
||||
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) {
|
||||
let mut logo_text = Text::from(RADARR_LOGO);
|
||||
logo_text.patch_style(Style::default().fg(Color::LightYellow));
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
use tui::backend::Backend;
|
||||
use tui::layout::{Alignment, Constraint, Rect};
|
||||
use tui::widgets::{Cell, Paragraph, Row};
|
||||
use tui::layout::{Constraint, Rect};
|
||||
use tui::widgets::{Cell, Row};
|
||||
use tui::Frame;
|
||||
|
||||
use crate::app::App;
|
||||
use crate::models::radarr_models::RootFolder;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS};
|
||||
use crate::models::Route;
|
||||
use crate::ui::utils::{
|
||||
borderless_block, layout_block_top_border, show_cursor, style_default, style_help, style_primary,
|
||||
title_block_centered, vertical_chunks_with_margin,
|
||||
};
|
||||
use crate::ui::utils::{layout_block_top_border, style_primary};
|
||||
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;
|
||||
|
||||
@@ -109,37 +107,12 @@ fn draw_add_root_folder_prompt_box<B: Backend>(
|
||||
app: &mut App<'_>,
|
||||
area: Rect,
|
||||
) {
|
||||
let chunks = vertical_chunks_with_margin(
|
||||
vec![
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(1),
|
||||
Constraint::Min(0),
|
||||
],
|
||||
draw_input_box_popup(
|
||||
f,
|
||||
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>(
|
||||
|
||||
Reference in New Issue
Block a user