Completed edit movies implementation, cleaned up the Movies table, and fixed a bug when adding a movie from the CollectionDetails screen.
This commit is contained in:
@@ -8,14 +8,18 @@ use crate::app::radarr::ActiveRadarrBlock;
|
||||
use crate::models::radarr_models::AddMovieSearchResult;
|
||||
use crate::models::Route;
|
||||
use crate::ui::radarr_ui::collection_details_ui::draw_collection_details;
|
||||
use crate::ui::radarr_ui::{
|
||||
draw_select_minimum_availability_popup, draw_select_quality_profile_popup,
|
||||
};
|
||||
use crate::ui::utils::{
|
||||
borderless_block, get_width_from_percentage, horizontal_chunks, layout_block,
|
||||
layout_paragraph_borderless, show_cursor, style_default, style_help, style_primary,
|
||||
title_block_centered, vertical_chunks_with_margin,
|
||||
layout_paragraph_borderless, style_help, style_primary, title_block_centered,
|
||||
vertical_chunks_with_margin,
|
||||
};
|
||||
use crate::ui::{
|
||||
draw_button, draw_drop_down_list, draw_drop_down_menu_button, draw_drop_down_popup,
|
||||
draw_error_popup, draw_error_popup_over, draw_medium_popup_over, draw_table, TableProps,
|
||||
draw_error_popup, draw_error_popup_over, draw_medium_popup_over, draw_table, draw_text_box,
|
||||
TableProps,
|
||||
};
|
||||
use crate::utils::convert_runtime;
|
||||
use crate::App;
|
||||
@@ -80,14 +84,10 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area:
|
||||
);
|
||||
let block_content = app.data.radarr_data.search.as_str();
|
||||
|
||||
let search_paragraph = Paragraph::new(Text::from(block_content))
|
||||
.style(style_default())
|
||||
.block(title_block_centered("Add Movie"));
|
||||
|
||||
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
|
||||
match active_radarr_block {
|
||||
ActiveRadarrBlock::AddMovieSearchInput => {
|
||||
show_cursor(f, chunks[0], block_content);
|
||||
draw_text_box(f, chunks[0], Some("Add Movie"), block_content, true, false);
|
||||
f.render_widget(layout_block(), chunks[1]);
|
||||
|
||||
let mut help_text = Text::from("<esc> close");
|
||||
@@ -124,7 +124,7 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area:
|
||||
TableProps {
|
||||
content: &mut app.data.radarr_data.add_searched_movies,
|
||||
table_headers: vec![
|
||||
"✓",
|
||||
"✔",
|
||||
"Title",
|
||||
"Year",
|
||||
"Runtime",
|
||||
@@ -179,7 +179,7 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area:
|
||||
.iter()
|
||||
.any(|mov| mov.tmdb_id == movie.tmdb_id)
|
||||
{
|
||||
"✓"
|
||||
"✔"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
@@ -208,7 +208,7 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area:
|
||||
}
|
||||
}
|
||||
|
||||
f.render_widget(search_paragraph, chunks[0]);
|
||||
draw_text_box(f, chunks[0], Some("Add Movie"), block_content, false, false);
|
||||
}
|
||||
|
||||
fn draw_confirmation_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, prompt_area: Rect) {
|
||||
@@ -251,37 +251,11 @@ fn draw_select_monitor_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, po
|
||||
draw_drop_down_list(
|
||||
f,
|
||||
popup_area,
|
||||
&mut app.data.radarr_data.add_movie_monitor_list,
|
||||
&mut app.data.radarr_data.movie_monitor_list,
|
||||
|monitor| ListItem::new(monitor.to_display_str().to_owned()),
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_select_minimum_availability_popup<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
app: &mut App,
|
||||
popup_area: Rect,
|
||||
) {
|
||||
draw_drop_down_list(
|
||||
f,
|
||||
popup_area,
|
||||
&mut app.data.radarr_data.add_movie_minimum_availability_list,
|
||||
|minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()),
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_select_quality_profile_popup<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
app: &mut App,
|
||||
popup_area: Rect,
|
||||
) {
|
||||
draw_drop_down_list(
|
||||
f,
|
||||
popup_area,
|
||||
&mut app.data.radarr_data.add_movie_quality_profile_list,
|
||||
|quality_profile| ListItem::new(quality_profile.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, prompt_area: Rect) {
|
||||
let title = "Add Movie";
|
||||
let (movie_title, movie_overview) = if let Route::Radarr(_, Some(_)) = app.get_current_route() {
|
||||
@@ -292,7 +266,7 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
|
||||
.collection_movies
|
||||
.current_selection()
|
||||
.title
|
||||
.to_string(),
|
||||
.stationary_style(),
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
@@ -324,20 +298,16 @@ fn draw_confirmation_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, pro
|
||||
let selected_block = &app.data.radarr_data.selected_block;
|
||||
let highlight_yes_no = *selected_block == ActiveRadarrBlock::AddMovieConfirmPrompt;
|
||||
|
||||
let selected_monitor = app
|
||||
.data
|
||||
.radarr_data
|
||||
.add_movie_monitor_list
|
||||
.current_selection();
|
||||
let selected_monitor = app.data.radarr_data.movie_monitor_list.current_selection();
|
||||
let selected_minimum_availability = app
|
||||
.data
|
||||
.radarr_data
|
||||
.add_movie_minimum_availability_list
|
||||
.movie_minimum_availability_list
|
||||
.current_selection();
|
||||
let selected_quality_profile = app
|
||||
.data
|
||||
.radarr_data
|
||||
.add_movie_quality_profile_list
|
||||
.movie_quality_profile_list
|
||||
.current_selection();
|
||||
|
||||
f.render_widget(title_block_centered(title), prompt_area);
|
||||
|
||||
@@ -119,7 +119,7 @@ pub(super) fn draw_collection_details<B: Backend>(
|
||||
TableProps {
|
||||
content: &mut app.data.radarr_data.collection_movies,
|
||||
table_headers: vec![
|
||||
"✓",
|
||||
"✔",
|
||||
"Title",
|
||||
"Year",
|
||||
"Runtime",
|
||||
@@ -147,7 +147,7 @@ pub(super) fn draw_collection_details<B: Backend>(
|
||||
.iter()
|
||||
.any(|mov| mov.tmdb_id == movie.tmdb_id)
|
||||
{
|
||||
"✓"
|
||||
"✔"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
use tui::backend::Backend;
|
||||
use tui::layout::{Constraint, Rect};
|
||||
use tui::Frame;
|
||||
|
||||
use crate::app::radarr::ActiveRadarrBlock;
|
||||
use crate::app::App;
|
||||
use crate::models::Route;
|
||||
use crate::ui::radarr_ui::{
|
||||
draw_select_minimum_availability_popup, draw_select_quality_profile_popup,
|
||||
};
|
||||
use crate::ui::utils::{
|
||||
horizontal_chunks, layout_paragraph_borderless, title_block_centered, vertical_chunks_with_margin,
|
||||
};
|
||||
use crate::ui::{
|
||||
draw_button, draw_checkbox_with_label, draw_drop_down_menu_button, draw_drop_down_popup,
|
||||
draw_text_box_with_label,
|
||||
};
|
||||
|
||||
pub(super) fn draw_edit_movie_prompt<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
app: &mut App,
|
||||
prompt_area: Rect,
|
||||
) {
|
||||
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
|
||||
match active_radarr_block {
|
||||
ActiveRadarrBlock::EditMovieSelectMinimumAvailability => {
|
||||
draw_drop_down_popup(
|
||||
f,
|
||||
app,
|
||||
prompt_area,
|
||||
draw_edit_confirmation_prompt,
|
||||
draw_select_minimum_availability_popup,
|
||||
);
|
||||
}
|
||||
ActiveRadarrBlock::EditMovieSelectQualityProfile => {
|
||||
draw_drop_down_popup(
|
||||
f,
|
||||
app,
|
||||
prompt_area,
|
||||
draw_edit_confirmation_prompt,
|
||||
draw_select_quality_profile_popup,
|
||||
);
|
||||
}
|
||||
ActiveRadarrBlock::EditMoviePrompt
|
||||
| ActiveRadarrBlock::EditMovieToggleMonitored
|
||||
| ActiveRadarrBlock::EditMoviePathInput
|
||||
| ActiveRadarrBlock::EditMovieTagsInput => draw_edit_confirmation_prompt(f, app, prompt_area),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_edit_confirmation_prompt<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
app: &mut App,
|
||||
prompt_area: Rect,
|
||||
) {
|
||||
let (movie_title, movie_overview) = (
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.movies
|
||||
.current_selection()
|
||||
.title
|
||||
.to_string(),
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.movies
|
||||
.current_selection()
|
||||
.overview
|
||||
.clone(),
|
||||
);
|
||||
let title = format!("Edit - {}", movie_title);
|
||||
let yes_no_value = &app.data.radarr_data.prompt_confirm;
|
||||
let selected_block = &app.data.radarr_data.selected_block;
|
||||
let highlight_yes_no = *selected_block == ActiveRadarrBlock::EditMovieConfirmPrompt;
|
||||
|
||||
let selected_minimum_availability = app
|
||||
.data
|
||||
.radarr_data
|
||||
.movie_minimum_availability_list
|
||||
.current_selection();
|
||||
let selected_quality_profile = app
|
||||
.data
|
||||
.radarr_data
|
||||
.movie_quality_profile_list
|
||||
.current_selection();
|
||||
|
||||
f.render_widget(title_block_centered(&title), prompt_area);
|
||||
|
||||
let chunks = vertical_chunks_with_margin(
|
||||
vec![
|
||||
Constraint::Percentage(35),
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(3),
|
||||
Constraint::Min(0),
|
||||
Constraint::Length(3),
|
||||
],
|
||||
prompt_area,
|
||||
1,
|
||||
);
|
||||
|
||||
let prompt_paragraph = layout_paragraph_borderless(&movie_overview);
|
||||
f.render_widget(prompt_paragraph, chunks[0]);
|
||||
|
||||
let horizontal_chunks = horizontal_chunks(
|
||||
vec![Constraint::Percentage(50), Constraint::Percentage(50)],
|
||||
chunks[7],
|
||||
);
|
||||
|
||||
draw_checkbox_with_label(
|
||||
f,
|
||||
chunks[1],
|
||||
"Monitored",
|
||||
app.data.radarr_data.edit_monitored.unwrap_or_default(),
|
||||
*selected_block == ActiveRadarrBlock::EditMovieToggleMonitored,
|
||||
);
|
||||
|
||||
draw_drop_down_menu_button(
|
||||
f,
|
||||
chunks[2],
|
||||
"Minimum Availability",
|
||||
selected_minimum_availability.to_display_str(),
|
||||
*selected_block == ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
|
||||
);
|
||||
draw_drop_down_menu_button(
|
||||
f,
|
||||
chunks[3],
|
||||
"Quality Profile",
|
||||
selected_quality_profile,
|
||||
*selected_block == ActiveRadarrBlock::EditMovieSelectQualityProfile,
|
||||
);
|
||||
|
||||
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
|
||||
draw_text_box_with_label(
|
||||
f,
|
||||
chunks[4],
|
||||
"Path",
|
||||
&app.data.radarr_data.edit_path,
|
||||
*selected_block == ActiveRadarrBlock::EditMoviePathInput,
|
||||
active_radarr_block == ActiveRadarrBlock::EditMoviePathInput,
|
||||
);
|
||||
draw_text_box_with_label(
|
||||
f,
|
||||
chunks[5],
|
||||
"Tags",
|
||||
&app.data.radarr_data.edit_tags,
|
||||
*selected_block == ActiveRadarrBlock::EditMovieTagsInput,
|
||||
active_radarr_block == ActiveRadarrBlock::EditMovieTagsInput,
|
||||
);
|
||||
}
|
||||
|
||||
draw_button(
|
||||
f,
|
||||
horizontal_chunks[0],
|
||||
"Save",
|
||||
*yes_no_value && highlight_yes_no,
|
||||
);
|
||||
draw_button(
|
||||
f,
|
||||
horizontal_chunks[1],
|
||||
"Cancel",
|
||||
!*yes_no_value && highlight_yes_no,
|
||||
);
|
||||
}
|
||||
+72
-15
@@ -6,12 +6,12 @@ use tui::backend::Backend;
|
||||
use tui::layout::{Alignment, Constraint, Rect};
|
||||
use tui::style::{Color, Style};
|
||||
use tui::text::Text;
|
||||
use tui::widgets::{Cell, Paragraph, Row};
|
||||
use tui::widgets::{Cell, ListItem, Paragraph, Row};
|
||||
use tui::Frame;
|
||||
|
||||
use crate::app::radarr::{
|
||||
ActiveRadarrBlock, RadarrData, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, FILTER_BLOCKS,
|
||||
MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS,
|
||||
ActiveRadarrBlock, RadarrData, ADD_MOVIE_BLOCKS, COLLECTION_DETAILS_BLOCKS, EDIT_MOVIE_BLOCKS,
|
||||
FILTER_BLOCKS, MOVIE_DETAILS_BLOCKS, SEARCH_BLOCKS,
|
||||
};
|
||||
use crate::app::App;
|
||||
use crate::logos::RADARR_LOGO;
|
||||
@@ -19,27 +19,29 @@ use crate::models::radarr_models::{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;
|
||||
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::utils::{
|
||||
borderless_block, get_width_from_percentage, horizontal_chunks, layout_block,
|
||||
layout_block_top_border, line_gauge_with_label, line_gauge_with_title, show_cursor, style_bold,
|
||||
style_default, style_failure, style_primary, style_success, style_warning, title_block,
|
||||
title_block_centered, vertical_chunks_with_margin,
|
||||
style_default, style_failure, style_primary, style_success, style_unmonitored, style_warning,
|
||||
title_block, title_block_centered, vertical_chunks_with_margin,
|
||||
};
|
||||
use crate::ui::{
|
||||
draw_large_popup_over, draw_popup_over, draw_prompt_box, draw_prompt_popup_over, draw_table,
|
||||
draw_tabs, loading, TableProps,
|
||||
draw_drop_down_list, draw_large_popup_over, draw_medium_popup_over, draw_popup, draw_popup_over,
|
||||
draw_prompt_box, draw_prompt_popup_over, draw_table, draw_tabs, loading, TableProps,
|
||||
};
|
||||
use crate::utils::{convert_runtime, convert_to_gb};
|
||||
|
||||
mod add_movie_ui;
|
||||
mod collection_details_ui;
|
||||
mod edit_movie_ui;
|
||||
mod movie_details_ui;
|
||||
|
||||
pub(super) fn draw_radarr_ui<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
|
||||
let (content_rect, _) = draw_tabs(f, area, "Movies", &app.data.radarr_data.main_tabs);
|
||||
|
||||
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
|
||||
if let Route::Radarr(active_radarr_block, context_option) = *app.get_current_route() {
|
||||
match active_radarr_block {
|
||||
ActiveRadarrBlock::Movies => draw_library(f, app, content_rect),
|
||||
ActiveRadarrBlock::SearchMovie => {
|
||||
@@ -97,6 +99,20 @@ pub(super) fn draw_radarr_ui<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, ar
|
||||
draw_collections,
|
||||
draw_collection_details_popup,
|
||||
),
|
||||
_ if EDIT_MOVIE_BLOCKS.contains(&active_radarr_block) => {
|
||||
if let Some(context) = context_option {
|
||||
match context {
|
||||
ActiveRadarrBlock::Movies => {
|
||||
draw_medium_popup_over(f, app, content_rect, draw_library, draw_edit_movie_prompt)
|
||||
}
|
||||
_ if MOVIE_DETAILS_BLOCKS.contains(&context) => {
|
||||
draw_large_popup_over(f, app, content_rect, draw_library, draw_movie_info_popup);
|
||||
draw_popup(f, app, draw_edit_movie_prompt, 60, 60);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
ActiveRadarrBlock::DeleteMoviePrompt => {
|
||||
draw_prompt_popup_over(f, app, content_rect, draw_library, draw_delete_movie_prompt)
|
||||
}
|
||||
@@ -160,19 +176,25 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
|
||||
table_headers: vec![
|
||||
"Title",
|
||||
"Year",
|
||||
"Studio",
|
||||
"Runtime",
|
||||
"Rating",
|
||||
"Language",
|
||||
"Size",
|
||||
"Quality Profile",
|
||||
"Monitored",
|
||||
"Tags",
|
||||
],
|
||||
constraints: vec![
|
||||
Constraint::Percentage(25),
|
||||
Constraint::Percentage(12),
|
||||
Constraint::Percentage(12),
|
||||
Constraint::Percentage(12),
|
||||
Constraint::Percentage(12),
|
||||
Constraint::Percentage(12),
|
||||
Constraint::Percentage(27),
|
||||
Constraint::Percentage(4),
|
||||
Constraint::Percentage(17),
|
||||
Constraint::Percentage(6),
|
||||
Constraint::Percentage(6),
|
||||
Constraint::Percentage(6),
|
||||
Constraint::Percentage(6),
|
||||
Constraint::Percentage(10),
|
||||
Constraint::Percentage(6),
|
||||
Constraint::Percentage(12),
|
||||
],
|
||||
help: app
|
||||
@@ -182,13 +204,16 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
|
||||
.get_active_tab_contextual_help(),
|
||||
},
|
||||
|movie| {
|
||||
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());
|
||||
let certification = movie.certification.clone().unwrap_or_else(|| "".to_owned());
|
||||
let tags = "";
|
||||
|
||||
Row::new(vec![
|
||||
Cell::from(movie.title.to_owned()),
|
||||
Cell::from(movie.year.to_string()),
|
||||
Cell::from(movie.studio.to_string()),
|
||||
Cell::from(format!("{}h {}m", hours, minutes)),
|
||||
Cell::from(certification),
|
||||
Cell::from(movie.original_language.name.to_owned()),
|
||||
@@ -199,6 +224,8 @@ fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
|
||||
.unwrap()
|
||||
.to_owned(),
|
||||
),
|
||||
Cell::from(monitored.to_owned()),
|
||||
Cell::from(tags.to_owned()),
|
||||
])
|
||||
.style(determine_row_style(downloads_vec, movie))
|
||||
},
|
||||
@@ -601,5 +628,35 @@ fn determine_row_style(downloads_vec: &[DownloadRecord], movie: &Movie) -> Style
|
||||
return style_failure();
|
||||
}
|
||||
|
||||
style_success()
|
||||
if !movie.monitored {
|
||||
style_unmonitored()
|
||||
} else {
|
||||
style_success()
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_select_minimum_availability_popup<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
app: &mut App,
|
||||
popup_area: Rect,
|
||||
) {
|
||||
draw_drop_down_list(
|
||||
f,
|
||||
popup_area,
|
||||
&mut app.data.radarr_data.movie_minimum_availability_list,
|
||||
|minimum_availability| ListItem::new(minimum_availability.to_display_str().to_owned()),
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_select_quality_profile_popup<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
app: &mut App,
|
||||
popup_area: Rect,
|
||||
) {
|
||||
draw_drop_down_list(
|
||||
f,
|
||||
popup_area,
|
||||
&mut app.data.radarr_data.movie_quality_profile_list,
|
||||
|quality_profile| ListItem::new(quality_profile.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,13 @@ use crate::utils::convert_to_gb;
|
||||
pub(super) fn draw_movie_info_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
|
||||
let (content_area, _) = draw_tabs(f, area, "Movie Info", &app.data.radarr_data.movie_info_tabs);
|
||||
|
||||
if let Route::Radarr(active_radarr_block, _) = app.get_current_route() {
|
||||
match active_radarr_block {
|
||||
if let Route::Radarr(active_radarr_block, context_option) = app.get_current_route() {
|
||||
let match_block = if let Some(context) = context_option {
|
||||
context
|
||||
} else {
|
||||
active_radarr_block
|
||||
};
|
||||
match match_block {
|
||||
ActiveRadarrBlock::AutomaticallySearchMoviePrompt => draw_prompt_popup_over(
|
||||
f,
|
||||
app,
|
||||
|
||||
Reference in New Issue
Block a user