Added two new checkboxes to the delete movie UI that allows users to specify to delete the file and/or add an exclusion for the selected film on deletion. Also fixed the refresh bug in the root folders UI where you have to manually refresh to get the changes to show before 20 seconds. Also cleaned up code a bit and removed some unnecessary clone calls and references-dereferences since the types were copyable and not necessary to be referenced since they were all dereferenced anyway and copied. Made sense to just cut out the middleman on the copies.

This commit is contained in:
2023-08-08 10:50:06 -06:00
parent b7d00f4827
commit 435926f6f0
15 changed files with 618 additions and 132 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "managarr" name = "managarr"
version = "0.0.15" version = "0.0.16"
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"] authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
description = "A TUI for managing *arr servers" description = "A TUI for managing *arr servers"
keywords = ["managarr", "tui-rs", "dashboard", "servarr"] keywords = ["managarr", "tui-rs", "dashboard", "servarr"]
+116 -8
View File
@@ -51,6 +51,8 @@ pub struct RadarrData {
pub edit_search_on_add: Option<bool>, pub edit_search_on_add: Option<bool>,
pub sort_ascending: Option<bool>, pub sort_ascending: Option<bool>,
pub prompt_confirm: bool, pub prompt_confirm: bool,
pub delete_movie_files: bool,
pub add_list_exclusion: bool,
pub is_searching: bool, pub is_searching: bool,
pub is_filtering: bool, pub is_filtering: bool,
} }
@@ -60,6 +62,11 @@ impl RadarrData {
self.collection_movies = StatefulTable::default(); self.collection_movies = StatefulTable::default();
} }
pub fn reset_delete_movie_preferences(&mut self) {
self.delete_movie_files = false;
self.add_list_exclusion = false;
}
pub fn reset_search(&mut self) { pub fn reset_search(&mut self) {
self.is_searching = false; self.is_searching = false;
self.search = HorizontallyScrollableText::default(); self.search = HorizontallyScrollableText::default();
@@ -260,6 +267,8 @@ impl Default for RadarrData {
is_searching: false, is_searching: false,
is_filtering: false, is_filtering: false,
prompt_confirm: false, prompt_confirm: false,
delete_movie_files: false,
add_list_exclusion: false,
main_tabs: TabState::new(vec![ main_tabs: TabState::new(vec![
TabRoute { TabRoute {
title: "Library".to_owned(), title: "Library".to_owned(),
@@ -350,6 +359,9 @@ pub enum ActiveRadarrBlock {
Cast, Cast,
Crew, Crew,
DeleteMoviePrompt, DeleteMoviePrompt,
DeleteMovieConfirmPrompt,
DeleteMovieToggleDeleteFile,
DeleteMovieToggleAddListExclusion,
DeleteDownloadPrompt, DeleteDownloadPrompt,
DeleteRootFolderPrompt, DeleteRootFolderPrompt,
Downloads, Downloads,
@@ -440,6 +452,12 @@ pub const FILTER_BLOCKS: [ActiveRadarrBlock; 2] = [
ActiveRadarrBlock::FilterMovies, ActiveRadarrBlock::FilterMovies,
ActiveRadarrBlock::FilterCollections, ActiveRadarrBlock::FilterCollections,
]; ];
pub const DELETE_MOVIE_BLOCKS: [ActiveRadarrBlock; 4] = [
ActiveRadarrBlock::DeleteMoviePrompt,
ActiveRadarrBlock::DeleteMovieConfirmPrompt,
ActiveRadarrBlock::DeleteMovieToggleDeleteFile,
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion,
];
impl ActiveRadarrBlock { impl ActiveRadarrBlock {
pub fn next_add_movie_prompt_block(&self) -> Self { pub fn next_add_movie_prompt_block(&self) -> Self {
@@ -493,6 +511,19 @@ impl ActiveRadarrBlock {
} }
} }
pub fn next_delete_movie_prompt_block(&self) -> Self {
match self {
ActiveRadarrBlock::DeleteMovieToggleDeleteFile => {
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion
}
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion => {
ActiveRadarrBlock::DeleteMovieConfirmPrompt
}
ActiveRadarrBlock::DeleteMovieConfirmPrompt => ActiveRadarrBlock::DeleteMovieToggleDeleteFile,
_ => ActiveRadarrBlock::DeleteMovieToggleDeleteFile,
}
}
pub fn previous_add_movie_prompt_block(&self) -> Self { pub fn previous_add_movie_prompt_block(&self) -> Self {
match self { match self {
ActiveRadarrBlock::AddMovieSelectRootFolder => ActiveRadarrBlock::AddMovieConfirmPrompt, ActiveRadarrBlock::AddMovieSelectRootFolder => ActiveRadarrBlock::AddMovieConfirmPrompt,
@@ -548,6 +579,19 @@ impl ActiveRadarrBlock {
_ => ActiveRadarrBlock::EditCollectionToggleMonitored, _ => ActiveRadarrBlock::EditCollectionToggleMonitored,
} }
} }
pub fn previous_delete_movie_prompt_block(&self) -> Self {
match self {
ActiveRadarrBlock::DeleteMovieToggleDeleteFile => ActiveRadarrBlock::DeleteMovieConfirmPrompt,
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion => {
ActiveRadarrBlock::DeleteMovieToggleDeleteFile
}
ActiveRadarrBlock::DeleteMovieConfirmPrompt => {
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion
}
_ => ActiveRadarrBlock::DeleteMovieToggleDeleteFile,
}
}
} }
impl From<ActiveRadarrBlock> for Route { impl From<ActiveRadarrBlock> for Route {
@@ -683,6 +727,9 @@ impl App {
self self
.dispatch_network_event(RadarrEvent::GetTags.into()) .dispatch_network_event(RadarrEvent::GetTags.into())
.await; .await;
self
.dispatch_network_event(RadarrEvent::GetRootFolders.into())
.await;
self self
.dispatch_network_event(RadarrEvent::GetDownloads.into()) .dispatch_network_event(RadarrEvent::GetDownloads.into())
.await; .await;
@@ -730,6 +777,8 @@ pub mod radarr_test_utils {
let mut radarr_data = RadarrData { let mut radarr_data = RadarrData {
is_searching: true, is_searching: true,
is_filtering: true, is_filtering: true,
delete_movie_files: true,
add_list_exclusion: true,
search: "test search".to_owned().into(), search: "test search".to_owned().into(),
filter: "test filter".to_owned().into(), filter: "test filter".to_owned().into(),
edit_path: "test path".to_owned().into(), edit_path: "test path".to_owned().into(),
@@ -781,13 +830,6 @@ pub mod radarr_test_utils {
radarr_data radarr_data
} }
#[macro_export]
macro_rules! assert_movie_collection_table_reset {
($radarr_data:expr) => {
assert!($radarr_data.collection_movies.items.is_empty());
};
}
#[macro_export] #[macro_export]
macro_rules! assert_search_reset { macro_rules! assert_search_reset {
($radarr_data:expr) => { ($radarr_data:expr) => {
@@ -887,7 +929,17 @@ mod tests {
radarr_data.reset_movie_collection_table(); radarr_data.reset_movie_collection_table();
assert_movie_collection_table_reset!(radarr_data); assert!(radarr_data.collection_movies.items.is_empty());
}
#[test]
fn test_reset_delete_movie_preferences() {
let mut radarr_data = create_test_radarr_data();
radarr_data.reset_delete_movie_preferences();
assert!(!radarr_data.delete_movie_files);
assert!(!radarr_data.add_list_exclusion);
} }
#[test] #[test]
@@ -1128,6 +1180,8 @@ mod tests {
assert!(!radarr_data.is_searching); assert!(!radarr_data.is_searching);
assert!(!radarr_data.is_filtering); assert!(!radarr_data.is_filtering);
assert!(!radarr_data.prompt_confirm); assert!(!radarr_data.prompt_confirm);
assert!(!radarr_data.delete_movie_files);
assert!(!radarr_data.add_list_exclusion);
assert_eq!(radarr_data.main_tabs.tabs.len(), 4); assert_eq!(radarr_data.main_tabs.tabs.len(), 4);
@@ -1368,6 +1422,25 @@ mod tests {
); );
} }
#[test]
fn test_next_delete_movie_prompt_block() {
let active_block =
ActiveRadarrBlock::DeleteMovieToggleDeleteFile.next_delete_movie_prompt_block();
assert_eq!(
active_block,
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion
);
let active_block = active_block.next_delete_movie_prompt_block();
assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieConfirmPrompt);
let active_block = active_block.next_delete_movie_prompt_block();
assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieToggleDeleteFile);
}
#[test] #[test]
fn test_previous_add_movie_prompt_block() { fn test_previous_add_movie_prompt_block() {
let active_block = let active_block =
@@ -1478,6 +1551,25 @@ mod tests {
ActiveRadarrBlock::EditCollectionToggleMonitored ActiveRadarrBlock::EditCollectionToggleMonitored
); );
} }
#[test]
fn test_previous_delete_movie_prompt_block() {
let active_block =
ActiveRadarrBlock::DeleteMovieToggleDeleteFile.previous_delete_movie_prompt_block();
assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieConfirmPrompt);
let active_block = active_block.previous_delete_movie_prompt_block();
assert_eq!(
active_block,
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion
);
let active_block = active_block.previous_delete_movie_prompt_block();
assert_eq!(active_block, ActiveRadarrBlock::DeleteMovieToggleDeleteFile);
}
} }
mod radarr_tests { mod radarr_tests {
@@ -1857,6 +1949,14 @@ mod tests {
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetTags.into() RadarrEvent::GetTags.into()
); );
assert_eq!(
sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetRootFolders.into()
);
assert_eq!(
sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into()
);
assert!(app.is_loading); assert!(app.is_loading);
} }
@@ -1926,6 +2026,10 @@ mod tests {
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetTags.into() RadarrEvent::GetTags.into()
); );
assert_eq!(
sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetRootFolders.into()
);
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads.into()
@@ -1974,6 +2078,10 @@ mod tests {
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetTags.into() RadarrEvent::GetTags.into()
); );
assert_eq!(
sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetRootFolders.into()
);
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads.into()
@@ -57,7 +57,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for AddMovieHandler<'a> {
.data .data
.radarr_data .radarr_data
.selected_block .selected_block
.clone()
.previous_add_movie_prompt_block() .previous_add_movie_prompt_block()
} }
_ => (), _ => (),
@@ -228,10 +227,9 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for AddMovieHandler<'a> {
ActiveRadarrBlock::AddMovieConfirmPrompt => { ActiveRadarrBlock::AddMovieConfirmPrompt => {
if self.app.data.radarr_data.prompt_confirm { if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::AddMovie); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::AddMovie);
self.app.pop_navigation_stack();
} else {
self.app.pop_navigation_stack();
} }
self.app.pop_navigation_stack();
} }
ActiveRadarrBlock::AddMovieSelectMonitor ActiveRadarrBlock::AddMovieSelectMonitor
| ActiveRadarrBlock::AddMovieSelectMinimumAvailability | ActiveRadarrBlock::AddMovieSelectMinimumAvailability
@@ -515,7 +513,6 @@ mod tests {
use pretty_assertions::{assert_eq, assert_str_eq}; use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest; use rstest::rstest;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::models::radarr_models::Movie; use crate::models::radarr_models::Movie;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
@@ -0,0 +1,283 @@
use crate::app::radarr::ActiveRadarrBlock;
use crate::app::App;
use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::network::radarr_network::RadarrEvent;
pub(super) struct DeleteMovieHandler<'a> {
key: &'a Key,
app: &'a mut App,
active_radarr_block: &'a ActiveRadarrBlock,
_context: &'a Option<ActiveRadarrBlock>,
}
impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for DeleteMovieHandler<'a> {
fn with(
key: &'a Key,
app: &'a mut App,
active_block: &'a ActiveRadarrBlock,
_context: &'a Option<ActiveRadarrBlock>,
) -> Self {
DeleteMovieHandler {
key,
app,
active_radarr_block: active_block,
_context,
}
}
fn get_key(&self) -> &Key {
self.key
}
fn handle_scroll_up(&mut self) {
if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt {
self.app.data.radarr_data.selected_block = self
.app
.data
.radarr_data
.selected_block
.previous_delete_movie_prompt_block();
}
}
fn handle_scroll_down(&mut self) {
if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt {
self.app.data.radarr_data.selected_block = self
.app
.data
.radarr_data
.selected_block
.next_delete_movie_prompt_block();
}
}
fn handle_home(&mut self) {}
fn handle_end(&mut self) {}
fn handle_delete(&mut self) {}
fn handle_left_right_action(&mut self) {
if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt {
handle_prompt_toggle(self.app, self.key);
}
}
fn handle_submit(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::DeleteMoviePrompt {
match self.app.data.radarr_data.selected_block {
ActiveRadarrBlock::DeleteMovieConfirmPrompt => {
if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteMovie);
self.app.should_refresh = true;
} else {
self.app.data.radarr_data.reset_delete_movie_preferences();
}
self.app.pop_navigation_stack();
}
ActiveRadarrBlock::DeleteMovieToggleDeleteFile => {
self.app.data.radarr_data.delete_movie_files =
!self.app.data.radarr_data.delete_movie_files;
}
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion => {
self.app.data.radarr_data.add_list_exclusion =
!self.app.data.radarr_data.add_list_exclusion;
}
_ => (),
}
}
}
fn handle_esc(&mut self) {
if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt {
self.app.pop_navigation_stack();
self.app.data.radarr_data.reset_delete_movie_preferences();
self.app.data.radarr_data.prompt_confirm = false;
}
}
fn handle_char_key_event(&mut self) {}
}
#[cfg(test)]
mod tests {
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::radarr::ActiveRadarrBlock;
use crate::app::App;
use crate::event::Key;
use crate::handlers::radarr_handlers::delete_movie_handler::DeleteMovieHandler;
use crate::handlers::KeyEventHandler;
mod test_handle_scroll_up_and_down {
use pretty_assertions::assert_eq;
use rstest::rstest;
use super::*;
#[rstest]
fn test_delete_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default();
app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieToggleAddListExclusion;
DeleteMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::DeleteMoviePrompt, &None)
.handle();
if key == Key::Up {
assert_eq!(
app.data.radarr_data.selected_block,
ActiveRadarrBlock::DeleteMovieToggleDeleteFile
);
} else {
assert_eq!(
app.data.radarr_data.selected_block,
ActiveRadarrBlock::DeleteMovieConfirmPrompt
);
}
}
}
mod test_handle_left_right_action {
use rstest::rstest;
use super::*;
#[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default();
DeleteMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::DeleteMoviePrompt, &None)
.handle();
assert!(app.data.radarr_data.prompt_confirm);
DeleteMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::DeleteMoviePrompt, &None)
.handle();
assert!(!app.data.radarr_data.prompt_confirm);
}
}
mod test_handle_submit {
use pretty_assertions::assert_eq;
use crate::network::radarr_network::RadarrEvent;
use super::*;
const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key;
#[test]
fn test_delete_movie_prompt_prompt_decline_submit() {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieConfirmPrompt;
app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true;
DeleteMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
assert!(!app.data.radarr_data.prompt_confirm);
assert!(!app.data.radarr_data.delete_movie_files);
assert!(!app.data.radarr_data.add_list_exclusion);
}
#[test]
fn test_delete_movie_confirm_prompt_prompt_confirmation_submit() {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
app.data.radarr_data.prompt_confirm = true;
app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true;
app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieConfirmPrompt;
DeleteMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert_eq!(
app.data.radarr_data.prompt_confirm_action,
Some(RadarrEvent::DeleteMovie)
);
assert!(app.should_refresh);
assert!(app.data.radarr_data.prompt_confirm);
assert!(app.data.radarr_data.delete_movie_files);
assert!(app.data.radarr_data.add_list_exclusion);
}
#[test]
fn test_delete_movie_toggle_delete_files_submit() {
let current_route = ActiveRadarrBlock::DeleteMoviePrompt.into();
let mut app = App::default();
app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieToggleDeleteFile;
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
DeleteMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &current_route);
assert_eq!(app.data.radarr_data.delete_movie_files, true);
DeleteMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &current_route);
assert_eq!(app.data.radarr_data.delete_movie_files, false);
}
}
mod test_handle_esc {
use super::*;
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_delete_movie_prompt_esc() {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
app.data.radarr_data.prompt_confirm = true;
app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true;
DeleteMovieHandler::with(
&ESC_KEY,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.prompt_confirm);
assert!(!app.data.radarr_data.delete_movie_files);
assert!(!app.data.radarr_data.add_list_exclusion);
}
}
}
@@ -50,7 +50,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditCollectionHandler<'a> {
.data .data
.radarr_data .radarr_data
.selected_block .selected_block
.clone()
.previous_edit_collection_prompt_block() .previous_edit_collection_prompt_block()
} }
_ => (), _ => (),
@@ -140,11 +139,10 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditCollectionHandler<'a> {
ActiveRadarrBlock::EditCollectionConfirmPrompt => { ActiveRadarrBlock::EditCollectionConfirmPrompt => {
if self.app.data.radarr_data.prompt_confirm { if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditCollection); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditCollection);
self.app.pop_navigation_stack();
self.app.should_refresh = true; self.app.should_refresh = true;
} else {
self.app.pop_navigation_stack();
} }
self.app.pop_navigation_stack();
} }
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability ActiveRadarrBlock::EditCollectionSelectMinimumAvailability
| ActiveRadarrBlock::EditCollectionSelectQualityProfile => self | ActiveRadarrBlock::EditCollectionSelectQualityProfile => self
@@ -193,9 +191,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditCollectionHandler<'a> {
self.app.data.radarr_data.reset_add_edit_media_fields(); self.app.data.radarr_data.reset_add_edit_media_fields();
self.app.data.radarr_data.prompt_confirm = false; self.app.data.radarr_data.prompt_confirm = false;
} }
ActiveRadarrBlock::EditCollectionToggleMonitored ActiveRadarrBlock::EditCollectionSelectMinimumAvailability
| ActiveRadarrBlock::EditCollectionToggleSearchOnAdd
| ActiveRadarrBlock::EditCollectionSelectMinimumAvailability
| ActiveRadarrBlock::EditCollectionSelectQualityProfile => self.app.pop_navigation_stack(), | ActiveRadarrBlock::EditCollectionSelectQualityProfile => self.app.pop_navigation_stack(),
_ => (), _ => (),
} }
@@ -355,7 +351,6 @@ mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest; use rstest::rstest;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::models::Route; use crate::models::Route;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
@@ -635,8 +630,6 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_collection_esc( fn test_edit_collection_esc(
#[values( #[values(
ActiveRadarrBlock::EditCollectionToggleMonitored,
ActiveRadarrBlock::EditCollectionToggleSearchOnAdd,
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability,
ActiveRadarrBlock::EditCollectionSelectQualityProfile ActiveRadarrBlock::EditCollectionSelectQualityProfile
)] )]
@@ -50,7 +50,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditMovieHandler<'a> {
.data .data
.radarr_data .radarr_data
.selected_block .selected_block
.clone()
.previous_edit_movie_prompt_block() .previous_edit_movie_prompt_block()
} }
_ => (), _ => (),
@@ -141,11 +140,10 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditMovieHandler<'a> {
ActiveRadarrBlock::EditMovieConfirmPrompt => { ActiveRadarrBlock::EditMovieConfirmPrompt => {
if self.app.data.radarr_data.prompt_confirm { if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditMovie); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditMovie);
self.app.pop_navigation_stack();
self.app.should_refresh = true; self.app.should_refresh = true;
} else {
self.app.pop_navigation_stack();
} }
self.app.pop_navigation_stack();
} }
ActiveRadarrBlock::EditMovieSelectMinimumAvailability ActiveRadarrBlock::EditMovieSelectMinimumAvailability
| ActiveRadarrBlock::EditMovieSelectQualityProfile => self | ActiveRadarrBlock::EditMovieSelectQualityProfile => self
@@ -184,8 +182,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for EditMovieHandler<'a> {
self.app.data.radarr_data.reset_add_edit_media_fields(); self.app.data.radarr_data.reset_add_edit_media_fields();
self.app.data.radarr_data.prompt_confirm = false; self.app.data.radarr_data.prompt_confirm = false;
} }
ActiveRadarrBlock::EditMovieToggleMonitored ActiveRadarrBlock::EditMovieSelectMinimumAvailability
| ActiveRadarrBlock::EditMovieSelectMinimumAvailability
| ActiveRadarrBlock::EditMovieSelectQualityProfile => self.app.pop_navigation_stack(), | ActiveRadarrBlock::EditMovieSelectQualityProfile => self.app.pop_navigation_stack(),
_ => (), _ => (),
} }
@@ -350,7 +347,6 @@ mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest; use rstest::rstest;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::models::Route; use crate::models::Route;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
@@ -617,7 +613,6 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_movie_esc( fn test_edit_movie_esc(
#[values( #[values(
ActiveRadarrBlock::EditMovieToggleMonitored,
ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
ActiveRadarrBlock::EditMovieSelectQualityProfile ActiveRadarrBlock::EditMovieSelectQualityProfile
)] )]
+30 -30
View File
@@ -1,10 +1,11 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::radarr::{ use crate::app::radarr::{
ActiveRadarrBlock, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_BLOCKS, ActiveRadarrBlock, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, DELETE_MOVIE_BLOCKS,
EDIT_MOVIE_BLOCKS, FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS, EDIT_COLLECTION_BLOCKS, EDIT_MOVIE_BLOCKS, FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS,
}; };
use crate::handlers::radarr_handlers::add_movie_handler::AddMovieHandler; use crate::handlers::radarr_handlers::add_movie_handler::AddMovieHandler;
use crate::handlers::radarr_handlers::collection_details_handler::CollectionDetailsHandler; use crate::handlers::radarr_handlers::collection_details_handler::CollectionDetailsHandler;
use crate::handlers::radarr_handlers::delete_movie_handler::DeleteMovieHandler;
use crate::handlers::radarr_handlers::edit_collection_handler::EditCollectionHandler; use crate::handlers::radarr_handlers::edit_collection_handler::EditCollectionHandler;
use crate::handlers::radarr_handlers::edit_movie_handler::EditMovieHandler; use crate::handlers::radarr_handlers::edit_movie_handler::EditMovieHandler;
use crate::handlers::radarr_handlers::movie_details_handler::MovieDetailsHandler; use crate::handlers::radarr_handlers::movie_details_handler::MovieDetailsHandler;
@@ -16,6 +17,7 @@ use crate::{handle_text_box_keys, handle_text_box_left_right_keys, App, Key};
mod add_movie_handler; mod add_movie_handler;
mod collection_details_handler; mod collection_details_handler;
mod delete_movie_handler;
mod edit_collection_handler; mod edit_collection_handler;
mod edit_movie_handler; mod edit_movie_handler;
mod movie_details_handler; mod movie_details_handler;
@@ -44,6 +46,10 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
_ if EDIT_MOVIE_BLOCKS.contains(self.active_radarr_block) => { _ if EDIT_MOVIE_BLOCKS.contains(self.active_radarr_block) => {
EditMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle() EditMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle()
} }
_ if DELETE_MOVIE_BLOCKS.contains(self.active_radarr_block) => {
DeleteMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context)
.handle()
}
_ if EDIT_COLLECTION_BLOCKS.contains(self.active_radarr_block) => { _ if EDIT_COLLECTION_BLOCKS.contains(self.active_radarr_block) => {
EditCollectionHandler::with(self.key, self.app, self.active_radarr_block, self.context) EditCollectionHandler::with(self.key, self.app, self.active_radarr_block, self.context)
.handle() .handle()
@@ -212,9 +218,12 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
fn handle_delete(&mut self) { fn handle_delete(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Movies => self ActiveRadarrBlock::Movies => {
.app self
.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()), .app
.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
self.app.data.radarr_data.selected_block = ActiveRadarrBlock::DeleteMovieToggleDeleteFile;
}
ActiveRadarrBlock::Downloads => self ActiveRadarrBlock::Downloads => self
.app .app
.push_navigation_stack(ActiveRadarrBlock::DeleteDownloadPrompt.into()), .push_navigation_stack(ActiveRadarrBlock::DeleteDownloadPrompt.into()),
@@ -245,8 +254,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} }
_ => (), _ => (),
}, },
ActiveRadarrBlock::DeleteMoviePrompt ActiveRadarrBlock::DeleteDownloadPrompt
| ActiveRadarrBlock::DeleteDownloadPrompt
| ActiveRadarrBlock::DeleteRootFolderPrompt | ActiveRadarrBlock::DeleteRootFolderPrompt
| ActiveRadarrBlock::UpdateAllMoviesPrompt | ActiveRadarrBlock::UpdateAllMoviesPrompt
| ActiveRadarrBlock::UpdateAllCollectionsPrompt | ActiveRadarrBlock::UpdateAllCollectionsPrompt
@@ -359,13 +367,6 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
.set_items(filtered_collections); .set_items(filtered_collections);
} }
} }
ActiveRadarrBlock::DeleteMoviePrompt => {
if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteMovie);
}
self.app.pop_navigation_stack();
}
ActiveRadarrBlock::DeleteDownloadPrompt => { ActiveRadarrBlock::DeleteDownloadPrompt => {
if self.app.data.radarr_data.prompt_confirm { if self.app.data.radarr_data.prompt_confirm {
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteDownload); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteDownload);
@@ -429,8 +430,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
self.app.data.radarr_data.prompt_confirm = false; self.app.data.radarr_data.prompt_confirm = false;
self.app.should_ignore_quit_key = false; self.app.should_ignore_quit_key = false;
} }
ActiveRadarrBlock::DeleteMoviePrompt ActiveRadarrBlock::DeleteDownloadPrompt
| ActiveRadarrBlock::DeleteDownloadPrompt
| ActiveRadarrBlock::DeleteRootFolderPrompt | ActiveRadarrBlock::DeleteRootFolderPrompt
| ActiveRadarrBlock::UpdateAllMoviesPrompt | ActiveRadarrBlock::UpdateAllMoviesPrompt
| ActiveRadarrBlock::UpdateAllCollectionsPrompt | ActiveRadarrBlock::UpdateAllCollectionsPrompt
@@ -950,6 +950,10 @@ mod tests {
app.get_current_route(), app.get_current_route(),
&ActiveRadarrBlock::DeleteMoviePrompt.into() &ActiveRadarrBlock::DeleteMoviePrompt.into()
); );
assert_eq!(
app.data.radarr_data.selected_block,
ActiveRadarrBlock::DeleteMovieToggleDeleteFile
);
} }
#[test] #[test]
@@ -1050,7 +1054,6 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle( fn test_left_right_prompt_toggle(
#[values( #[values(
ActiveRadarrBlock::DeleteMoviePrompt,
ActiveRadarrBlock::DeleteDownloadPrompt, ActiveRadarrBlock::DeleteDownloadPrompt,
ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt,
ActiveRadarrBlock::UpdateAllMoviesPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt,
@@ -1344,11 +1347,6 @@ mod tests {
} }
#[rstest] #[rstest]
#[case(
ActiveRadarrBlock::Movies,
ActiveRadarrBlock::DeleteMoviePrompt,
RadarrEvent::DeleteMovie
)]
#[case( #[case(
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
ActiveRadarrBlock::DeleteDownloadPrompt, ActiveRadarrBlock::DeleteDownloadPrompt,
@@ -1395,7 +1393,6 @@ mod tests {
} }
#[rstest] #[rstest]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::DeleteMoviePrompt)]
#[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::DeleteDownloadPrompt)] #[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::DeleteDownloadPrompt)]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)] #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)]
#[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::UpdateDownloadsPrompt)] #[case(ActiveRadarrBlock::Downloads, ActiveRadarrBlock::UpdateDownloadsPrompt)]
@@ -1471,7 +1468,6 @@ mod tests {
} }
#[rstest] #[rstest]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::DeleteMoviePrompt)]
#[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)] #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::UpdateAllMoviesPrompt)]
#[case( #[case(
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -1551,7 +1547,6 @@ mod tests {
use serde_json::Number; use serde_json::Number;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::radarr::radarr_test_utils::create_test_radarr_data; use crate::app::radarr::radarr_test_utils::create_test_radarr_data;
use crate::app::radarr::RadarrData; use crate::app::radarr::RadarrData;
use crate::models::radarr_models::MinimumAvailability; use crate::models::radarr_models::MinimumAvailability;
@@ -1996,23 +1991,28 @@ mod tests {
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
ActiveRadarrBlock::EditMovieSelectQualityProfile, ActiveRadarrBlock::EditMovieSelectQualityProfile,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput
ActiveRadarrBlock::EditMovieToggleMonitored
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
test_handler_delegation!(ActiveRadarrBlock::Movies, active_radarr_block); test_handler_delegation!(ActiveRadarrBlock::Movies, active_radarr_block);
} }
#[test]
fn test_delegate_delete_movie_blocks_to_delete_movie_handler() {
test_handler_delegation!(
ActiveRadarrBlock::Movies,
ActiveRadarrBlock::DeleteMoviePrompt
);
}
#[rstest] #[rstest]
fn test_delegate_edit_collection_blocks_to_edit_collection_handler( fn test_delegate_edit_collection_blocks_to_edit_collection_handler(
#[values( #[values(
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability,
ActiveRadarrBlock::EditCollectionSelectQualityProfile, ActiveRadarrBlock::EditCollectionSelectQualityProfile
ActiveRadarrBlock::EditCollectionToggleSearchOnAdd,
ActiveRadarrBlock::EditCollectionToggleMonitored
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
+35 -10
View File
@@ -686,12 +686,24 @@ impl<'a> Network<'a> {
async fn delete_movie(&self) { async fn delete_movie(&self) {
let movie_id = self.extract_movie_id().await; let movie_id = self.extract_movie_id().await;
let delete_files = self.app.lock().await.data.radarr_data.delete_movie_files;
let add_import_exclusion = self.app.lock().await.data.radarr_data.add_list_exclusion;
info!("Deleting Radarr movie with id: {}", movie_id); info!(
"Deleting Radarr movie with id: {} with deleteFiles={} and addImportExclusion={}",
movie_id, delete_files, add_import_exclusion
);
let request_props = self let request_props = self
.radarr_request_props_from( .radarr_request_props_from(
format!("{}/{}", RadarrEvent::DeleteMovie.resource(), movie_id).as_str(), format!(
"{}/{}?deleteFiles={}&addImportExclusion={}",
RadarrEvent::DeleteMovie.resource(),
movie_id,
delete_files,
add_import_exclusion
)
.as_str(),
RequestMethod::Delete, RequestMethod::Delete,
None::<()>, None::<()>,
) )
@@ -700,6 +712,14 @@ impl<'a> Network<'a> {
self self
.handle_request::<(), ()>(request_props, |_, _| ()) .handle_request::<(), ()>(request_props, |_, _| ())
.await; .await;
self
.app
.lock()
.await
.data
.radarr_data
.reset_delete_movie_preferences();
} }
async fn delete_download(&self) { async fn delete_download(&self) {
@@ -2200,21 +2220,26 @@ mod test {
RequestMethod::Delete, RequestMethod::Delete,
None, None,
None, None,
format!("{}/1", RadarrEvent::DeleteMovie.resource()).as_str(), format!(
"{}/1?deleteFiles=true&addImportExclusion=true",
RadarrEvent::DeleteMovie.resource()
)
.as_str(),
) )
.await; .await;
app_arc {
.lock() let mut app = app_arc.lock().await;
.await app.data.radarr_data.movies.set_items(vec![movie()]);
.data app.data.radarr_data.delete_movie_files = true;
.radarr_data app.data.radarr_data.add_list_exclusion = true;
.movies }
.set_items(vec![movie()]);
let network = Network::new(reqwest::Client::new(), &app_arc); let network = Network::new(reqwest::Client::new(), &app_arc);
network.handle_radarr_event(RadarrEvent::DeleteMovie).await; network.handle_radarr_event(RadarrEvent::DeleteMovie).await;
async_server.assert_async().await; async_server.assert_async().await;
assert!(!app_arc.lock().await.data.radarr_data.delete_movie_files);
assert!(!app_arc.lock().await.data.radarr_data.add_list_exclusion);
} }
#[tokio::test] #[tokio::test]
+57 -5
View File
@@ -1,3 +1,5 @@
use std::iter;
use tui::backend::Backend; use tui::backend::Backend;
use tui::layout::{Alignment, Constraint, Rect}; use tui::layout::{Alignment, Constraint, Rect};
use tui::style::Modifier; use tui::style::Modifier;
@@ -141,7 +143,7 @@ pub fn draw_prompt_popup_over<B: Backend>(
background_fn: fn(&mut Frame<'_, B>, &mut App, Rect), background_fn: fn(&mut Frame<'_, B>, &mut App, Rect),
popup_fn: fn(&mut Frame<'_, B>, &mut App, Rect), popup_fn: fn(&mut Frame<'_, B>, &mut App, Rect),
) { ) {
draw_popup_over(f, app, area, background_fn, popup_fn, 30, 30); draw_popup_over(f, app, area, background_fn, popup_fn, 35, 35);
} }
pub fn draw_small_popup_over<B: Backend>( pub fn draw_small_popup_over<B: Backend>(
@@ -334,7 +336,7 @@ pub fn draw_prompt_box<B: Backend>(
prompt_area: Rect, prompt_area: Rect,
title: &str, title: &str,
prompt: &str, prompt: &str,
yes_no_value: &bool, yes_no_value: bool,
) { ) {
draw_prompt_box_with_content(f, prompt_area, title, prompt, None, yes_no_value); draw_prompt_box_with_content(f, prompt_area, title, prompt, None, yes_no_value);
} }
@@ -345,7 +347,7 @@ pub fn draw_prompt_box_with_content<B: Backend>(
title: &str, title: &str,
prompt: &str, prompt: &str,
content: Option<Paragraph<'_>>, content: Option<Paragraph<'_>>,
yes_no_value: &bool, yes_no_value: bool,
) { ) {
f.render_widget(title_block_centered(title), prompt_area); f.render_widget(title_block_centered(title), prompt_area);
@@ -384,8 +386,58 @@ pub fn draw_prompt_box_with_content<B: Backend>(
chunks[2], chunks[2],
); );
draw_button(f, horizontal_chunks[0], "Yes", *yes_no_value); draw_button(f, horizontal_chunks[0], "Yes", yes_no_value);
draw_button(f, horizontal_chunks[1], "No", !*yes_no_value); draw_button(f, horizontal_chunks[1], "No", !yes_no_value);
}
pub fn draw_prompt_box_with_checkboxes<B: Backend>(
f: &mut Frame<'_, B>,
prompt_area: Rect,
title: &str,
prompt: &str,
checkboxes: Vec<(&str, bool, bool)>,
highlight_yes_no: bool,
yes_no_value: bool,
) {
f.render_widget(title_block_centered(title), prompt_area);
let mut constraints = vec![
Constraint::Length(4),
Constraint::Min(0),
Constraint::Length(3),
];
constraints.splice(
1..1,
iter::repeat(Constraint::Length(3)).take(checkboxes.len()),
);
let chunks = vertical_chunks_with_margin(constraints, prompt_area, 1);
let prompt_paragraph = layout_paragraph_borderless(prompt);
f.render_widget(prompt_paragraph, chunks[0]);
for i in 0..checkboxes.len() {
let (label, is_checked, is_selected) = checkboxes[i];
draw_checkbox_with_label(f, chunks[i + 1], label, is_checked, is_selected);
}
let horizontal_chunks = horizontal_chunks(
vec![Constraint::Percentage(50), Constraint::Percentage(50)],
chunks[checkboxes.len() + 2],
);
draw_button(
f,
horizontal_chunks[0],
"Yes",
highlight_yes_no && yes_no_value,
);
draw_button(
f,
horizontal_chunks[1],
"No",
highlight_yes_no && !yes_no_value,
);
} }
pub fn draw_checkbox<B: Backend>( pub fn draw_checkbox<B: Backend>(
+10 -10
View File
@@ -327,9 +327,9 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
}; };
let title = format!("Add Movie - {}", movie_title); let title = format!("Add Movie - {}", movie_title);
let prompt = movie_overview; let prompt = movie_overview;
let yes_no_value = &app.data.radarr_data.prompt_confirm; let yes_no_value = app.data.radarr_data.prompt_confirm;
let selected_block = &app.data.radarr_data.selected_block; let selected_block = app.data.radarr_data.selected_block;
let highlight_yes_no = *selected_block == ActiveRadarrBlock::AddMovieConfirmPrompt; let highlight_yes_no = selected_block == ActiveRadarrBlock::AddMovieConfirmPrompt;
let selected_monitor = app.data.radarr_data.monitor_list.current_selection(); let selected_monitor = app.data.radarr_data.monitor_list.current_selection();
let selected_minimum_availability = app let selected_minimum_availability = app
@@ -374,7 +374,7 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
chunks[1], chunks[1],
"Root Folder", "Root Folder",
&selected_root_folder.path, &selected_root_folder.path,
*selected_block == ActiveRadarrBlock::AddMovieSelectRootFolder, selected_block == ActiveRadarrBlock::AddMovieSelectRootFolder,
); );
draw_drop_down_menu_button( draw_drop_down_menu_button(
@@ -382,7 +382,7 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
chunks[2], chunks[2],
"Monitor", "Monitor",
selected_monitor.to_display_str(), selected_monitor.to_display_str(),
*selected_block == ActiveRadarrBlock::AddMovieSelectMonitor, selected_block == ActiveRadarrBlock::AddMovieSelectMonitor,
); );
draw_drop_down_menu_button( draw_drop_down_menu_button(
@@ -390,14 +390,14 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
chunks[3], chunks[3],
"Minimum Availability", "Minimum Availability",
selected_minimum_availability.to_display_str(), selected_minimum_availability.to_display_str(),
*selected_block == ActiveRadarrBlock::AddMovieSelectMinimumAvailability, selected_block == ActiveRadarrBlock::AddMovieSelectMinimumAvailability,
); );
draw_drop_down_menu_button( draw_drop_down_menu_button(
f, f,
chunks[4], chunks[4],
"Quality Profile", "Quality Profile",
selected_quality_profile, selected_quality_profile,
*selected_block == ActiveRadarrBlock::AddMovieSelectQualityProfile, selected_block == ActiveRadarrBlock::AddMovieSelectQualityProfile,
); );
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
@@ -407,7 +407,7 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
"Tags", "Tags",
&app.data.radarr_data.edit_tags.text, &app.data.radarr_data.edit_tags.text,
*app.data.radarr_data.edit_tags.offset.borrow(), *app.data.radarr_data.edit_tags.offset.borrow(),
*selected_block == ActiveRadarrBlock::AddMovieTagsInput, selected_block == ActiveRadarrBlock::AddMovieTagsInput,
active_radarr_block == ActiveRadarrBlock::AddMovieTagsInput, active_radarr_block == ActiveRadarrBlock::AddMovieTagsInput,
); );
} }
@@ -416,12 +416,12 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
f, f,
horizontal_chunks[0], horizontal_chunks[0],
"Add", "Add",
*yes_no_value && highlight_yes_no, yes_no_value && highlight_yes_no,
); );
draw_button( draw_button(
f, f,
horizontal_chunks[1], horizontal_chunks[1],
"Cancel", "Cancel",
!*yes_no_value && highlight_yes_no, !yes_no_value && highlight_yes_no,
); );
} }
+45
View File
@@ -0,0 +1,45 @@
use tui::backend::Backend;
use tui::layout::Rect;
use tui::Frame;
use crate::app::radarr::ActiveRadarrBlock;
use crate::app::App;
use crate::models::Route;
use crate::ui::draw_prompt_box_with_checkboxes;
pub(super) fn draw_delete_movie_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App,
prompt_area: Rect,
) {
if matches!(
*app.get_current_route(),
Route::Radarr(ActiveRadarrBlock::DeleteMoviePrompt, _)
) {
let selected_block = app.data.radarr_data.selected_block;
draw_prompt_box_with_checkboxes(
f,
prompt_area,
"Delete Movie",
format!(
"Do you really want to delete: {}?",
app.data.radarr_data.movies.current_selection().title
)
.as_str(),
vec![
(
"Delete Movie Files",
app.data.radarr_data.delete_movie_files,
selected_block == ActiveRadarrBlock::DeleteMovieToggleDeleteFile,
),
(
"Add List Exclusion",
app.data.radarr_data.add_list_exclusion,
selected_block == ActiveRadarrBlock::DeleteMovieToggleAddListExclusion,
),
],
selected_block == ActiveRadarrBlock::DeleteMovieConfirmPrompt,
app.data.radarr_data.prompt_confirm,
)
}
}
+10 -10
View File
@@ -96,9 +96,9 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
) )
}; };
let title = format!("Edit - {}", collection_title); let title = format!("Edit - {}", collection_title);
let yes_no_value = &app.data.radarr_data.prompt_confirm; let yes_no_value = app.data.radarr_data.prompt_confirm;
let selected_block = &app.data.radarr_data.selected_block; let selected_block = app.data.radarr_data.selected_block;
let highlight_yes_no = *selected_block == ActiveRadarrBlock::EditCollectionConfirmPrompt; let highlight_yes_no = selected_block == ActiveRadarrBlock::EditCollectionConfirmPrompt;
let selected_minimum_availability = app let selected_minimum_availability = app
.data .data
@@ -141,7 +141,7 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
chunks[1], chunks[1],
"Monitored", "Monitored",
app.data.radarr_data.edit_monitored.unwrap_or_default(), app.data.radarr_data.edit_monitored.unwrap_or_default(),
*selected_block == ActiveRadarrBlock::EditCollectionToggleMonitored, selected_block == ActiveRadarrBlock::EditCollectionToggleMonitored,
); );
draw_drop_down_menu_button( draw_drop_down_menu_button(
@@ -149,14 +149,14 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
chunks[2], chunks[2],
"Minimum Availability", "Minimum Availability",
selected_minimum_availability.to_display_str(), selected_minimum_availability.to_display_str(),
*selected_block == ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, selected_block == ActiveRadarrBlock::EditCollectionSelectMinimumAvailability,
); );
draw_drop_down_menu_button( draw_drop_down_menu_button(
f, f,
chunks[3], chunks[3],
"Quality Profile", "Quality Profile",
selected_quality_profile, selected_quality_profile,
*selected_block == ActiveRadarrBlock::EditCollectionSelectQualityProfile, selected_block == ActiveRadarrBlock::EditCollectionSelectQualityProfile,
); );
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
@@ -166,7 +166,7 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
"Root Folder", "Root Folder",
&app.data.radarr_data.edit_path.text, &app.data.radarr_data.edit_path.text,
*app.data.radarr_data.edit_path.offset.borrow(), *app.data.radarr_data.edit_path.offset.borrow(),
*selected_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput, selected_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput,
active_radarr_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput, active_radarr_block == ActiveRadarrBlock::EditCollectionRootFolderPathInput,
); );
} }
@@ -176,19 +176,19 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
chunks[5], chunks[5],
"Search on Add", "Search on Add",
app.data.radarr_data.edit_search_on_add.unwrap_or_default(), app.data.radarr_data.edit_search_on_add.unwrap_or_default(),
*selected_block == ActiveRadarrBlock::EditCollectionToggleSearchOnAdd, selected_block == ActiveRadarrBlock::EditCollectionToggleSearchOnAdd,
); );
draw_button( draw_button(
f, f,
horizontal_chunks[0], horizontal_chunks[0],
"Save", "Save",
*yes_no_value && highlight_yes_no, yes_no_value && highlight_yes_no,
); );
draw_button( draw_button(
f, f,
horizontal_chunks[1], horizontal_chunks[1],
"Cancel", "Cancel",
!*yes_no_value && highlight_yes_no, !yes_no_value && highlight_yes_no,
); );
} }
+10 -10
View File
@@ -93,9 +93,9 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
) )
}; };
let title = format!("Edit - {}", movie_title); let title = format!("Edit - {}", movie_title);
let yes_no_value = &app.data.radarr_data.prompt_confirm; let yes_no_value = app.data.radarr_data.prompt_confirm;
let selected_block = &app.data.radarr_data.selected_block; let selected_block = app.data.radarr_data.selected_block;
let highlight_yes_no = *selected_block == ActiveRadarrBlock::EditMovieConfirmPrompt; let highlight_yes_no = selected_block == ActiveRadarrBlock::EditMovieConfirmPrompt;
let selected_minimum_availability = app let selected_minimum_availability = app
.data .data
@@ -138,7 +138,7 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
chunks[1], chunks[1],
"Monitored", "Monitored",
app.data.radarr_data.edit_monitored.unwrap_or_default(), app.data.radarr_data.edit_monitored.unwrap_or_default(),
*selected_block == ActiveRadarrBlock::EditMovieToggleMonitored, selected_block == ActiveRadarrBlock::EditMovieToggleMonitored,
); );
draw_drop_down_menu_button( draw_drop_down_menu_button(
@@ -146,14 +146,14 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
chunks[2], chunks[2],
"Minimum Availability", "Minimum Availability",
selected_minimum_availability.to_display_str(), selected_minimum_availability.to_display_str(),
*selected_block == ActiveRadarrBlock::EditMovieSelectMinimumAvailability, selected_block == ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
); );
draw_drop_down_menu_button( draw_drop_down_menu_button(
f, f,
chunks[3], chunks[3],
"Quality Profile", "Quality Profile",
selected_quality_profile, selected_quality_profile,
*selected_block == ActiveRadarrBlock::EditMovieSelectQualityProfile, selected_block == ActiveRadarrBlock::EditMovieSelectQualityProfile,
); );
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() { if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
@@ -163,7 +163,7 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
"Path", "Path",
&app.data.radarr_data.edit_path.text, &app.data.radarr_data.edit_path.text,
*app.data.radarr_data.edit_path.offset.borrow(), *app.data.radarr_data.edit_path.offset.borrow(),
*selected_block == ActiveRadarrBlock::EditMoviePathInput, selected_block == ActiveRadarrBlock::EditMoviePathInput,
active_radarr_block == ActiveRadarrBlock::EditMoviePathInput, active_radarr_block == ActiveRadarrBlock::EditMoviePathInput,
); );
draw_text_box_with_label( draw_text_box_with_label(
@@ -172,7 +172,7 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
"Tags", "Tags",
&app.data.radarr_data.edit_tags.text, &app.data.radarr_data.edit_tags.text,
*app.data.radarr_data.edit_tags.offset.borrow(), *app.data.radarr_data.edit_tags.offset.borrow(),
*selected_block == ActiveRadarrBlock::EditMovieTagsInput, selected_block == ActiveRadarrBlock::EditMovieTagsInput,
active_radarr_block == ActiveRadarrBlock::EditMovieTagsInput, active_radarr_block == ActiveRadarrBlock::EditMovieTagsInput,
); );
} }
@@ -181,12 +181,12 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
f, f,
horizontal_chunks[0], horizontal_chunks[0],
"Save", "Save",
*yes_no_value && highlight_yes_no, yes_no_value && highlight_yes_no,
); );
draw_button( draw_button(
f, f,
horizontal_chunks[1], horizontal_chunks[1],
"Cancel", "Cancel",
!*yes_no_value && highlight_yes_no, !yes_no_value && highlight_yes_no,
); );
} }
+9 -21
View File
@@ -10,7 +10,7 @@ use tui::widgets::{Cell, ListItem, Paragraph, Row};
use tui::Frame; use tui::Frame;
use crate::app::radarr::{ use crate::app::radarr::{
ActiveRadarrBlock, RadarrData, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, ActiveRadarrBlock, RadarrData, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, DELETE_MOVIE_BLOCKS,
EDIT_COLLECTION_BLOCKS, EDIT_MOVIE_BLOCKS, FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS, EDIT_COLLECTION_BLOCKS, EDIT_MOVIE_BLOCKS, FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS,
}; };
use crate::app::App; use crate::app::App;
@@ -19,6 +19,7 @@ use crate::models::radarr_models::{Collection, DiskSpace, DownloadRecord, Movie,
use crate::models::{HorizontallyScrollableText, Route}; use crate::models::{HorizontallyScrollableText, Route};
use crate::ui::radarr_ui::add_movie_ui::draw_add_movie_search_popup; 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; use crate::ui::radarr_ui::collection_details_ui::draw_collection_details_popup;
use crate::ui::radarr_ui::delete_movie_ui::draw_delete_movie_prompt;
use crate::ui::radarr_ui::edit_collection_ui::draw_edit_collection_prompt; use crate::ui::radarr_ui::edit_collection_ui::draw_edit_collection_prompt;
use crate::ui::radarr_ui::edit_movie_ui::draw_edit_movie_prompt; use crate::ui::radarr_ui::edit_movie_ui::draw_edit_movie_prompt;
use crate::ui::radarr_ui::movie_details_ui::draw_movie_info_popup; use crate::ui::radarr_ui::movie_details_ui::draw_movie_info_popup;
@@ -37,6 +38,7 @@ use crate::utils::{convert_runtime, convert_to_gb};
mod add_movie_ui; mod add_movie_ui;
mod collection_details_ui; mod collection_details_ui;
mod delete_movie_ui;
mod edit_collection_ui; mod edit_collection_ui;
mod edit_movie_ui; mod edit_movie_ui;
mod movie_details_ui; mod movie_details_ui;
@@ -150,7 +152,7 @@ pub(super) fn draw_radarr_ui<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, ar
} }
} }
} }
ActiveRadarrBlock::DeleteMoviePrompt => { _ if DELETE_MOVIE_BLOCKS.contains(&active_radarr_block) => {
draw_prompt_popup_over(f, app, content_rect, draw_library, draw_delete_movie_prompt) draw_prompt_popup_over(f, app, content_rect, draw_library, draw_delete_movie_prompt)
} }
ActiveRadarrBlock::DeleteDownloadPrompt => draw_prompt_popup_over( ActiveRadarrBlock::DeleteDownloadPrompt => draw_prompt_popup_over(
@@ -320,7 +322,7 @@ fn draw_update_all_movies_prompt<B: Backend>(
prompt_area, prompt_area,
"Update All Movies", "Update All Movies",
"Do you want to update info and scan your disks for all of your movies?", "Do you want to update info and scan your disks for all of your movies?",
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} }
@@ -334,7 +336,7 @@ fn draw_update_downloads_prompt<B: Backend>(
prompt_area, prompt_area,
"Update Downloads", "Update Downloads",
"Do you want to update your downloads?", "Do you want to update your downloads?",
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} }
@@ -348,21 +350,7 @@ fn draw_update_all_collections_prompt<B: Backend>(
prompt_area, prompt_area,
"Update All Collections", "Update All Collections",
"Do you want to update all of your collections?", "Do you want to update all of your collections?",
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
);
}
fn draw_delete_movie_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
"Delete Movie",
format!(
"Do you really want to delete: {}?",
app.data.radarr_data.movies.current_selection().title
)
.as_str(),
&app.data.radarr_data.prompt_confirm,
); );
} }
@@ -376,7 +364,7 @@ fn draw_delete_download_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App,
app.data.radarr_data.downloads.current_selection().title app.data.radarr_data.downloads.current_selection().title
) )
.as_str(), .as_str(),
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} }
@@ -394,7 +382,7 @@ fn draw_delete_root_folder_prompt<B: Backend>(
app.data.radarr_data.root_folders.current_selection().path app.data.radarr_data.root_folders.current_selection().path
) )
.as_str(), .as_str(),
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} }
+4 -4
View File
@@ -93,7 +93,7 @@ fn draw_search_movie_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
app.data.radarr_data.movies.current_selection().title app.data.radarr_data.movies.current_selection().title
) )
.as_str(), .as_str(),
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} }
@@ -107,7 +107,7 @@ fn draw_update_and_scan_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App,
app.data.radarr_data.movies.current_selection().title app.data.radarr_data.movies.current_selection().title
) )
.as_str(), .as_str(),
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} }
@@ -521,7 +521,7 @@ fn draw_manual_search_confirm_prompt<B: Backend>(
title, title,
&prompt, &prompt,
Some(content_paragraph), Some(content_paragraph),
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} else { } else {
draw_prompt_box( draw_prompt_box(
@@ -529,7 +529,7 @@ fn draw_manual_search_confirm_prompt<B: Backend>(
prompt_area, prompt_area,
title, title,
&prompt, &prompt,
&app.data.radarr_data.prompt_confirm, app.data.radarr_data.prompt_confirm,
); );
} }
} }