Fully added filtering and searching!

This commit is contained in:
2023-08-08 10:50:04 -06:00
parent 25730a3324
commit ca86cad950
9 changed files with 164 additions and 174 deletions
+24 -5
View File
@@ -16,6 +16,7 @@ pub struct RadarrData {
pub version: String, pub version: String,
pub start_time: DateTime<Utc>, pub start_time: DateTime<Utc>,
pub movies: StatefulTable<Movie>, pub movies: StatefulTable<Movie>,
pub filtered_movies: StatefulTable<Movie>,
pub downloads: StatefulTable<DownloadRecord>, pub downloads: StatefulTable<DownloadRecord>,
pub quality_profile_map: HashMap<u64, String>, pub quality_profile_map: HashMap<u64, String>,
pub movie_details: ScrollableText, pub movie_details: ScrollableText,
@@ -26,6 +27,7 @@ pub struct RadarrData {
pub movie_cast: StatefulTable<Credit>, pub movie_cast: StatefulTable<Credit>,
pub movie_crew: StatefulTable<Credit>, pub movie_crew: StatefulTable<Credit>,
pub collections: StatefulTable<Collection>, pub collections: StatefulTable<Collection>,
pub filtered_collections: StatefulTable<Collection>,
pub collection_movies: StatefulTable<CollectionMovie>, pub collection_movies: StatefulTable<CollectionMovie>,
pub main_tabs: TabState, pub main_tabs: TabState,
pub movie_info_tabs: TabState, pub movie_info_tabs: TabState,
@@ -43,6 +45,8 @@ impl RadarrData {
self.is_searching = false; self.is_searching = false;
self.search = String::default(); self.search = String::default();
self.filter = String::default(); self.filter = String::default();
self.filtered_movies = StatefulTable::default();
self.filtered_collections = StatefulTable::default();
} }
pub fn reset_movie_info_tabs(&mut self) { pub fn reset_movie_info_tabs(&mut self) {
@@ -68,6 +72,7 @@ impl Default for RadarrData {
version: String::default(), version: String::default(),
start_time: DateTime::default(), start_time: DateTime::default(),
movies: StatefulTable::default(), movies: StatefulTable::default(),
filtered_movies: StatefulTable::default(),
downloads: StatefulTable::default(), downloads: StatefulTable::default(),
quality_profile_map: HashMap::default(), quality_profile_map: HashMap::default(),
file_details: String::default(), file_details: String::default(),
@@ -78,6 +83,7 @@ impl Default for RadarrData {
movie_cast: StatefulTable::default(), movie_cast: StatefulTable::default(),
movie_crew: StatefulTable::default(), movie_crew: StatefulTable::default(),
collections: StatefulTable::default(), collections: StatefulTable::default(),
filtered_collections: StatefulTable::default(),
collection_movies: StatefulTable::default(), collection_movies: StatefulTable::default(),
search: String::default(), search: String::default(),
filter: String::default(), filter: String::default(),
@@ -86,7 +92,7 @@ impl Default for RadarrData {
TabRoute { TabRoute {
title: "Library".to_owned(), title: "Library".to_owned(),
route: ActiveRadarrBlock::Movies.into(), route: ActiveRadarrBlock::Movies.into(),
help: "<↑↓> scroll | <s> search | <f> filter | <enter> details | ←→ change tab " help: "<↑↓> scroll | <s> search | <f> filter | <enter> details | <esc> cancel filter | ←→ change tab "
.to_owned(), .to_owned(),
}, },
TabRoute { TabRoute {
@@ -97,7 +103,7 @@ impl Default for RadarrData {
TabRoute { TabRoute {
title: "Collections".to_owned(), title: "Collections".to_owned(),
route: ActiveRadarrBlock::Collections.into(), route: ActiveRadarrBlock::Collections.into(),
help: "<↑↓> scroll | <s> search | <f> filter | <enter> details | ←→ change tab " help: "<↑↓> scroll | <s> search | <f> filter | <enter> details | <esc> cancel filter | ←→ change tab "
.to_owned(), .to_owned(),
}, },
]), ]),
@@ -245,14 +251,27 @@ impl App {
} }
async fn populate_movie_collection_table(&mut self) { async fn populate_movie_collection_table(&mut self) {
self.data.radarr_data.collection_movies.set_items( let collection_movies = if !self.data.radarr_data.filtered_collections.items.is_empty() {
self
.data
.radarr_data
.filtered_collections
.current_selection_clone()
.movies
.unwrap_or_default()
} else {
self self
.data .data
.radarr_data .radarr_data
.collections .collections
.current_selection_clone() .current_selection_clone()
.movies .movies
.unwrap_or_default(), .unwrap_or_default()
); };
self
.data
.radarr_data
.collection_movies
.set_items(collection_movies);
} }
} }
+67 -71
View File
@@ -1,11 +1,9 @@
use regex::Regex;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::radarr::ActiveRadarrBlock; use crate::app::radarr::ActiveRadarrBlock;
use crate::handlers::radarr_handlers::collection_details_handler::CollectionDetailsHandler; use crate::handlers::radarr_handlers::collection_details_handler::CollectionDetailsHandler;
use crate::handlers::radarr_handlers::movie_details_handler::MovieDetailsHandler; use crate::handlers::radarr_handlers::movie_details_handler::MovieDetailsHandler;
use crate::handlers::{handle_clear_errors, KeyEventHandler}; use crate::handlers::{handle_clear_errors, KeyEventHandler};
use crate::models::radarr_models::Movie; use crate::models::radarr_models::{Collection, Movie};
use crate::models::Scrollable; use crate::models::Scrollable;
use crate::utils::strip_non_alphanumeric_characters; use crate::utils::strip_non_alphanumeric_characters;
use crate::{App, Key}; use crate::{App, Key};
@@ -55,16 +53,15 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
fn handle_scroll_up(&mut self) { fn handle_scroll_up(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Collections => { ActiveRadarrBlock::Collections => {
if !self.app.data.radarr_data.filter.is_empty() { if !self
self .app
.app .data
.data .radarr_data
.radarr_data .filtered_collections
.collections .items
.scroll_up_with_filter(|&collection| { .is_empty()
strip_non_alphanumeric_characters(&collection.title) {
.starts_with(&self.app.data.radarr_data.filter) self.app.data.radarr_data.filtered_collections.scroll_up();
});
} else { } else {
self.app.data.radarr_data.collections.scroll_up() self.app.data.radarr_data.collections.scroll_up()
} }
@@ -73,16 +70,8 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
self.app.data.radarr_data.collection_movies.scroll_up() self.app.data.radarr_data.collection_movies.scroll_up()
} }
ActiveRadarrBlock::Movies => { ActiveRadarrBlock::Movies => {
if !self.app.data.radarr_data.filter.is_empty() { if !self.app.data.radarr_data.filtered_movies.items.is_empty() {
self self.app.data.radarr_data.filtered_movies.scroll_up();
.app
.data
.radarr_data
.movies
.scroll_up_with_filter(|&movie| {
strip_non_alphanumeric_characters(&movie.title)
.starts_with(&self.app.data.radarr_data.filter)
});
} else { } else {
self.app.data.radarr_data.movies.scroll_up() self.app.data.radarr_data.movies.scroll_up()
} }
@@ -95,16 +84,15 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
fn handle_scroll_down(&mut self) { fn handle_scroll_down(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Collections => { ActiveRadarrBlock::Collections => {
if !self.app.data.radarr_data.filter.is_empty() { if !self
self .app
.app .data
.data .radarr_data
.radarr_data .filtered_collections
.collections .items
.scroll_down_with_filter(|&collection| { .is_empty()
strip_non_alphanumeric_characters(&collection.title) {
.starts_with(&self.app.data.radarr_data.filter) self.app.data.radarr_data.filtered_collections.scroll_down();
});
} else { } else {
self.app.data.radarr_data.collections.scroll_down() self.app.data.radarr_data.collections.scroll_down()
} }
@@ -113,16 +101,8 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
self.app.data.radarr_data.collection_movies.scroll_down() self.app.data.radarr_data.collection_movies.scroll_down()
} }
ActiveRadarrBlock::Movies => { ActiveRadarrBlock::Movies => {
if !self.app.data.radarr_data.filter.is_empty() { if !self.app.data.radarr_data.filtered_movies.items.is_empty() {
self self.app.data.radarr_data.filtered_movies.scroll_down();
.app
.data
.radarr_data
.movies
.scroll_down_with_filter(|&movie| {
strip_non_alphanumeric_characters(&movie.title)
.starts_with(&self.app.data.radarr_data.filter)
});
} else { } else {
self.app.data.radarr_data.movies.scroll_down() self.app.data.radarr_data.movies.scroll_down()
} }
@@ -192,7 +172,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
.items .items
.iter() .iter()
.position(|movie| { .position(|movie| {
strip_non_alphanumeric_characters(&movie.title).starts_with(&search_string) strip_non_alphanumeric_characters(&movie.title).contains(&search_string)
}); });
self.app.data.radarr_data.is_searching = false; self.app.data.radarr_data.is_searching = false;
@@ -220,7 +200,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
.items .items
.iter() .iter()
.position(|collection| { .position(|collection| {
strip_non_alphanumeric_characters(&collection.title).starts_with(&search_string) strip_non_alphanumeric_characters(&collection.title).contains(&search_string)
}); });
self.app.data.radarr_data.is_searching = false; self.app.data.radarr_data.is_searching = false;
@@ -236,47 +216,63 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} }
} }
ActiveRadarrBlock::FilterMovies => { ActiveRadarrBlock::FilterMovies => {
self.app.data.radarr_data.filter = let filter = strip_non_alphanumeric_characters(
strip_non_alphanumeric_characters(&self.app.data.radarr_data.filter); &self
let filter_string = &self.app.data.radarr_data.filter; .app
let filter_matches = self .data
.app .radarr_data
.data .filter
.radarr_data .drain(..)
.movies .collect::<String>(),
.items );
let movie_list = self.app.data.radarr_data.movies.items.clone();
let filter_matches = movie_list
.iter() .iter()
.filter(|&movie| { .filter(|&movie| strip_non_alphanumeric_characters(&movie.title).contains(&filter))
strip_non_alphanumeric_characters(&movie.title).starts_with(filter_string) .map(|movie| movie.to_owned())
}) .collect::<Vec<Movie>>();
.count();
self.app.data.radarr_data.is_searching = false; self.app.data.radarr_data.is_searching = false;
if filter_matches > 0 { if !filter_matches.is_empty() {
self.app.pop_navigation_stack(); self.app.pop_navigation_stack();
self
.app
.data
.radarr_data
.filtered_movies
.set_items(filter_matches);
} }
} }
ActiveRadarrBlock::FilterCollections => { ActiveRadarrBlock::FilterCollections => {
self.app.data.radarr_data.filter = let filter = strip_non_alphanumeric_characters(
strip_non_alphanumeric_characters(&self.app.data.radarr_data.filter); &self
let filter_string = &self.app.data.radarr_data.filter; .app
let filter_matches = self .data
.app .radarr_data
.data .filter
.radarr_data .drain(..)
.collections .collect::<String>(),
.items );
let collection_list = self.app.data.radarr_data.collections.items.clone();
let filter_matches = collection_list
.iter() .iter()
.filter(|&collection| { .filter(|&collection| {
strip_non_alphanumeric_characters(&collection.title).starts_with(filter_string) strip_non_alphanumeric_characters(&collection.title).contains(&filter)
}) })
.count(); .map(|collection| collection.to_owned())
.collect::<Vec<Collection>>();
self.app.data.radarr_data.is_searching = false; self.app.data.radarr_data.is_searching = false;
if filter_matches > 0 { if !filter_matches.is_empty() {
self.app.pop_navigation_stack(); self.app.pop_navigation_stack();
self
.app
.data
.radarr_data
.filtered_collections
.set_items(filter_matches);
} }
} }
_ => (), _ => (),
+3 -51
View File
@@ -1,6 +1,7 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::{Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use log::debug;
use serde::Deserialize; use serde::Deserialize;
use tui::widgets::TableState; use tui::widgets::TableState;
@@ -40,7 +41,7 @@ impl<T> Default for StatefulTable<T> {
} }
} }
impl<T: Clone + PartialEq + Eq> StatefulTable<T> { impl<T: Clone + PartialEq + Eq + Debug> StatefulTable<T> {
pub fn set_items(&mut self, items: Vec<T>) { pub fn set_items(&mut self, items: Vec<T>) {
let items_len = items.len(); let items_len = items.len();
self.items = items; self.items = items;
@@ -69,55 +70,6 @@ impl<T: Clone + PartialEq + Eq> StatefulTable<T> {
pub fn select_index(&mut self, index: Option<usize>) { pub fn select_index(&mut self, index: Option<usize>) {
self.state.select(index); self.state.select(index);
} }
pub fn scroll_up_with_filter<F>(&mut self, filter: F)
where
F: FnMut(&&T) -> bool,
{
let filtered_list: Vec<&T> = self.items.iter().filter(filter).collect();
let element_position = filtered_list
.iter()
.position(|&item| item == self.current_selection())
.unwrap();
if element_position == 0 {
let selected_index = self
.items
.iter()
.position(|item| item == filtered_list[filtered_list.len()]);
self.select_index(selected_index);
} else {
let selected_index = self
.items
.iter()
.position(|item| item == filtered_list[element_position - 1]);
self.select_index(selected_index)
}
}
pub fn scroll_down_with_filter<F>(&mut self, filter: F)
where
F: FnMut(&&T) -> bool,
{
let filtered_list: Vec<&T> = self.items.iter().filter(filter).collect();
let element_position = filtered_list
.iter()
.position(|&item| item == self.current_selection())
.unwrap();
if element_position + 1 > filtered_list.len() {
let selected_index = self.items.iter().position(|item| item == filtered_list[0]);
self.select_index(selected_index);
} else {
let selected_index = self
.items
.iter()
.position(|item| item == filtered_list[element_position + 1]);
self.select_index(selected_index)
}
}
} }
impl<T> Scrollable for StatefulTable<T> { impl<T> Scrollable for StatefulTable<T> {
+34 -7
View File
@@ -1,3 +1,5 @@
use std::ops::Deref;
use anyhow::anyhow; use anyhow::anyhow;
use indoc::formatdoc; use indoc::formatdoc;
use log::{debug, error}; use log::{debug, error};
@@ -195,6 +197,7 @@ impl<'a> Network<'a> {
let status = get_movie_status(has_file, &app.data.radarr_data.downloads.items, id); let status = get_movie_status(has_file, &app.data.radarr_data.downloads.items, id);
let collection = collection.unwrap_or_default(); let collection = collection.unwrap_or_default();
debug!("title: {:?}", title);
app.data.radarr_data.movie_details = ScrollableText::with_string(formatdoc!( app.data.radarr_data.movie_details = ScrollableText::with_string(formatdoc!(
"Title: {} "Title: {}
@@ -394,18 +397,42 @@ impl<'a> Network<'a> {
} }
async fn extract_movie_id(&self) -> u64 { async fn extract_movie_id(&self) -> u64 {
self if !self
.app .app
.lock() .lock()
.await .await
.data .data
.radarr_data .radarr_data
.movies .filtered_movies
.current_selection() .items
.id .is_empty()
.clone() {
.as_u64() self
.unwrap() .app
.lock()
.await
.data
.radarr_data
.filtered_movies
.current_selection()
.id
.clone()
.as_u64()
.unwrap()
} else {
self
.app
.lock()
.await
.data
.radarr_data
.movies
.current_selection()
.id
.clone()
.as_u64()
.unwrap()
}
} }
async fn append_movie_id_param(&self, resource: &str) -> String { async fn append_movie_id_param(&self, resource: &str) -> String {
+2 -4
View File
@@ -201,18 +201,16 @@ pub struct TableProps<'a, T> {
pub constraints: Vec<Constraint>, pub constraints: Vec<Constraint>,
} }
fn draw_table<'a, B, T, F, S>( fn draw_table<'a, B, T, F>(
f: &mut Frame<'_, B>, f: &mut Frame<'_, B>,
content_area: Rect, content_area: Rect,
block: Block, block: Block,
table_props: TableProps<'a, T>, table_props: TableProps<'a, T>,
row_mapper: F, row_mapper: F,
filter_fn: S,
is_loading: bool, is_loading: bool,
) where ) where
B: Backend, B: Backend,
F: Fn(&T) -> Row<'a>, F: Fn(&T) -> Row<'a>,
S: FnMut(&&T) -> bool,
{ {
let TableProps { let TableProps {
content, content,
@@ -221,7 +219,7 @@ fn draw_table<'a, B, T, F, S>(
} = table_props; } = table_props;
if !content.items.is_empty() { if !content.items.is_empty() {
let rows = content.items.iter().filter(filter_fn).map(row_mapper); let rows = content.items.iter().map(row_mapper);
let headers = Row::new(table_headers) let headers = Row::new(table_headers)
.style(style_default_bold()) .style(style_default_bold())
+9 -2
View File
@@ -46,7 +46,15 @@ fn draw_collection_details<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, cont
content_area, content_area,
1, 1,
); );
let collection_selection = app.data.radarr_data.collections.current_selection(); let collection_selection = if !app.data.radarr_data.filtered_collections.items.is_empty() {
app
.data
.radarr_data
.filtered_collections
.current_selection()
} else {
app.data.radarr_data.collections.current_selection()
};
let quality_profile = app let quality_profile = app
.data .data
.radarr_data .radarr_data
@@ -150,7 +158,6 @@ fn draw_collection_details<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, cont
]) ])
.style(style_primary()) .style(style_primary())
}, },
|_| true,
app.is_loading, app.is_loading,
); );
} }
+24 -30
View File
@@ -2,7 +2,6 @@ use std::iter;
use std::ops::Sub; use std::ops::Sub;
use chrono::{Duration, Utc}; use chrono::{Duration, Utc};
use regex::Regex;
use tui::backend::Backend; use tui::backend::Backend;
use tui::layout::{Alignment, Constraint, Rect}; use tui::layout::{Alignment, Constraint, Rect};
use tui::style::{Color, Style}; use tui::style::{Color, Style};
@@ -13,7 +12,7 @@ use tui::Frame;
use crate::app::radarr::{ActiveRadarrBlock, RadarrData}; use crate::app::radarr::{ActiveRadarrBlock, RadarrData};
use crate::app::App; use crate::app::App;
use crate::logos::RADARR_LOGO; use crate::logos::RADARR_LOGO;
use crate::models::radarr_models::{Collection, DiskSpace, DownloadRecord, Movie}; use crate::models::radarr_models::{DiskSpace, DownloadRecord, Movie};
use crate::models::Route; use crate::models::Route;
use crate::ui::radarr_ui::collection_details_ui::draw_collection_details_popup; use crate::ui::radarr_ui::collection_details_ui::draw_collection_details_popup;
use crate::ui::radarr_ui::movie_details_ui::draw_movie_info; use crate::ui::radarr_ui::movie_details_ui::draw_movie_info;
@@ -84,15 +83,12 @@ pub(super) fn draw_radarr_context_row<B: Backend>(f: &mut Frame<'_, B>, app: &Ap
fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) { fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
let quality_profile_map = &app.data.radarr_data.quality_profile_map; let quality_profile_map = &app.data.radarr_data.quality_profile_map;
let downloads_vec = &app.data.radarr_data.downloads.items; let downloads_vec = &app.data.radarr_data.downloads.items;
let filter_fn: Box<dyn FnMut(&&Movie) -> bool> = if !app.data.radarr_data.filter.is_empty() { let content = if !app.data.radarr_data.filtered_movies.items.is_empty()
Box::new(|&movie| { && !app.data.radarr_data.is_searching
Regex::new(r"[^a-zA-Z0-9\s]") {
.unwrap() &mut app.data.radarr_data.filtered_movies
.replace_all(&movie.title.to_lowercase(), "")
.starts_with(&app.data.radarr_data.filter)
})
} else { } else {
Box::new(|_| true) &mut app.data.radarr_data.movies
}; };
draw_table( draw_table(
@@ -100,7 +96,7 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
area, area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app.data.radarr_data.movies, content,
table_headers: vec![ table_headers: vec![
"Title", "Title",
"Year", "Year",
@@ -141,7 +137,6 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
]) ])
.style(determine_row_style(downloads_vec, movie)) .style(determine_row_style(downloads_vec, movie))
}, },
filter_fn,
app.is_loading, app.is_loading,
); );
} }
@@ -166,19 +161,23 @@ fn draw_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect)
f.render_widget(input, chunks[0]); f.render_widget(input, chunks[0]);
} else { } else {
let block_title = match app.get_current_route() { let (block_title, block_content) = match app.get_current_route() {
Route::Radarr(active_radarr_block) => match active_radarr_block { Route::Radarr(active_radarr_block) => match active_radarr_block {
ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchCollection => "Search", ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchCollection => {
ActiveRadarrBlock::FilterMovies | ActiveRadarrBlock::FilterCollections => "Filter", ("Search", app.data.radarr_data.search.as_str())
_ => "", }
ActiveRadarrBlock::FilterMovies | ActiveRadarrBlock::FilterCollections => {
("Filter", app.data.radarr_data.filter.as_str())
}
_ => ("", ""),
}, },
_ => "", _ => ("", ""),
}; };
let input = Paragraph::new(app.data.radarr_data.search.as_ref()) let input = Paragraph::new(block_content)
.style(style_default()) .style(style_default())
.block(title_block(block_title)); .block(title_block(block_title));
show_cursor(f, chunks[0], &app.data.radarr_data.search); show_cursor(f, chunks[0], block_content);
f.render_widget(input, chunks[0]); f.render_widget(input, chunks[0]);
} }
@@ -275,29 +274,25 @@ fn draw_downloads<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
]) ])
.style(style_primary()) .style(style_primary())
}, },
|_| true,
app.is_loading, app.is_loading,
); );
} }
fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) { fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
let quality_profile_map = &app.data.radarr_data.quality_profile_map; let quality_profile_map = &app.data.radarr_data.quality_profile_map;
let filter_fn: Box<dyn FnMut(&&Collection) -> bool> = if !app.data.radarr_data.filter.is_empty() { let content = if !app.data.radarr_data.filtered_collections.items.is_empty()
Box::new(|&collection| { && !app.data.radarr_data.is_searching
Regex::new(r"[^a-zA-Z0-9\s]") {
.unwrap() &mut app.data.radarr_data.filtered_collections
.replace_all(&collection.title.to_lowercase(), "")
.starts_with(&app.data.radarr_data.filter)
})
} else { } else {
Box::new(|_| true) &mut app.data.radarr_data.collections
}; };
draw_table( draw_table(
f, f,
area, area,
layout_block_top_border(), layout_block_top_border(),
TableProps { TableProps {
content: &mut app.data.radarr_data.collections, content,
table_headers: vec![ table_headers: vec![
"Collection", "Collection",
"Search on Add?", "Search on Add?",
@@ -324,7 +319,6 @@ fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect)
]) ])
.style(style_primary()) .style(style_primary())
}, },
filter_fn,
app.is_loading, app.is_loading,
); );
} }
-3
View File
@@ -196,7 +196,6 @@ fn draw_movie_history<B: Backend>(
]) ])
.style(style_success()) .style(style_success())
}, },
|_| true,
app.is_loading, app.is_loading,
); );
} }
@@ -229,7 +228,6 @@ fn draw_movie_cast<B: Backend>(
]) ])
.style(style_success()) .style(style_success())
}, },
|_| true,
app.is_loading, app.is_loading,
) )
} }
@@ -264,7 +262,6 @@ fn draw_movie_crew<B: Backend>(
]) ])
.style(style_success()) .style(style_success())
}, },
|_| true,
app.is_loading, app.is_loading,
); );
} }
+1 -1
View File
@@ -206,6 +206,6 @@ pub fn line_gauge_with_label(title: &str, ratio: f64) -> LineGauge {
.label(Spans::from(format!("{}: {:.0}%", title, ratio * 100.0))) .label(Spans::from(format!("{}: {:.0}%", title, ratio * 100.0)))
} }
pub fn show_cursor<B: Backend>(f: &mut Frame<'_, B>, area: Rect, string: &String) { pub fn show_cursor<B: Backend>(f: &mut Frame<'_, B>, area: Rect, string: &str) {
f.set_cursor(area.x + string.len() as u16 + 1, area.y + 1); f.set_cursor(area.x + string.len() as u16 + 1, area.y + 1);
} }