Added horizontal scrolling for long movie titles, a refresh key, and fixed the network issues so that network requests are sent once every 20 seconds by default to not stress out the server.

This commit is contained in:
2023-08-08 10:50:06 -06:00
parent 7f3dd18478
commit 514fd2244a
12 changed files with 337 additions and 205 deletions
+5
View File
@@ -20,6 +20,7 @@ generate_keybindings! {
sort,
edit,
refresh,
update,
home,
end,
delete,
@@ -78,6 +79,10 @@ pub const DEFAULT_KEYBINDINGS: KeyBindings = KeyBindings {
key: Key::Char('r'),
desc: "Refresh",
},
update: KeyBinding {
key: Key::Char('u'),
desc: "Update All",
},
home: KeyBinding {
key: Key::Home,
desc: "Home",
+2 -9
View File
@@ -1,5 +1,3 @@
use std::time::Duration;
use anyhow::anyhow;
use log::{debug, error};
use reqwest::Client;
@@ -28,7 +26,6 @@ pub struct App {
pub ticks_until_scroll: u64,
pub tick_count: u64,
pub last_tick: Instant,
pub network_tick_frequency: Duration,
pub is_routing: bool,
pub is_loading: bool,
pub should_refresh: bool,
@@ -137,10 +134,9 @@ impl Default for App {
]),
client: Client::new(),
title: "Managarr",
tick_until_poll: 50,
tick_until_poll: 400,
ticks_until_scroll: 4,
tick_count: 0,
network_tick_frequency: Duration::from_secs(20),
last_tick: Instant::now(),
is_loading: false,
is_routing: false,
@@ -181,8 +177,6 @@ impl Default for RadarrConfig {
#[cfg(test)]
mod tests {
use std::time::Duration;
use anyhow::anyhow;
use pretty_assertions::{assert_eq, assert_str_eq};
use tokio::sync::mpsc;
@@ -220,10 +214,9 @@ mod tests {
]
);
assert_str_eq!(app.title, "Managarr");
assert_eq!(app.tick_until_poll, 50);
assert_eq!(app.tick_until_poll, 400);
assert_eq!(app.ticks_until_scroll, 4);
assert_eq!(app.tick_count, 0);
assert_eq!(app.network_tick_frequency, Duration::from_secs(20));
assert!(!app.is_loading);
assert!(!app.is_routing);
assert!(!app.should_refresh);
+19 -25
View File
@@ -1,5 +1,3 @@
use std::time::Duration;
use bimap::BiMap;
use chrono::{DateTime, Utc};
use strum::IntoEnumIterator;
@@ -218,7 +216,7 @@ impl Default for RadarrData {
title: "Library".to_owned(),
route: ActiveRadarrBlock::Movies.into(),
help: String::default(),
contextual_help: Some("<a> add | <e> edit | <s> search | <f> filter | <r> refresh | <enter> details | <esc> cancel filter | <del> delete"
contextual_help: Some("<a> add | <e> edit | <s> search | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter | <del> delete"
.to_owned()),
},
TabRoute {
@@ -231,7 +229,7 @@ impl Default for RadarrData {
title: "Collections".to_owned(),
route: ActiveRadarrBlock::Collections.into(),
help: String::default(),
contextual_help: Some("<s> search | <f> filter | <r> refresh | <enter> details | <esc> cancel filter"
contextual_help: Some("<s> search | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter"
.to_owned()),
},
]),
@@ -239,37 +237,37 @@ impl Default for RadarrData {
TabRoute {
title: "Details".to_owned(),
route: ActiveRadarrBlock::MovieDetails.into(),
help: "<r> refresh | <e> edit | <s> auto search | <esc> close".to_owned(),
help: "<r> refresh | <u> update | <e> edit | <s> auto search | <esc> close".to_owned(),
contextual_help: None
},
TabRoute {
title: "History".to_owned(),
route: ActiveRadarrBlock::MovieHistory.into(),
help: "<r> refresh | <e> edit | <s> auto search | <esc> close".to_owned(),
help: "<r> refresh | <u> update | <e> edit | <s> auto search | <esc> close".to_owned(),
contextual_help: None
},
TabRoute {
title: "File".to_owned(),
route: ActiveRadarrBlock::FileInfo.into(),
help: "<r> refresh | <e> edit | <s> auto search | <esc> close".to_owned(),
help: "<r> refresh | <u> update | <e> edit | <s> auto search | <esc> close".to_owned(),
contextual_help: None,
},
TabRoute {
title: "Cast".to_owned(),
route: ActiveRadarrBlock::Cast.into(),
help: "<r> refresh | <e> edit | <s> auto search | <esc> close".to_owned(),
help: "<r> refresh | <u> update | <e> edit | <s> auto search | <esc> close".to_owned(),
contextual_help: None,
},
TabRoute {
title: "Crew".to_owned(),
route: ActiveRadarrBlock::Crew.into(),
help: "<r> refresh | <e> edit | <s> auto search | <esc> close".to_owned(),
help: "<r> refresh | <u> update | <e> edit | <s> auto search | <esc> close".to_owned(),
contextual_help: None,
},
TabRoute {
title: "Manual Search".to_owned(),
route: ActiveRadarrBlock::ManualSearch.into(),
help: "<r> refresh | <e> edit | <o> sort | <s> auto search | <esc> close".to_owned(),
help: "<r> refresh | <u> update | <e> edit | <o> sort | <s> auto search | <esc> close".to_owned(),
contextual_help: Some("<enter> details".to_owned())
}
]),
@@ -313,10 +311,10 @@ pub enum ActiveRadarrBlock {
MovieDetails,
MovieHistory,
Movies,
RefreshAndScanPrompt,
RefreshAllCollectionsPrompt,
RefreshAllMoviesPrompt,
RefreshDownloadsPrompt,
UpdateAndScanPrompt,
UpdateAllCollectionsPrompt,
UpdateAllMoviesPrompt,
UpdateDownloadsPrompt,
SearchMovie,
SearchCollection,
ViewMovieOverview,
@@ -349,7 +347,7 @@ pub const MOVIE_DETAILS_BLOCKS: [ActiveRadarrBlock; 10] = [
ActiveRadarrBlock::Cast,
ActiveRadarrBlock::Crew,
ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
ActiveRadarrBlock::RefreshAndScanPrompt,
ActiveRadarrBlock::UpdateAndScanPrompt,
ActiveRadarrBlock::ManualSearch,
ActiveRadarrBlock::ManualSearchSortPrompt,
ActiveRadarrBlock::ManualSearchConfirmPrompt,
@@ -540,13 +538,7 @@ impl App {
self.dispatch_by_radarr_block(&active_radarr_block).await;
}
if self.is_routing
|| self
.network_tick_frequency
.checked_sub(self.last_tick.elapsed())
.unwrap_or_else(|| Duration::from_secs(0))
.is_zero()
{
if self.is_routing || self.tick_count % self.tick_until_poll == 0 {
self.refresh_metadata().await;
self.dispatch_by_radarr_block(&active_radarr_block).await;
}
@@ -559,6 +551,9 @@ impl App {
self
.dispatch_network_event(RadarrEvent::GetTags.into())
.await;
self
.dispatch_network_event(RadarrEvent::GetDownloads.into())
.await;
}
async fn populate_movie_collection_table(&mut self) {
@@ -1019,8 +1014,6 @@ mod tests {
}
mod radarr_tests {
use std::time::Duration;
use pretty_assertions::assert_eq;
use tokio::sync::mpsc;
@@ -1456,7 +1449,8 @@ mod tests {
#[tokio::test]
async fn test_radarr_on_tick_network_tick_frequency() {
let (mut app, mut sync_network_rx) = construct_app_unit();
app.network_tick_frequency = Duration::from_secs(0);
app.tick_count = 2;
app.tick_until_poll = 2;
app
.radarr_on_tick(ActiveRadarrBlock::Downloads, false)
+164 -86
View File
@@ -231,9 +231,9 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
}
ActiveRadarrBlock::DeleteMoviePrompt
| ActiveRadarrBlock::DeleteDownloadPrompt
| ActiveRadarrBlock::RefreshAllMoviesPrompt
| ActiveRadarrBlock::RefreshAllCollectionsPrompt
| ActiveRadarrBlock::RefreshDownloadsPrompt => handle_prompt_toggle(self.app, self.key),
| ActiveRadarrBlock::UpdateAllMoviesPrompt
| ActiveRadarrBlock::UpdateAllCollectionsPrompt
| ActiveRadarrBlock::UpdateDownloadsPrompt => handle_prompt_toggle(self.app, self.key),
ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchCollection => {
handle_text_box_left_right_keys!(self, self.key, self.app.data.radarr_data.search)
}
@@ -256,7 +256,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
if self.app.data.radarr_data.filtered_movies.items.is_empty() {
let selected_index = self
.search_table(&self.app.data.radarr_data.movies.items.clone(), |movie| {
&movie.title
&movie.title.text
});
self
.app
@@ -267,7 +267,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} else {
let selected_index = self.search_table(
&self.app.data.radarr_data.filtered_movies.items.clone(),
|movie| &movie.title,
|movie| &movie.title.text,
);
self
.app
@@ -288,7 +288,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
{
let selected_index = self.search_table(
&self.app.data.radarr_data.collections.items.clone(),
|collection| &collection.title,
|collection| &collection.title.text,
);
self
.app
@@ -299,7 +299,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} else {
let selected_index = self.search_table(
&self.app.data.radarr_data.filtered_collections.items.clone(),
|collection| &collection.title,
|collection| &collection.title.text,
);
self
.app
@@ -312,7 +312,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
ActiveRadarrBlock::FilterMovies => {
let filtered_movies = self
.filter_table(&self.app.data.radarr_data.movies.items.clone(), |movie| {
&movie.title
&movie.title.text
});
if !filtered_movies.is_empty() {
@@ -327,7 +327,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
ActiveRadarrBlock::FilterCollections => {
let filtered_collections = self.filter_table(
&self.app.data.radarr_data.collections.items.clone(),
|collection| &collection.title,
|collection| &collection.title.text,
);
if !filtered_collections.is_empty() {
@@ -353,23 +353,23 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
self.app.pop_navigation_stack();
}
ActiveRadarrBlock::RefreshAllMoviesPrompt => {
ActiveRadarrBlock::UpdateAllMoviesPrompt => {
if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateAllMovies);
}
self.app.pop_navigation_stack();
}
ActiveRadarrBlock::RefreshDownloadsPrompt => {
ActiveRadarrBlock::UpdateDownloadsPrompt => {
if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::RefreshDownloads);
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateDownloads);
}
self.app.pop_navigation_stack();
}
ActiveRadarrBlock::RefreshAllCollectionsPrompt => {
ActiveRadarrBlock::UpdateAllCollectionsPrompt => {
if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::RefreshCollections);
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateCollections);
}
self.app.pop_navigation_stack();
@@ -392,9 +392,9 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
}
ActiveRadarrBlock::DeleteMoviePrompt
| ActiveRadarrBlock::DeleteDownloadPrompt
| ActiveRadarrBlock::RefreshAllMoviesPrompt
| ActiveRadarrBlock::RefreshAllCollectionsPrompt
| ActiveRadarrBlock::RefreshDownloadsPrompt => {
| ActiveRadarrBlock::UpdateAllMoviesPrompt
| ActiveRadarrBlock::UpdateAllCollectionsPrompt
| ActiveRadarrBlock::UpdateDownloadsPrompt => {
self.app.pop_navigation_stack();
self.app.data.radarr_data.prompt_confirm = false;
}
@@ -441,18 +441,28 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
self.app.should_ignore_quit_key = true;
}
_ if *key == DEFAULT_KEYBINDINGS.update.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
}
_ if *key == DEFAULT_KEYBINDINGS.refresh.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::RefreshAllMoviesPrompt.into());
.pop_and_push_navigation_stack((*self.active_radarr_block).into());
}
_ => (),
},
ActiveRadarrBlock::Downloads => match self.key {
_ if *key == DEFAULT_KEYBINDINGS.update.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::UpdateDownloadsPrompt.into());
}
_ if *key == DEFAULT_KEYBINDINGS.refresh.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::RefreshDownloadsPrompt.into());
.pop_and_push_navigation_stack((*self.active_radarr_block).into());
}
_ => (),
},
@@ -471,10 +481,15 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
self.app.data.radarr_data.is_filtering = true;
self.app.should_ignore_quit_key = true;
}
_ if *key == DEFAULT_KEYBINDINGS.update.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
}
_ if *key == DEFAULT_KEYBINDINGS.refresh.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::RefreshAllCollectionsPrompt.into());
.pop_and_push_navigation_stack((*self.active_radarr_block).into());
}
_ => (),
},
@@ -614,6 +629,7 @@ mod tests {
use crate::handlers::radarr_handlers::RadarrHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::{Collection, Movie};
use crate::models::HorizontallyScrollableText;
use crate::{extended_stateful_iterable_vec, test_handler_delegation};
mod test_handle_scroll_up_and_down {
@@ -628,40 +644,44 @@ mod tests {
test_collections_scroll,
RadarrHandler,
collections,
Collection,
simple_stateful_iterable_vec!(Collection, HorizontallyScrollableText),
ActiveRadarrBlock::Collections,
None,
title
title,
to_string
);
test_iterable_scroll!(
test_filtered_collections_scroll,
RadarrHandler,
filtered_collections,
Collection,
simple_stateful_iterable_vec!(Collection, HorizontallyScrollableText),
ActiveRadarrBlock::Collections,
None,
title
title,
to_string
);
test_iterable_scroll!(
test_movies_scroll,
RadarrHandler,
movies,
Movie,
simple_stateful_iterable_vec!(Movie, HorizontallyScrollableText),
ActiveRadarrBlock::Movies,
None,
title
title,
to_string
);
test_iterable_scroll!(
test_filtered_movies_scroll,
RadarrHandler,
filtered_movies,
Movie,
simple_stateful_iterable_vec!(Movie, HorizontallyScrollableText),
ActiveRadarrBlock::Movies,
None,
title
title,
to_string
);
test_iterable_scroll!(
@@ -689,40 +709,44 @@ mod tests {
test_collections_home_end,
RadarrHandler,
collections,
Collection,
extended_stateful_iterable_vec!(Collection, HorizontallyScrollableText),
ActiveRadarrBlock::Collections,
None,
title
title,
to_string
);
test_iterable_home_and_end!(
test_filtered_collections_home_end,
RadarrHandler,
filtered_collections,
Collection,
extended_stateful_iterable_vec!(Collection, HorizontallyScrollableText),
ActiveRadarrBlock::Collections,
None,
title
title,
to_string
);
test_iterable_home_and_end!(
test_movies_home_end,
RadarrHandler,
movies,
Movie,
extended_stateful_iterable_vec!(Movie, HorizontallyScrollableText),
ActiveRadarrBlock::Movies,
None,
title
title,
to_string
);
test_iterable_home_and_end!(
test_filtered_movies_home_end,
RadarrHandler,
filtered_movies,
Movie,
extended_stateful_iterable_vec!(Movie, HorizontallyScrollableText),
ActiveRadarrBlock::Movies,
None,
title
title,
to_string
);
test_iterable_home_and_end!(
@@ -851,9 +875,9 @@ mod tests {
#[values(
ActiveRadarrBlock::DeleteMoviePrompt,
ActiveRadarrBlock::DeleteDownloadPrompt,
ActiveRadarrBlock::RefreshAllMoviesPrompt,
ActiveRadarrBlock::RefreshAllCollectionsPrompt,
ActiveRadarrBlock::RefreshDownloadsPrompt
ActiveRadarrBlock::UpdateAllMoviesPrompt,
ActiveRadarrBlock::UpdateAllCollectionsPrompt,
ActiveRadarrBlock::UpdateDownloadsPrompt
)]
active_radarr_block: ActiveRadarrBlock,
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
@@ -917,7 +941,10 @@ mod tests {
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(Movie));
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.search = "Test 2".to_owned().into();
RadarrHandler::with(
@@ -929,7 +956,7 @@ mod tests {
.handle();
assert_str_eq!(
app.data.radarr_data.movies.current_selection().title,
app.data.radarr_data.movies.current_selection().title.text,
"Test 2"
);
}
@@ -941,7 +968,10 @@ mod tests {
.data
.radarr_data
.filtered_movies
.set_items(extended_stateful_iterable_vec!(Movie));
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.search = "Test 2".to_owned().into();
RadarrHandler::with(
@@ -958,7 +988,8 @@ mod tests {
.radarr_data
.filtered_movies
.current_selection()
.title,
.title
.text,
"Test 2"
);
}
@@ -970,7 +1001,10 @@ mod tests {
.data
.radarr_data
.collections
.set_items(extended_stateful_iterable_vec!(Collection));
.set_items(extended_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
app.data.radarr_data.search = "Test 2".to_owned().into();
RadarrHandler::with(
@@ -982,7 +1016,13 @@ mod tests {
.handle();
assert_str_eq!(
app.data.radarr_data.collections.current_selection().title,
app
.data
.radarr_data
.collections
.current_selection()
.title
.text,
"Test 2"
);
}
@@ -994,7 +1034,10 @@ mod tests {
.data
.radarr_data
.filtered_collections
.set_items(extended_stateful_iterable_vec!(Collection));
.set_items(extended_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
app.data.radarr_data.search = "Test 2".to_owned().into();
RadarrHandler::with(
@@ -1011,7 +1054,8 @@ mod tests {
.radarr_data
.filtered_collections
.current_selection()
.title,
.title
.text,
"Test 2"
);
}
@@ -1023,7 +1067,10 @@ mod tests {
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(Movie));
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.filter = "Test".to_owned().into();
RadarrHandler::with(
@@ -1041,7 +1088,8 @@ mod tests {
.radarr_data
.filtered_movies
.current_selection()
.title,
.title
.text,
"Test 1"
);
}
@@ -1053,7 +1101,10 @@ mod tests {
.data
.radarr_data
.collections
.set_items(extended_stateful_iterable_vec!(Collection));
.set_items(extended_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
app.data.radarr_data.filter = "Test".to_owned().into();
RadarrHandler::with(
@@ -1071,7 +1122,8 @@ mod tests {
.radarr_data
.filtered_collections
.current_selection()
.title,
.title
.text,
"Test 1"
);
}
@@ -1089,18 +1141,18 @@ mod tests {
)]
#[case(
ActiveRadarrBlock::Movies,
ActiveRadarrBlock::RefreshAllMoviesPrompt,
ActiveRadarrBlock::UpdateAllMoviesPrompt,
RadarrEvent::UpdateAllMovies
)]
#[case(
ActiveRadarrBlock::Downloads,
ActiveRadarrBlock::RefreshDownloadsPrompt,
RadarrEvent::RefreshDownloads
ActiveRadarrBlock::UpdateDownloadsPrompt,
RadarrEvent::UpdateDownloads
)]
#[case(
ActiveRadarrBlock::Collections,
ActiveRadarrBlock::RefreshAllCollectionsPrompt,
RadarrEvent::RefreshCollections
ActiveRadarrBlock::UpdateAllCollectionsPrompt,
RadarrEvent::UpdateCollections
)]
fn test_prompt_confirm_submit(
#[case] base_route: ActiveRadarrBlock,
@@ -1125,14 +1177,11 @@ mod tests {
#[rstest]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::DeleteMoviePrompt)]
#[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::DeleteDownloadPrompt)]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::RefreshAllMoviesPrompt)]
#[case(
ActiveRadarrBlock::Downloads,
ActiveRadarrBlock::RefreshDownloadsPrompt
)]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)]
#[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::UpdateDownloadsPrompt)]
#[case(
ActiveRadarrBlock::Collections,
ActiveRadarrBlock::RefreshAllCollectionsPrompt
ActiveRadarrBlock::UpdateAllCollectionsPrompt
)]
fn test_prompt_decline_submit(
#[case] base_route: ActiveRadarrBlock,
@@ -1203,15 +1252,12 @@ mod tests {
#[rstest]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::DeleteMoviePrompt)]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::RefreshAllMoviesPrompt)]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)]
#[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::DeleteDownloadPrompt)]
#[case(
ActiveRadarrBlock::Downloads,
ActiveRadarrBlock::RefreshDownloadsPrompt
)]
#[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::UpdateDownloadsPrompt)]
#[case(
ActiveRadarrBlock::Collections,
ActiveRadarrBlock::RefreshAllCollectionsPrompt
ActiveRadarrBlock::UpdateAllCollectionsPrompt
)]
fn test_prompt_blocks_esc(
#[case] base_block: ActiveRadarrBlock,
@@ -1337,21 +1383,40 @@ mod tests {
}
#[rstest]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::RefreshAllMoviesPrompt)]
#[case(
ActiveRadarrBlock::Downloads,
ActiveRadarrBlock::RefreshDownloadsPrompt
)]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)]
#[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::UpdateDownloadsPrompt)]
#[case(
ActiveRadarrBlock::Collections,
ActiveRadarrBlock::RefreshAllCollectionsPrompt
ActiveRadarrBlock::UpdateAllCollectionsPrompt
)]
fn test_refresh_key(
fn test_update_key(
#[case] active_radarr_block: ActiveRadarrBlock,
#[case] expected_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
RadarrHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&active_radarr_block,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &expected_radarr_block.into());
}
#[rstest]
fn test_refresh_key(
#[values(
ActiveRadarrBlock::Movies,
ActiveRadarrBlock::Collections,
ActiveRadarrBlock::Downloads
)]
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
RadarrHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
@@ -1360,7 +1425,8 @@ mod tests {
)
.handle();
assert_eq!(app.get_current_route(), &expected_radarr_block.into());
assert_eq!(app.get_current_route(), &active_radarr_block.into());
assert!(app.is_routing);
}
#[rstest]
@@ -1433,7 +1499,10 @@ mod tests {
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(Movie));
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.search = "Test 2".to_owned().into();
app.data.radarr_data.is_searching = true;
app.should_ignore_quit_key = true;
@@ -1447,7 +1516,7 @@ mod tests {
&ActiveRadarrBlock::SearchMovie,
&None,
)
.search_table(movies, |movie| &movie.title);
.search_table(movies, |movie| &movie.title.text);
assert_eq!(index, Some(1));
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
@@ -1463,7 +1532,10 @@ mod tests {
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(Movie));
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.search = "Test 5".to_owned().into();
app.data.radarr_data.is_searching = true;
app.should_ignore_quit_key = true;
@@ -1477,7 +1549,7 @@ mod tests {
&ActiveRadarrBlock::SearchMovie,
&None,
)
.search_table(movies, |movie| &movie.title);
.search_table(movies, |movie| &movie.title.text);
assert_eq!(index, None);
assert_eq!(
@@ -1496,7 +1568,10 @@ mod tests {
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(Movie));
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.filter = "Test 2".to_owned().into();
app.data.radarr_data.is_searching = true;
app.should_ignore_quit_key = true;
@@ -1510,10 +1585,10 @@ mod tests {
&ActiveRadarrBlock::FilterMovies,
&None,
)
.filter_table(movies, |movie| &movie.title);
.filter_table(movies, |movie| &movie.title.text);
assert_eq!(filter_matches.len(), 1);
assert_str_eq!(filter_matches[0].title, "Test 2");
assert_str_eq!(filter_matches[0].title.text, "Test 2");
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key);
@@ -1527,7 +1602,10 @@ mod tests {
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(Movie));
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.filter = "Test 5".to_owned().into();
app.data.radarr_data.is_filtering = true;
app.should_ignore_quit_key = true;
@@ -1541,7 +1619,7 @@ mod tests {
&ActiveRadarrBlock::FilterMovies,
&None,
)
.filter_table(movies, |movie| &movie.title);
.filter_table(movies, |movie| &movie.title.text);
assert!(filter_matches.is_empty());
assert_eq!(
@@ -1590,7 +1668,7 @@ mod tests {
ActiveRadarrBlock::Cast,
ActiveRadarrBlock::Crew,
ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
ActiveRadarrBlock::RefreshAndScanPrompt,
ActiveRadarrBlock::UpdateAndScanPrompt,
ActiveRadarrBlock::ManualSearch,
ActiveRadarrBlock::ManualSearchConfirmPrompt
)]
@@ -127,7 +127,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for MovieDetailsHandler<'a> {
_ => (),
},
ActiveRadarrBlock::AutomaticallySearchMoviePrompt
| ActiveRadarrBlock::RefreshAndScanPrompt
| ActiveRadarrBlock::UpdateAndScanPrompt
| ActiveRadarrBlock::ManualSearchConfirmPrompt => handle_prompt_toggle(self.app, self.key),
_ => (),
}
@@ -143,9 +143,9 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for MovieDetailsHandler<'a> {
self.app.pop_navigation_stack();
}
ActiveRadarrBlock::RefreshAndScanPrompt => {
ActiveRadarrBlock::UpdateAndScanPrompt => {
if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::RefreshAndScan);
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateAndScan);
}
self.app.pop_navigation_stack();
@@ -201,7 +201,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for MovieDetailsHandler<'a> {
self.app.data.radarr_data.reset_movie_info_tabs();
}
ActiveRadarrBlock::AutomaticallySearchMoviePrompt
| ActiveRadarrBlock::RefreshAndScanPrompt
| ActiveRadarrBlock::UpdateAndScanPrompt
| ActiveRadarrBlock::ManualSearchConfirmPrompt
| ActiveRadarrBlock::ManualSearchSortPrompt => {
self.app.pop_navigation_stack();
@@ -236,10 +236,15 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for MovieDetailsHandler<'a> {
self.app.data.radarr_data.populate_edit_movie_fields();
self.app.data.radarr_data.selected_block = ActiveRadarrBlock::EditMovieToggleMonitored;
}
_ if *key == DEFAULT_KEYBINDINGS.update.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::UpdateAndScanPrompt.into());
}
_ if *key == DEFAULT_KEYBINDINGS.refresh.key => {
self
.app
.push_navigation_stack(ActiveRadarrBlock::RefreshAndScanPrompt.into());
.pop_and_push_navigation_stack((*self.active_radarr_block).into());
}
_ if *key == DEFAULT_KEYBINDINGS.sort.key => {
self
@@ -534,7 +539,7 @@ mod tests {
fn test_left_right_prompt_toggle(
#[values(
ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
ActiveRadarrBlock::RefreshAndScanPrompt,
ActiveRadarrBlock::UpdateAndScanPrompt,
ActiveRadarrBlock::ManualSearchConfirmPrompt
)]
active_radarr_block: ActiveRadarrBlock,
@@ -628,7 +633,7 @@ mod tests {
ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
RadarrEvent::TriggerAutomaticSearch
)]
#[case(ActiveRadarrBlock::RefreshAndScanPrompt, RadarrEvent::RefreshAndScan)]
#[case(ActiveRadarrBlock::UpdateAndScanPrompt, RadarrEvent::UpdateAndScan)]
#[case(
ActiveRadarrBlock::ManualSearchConfirmPrompt,
RadarrEvent::DownloadRelease
@@ -659,7 +664,7 @@ mod tests {
fn test_movie_info_prompt_decline_submit(
#[values(
ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
ActiveRadarrBlock::RefreshAndScanPrompt,
ActiveRadarrBlock::UpdateAndScanPrompt,
ActiveRadarrBlock::ManualSearchConfirmPrompt
)]
prompt_block: ActiveRadarrBlock,
@@ -748,7 +753,7 @@ mod tests {
fn test_movie_info_prompts_esc(
#[values(
ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
ActiveRadarrBlock::RefreshAndScanPrompt,
ActiveRadarrBlock::UpdateAndScanPrompt,
ActiveRadarrBlock::ManualSearchConfirmPrompt,
ActiveRadarrBlock::ManualSearchSortPrompt
)]
@@ -849,6 +854,34 @@ mod tests {
);
}
#[rstest]
fn test_update_key(
#[values(
ActiveRadarrBlock::MovieDetails,
ActiveRadarrBlock::MovieHistory,
ActiveRadarrBlock::FileInfo,
ActiveRadarrBlock::Cast,
ActiveRadarrBlock::Crew,
ActiveRadarrBlock::ManualSearch
)]
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
MovieDetailsHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&active_radarr_block,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::UpdateAndScanPrompt.into()
);
}
#[rstest]
fn test_refresh_key(
#[values(
@@ -871,10 +904,8 @@ mod tests {
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::RefreshAndScanPrompt.into()
);
assert_eq!(app.get_current_route(), &active_radarr_block.into());
assert!(app.is_routing);
}
}
+6 -7
View File
@@ -219,9 +219,8 @@ impl HorizontallyScrollableText {
}
pub fn scroll_left_or_reset(&self, width: usize, is_current_selection: bool, can_scroll: bool) {
if can_scroll {
if is_current_selection && self.text.len() >= width && *self.offset.borrow() < self.text.len()
{
if can_scroll && is_current_selection && self.text.len() >= width {
if *self.offset.borrow() < self.text.len() {
self.scroll_left();
} else {
self.reset_offset();
@@ -563,19 +562,19 @@ mod tests {
horizontally_scrollable_text.scroll_left_or_reset(width, false, true);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 0);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 1);
horizontally_scrollable_text.scroll_left_or_reset(width, true, false);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 0);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 1);
horizontally_scrollable_text.scroll_left_or_reset(width, true, true);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 1);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 2);
horizontally_scrollable_text.scroll_left_or_reset(test_text.len(), false, true);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 0);
assert_eq!(*horizontally_scrollable_text.offset.borrow(), 2);
}
#[test]
+2 -2
View File
@@ -36,7 +36,7 @@ pub struct RootFolder {
pub struct Movie {
#[derivative(Default(value = "Number::from(0)"))]
pub id: Number,
pub title: String,
pub title: HorizontallyScrollableText,
pub original_language: Language,
#[derivative(Default(value = "Number::from(0)"))]
pub size_on_disk: Number,
@@ -84,7 +84,7 @@ pub struct CollectionMovie {
#[serde(rename_all = "camelCase")]
pub struct Collection {
#[serde(default)]
pub title: String,
pub title: HorizontallyScrollableText,
pub root_folder_path: Option<String>,
pub search_on_add: bool,
pub overview: Option<String>,
+32 -32
View File
@@ -37,12 +37,12 @@ pub enum RadarrEvent {
GetStatus,
GetTags,
HealthCheck,
RefreshAndScan,
RefreshCollections,
RefreshDownloads,
SearchNewMovie,
TriggerAutomaticSearch,
UpdateAllMovies,
UpdateAndScan,
UpdateCollections,
UpdateDownloads,
}
impl RadarrEvent {
@@ -65,10 +65,10 @@ impl RadarrEvent {
RadarrEvent::GetStatus => "/system/status",
RadarrEvent::GetTags => "/tag",
RadarrEvent::TriggerAutomaticSearch
| RadarrEvent::RefreshAndScan
| RadarrEvent::UpdateAndScan
| RadarrEvent::UpdateAllMovies
| RadarrEvent::RefreshDownloads
| RadarrEvent::RefreshCollections => "/command",
| RadarrEvent::UpdateDownloads
| RadarrEvent::UpdateCollections => "/command",
RadarrEvent::HealthCheck => "/health",
}
}
@@ -101,12 +101,12 @@ impl<'a> Network<'a> {
RadarrEvent::GetStatus => self.get_status().await,
RadarrEvent::GetTags => self.get_tags().await,
RadarrEvent::HealthCheck => self.get_healthcheck().await,
RadarrEvent::RefreshAndScan => self.refresh_and_scan().await,
RadarrEvent::RefreshCollections => self.refresh_collections().await,
RadarrEvent::RefreshDownloads => self.refresh_downloads().await,
RadarrEvent::SearchNewMovie => self.search_movie().await,
RadarrEvent::TriggerAutomaticSearch => self.trigger_automatic_search().await,
RadarrEvent::UpdateAllMovies => self.update_all_movies().await,
RadarrEvent::UpdateAndScan => self.update_and_scan().await,
RadarrEvent::UpdateCollections => self.update_collections().await,
RadarrEvent::UpdateDownloads => self.update_downloads().await,
}
}
@@ -258,9 +258,9 @@ impl<'a> Network<'a> {
.await;
}
async fn refresh_and_scan(&self) {
async fn update_and_scan(&self) {
let movie_id = self.extract_movie_id().await;
info!("Refreshing and scanning movie with id: {}", movie_id);
info!("Updating and scanning movie with id: {}", movie_id);
let body = MovieCommandBody {
name: "RefreshMovie".to_owned(),
movie_ids: vec![movie_id],
@@ -268,7 +268,7 @@ impl<'a> Network<'a> {
let request_props = self
.radarr_request_props_from(
RadarrEvent::RefreshAndScan.resource(),
RadarrEvent::UpdateAndScan.resource(),
RequestMethod::Post,
Some(body),
)
@@ -299,15 +299,15 @@ impl<'a> Network<'a> {
.await;
}
async fn refresh_downloads(&self) {
info!("Refreshing downloads");
async fn update_downloads(&self) {
info!("Updating downloads");
let body = CommandBody {
name: "RefreshMonitoredDownloads".to_owned(),
};
let request_props = self
.radarr_request_props_from(
RadarrEvent::RefreshDownloads.resource(),
RadarrEvent::UpdateDownloads.resource(),
RequestMethod::Post,
Some(body),
)
@@ -318,15 +318,15 @@ impl<'a> Network<'a> {
.await;
}
async fn refresh_collections(&self) {
info!("Refreshing collections");
async fn update_collections(&self) {
info!("Updating collections");
let body = CommandBody {
name: "RefreshCollections".to_owned(),
};
let request_props = self
.radarr_request_props_from(
RadarrEvent::RefreshCollections.resource(),
RadarrEvent::UpdateCollections.resource(),
RequestMethod::Post,
Some(body),
)
@@ -1176,10 +1176,10 @@ mod test {
fn test_resource_command(
#[values(
RadarrEvent::TriggerAutomaticSearch,
RadarrEvent::RefreshAndScan,
RadarrEvent::UpdateAndScan,
RadarrEvent::UpdateAllMovies,
RadarrEvent::RefreshDownloads,
RadarrEvent::RefreshCollections
RadarrEvent::UpdateDownloads,
RadarrEvent::UpdateCollections
)]
event: RadarrEvent,
) {
@@ -1484,7 +1484,7 @@ mod test {
}
#[tokio::test]
async fn test_handle_refresh_and_scan_event() {
async fn test_handle_update_and_scan_event() {
let (async_server, app_arc, _server) = mock_radarr_api(
RequestMethod::Post,
Some(json!({
@@ -1492,7 +1492,7 @@ mod test {
"movieIds": [ 1 ]
})),
None,
RadarrEvent::RefreshAndScan.resource(),
RadarrEvent::UpdateAndScan.resource(),
)
.await;
app_arc
@@ -1505,7 +1505,7 @@ mod test {
let network = Network::new(reqwest::Client::new(), &app_arc);
network
.handle_radarr_event(RadarrEvent::RefreshAndScan)
.handle_radarr_event(RadarrEvent::UpdateAndScan)
.await;
async_server.assert_async().await;
@@ -1533,40 +1533,40 @@ mod test {
}
#[tokio::test]
async fn test_handle_refresh_downloads_event() {
async fn test_handle_update_downloads_event() {
let (async_server, app_arc, _server) = mock_radarr_api(
RequestMethod::Post,
Some(json!({
"name": "RefreshMonitoredDownloads"
})),
None,
RadarrEvent::RefreshDownloads.resource(),
RadarrEvent::UpdateDownloads.resource(),
)
.await;
let network = Network::new(reqwest::Client::new(), &app_arc);
network
.handle_radarr_event(RadarrEvent::RefreshDownloads)
.handle_radarr_event(RadarrEvent::UpdateDownloads)
.await;
async_server.assert_async().await;
}
#[tokio::test]
async fn test_handle_refresh_collections_event() {
async fn test_handle_update_collections_event() {
let (async_server, app_arc, _server) = mock_radarr_api(
RequestMethod::Post,
Some(json!({
"name": "RefreshCollections"
})),
None,
RadarrEvent::RefreshCollections.resource(),
RadarrEvent::UpdateCollections.resource(),
)
.await;
let network = Network::new(reqwest::Client::new(), &app_arc);
network
.handle_radarr_event(RadarrEvent::RefreshCollections)
.handle_radarr_event(RadarrEvent::UpdateCollections)
.await;
async_server.assert_async().await;
@@ -2562,7 +2562,7 @@ mod test {
fn collection() -> Collection {
Collection {
title: "Test Collection".to_owned(),
title: "Test Collection".to_owned().into(),
root_folder_path: None,
search_on_add: true,
overview: Some("Collection blah blah blah".to_owned()),
@@ -2574,7 +2574,7 @@ mod test {
fn movie() -> Movie {
Movie {
id: Number::from(1),
title: "Test".to_owned(),
title: "Test".to_owned().into(),
original_language: language(),
size_on_disk: Number::from(3543348019u64),
status: "Downloaded".to_owned(),
+5 -3
View File
@@ -92,9 +92,11 @@ fn draw_error<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
.style(style_failure())
.borders(Borders::ALL);
if app.error.text.len() > area.width as usize {
app.error.scroll_left();
}
app.error.scroll_left_or_reset(
area.width as usize,
true,
app.tick_count % app.ticks_until_scroll == 0,
);
let mut text = Text::from(app.error.to_string());
text.patch_style(style_failure());
+1 -1
View File
@@ -108,7 +108,7 @@ pub(super) fn draw_collection_details<B: Backend>(
.block(borderless_block())
.alignment(Alignment::Center);
f.render_widget(title_block(&collection_selection.title), content_area);
f.render_widget(title_block(&collection_selection.title.text), content_area);
f.render_widget(description_paragraph, chunks[0]);
f.render_widget(help_paragraph, chunks[2]);
+52 -18
View File
@@ -15,7 +15,7 @@ use crate::app::radarr::{
};
use crate::app::App;
use crate::logos::RADARR_LOGO;
use crate::models::radarr_models::{DiskSpace, DownloadRecord, Movie};
use crate::models::radarr_models::{Collection, DiskSpace, DownloadRecord, Movie};
use crate::models::Route;
use crate::ui::radarr_ui::add_movie_ui::draw_add_movie_search_popup;
use crate::ui::radarr_ui::collection_details_ui::draw_collection_details_popup;
@@ -123,26 +123,26 @@ pub(super) fn draw_radarr_ui<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, ar
draw_downloads,
draw_delete_download_prompt,
),
ActiveRadarrBlock::RefreshDownloadsPrompt => draw_prompt_popup_over(
ActiveRadarrBlock::UpdateDownloadsPrompt => draw_prompt_popup_over(
f,
app,
content_rect,
draw_downloads,
draw_refresh_downloads_prompt,
draw_update_downloads_prompt,
),
ActiveRadarrBlock::RefreshAllMoviesPrompt => draw_prompt_popup_over(
ActiveRadarrBlock::UpdateAllMoviesPrompt => draw_prompt_popup_over(
f,
app,
content_rect,
draw_library,
draw_refresh_all_movies_prompt,
draw_update_all_movies_prompt,
),
ActiveRadarrBlock::RefreshAllCollectionsPrompt => draw_prompt_popup_over(
ActiveRadarrBlock::UpdateAllCollectionsPrompt => draw_prompt_popup_over(
f,
app,
content_rect,
draw_collections,
draw_refresh_all_collections_prompt,
draw_update_all_collections_prompt,
),
_ => (),
}
@@ -157,6 +157,18 @@ 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) {
let current_selection = if !app.data.radarr_data.filtered_movies.items.is_empty() {
app
.data
.radarr_data
.filtered_movies
.current_selection()
.clone()
} else if !app.data.radarr_data.movies.items.is_empty() {
app.data.radarr_data.movies.current_selection().clone()
} else {
Movie::default()
};
let quality_profile_map = &app.data.radarr_data.quality_profile_map;
let tags_map = &app.data.radarr_data.tags_map;
let downloads_vec = &app.data.radarr_data.downloads.items;
@@ -205,6 +217,11 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
.get_active_tab_contextual_help(),
},
|movie| {
movie.title.scroll_left_or_reset(
get_width_from_percentage(area, 27),
*movie == current_selection,
app.tick_count % app.ticks_until_scroll == 0,
);
let monitored = if movie.monitored { "🏷" } else { "" };
let (hours, minutes) = convert_runtime(movie.runtime.as_u64().unwrap());
let file_size: f64 = convert_to_gb(movie.size_on_disk.as_u64().unwrap());
@@ -226,7 +243,7 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
.join(", ");
Row::new(vec![
Cell::from(movie.title.to_owned()),
Cell::from(movie.title.to_string()),
Cell::from(movie.year.to_string()),
Cell::from(movie.studio.to_string()),
Cell::from(format!("{}h {}m", hours, minutes)),
@@ -243,7 +260,7 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
);
}
fn draw_refresh_all_movies_prompt<B: Backend>(
fn draw_update_all_movies_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App,
prompt_area: Rect,
@@ -251,13 +268,13 @@ fn draw_refresh_all_movies_prompt<B: Backend>(
draw_prompt_box(
f,
prompt_area,
"Refresh All Movies",
"Do you want to refresh info and scan your disks for all of your movies?",
"Update All Movies",
"Do you want to update info and scan your disks for all of your movies?",
&app.data.radarr_data.prompt_confirm,
);
}
fn draw_refresh_downloads_prompt<B: Backend>(
fn draw_update_downloads_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App,
prompt_area: Rect,
@@ -265,13 +282,13 @@ fn draw_refresh_downloads_prompt<B: Backend>(
draw_prompt_box(
f,
prompt_area,
"Refresh Downloads",
"Do you want to refresh your downloads?",
"Update Downloads",
"Do you want to update your downloads?",
&app.data.radarr_data.prompt_confirm,
);
}
fn draw_refresh_all_collections_prompt<B: Backend>(
fn draw_update_all_collections_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App,
prompt_area: Rect,
@@ -279,8 +296,8 @@ fn draw_refresh_all_collections_prompt<B: Backend>(
draw_prompt_box(
f,
prompt_area,
"Refresh All Collections",
"Do you want to refresh all of your collections?",
"Update All Collections",
"Do you want to update all of your collections?",
&app.data.radarr_data.prompt_confirm,
);
}
@@ -496,6 +513,18 @@ fn draw_downloads<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 current_selection = if !app.data.radarr_data.filtered_collections.items.is_empty() {
app
.data
.radarr_data
.filtered_collections
.current_selection()
.clone()
} else if !app.data.radarr_data.collections.items.is_empty() {
app.data.radarr_data.collections.current_selection().clone()
} else {
Collection::default()
};
let quality_profile_map = &app.data.radarr_data.quality_profile_map;
let content = if !app.data.radarr_data.filtered_collections.items.is_empty()
&& !app.data.radarr_data.is_filtering
@@ -526,9 +555,14 @@ fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect)
},
|collection| {
let number_of_movies = collection.movies.clone().unwrap_or_default().len();
collection.title.scroll_left_or_reset(
get_width_from_percentage(area, 100 / 5),
*collection == current_selection,
app.tick_count % app.ticks_until_scroll == 0,
);
Row::new(vec![
Cell::from(collection.title.to_owned()),
Cell::from(collection.title.to_string()),
Cell::from(collection.search_on_add.to_string()),
Cell::from(number_of_movies.to_string()),
Cell::from(collection.root_folder_path.clone().unwrap_or_default()),
+5 -9
View File
@@ -39,12 +39,12 @@ pub(super) fn draw_movie_info_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut
draw_movie_info,
draw_search_movie_prompt,
),
ActiveRadarrBlock::RefreshAndScanPrompt => draw_prompt_popup_over(
ActiveRadarrBlock::UpdateAndScanPrompt => draw_prompt_popup_over(
f,
app,
content_area,
draw_movie_info,
draw_refresh_and_scan_prompt,
draw_update_and_scan_prompt,
),
ActiveRadarrBlock::ManualSearchSortPrompt => draw_drop_down_popup(
f,
@@ -102,17 +102,13 @@ fn draw_search_movie_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
);
}
fn draw_refresh_and_scan_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App,
prompt_area: Rect,
) {
fn draw_update_and_scan_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
"Refresh and Scan",
"Update and Scan",
format!(
"Do you want to trigger a refresh and disk scan for the movie: {}?",
"Do you want to trigger an update and disk scan for the movie: {}?",
app.data.radarr_data.movies.current_selection().title
)
.as_str(),