From 05b8f85dfb1f1288bb16c787f6af50fb1a2fccc1 Mon Sep 17 00:00:00 2001 From: Dark-Alex-17 Date: Tue, 8 Aug 2023 10:50:05 -0600 Subject: [PATCH] Updated UI to have contextual help with tables so the UI doesn't feel so crowded --- src/app/mod.rs | 25 ++++++------------ src/app/radarr.rs | 32 +++++++++++++++-------- src/models/mod.rs | 5 ++++ src/ui/mod.rs | 22 +++++++++++++++- src/ui/radarr_ui/add_movie_ui.rs | 3 ++- src/ui/radarr_ui/collection_details_ui.rs | 5 ++++ src/ui/radarr_ui/mod.rs | 15 +++++++++++ src/ui/radarr_ui/movie_details_ui.rs | 20 ++++++++++++++ 8 files changed, 97 insertions(+), 30 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index b109bc1..c38c450 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -72,13 +72,10 @@ impl App { pub async fn on_tick(&mut self, is_first_render: bool) { if self.tick_count % self.tick_until_poll == 0 || self.is_routing || self.should_refresh { - match self.get_current_route() { - Route::Radarr(active_radarr_block) => { - self - .radarr_on_tick(active_radarr_block.clone(), is_first_render) - .await; - } - _ => (), + if let Route::Radarr(active_radarr_block) = self.get_current_route() { + self + .radarr_on_tick(active_radarr_block.clone(), is_first_render) + .await; } self.is_routing = false; @@ -108,14 +105,6 @@ impl App { pub fn get_current_route(&self) -> &Route { self.navigation_stack.last().unwrap_or(&DEFAULT_ROUTE) } - - pub fn get_previous_route(&self) -> &Route { - if self.navigation_stack.len() > 1 { - &self.navigation_stack[self.navigation_stack.len() - 2] - } else { - self.get_current_route() - } - } } impl Default for App { @@ -128,13 +117,15 @@ impl Default for App { TabRoute { title: "Radarr".to_owned(), route: ActiveRadarrBlock::Movies.into(), - help: "<↑↓> scroll | ←→ change tab | change servarr | help | quit " + help: "<↑↓> scroll | ←→ change tab | change servarr | help | quit " .to_owned(), + contextual_help: None, }, TabRoute { title: "Sonarr".to_owned(), route: Route::Sonarr, - help: " change servarr | help | quit ".to_owned(), + help: " change servarr | help | quit ".to_owned(), + contextual_help: None, }, ]), client: Client::new(), diff --git a/src/app/radarr.rs b/src/app/radarr.rs index 210ca9e..0274e34 100644 --- a/src/app/radarr.rs +++ b/src/app/radarr.rs @@ -118,51 +118,60 @@ impl Default for RadarrData { TabRoute { title: "Library".to_owned(), route: ActiveRadarrBlock::Movies.into(), - help: " add | search | filter | details | cancel filter | delete " - .to_owned(), + help: String::default(), + contextual_help: Some(" add | search | filter | details | cancel filter | delete" + .to_owned()), }, TabRoute { title: "Downloads".to_owned(), route: ActiveRadarrBlock::Downloads.into(), - help: " delete ".to_owned(), + help: String::default(), + contextual_help: Some(" delete".to_owned()), }, TabRoute { title: "Collections".to_owned(), route: ActiveRadarrBlock::Collections.into(), - help: " search | filter | details | cancel filter " - .to_owned(), + help: String::default(), + contextual_help: Some(" search | filter | details | cancel filter" + .to_owned()), }, ]), movie_info_tabs: TabState::new(vec![ TabRoute { title: "Details".to_owned(), route: ActiveRadarrBlock::MovieDetails.into(), - help: " refresh | auto search | ←→ change tab | close ".to_owned(), + help: " refresh | auto search | close".to_owned(), + contextual_help: None }, TabRoute { title: "History".to_owned(), route: ActiveRadarrBlock::MovieHistory.into(), - help: " refresh | auto search | <↑↓> scroll | ←→ change tab | close ".to_owned(), + help: " refresh | auto search | close".to_owned(), + contextual_help: None }, TabRoute { title: "File".to_owned(), route: ActiveRadarrBlock::FileInfo.into(), - help: " refresh | auto search | ←→ change tab | close ".to_owned(), + help: " refresh | auto search | close".to_owned(), + contextual_help: None, }, TabRoute { title: "Cast".to_owned(), route: ActiveRadarrBlock::Cast.into(), - help: " refresh | auto search | <↑↓> scroll | ←→ change tab | close ".to_owned(), + help: " refresh | auto search | close".to_owned(), + contextual_help: None, }, TabRoute { title: "Crew".to_owned(), route: ActiveRadarrBlock::Crew.into(), - help: " refresh | auto search | <↑↓> scroll | ←→ change tab | close ".to_owned(), + help: " refresh | auto search | close".to_owned(), + contextual_help: None, }, TabRoute { title: "Manual Search".to_owned(), route: ActiveRadarrBlock::ManualSearch.into(), - help: " refresh | auto search | <↑↓> scroll | details | ←→ change tab | close ".to_owned(), + help: " refresh | auto search | close".to_owned(), + contextual_help: Some(" details | sort".to_owned()) } ]), } @@ -189,6 +198,7 @@ pub enum ActiveRadarrBlock { FilterCollections, FilterMovies, ManualSearch, + ManualSearchConfirmPrompt, Movies, MovieDetails, MovieHistory, diff --git a/src/models/mod.rs b/src/models/mod.rs index 084017a..0655b03 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -296,6 +296,7 @@ pub struct TabRoute { pub title: String, pub route: Route, pub help: String, + pub contextual_help: Option, } pub struct TabState { @@ -321,6 +322,10 @@ impl TabState { self.tabs[self.index].help.clone() } + pub fn get_active_tab_contextual_help(&self) -> Option { + self.tabs[self.index].contextual_help.clone() + } + pub fn next(&mut self) { self.index = (self.index + 1) % self.tabs.len(); } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index f70cef2..57cf879 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -17,7 +17,7 @@ use crate::ui::utils::{ layout_block_top_border, layout_button_paragraph, layout_button_paragraph_borderless, logo_block, style_button_highlight, style_default_bold, style_failure, style_help, style_highlight, style_primary, style_secondary, style_system_function, title_block, title_block_centered, - vertical_chunks_with_margin, + vertical_chunks, vertical_chunks_with_margin, }; mod radarr_ui; @@ -217,6 +217,7 @@ pub struct TableProps<'a, T> { pub content: &'a mut StatefulTable, pub table_headers: Vec<&'a str>, pub constraints: Vec, + pub help: Option, } fn draw_table<'a, B, T, F>( @@ -234,8 +235,27 @@ fn draw_table<'a, B, T, F>( content, table_headers, constraints, + help, } = table_props; + let content_area = if let Some(help_string) = help { + let chunks = vertical_chunks( + vec![Constraint::Min(0), Constraint::Length(3)], + content_area, + ); + let mut help_text = Text::from(format!(" {}", help_string)); + help_text.patch_style(style_help()); + let help_paragraph = Paragraph::new(help_text) + .block(layout_block_top_border()) + .alignment(Alignment::Left); + + f.render_widget(help_paragraph, chunks[1]); + + chunks[0] + } else { + content_area + }; + if !content.items.is_empty() { let rows = content.items.iter().map(row_mapper); diff --git a/src/ui/radarr_ui/add_movie_ui.rs b/src/ui/radarr_ui/add_movie_ui.rs index 4782853..9ac3934 100644 --- a/src/ui/radarr_ui/add_movie_ui.rs +++ b/src/ui/radarr_ui/add_movie_ui.rs @@ -84,7 +84,7 @@ fn draw_add_movie_search(f: &mut Frame<'_, B>, app: &mut App, area: | ActiveRadarrBlock::AddMovieSelectMonitor | ActiveRadarrBlock::AddMovieSelectMinimumAvailability | ActiveRadarrBlock::AddMovieSelectQualityProfile => { - let mut help_text = Text::from(" edit search"); + let mut help_text = Text::from(" details | edit search"); help_text.patch_style(style_help()); let help_paragraph = Paragraph::new(help_text) .block(borderless_block()) @@ -113,6 +113,7 @@ fn draw_add_movie_search(f: &mut Frame<'_, B>, app: &mut App, area: Constraint::Percentage(14), Constraint::Percentage(30), ], + help: None, }, |movie| { let (hours, minutes) = convert_runtime(movie.runtime.as_u64().unwrap()); diff --git a/src/ui/radarr_ui/collection_details_ui.rs b/src/ui/radarr_ui/collection_details_ui.rs index 266de8a..99c44d3 100644 --- a/src/ui/radarr_ui/collection_details_ui.rs +++ b/src/ui/radarr_ui/collection_details_ui.rs @@ -118,6 +118,11 @@ fn draw_collection_details(f: &mut Frame<'_, B>, app: &mut App, cont Constraint::Percentage(18), Constraint::Percentage(30), ], + help: app + .data + .radarr_data + .main_tabs + .get_active_tab_contextual_help(), }, |movie| { let (hours, minutes) = convert_runtime(movie.runtime.as_u64().unwrap()); diff --git a/src/ui/radarr_ui/mod.rs b/src/ui/radarr_ui/mod.rs index affbf32..a7f7633 100644 --- a/src/ui/radarr_ui/mod.rs +++ b/src/ui/radarr_ui/mod.rs @@ -143,6 +143,11 @@ fn draw_library(f: &mut Frame<'_, B>, app: &mut App, area: Rect) { Constraint::Percentage(12), Constraint::Percentage(12), ], + help: app + .data + .radarr_data + .main_tabs + .get_active_tab_contextual_help(), }, |movie| { let (hours, minutes) = convert_runtime(movie.runtime.as_u64().unwrap()); @@ -298,6 +303,11 @@ fn draw_downloads(f: &mut Frame<'_, B>, app: &mut App, area: Rect) { Constraint::Percentage(17), Constraint::Percentage(13), ], + help: app + .data + .radarr_data + .main_tabs + .get_active_tab_contextual_help(), }, |download_record| { let DownloadRecord { @@ -352,6 +362,11 @@ fn draw_collections(f: &mut Frame<'_, B>, app: &mut App, area: Rect) "Quality Profile", ], constraints: iter::repeat(Constraint::Ratio(1, 5)).take(5).collect(), + help: app + .data + .radarr_data + .main_tabs + .get_active_tab_contextual_help(), }, |collection| { let number_of_movies = collection.movies.clone().unwrap_or_default().len(); diff --git a/src/ui/radarr_ui/movie_details_ui.rs b/src/ui/radarr_ui/movie_details_ui.rs index f87c344..85c164e 100644 --- a/src/ui/radarr_ui/movie_details_ui.rs +++ b/src/ui/radarr_ui/movie_details_ui.rs @@ -220,6 +220,11 @@ fn draw_movie_history(f: &mut Frame<'_, B>, app: &mut App, content_a Constraint::Percentage(14), Constraint::Percentage(21), ], + help: app + .data + .radarr_data + .movie_info_tabs + .get_active_tab_contextual_help(), }, |movie_history_item| { let MovieHistoryItem { @@ -268,6 +273,11 @@ fn draw_movie_cast(f: &mut Frame<'_, B>, app: &mut App, content_area content: &mut app.data.radarr_data.movie_cast, constraints: iter::repeat(Constraint::Ratio(1, 2)).take(2).collect(), table_headers: vec!["Cast Member", "Character"], + help: app + .data + .radarr_data + .movie_info_tabs + .get_active_tab_contextual_help(), }, |cast_member| { let Credit { @@ -295,6 +305,11 @@ fn draw_movie_crew(f: &mut Frame<'_, B>, app: &mut App, content_area content: &mut app.data.radarr_data.movie_crew, constraints: iter::repeat(Constraint::Ratio(1, 3)).take(3).collect(), table_headers: vec!["Crew Member", "Job", "Department"], + help: app + .data + .radarr_data + .movie_info_tabs + .get_active_tab_contextual_help(), }, |crew_member| { let Credit { @@ -346,6 +361,11 @@ fn draw_movie_releases(f: &mut Frame<'_, B>, app: &mut App, content_ table_headers: vec![ "Source", "Age", "⛔", "Title", "Indexer", "Size", "Peers", "Language", "Quality", ], + help: app + .data + .radarr_data + .movie_info_tabs + .get_active_tab_contextual_help(), }, |release| { let Release {