Added 'Test All Indexers' table and functionality to the Indexers tab, and upgraded to Ratatui 0.24.0 and cleaned up code for newer Ratatui version

This commit is contained in:
2023-11-25 17:36:30 -07:00
parent d0ce98eb93
commit 76e21e7697
44 changed files with 1132 additions and 428 deletions
@@ -1,8 +1,7 @@
use tui::backend::Backend;
use tui::layout::{Alignment, Constraint, Rect};
use tui::text::Text;
use tui::widgets::{Cell, Paragraph, Row, Wrap};
use tui::Frame;
use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::text::Text;
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
use ratatui::Frame;
use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CLUES};
use crate::app::radarr::radarr_context_clues::COLLECTION_DETAILS_CONTEXT_CLUES;
@@ -36,10 +35,10 @@ impl DrawUi for CollectionDetailsUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, context_option) = *app.get_current_route() {
let draw_collection_details_popup =
|f: &mut Frame<'_, B>, app: &mut App<'_>, popup_area: Rect| match context_option
|f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| match context_option
.unwrap_or(active_radarr_block)
{
ActiveRadarrBlock::ViewMovieOverview => {
@@ -66,11 +65,7 @@ impl DrawUi for CollectionDetailsUi {
}
}
pub fn draw_collection_details<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
content_area: Rect,
) {
pub fn draw_collection_details(f: &mut Frame<'_>, app: &mut App<'_>, content_area: Rect) {
let chunks = vertical_chunks_with_margin(
vec![
Constraint::Percentage(25),
@@ -242,7 +237,7 @@ pub fn draw_collection_details<B: Backend>(
);
}
fn draw_movie_overview<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_area: Rect) {
fn draw_movie_overview(f: &mut Frame<'_>, app: &mut App<'_>, content_area: Rect) {
let title_block = title_block("Overview");
f.render_widget(title_block, content_area);
@@ -1,7 +1,6 @@
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::widgets::ListItem;
use tui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::ListItem;
use ratatui::Frame;
use crate::app::App;
use crate::models::servarr_data::radarr::modals::EditCollectionModal;
@@ -35,10 +34,10 @@ impl DrawUi for EditCollectionUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, context_option) = *app.get_current_route() {
let draw_edit_collection_prompt =
|f: &mut Frame<'_, B>, app: &mut App<'_>, prompt_area: Rect| match active_radarr_block {
|f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| match active_radarr_block {
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability => {
draw_drop_down_popup(
f,
@@ -76,7 +75,7 @@ impl DrawUi for EditCollectionUi {
draw_edit_collection_prompt,
),
_ if COLLECTION_DETAILS_BLOCKS.contains(&context) => {
draw_large_popup_over_background_fn_with_ui::<B, CollectionDetailsUi>(
draw_large_popup_over_background_fn_with_ui::<CollectionDetailsUi>(
f,
app,
content_rect,
@@ -91,8 +90,8 @@ impl DrawUi for EditCollectionUi {
}
}
fn draw_edit_collection_confirmation_prompt<B: Backend>(
f: &mut Frame<'_, B>,
fn draw_edit_collection_confirmation_prompt(
f: &mut Frame<'_>,
app: &mut App<'_>,
prompt_area: Rect,
) {
@@ -223,8 +222,8 @@ fn draw_edit_collection_confirmation_prompt<B: Backend>(
);
}
fn draw_edit_collection_select_minimum_availability_popup<B: Backend>(
f: &mut Frame<'_, B>,
fn draw_edit_collection_select_minimum_availability_popup(
f: &mut Frame<'_>,
app: &mut App<'_>,
popup_area: Rect,
) {
@@ -242,8 +241,8 @@ fn draw_edit_collection_select_minimum_availability_popup<B: Backend>(
);
}
fn draw_edit_collection_select_quality_profile_popup<B: Backend>(
f: &mut Frame<'_, B>,
fn draw_edit_collection_select_quality_profile_popup(
f: &mut Frame<'_>,
app: &mut App<'_>,
popup_area: Rect,
) {
+10 -19
View File
@@ -1,7 +1,6 @@
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::widgets::{Cell, Row};
use tui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
pub(super) use collection_details_ui::draw_collection_details;
@@ -36,7 +35,7 @@ impl DrawUi for CollectionsUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
let route = *app.get_current_route();
let mut collections_ui_matcher = |active_radarr_block| match active_radarr_block {
ActiveRadarrBlock::Collections => draw_collections(f, app, content_rect),
@@ -99,7 +98,7 @@ impl DrawUi for CollectionsUi {
}
}
pub(super) fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
pub(super) fn draw_collections(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let current_selection =
if let Some(filtered_collections) = app.data.radarr_data.filtered_collections.as_ref() {
filtered_collections.current_selection().clone()
@@ -176,11 +175,7 @@ pub(super) fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'
);
}
fn draw_update_all_collections_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_update_all_collections_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -190,7 +185,7 @@ fn draw_update_all_collections_prompt<B: Backend>(
);
}
fn draw_collection_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_collection_search_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_input_box_popup(
f,
area,
@@ -199,7 +194,7 @@ fn draw_collection_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_
);
}
fn draw_filter_collections_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_filter_collections_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_input_box_popup(
f,
area,
@@ -208,14 +203,10 @@ fn draw_filter_collections_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'
)
}
fn draw_search_collection_error_box<B: Backend>(f: &mut Frame<'_, B>, _: &mut App<'_>, area: Rect) {
fn draw_search_collection_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) {
draw_error_message_popup(f, area, "Collection not found!");
}
fn draw_filter_collections_error_box<B: Backend>(
f: &mut Frame<'_, B>,
_: &mut App<'_>,
area: Rect,
) {
fn draw_filter_collections_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) {
draw_error_message_popup(f, area, "No collections found matching the given filter!");
}
+7 -16
View File
@@ -1,7 +1,6 @@
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::widgets::{Cell, Row};
use tui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::radarr_models::DownloadRecord;
@@ -26,7 +25,7 @@ impl DrawUi for DownloadsUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
match active_radarr_block {
ActiveRadarrBlock::Downloads => draw_downloads(f, app, content_rect),
@@ -50,7 +49,7 @@ impl DrawUi for DownloadsUi {
}
}
fn draw_downloads<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_downloads(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let current_selection = if app.data.radarr_data.downloads.items.is_empty() {
DownloadRecord::default()
} else {
@@ -128,11 +127,7 @@ fn draw_downloads<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rec
);
}
fn draw_delete_download_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_delete_download_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -146,11 +141,7 @@ fn draw_delete_download_prompt<B: Backend>(
);
}
fn draw_update_downloads_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_update_downloads_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -1,7 +1,6 @@
use ratatui::layout::{Constraint, Rect};
use ratatui::Frame;
use std::iter;
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::Frame;
use crate::app::App;
use crate::models::servarr_data::radarr::radarr_data::{
@@ -32,7 +31,7 @@ impl DrawUi for IndexerSettingsUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
draw_popup_over(
f,
app,
@@ -45,11 +44,7 @@ impl DrawUi for IndexerSettingsUi {
}
}
fn draw_edit_indexer_settings_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_edit_indexer_settings_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
let block = title_block_centered("Configure All Indexer Settings");
let yes_no_value = app.data.radarr_data.prompt_confirm;
let selected_block = app.data.radarr_data.selected_block.get_active_block();
+10 -12
View File
@@ -1,14 +1,14 @@
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::text::Text;
use tui::widgets::{Cell, Row};
use tui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::text::Text;
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::radarr_models::Indexer;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, INDEXERS_BLOCKS};
use crate::models::Route;
use crate::ui::radarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi;
use crate::ui::radarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi;
use crate::ui::utils::{layout_block_top_border, style_failure, style_primary, style_success};
use crate::ui::{draw_prompt_box, draw_prompt_popup_over, draw_table, DrawUi, TableProps};
@@ -17,6 +17,7 @@ mod indexer_settings_ui;
#[cfg(test)]
#[path = "indexers_ui_tests.rs"]
mod indexers_ui_tests;
mod test_all_indexers_ui;
pub(super) struct IndexersUi;
@@ -29,7 +30,7 @@ impl DrawUi for IndexersUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
let route = *app.get_current_route();
let mut indexers_matchers = |active_radarr_block| match active_radarr_block {
ActiveRadarrBlock::Indexers => draw_indexers(f, app, content_rect),
@@ -45,6 +46,7 @@ impl DrawUi for IndexersUi {
match route {
_ if IndexerSettingsUi::accepts(route) => IndexerSettingsUi::draw(f, app, content_rect),
_ if TestAllIndexersUi::accepts(route) => TestAllIndexersUi::draw(f, app, content_rect),
Route::Radarr(active_radarr_block, _) if INDEXERS_BLOCKS.contains(&active_radarr_block) => {
indexers_matchers(active_radarr_block)
}
@@ -53,7 +55,7 @@ impl DrawUi for IndexersUi {
}
}
fn draw_indexers<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_indexers(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_table(
f,
area,
@@ -125,11 +127,7 @@ fn draw_indexers<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect
)
}
fn draw_delete_indexer_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_delete_indexer_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -0,0 +1,95 @@
use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CLUES};
use crate::app::App;
use crate::models::servarr_data::radarr::modals::IndexerTestResultModalItem;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::Route;
use crate::ui::radarr_ui::indexers::draw_indexers;
use crate::ui::utils::{
borderless_block, get_width_from_percentage, style_failure, style_success, title_block,
};
use crate::ui::{
draw_help_and_get_content_rect, draw_large_popup_over, draw_table, DrawUi, TableProps,
};
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
#[cfg(test)]
#[path = "test_all_indexers_ui_tests.rs"]
mod test_all_indexers_ui_tests;
pub(super) struct TestAllIndexersUi;
impl DrawUi for TestAllIndexersUi {
fn accepts(route: Route) -> bool {
if let Route::Radarr(active_radarr_block, _) = route {
return active_radarr_block == ActiveRadarrBlock::TestAllIndexers;
}
false
}
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
draw_large_popup_over(
f,
app,
content_rect,
draw_indexers,
draw_test_all_indexers_test_results,
);
}
}
fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let current_selection =
if let Some(test_all_results) = app.data.radarr_data.indexer_test_all_results.as_ref() {
test_all_results.current_selection().clone()
} else {
IndexerTestResultModalItem::default()
};
f.render_widget(title_block("Test All Indexers"), area);
let help = Some(format!(
"<↑↓> scroll | {}",
build_context_clue_string(&BARE_POPUP_CONTEXT_CLUES)
));
let content_area = draw_help_and_get_content_rect(f, area, help);
draw_table(
f,
content_area,
borderless_block(),
TableProps {
content: app.data.radarr_data.indexer_test_all_results.as_mut(),
wrapped_content: None,
table_headers: vec!["Indexer", "Pass/Fail", "Failure Messages"],
constraints: vec![
Constraint::Percentage(20),
Constraint::Percentage(10),
Constraint::Percentage(70),
],
help: None,
},
|result| {
result.validation_failures.scroll_left_or_reset(
get_width_from_percentage(area, 86),
*result == current_selection,
app.tick_count % app.ticks_until_scroll == 0,
);
let pass_fail = if result.is_valid { "" } else { "" };
let row_style = if result.is_valid {
style_success()
} else {
style_failure()
};
Row::new(vec![
Cell::from(result.name.to_owned()),
Cell::from(pass_fail.to_owned()),
Cell::from(result.validation_failures.to_string()),
])
.style(row_style)
},
app.is_loading,
true,
);
}
@@ -0,0 +1,19 @@
#[cfg(test)]
mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::ui::radarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi;
use crate::ui::DrawUi;
#[test]
fn test_test_all_indexers_ui_accepts() {
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if active_radarr_block == ActiveRadarrBlock::TestAllIndexers {
assert!(TestAllIndexersUi::accepts(active_radarr_block.into()));
} else {
assert!(!TestAllIndexersUi::accepts(active_radarr_block.into()));
}
});
}
}
+15 -28
View File
@@ -1,8 +1,7 @@
use tui::backend::Backend;
use tui::layout::{Alignment, Constraint, Rect};
use tui::text::Text;
use tui::widgets::{Cell, ListItem, Paragraph, Row};
use tui::Frame;
use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::text::Text;
use ratatui::widgets::{Cell, ListItem, Paragraph, Row};
use ratatui::Frame;
use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CLUES};
use crate::app::radarr::radarr_context_clues::ADD_MOVIE_SEARCH_RESULTS_CONTEXT_CLUES;
@@ -40,10 +39,10 @@ impl DrawUi for AddMovieUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, context_option) = *app.get_current_route() {
let draw_add_movie_search_popup =
|f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect| match active_radarr_block {
|f: &mut Frame<'_>, app: &mut App<'_>, area: Rect| match active_radarr_block {
ActiveRadarrBlock::AddMovieSearchInput
| ActiveRadarrBlock::AddMovieSearchResults
| ActiveRadarrBlock::AddMovieEmptySearchResults => {
@@ -103,7 +102,7 @@ impl DrawUi for AddMovieUi {
}
}
fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_add_movie_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let is_loading = app.is_loading || app.data.radarr_data.add_searched_movies.is_none();
let current_selection =
if let Some(add_searched_movies) = app.data.radarr_data.add_searched_movies.as_ref() {
@@ -277,7 +276,7 @@ fn draw_add_movie_search<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, ar
);
}
fn draw_confirmation_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, prompt_area: Rect) {
fn draw_confirmation_popup(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
match active_radarr_block {
ActiveRadarrBlock::AddMovieSelectMonitor => {
@@ -324,11 +323,7 @@ fn draw_confirmation_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>,
}
}
fn draw_confirmation_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_confirmation_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
let (movie_title, movie_overview) = if let Route::Radarr(_, Some(_)) = app.get_current_route() {
(
&app
@@ -469,11 +464,7 @@ fn draw_confirmation_prompt<B: Backend>(
);
}
fn draw_add_movie_select_monitor_popup<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
popup_area: Rect,
) {
fn draw_add_movie_select_monitor_popup(f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect) {
draw_selectable_list(
f,
popup_area,
@@ -488,8 +479,8 @@ fn draw_add_movie_select_monitor_popup<B: Backend>(
);
}
fn draw_add_movie_select_minimum_availability_popup<B: Backend>(
f: &mut Frame<'_, B>,
fn draw_add_movie_select_minimum_availability_popup(
f: &mut Frame<'_>,
app: &mut App<'_>,
popup_area: Rect,
) {
@@ -507,8 +498,8 @@ fn draw_add_movie_select_minimum_availability_popup<B: Backend>(
);
}
fn draw_add_movie_select_quality_profile_popup<B: Backend>(
f: &mut Frame<'_, B>,
fn draw_add_movie_select_quality_profile_popup(
f: &mut Frame<'_>,
app: &mut App<'_>,
popup_area: Rect,
) {
@@ -526,11 +517,7 @@ fn draw_add_movie_select_quality_profile_popup<B: Backend>(
);
}
fn draw_add_movie_select_root_folder_popup<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
popup_area: Rect,
) {
fn draw_add_movie_select_root_folder_popup(f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect) {
draw_selectable_list(
f,
popup_area,
+29 -31
View File
@@ -1,6 +1,5 @@
use tui::backend::Backend;
use tui::layout::Rect;
use tui::Frame;
use ratatui::layout::Rect;
use ratatui::Frame;
use crate::app::App;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS};
@@ -23,39 +22,38 @@ impl DrawUi for DeleteMovieUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if matches!(
*app.get_current_route(),
Route::Radarr(ActiveRadarrBlock::DeleteMoviePrompt, _)
) {
let draw_delete_movie_prompt =
|f: &mut Frame<'_, B>, app: &mut App<'_>, prompt_area: Rect| {
let selected_block = app.data.radarr_data.selected_block.get_active_block();
draw_prompt_box_with_checkboxes(
f,
prompt_area,
"Delete Movie",
format!(
"Do you really want to delete: \n{}?",
app.data.radarr_data.movies.current_selection().title.text
)
.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,
let draw_delete_movie_prompt = |f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| {
let selected_block = app.data.radarr_data.selected_block.get_active_block();
draw_prompt_box_with_checkboxes(
f,
prompt_area,
"Delete Movie",
format!(
"Do you really want to delete: \n{}?",
app.data.radarr_data.movies.current_selection().title.text
)
};
.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,
)
};
draw_prompt_popup_over(f, app, content_rect, draw_library, draw_delete_movie_prompt);
}
+11 -16
View File
@@ -1,7 +1,6 @@
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::widgets::ListItem;
use tui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::ListItem;
use ratatui::Frame;
use crate::app::App;
use crate::models::servarr_data::radarr::modals::EditMovieModal;
@@ -36,10 +35,10 @@ impl DrawUi for EditMovieUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, context_option) = *app.get_current_route() {
let draw_edit_movie_prompt =
|f: &mut Frame<'_, B>, app: &mut App<'_>, prompt_area: Rect| match active_radarr_block {
|f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| match active_radarr_block {
ActiveRadarrBlock::EditMovieSelectMinimumAvailability => {
draw_drop_down_popup(
f,
@@ -73,7 +72,7 @@ impl DrawUi for EditMovieUi {
draw_medium_popup_over(f, app, content_rect, draw_library, draw_edit_movie_prompt);
}
_ if MOVIE_DETAILS_BLOCKS.contains(&context) => {
draw_large_popup_over_background_fn_with_ui::<B, MovieDetailsUi>(
draw_large_popup_over_background_fn_with_ui::<MovieDetailsUi>(
f,
app,
content_rect,
@@ -88,11 +87,7 @@ impl DrawUi for EditMovieUi {
}
}
fn draw_edit_movie_confirmation_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_edit_movie_confirmation_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
let (movie_title, movie_overview) =
if let Some(filtered_movies) = app.data.radarr_data.filtered_movies.as_ref() {
(
@@ -216,8 +211,8 @@ fn draw_edit_movie_confirmation_prompt<B: Backend>(
);
}
fn draw_edit_movie_select_minimum_availability_popup<B: Backend>(
f: &mut Frame<'_, B>,
fn draw_edit_movie_select_minimum_availability_popup(
f: &mut Frame<'_>,
app: &mut App<'_>,
popup_area: Rect,
) {
@@ -235,8 +230,8 @@ fn draw_edit_movie_select_minimum_availability_popup<B: Backend>(
);
}
fn draw_edit_movie_select_quality_profile_popup<B: Backend>(
f: &mut Frame<'_, B>,
fn draw_edit_movie_select_quality_profile_popup(
f: &mut Frame<'_>,
app: &mut App<'_>,
popup_area: Rect,
) {
+10 -15
View File
@@ -1,7 +1,6 @@
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::widgets::{Cell, Row};
use tui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::radarr_models::Movie;
@@ -43,7 +42,7 @@ impl DrawUi for LibraryUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
let route = *app.get_current_route();
let mut library_ui_matchers = |active_radarr_block: ActiveRadarrBlock| match active_radarr_block
{
@@ -107,7 +106,7 @@ impl DrawUi for LibraryUi {
}
}
pub(super) fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
pub(super) fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let current_selection =
if let Some(filtered_movies) = app.data.radarr_data.filtered_movies.as_ref() {
filtered_movies.current_selection().clone()
@@ -206,11 +205,7 @@ pub(super) fn draw_library<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>,
);
}
fn draw_update_all_movies_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_update_all_movies_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -220,7 +215,7 @@ fn draw_update_all_movies_prompt<B: Backend>(
);
}
fn draw_movie_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_movie_search_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_input_box_popup(
f,
area,
@@ -229,7 +224,7 @@ fn draw_movie_search_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, ar
);
}
fn draw_filter_movies_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_filter_movies_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_input_box_popup(
f,
area,
@@ -238,10 +233,10 @@ fn draw_filter_movies_box<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, a
)
}
fn draw_search_movie_error_box<B: Backend>(f: &mut Frame<'_, B>, _: &mut App<'_>, area: Rect) {
fn draw_search_movie_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) {
draw_error_message_popup(f, area, "Movie not found!");
}
fn draw_filter_movies_error_box<B: Backend>(f: &mut Frame<'_, B>, _: &mut App<'_>, area: Rect) {
fn draw_filter_movies_error_box(f: &mut Frame<'_>, _: &mut App<'_>, area: Rect) {
draw_error_message_popup(f, area, "No movies found matching the given filter!");
}
+17 -30
View File
@@ -1,11 +1,10 @@
use std::iter;
use tui::backend::Backend;
use tui::layout::{Alignment, Constraint, Rect};
use tui::style::{Modifier, Style};
use tui::text::{Line, Span, Text};
use tui::widgets::{Cell, ListItem, Paragraph, Row, Wrap};
use tui::Frame;
use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span, Text};
use ratatui::widgets::{Cell, ListItem, Paragraph, Row, Wrap};
use ratatui::Frame;
use crate::app::App;
use crate::models::radarr_models::{Credit, MovieHistoryItem, Release, ReleaseField};
@@ -39,9 +38,9 @@ impl DrawUi for MovieDetailsUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, context_option) = *app.get_current_route() {
let draw_movie_info_popup = |f: &mut Frame<'_, B>, app: &mut App<'_>, popup_area: Rect| {
let draw_movie_info_popup = |f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| {
let (content_area, _) = draw_tabs(
f,
popup_area,
@@ -100,7 +99,7 @@ impl DrawUi for MovieDetailsUi {
}
}
fn draw_movie_info<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_movie_info(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
if let Route::Radarr(active_radarr_block, _) =
app.data.radarr_data.movie_info_tabs.get_active_route()
{
@@ -116,11 +115,7 @@ fn draw_movie_info<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Re
}
}
fn draw_search_movie_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_search_movie_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -134,11 +129,7 @@ fn draw_search_movie_prompt<B: Backend>(
);
}
fn draw_update_and_scan_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_update_and_scan_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -152,7 +143,7 @@ fn draw_update_and_scan_prompt<B: Backend>(
);
}
fn draw_file_info<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, content_area: Rect) {
fn draw_file_info(f: &mut Frame<'_>, app: &App<'_>, content_area: Rect) {
match app.data.radarr_data.movie_details_modal.as_ref() {
Some(movie_details_modal)
if !movie_details_modal.file_details.is_empty() && !app.is_loading =>
@@ -210,7 +201,7 @@ fn draw_file_info<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, content_area:
}
}
fn draw_movie_details<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, content_area: Rect) {
fn draw_movie_details(f: &mut Frame<'_>, app: &App<'_>, content_area: Rect) {
let block = layout_block_top_border();
match app.data.radarr_data.movie_details_modal.as_ref() {
@@ -253,7 +244,7 @@ fn draw_movie_details<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, content_a
}
}
fn draw_movie_history<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_area: Rect) {
fn draw_movie_history(f: &mut Frame<'_>, app: &mut App<'_>, content_area: Rect) {
if let Some(movie_details_modal) = app.data.radarr_data.movie_details_modal.as_mut() {
let current_selection = if movie_details_modal.movie_history.items.is_empty() {
MovieHistoryItem::default()
@@ -321,7 +312,7 @@ fn draw_movie_history<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, conte
}
}
fn draw_movie_cast<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_area: Rect) {
fn draw_movie_cast(f: &mut Frame<'_>, app: &mut App<'_>, content_area: Rect) {
draw_table(
f,
content_area,
@@ -363,7 +354,7 @@ fn draw_movie_cast<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_
);
}
fn draw_movie_crew<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_area: Rect) {
fn draw_movie_crew(f: &mut Frame<'_>, app: &mut App<'_>, content_area: Rect) {
draw_table(
f,
content_area,
@@ -407,7 +398,7 @@ fn draw_movie_crew<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_
);
}
fn draw_movie_releases<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_area: Rect) {
fn draw_movie_releases(f: &mut Frame<'_>, app: &mut App<'_>, content_area: Rect) {
let (current_selection, is_empty, sort_ascending) =
match app.data.radarr_data.movie_details_modal.as_ref() {
Some(movie_details_modal) if !movie_details_modal.movie_releases.items.is_empty() => (
@@ -549,11 +540,7 @@ fn draw_movie_releases<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, cont
);
}
fn draw_manual_search_confirm_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_manual_search_confirm_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
let current_selection = app
.data
.radarr_data
+10 -11
View File
@@ -1,12 +1,11 @@
use std::iter;
use chrono::{Duration, Utc};
use tui::backend::Backend;
use tui::layout::{Alignment, Constraint, Rect};
use tui::style::{Color, Style};
use tui::text::Text;
use tui::widgets::Paragraph;
use tui::Frame;
use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::style::{Color, Style};
use ratatui::text::Text;
use ratatui::widgets::Paragraph;
use ratatui::Frame;
use crate::app::App;
use crate::logos::RADARR_LOGO;
@@ -48,7 +47,7 @@ impl DrawUi for RadarrUi {
matches!(route, Route::Radarr(_, _))
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let (content_rect, _) = draw_tabs(f, area, "Movies", &app.data.radarr_data.main_tabs);
let route = *app.get_current_route();
@@ -63,7 +62,7 @@ impl DrawUi for RadarrUi {
}
}
fn draw_context_row<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, area: Rect) {
fn draw_context_row(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
let chunks = horizontal_chunks(vec![Constraint::Min(0), Constraint::Length(20)], area);
let context_chunks = horizontal_chunks(
@@ -77,7 +76,7 @@ impl DrawUi for RadarrUi {
}
}
fn draw_stats_context<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, area: Rect) {
fn draw_stats_context(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
let block = title_block("Stats");
if !app.data.radarr_data.version.is_empty() {
@@ -169,7 +168,7 @@ fn draw_stats_context<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, area: Rec
}
}
fn draw_downloads_context<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, area: Rect) {
fn draw_downloads_context(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
let block = title_block("Downloads");
let downloads_vec = &app.data.radarr_data.downloads.items;
@@ -224,7 +223,7 @@ fn determine_row_style(downloads_vec: &[DownloadRecord], movie: &Movie) -> Style
}
}
fn draw_radarr_logo<B: Backend>(f: &mut Frame<'_, B>, area: Rect) {
fn draw_radarr_logo(f: &mut Frame<'_>, area: Rect) {
let mut logo_text = Text::from(RADARR_LOGO);
logo_text.patch_style(Style::default().fg(Color::LightYellow));
let logo = Paragraph::new(logo_text)
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::ui::utils::{style_default, style_failure, style_secondary};
use tui::style::{Color, Modifier, Style};
use ratatui::style::{Color, Modifier, Style};
#[cfg(test)]
#[path = "radarr_ui_utils_tests.rs"]
+7 -16
View File
@@ -1,7 +1,6 @@
use tui::backend::Backend;
use tui::layout::{Constraint, Rect};
use tui::widgets::{Cell, Row};
use tui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::radarr_models::RootFolder;
@@ -29,7 +28,7 @@ impl DrawUi for RootFoldersUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
match active_radarr_block {
ActiveRadarrBlock::RootFolders => draw_root_folders(f, app, content_rect),
@@ -55,7 +54,7 @@ impl DrawUi for RootFoldersUi {
}
}
fn draw_root_folders<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_root_folders(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_table(
f,
area,
@@ -103,11 +102,7 @@ fn draw_root_folders<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area:
);
}
fn draw_add_root_folder_prompt_box<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
area: Rect,
) {
fn draw_add_root_folder_prompt_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_input_box_popup(
f,
area,
@@ -116,11 +111,7 @@ fn draw_add_root_folder_prompt_box<B: Backend>(
);
}
fn draw_delete_root_folder_prompt<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
prompt_area: Rect,
) {
fn draw_delete_root_folder_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
+10 -15
View File
@@ -1,11 +1,10 @@
use std::ops::Sub;
use chrono::Utc;
use tui::layout::Alignment;
use tui::text::{Span, Text};
use tui::widgets::{Cell, Paragraph, Row};
use tui::{
backend::Backend,
use ratatui::layout::Alignment;
use ratatui::text::{Span, Text};
use ratatui::widgets::{Cell, Paragraph, Row};
use ratatui::{
layout::{Constraint, Rect},
widgets::ListItem,
Frame,
@@ -62,7 +61,7 @@ impl DrawUi for SystemUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
let route = *app.get_current_route();
match route {
@@ -75,11 +74,7 @@ impl DrawUi for SystemUi {
}
}
pub(super) fn draw_system_ui_layout<B: Backend>(
f: &mut Frame<'_, B>,
app: &mut App<'_>,
area: Rect,
) {
pub(super) fn draw_system_ui_layout(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let vertical_chunks = vertical_chunks(
vec![
Constraint::Ratio(1, 2),
@@ -100,7 +95,7 @@ pub(super) fn draw_system_ui_layout<B: Backend>(
draw_help(f, app, vertical_chunks[2]);
}
fn draw_tasks<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_tasks(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_table(
f,
area,
@@ -129,7 +124,7 @@ fn draw_tasks<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
);
}
pub(super) fn draw_queued_events<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
pub(super) fn draw_queued_events(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_table(
f,
area,
@@ -189,7 +184,7 @@ pub(super) fn draw_queued_events<B: Backend>(f: &mut Frame<'_, B>, app: &mut App
);
}
fn draw_logs<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_logs(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_list_box(
f,
area,
@@ -210,7 +205,7 @@ fn draw_logs<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
);
}
fn draw_help<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_help(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let mut help_text = Text::from(format!(
" {}",
app
+10 -11
View File
@@ -1,8 +1,7 @@
use tui::backend::Backend;
use tui::layout::Rect;
use tui::text::{Span, Text};
use tui::widgets::{Cell, ListItem, Paragraph, Row};
use tui::Frame;
use ratatui::layout::Rect;
use ratatui::text::{Span, Text};
use ratatui::widgets::{Cell, ListItem, Paragraph, Row};
use ratatui::Frame;
use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CLUES};
use crate::app::radarr::radarr_context_clues::SYSTEM_TASKS_CONTEXT_CLUES;
@@ -35,7 +34,7 @@ impl DrawUi for SystemDetailsUi {
false
}
fn draw<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, content_rect: Rect) {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, content_rect: Rect) {
if let Route::Radarr(active_radarr_block, _) = *app.get_current_route() {
match active_radarr_block {
ActiveRadarrBlock::SystemLogs => {
@@ -70,7 +69,7 @@ impl DrawUi for SystemDetailsUi {
}
}
fn draw_logs_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_logs_popup(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_list_box(
f,
area,
@@ -94,8 +93,8 @@ fn draw_logs_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Re
);
}
fn draw_tasks_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
let tasks_popup_table = |f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect| {
fn draw_tasks_popup(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let tasks_popup_table = |f: &mut Frame<'_>, app: &mut App<'_>, area: Rect| {
f.render_widget(title_block("Tasks"), area);
let context_area = draw_help_and_get_content_rect(
@@ -142,7 +141,7 @@ fn draw_tasks_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: R
}
}
fn draw_start_task_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, prompt_area: Rect) {
fn draw_start_task_prompt(f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect) {
draw_prompt_box(
f,
prompt_area,
@@ -156,7 +155,7 @@ fn draw_start_task_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, p
);
}
fn draw_updates_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
fn draw_updates_popup(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
f.render_widget(title_block("Updates"), area);
let content_rect = draw_help_and_get_content_rect(