test: Updated Rust edition to 2024 and refactored network module tests to be more idiomatic

This commit is contained in:
2025-12-03 14:49:27 -07:00
parent c4e8d64710
commit ad58912baf
257 changed files with 4033 additions and 4380 deletions
@@ -1,8 +1,8 @@
#[cfg(test)]
mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, BLOCKLIST_BLOCKS};
use crate::ui::sonarr_ui::blocklist::BlocklistUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::blocklist::BlocklistUi;
use strum::IntoEnumIterator;
#[test]
+3 -3
View File
@@ -1,19 +1,19 @@
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, BLOCKLIST_BLOCKS};
use crate::models::sonarr_models::BlocklistItem;
use crate::models::Route;
use crate::ui::DrawUi;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::layout_block_top_border;
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::message::Message;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::DrawUi;
use ratatui::Frame;
use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::text::{Line, Text};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
#[cfg(test)]
#[path = "blocklist_ui_tests.rs"]
@@ -3,8 +3,8 @@ mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS};
use crate::ui::sonarr_ui::downloads::DownloadsUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::downloads::DownloadsUi;
#[test]
fn test_downloads_ui_accepts() {
+2 -2
View File
@@ -1,17 +1,17 @@
use ratatui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS};
use crate::models::sonarr_models::DownloadRecord;
use crate::models::{HorizontallyScrollableText, Route};
use crate::ui::DrawUi;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::DrawUi;
use crate::utils::convert_f64_to_gb;
#[cfg(test)]
+1 -1
View File
@@ -1,8 +1,8 @@
#[cfg(test)]
mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS};
use crate::ui::sonarr_ui::history::HistoryUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::history::HistoryUi;
use strum::IntoEnumIterator;
#[test]
+3 -3
View File
@@ -1,18 +1,18 @@
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS};
use crate::models::sonarr_models::{SonarrHistoryEventType, SonarrHistoryItem};
use crate::models::Route;
use crate::ui::DrawUi;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::message::Message;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::DrawUi;
use ratatui::Frame;
use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::style::Style;
use ratatui::text::Text;
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use super::sonarr_ui_utils::{
create_download_failed_history_event_details,
+17 -12
View File
@@ -1,8 +1,8 @@
use std::sync::atomic::Ordering;
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS};
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS};
use crate::render_selectable_input_box;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::title_block_centered;
@@ -11,9 +11,9 @@ use crate::ui::widgets::checkbox::Checkbox;
use crate::ui::widgets::input_box::InputBox;
use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::widgets::popup::Size;
use crate::ui::{draw_popup, DrawUi};
use ratatui::layout::{Constraint, Flex, Layout, Rect};
use crate::ui::{DrawUi, draw_popup};
use ratatui::Frame;
use ratatui::layout::{Constraint, Flex, Layout, Rect};
#[cfg(test)]
#[path = "edit_indexer_ui_tests.rs"]
@@ -55,15 +55,20 @@ fn draw_edit_indexer_prompt(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
Layout::horizontal([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)])
.margin(1)
.areas(settings_area);
let [name_area, rss_area, auto_search_area, interactive_search_area, priority_area] =
Layout::vertical([
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
])
.areas(left_side_area);
let [
name_area,
rss_area,
auto_search_area,
interactive_search_area,
priority_area,
] = Layout::vertical([
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
])
.areas(left_side_area);
let [url_area, api_key_area, seed_ratio_area, tags_area] = Layout::vertical([
Constraint::Length(3),
Constraint::Length(3),
@@ -1,8 +1,8 @@
#[cfg(test)]
mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS};
use crate::ui::sonarr_ui::indexers::edit_indexer_ui::EditIndexerUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::edit_indexer_ui::EditIndexerUi;
use strum::IntoEnumIterator;
#[test]
@@ -1,11 +1,11 @@
use ratatui::layout::{Constraint, Flex, Layout, Rect};
use ratatui::Frame;
use ratatui::layout::{Constraint, Flex, Layout, Rect};
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, INDEXER_SETTINGS_BLOCKS,
};
use crate::models::Route;
use crate::render_selectable_input_box;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::title_block_centered;
@@ -13,7 +13,7 @@ use crate::ui::widgets::button::Button;
use crate::ui::widgets::input_box::InputBox;
use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::widgets::popup::Size;
use crate::ui::{draw_popup, DrawUi};
use crate::ui::{DrawUi, draw_popup};
#[cfg(test)]
#[path = "indexer_settings_ui_tests.rs"]
@@ -46,18 +46,25 @@ fn draw_edit_indexer_settings_prompt(f: &mut Frame<'_>, app: &mut App<'_>, area:
f.render_widget(block, area);
let indexer_settings = indexer_settings_option.as_ref().unwrap();
let [_, min_age_area, retention_area, max_size_area, rss_sync_area, _, buttons_area] =
Layout::vertical([
Constraint::Fill(1),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Fill(1),
Constraint::Length(3),
])
.margin(1)
.areas(area);
let [
_,
min_age_area,
retention_area,
max_size_area,
rss_sync_area,
_,
buttons_area,
] = Layout::vertical([
Constraint::Fill(1),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Fill(1),
Constraint::Length(3),
])
.margin(1)
.areas(area);
if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() {
let min_age = indexer_settings.minimum_age.to_string();
@@ -5,8 +5,8 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, INDEXER_SETTINGS_BLOCKS,
};
use crate::ui::sonarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi;
#[test]
fn test_indexer_settings_ui_accepts() {
@@ -3,10 +3,10 @@ mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EDIT_INDEXER_BLOCKS, INDEXERS_BLOCKS, INDEXER_SETTINGS_BLOCKS,
ActiveSonarrBlock, EDIT_INDEXER_BLOCKS, INDEXER_SETTINGS_BLOCKS, INDEXERS_BLOCKS,
};
use crate::ui::sonarr_ui::indexers::IndexersUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::IndexersUi;
#[test]
fn test_indexers_ui_accepts() {
+3 -3
View File
@@ -1,13 +1,14 @@
use ratatui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::text::Text;
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, INDEXERS_BLOCKS};
use crate::models::servarr_models::Indexer;
use crate::models::Route;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::edit_indexer_ui::EditIndexerUi;
use crate::ui::sonarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi;
use crate::ui::sonarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi;
@@ -18,7 +19,6 @@ use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::message::Message;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::DrawUi;
mod edit_indexer_ui;
mod indexer_settings_ui;
@@ -1,15 +1,15 @@
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::modals::IndexerTestResultModalItem;
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
use crate::models::Route;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::{get_width_from_percentage, title_block};
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::popup::Size;
use crate::ui::{draw_popup, DrawUi};
use crate::ui::{DrawUi, draw_popup};
use ratatui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
#[cfg(test)]
#[path = "test_all_indexers_ui_tests.rs"]
@@ -3,8 +3,8 @@ mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
use crate::ui::sonarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi;
#[test]
fn test_test_all_indexers_ui_accepts() {
+31 -21
View File
@@ -1,13 +1,13 @@
use std::sync::atomic::Ordering;
use ratatui::Frame;
use ratatui::layout::{Constraint, Layout, Rect};
use ratatui::widgets::{Cell, ListItem, Row};
use ratatui::Frame;
use crate::models::servarr_data::sonarr::modals::AddSeriesModal;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ADD_SERIES_BLOCKS};
use crate::models::sonarr_models::AddSeriesSearchResult;
use crate::models::Route;
use crate::models::servarr_data::sonarr::modals::AddSeriesModal;
use crate::models::servarr_data::sonarr::sonarr_data::{ADD_SERIES_BLOCKS, ActiveSonarrBlock};
use crate::models::sonarr_models::AddSeriesSearchResult;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::{
get_width_from_percentage, layout_block, layout_paragraph_borderless, title_block_centered,
@@ -19,8 +19,8 @@ use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::message::Message;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::widgets::selectable_list::SelectableList;
use crate::ui::{draw_popup, DrawUi};
use crate::{render_selectable_input_box, App};
use crate::ui::{DrawUi, draw_popup};
use crate::{App, render_selectable_input_box};
#[cfg(test)]
#[path = "add_series_ui_tests.rs"]
@@ -272,21 +272,31 @@ fn draw_confirmation_prompt(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
f.render_widget(title_block_centered(&title), area);
let [paragraph_area, root_folder_area, monitor_area, quality_profile_area, language_profile_area, series_type_area, season_folder_area, tags_area, _, buttons_area] =
Layout::vertical([
Constraint::Length(6),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Fill(1),
Constraint::Length(3),
])
.margin(1)
.areas(area);
let [
paragraph_area,
root_folder_area,
monitor_area,
quality_profile_area,
language_profile_area,
series_type_area,
season_folder_area,
tags_area,
_,
buttons_area,
] = Layout::vertical([
Constraint::Length(6),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Fill(1),
Constraint::Length(3),
])
.margin(1)
.areas(area);
let prompt_paragraph = layout_paragraph_borderless(&prompt);
f.render_widget(prompt_paragraph, paragraph_area);
@@ -2,9 +2,9 @@
mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ADD_SERIES_BLOCKS};
use crate::ui::sonarr_ui::library::add_series_ui::AddSeriesUi;
use crate::models::servarr_data::sonarr::sonarr_data::{ADD_SERIES_BLOCKS, ActiveSonarrBlock};
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::add_series_ui::AddSeriesUi;
#[test]
fn test_add_series_ui_accepts() {
+3 -3
View File
@@ -1,13 +1,13 @@
use ratatui::layout::Rect;
use ratatui::Frame;
use ratatui::layout::Rect;
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DELETE_SERIES_BLOCKS};
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DELETE_SERIES_BLOCKS};
use crate::ui::DrawUi;
use crate::ui::widgets::checkbox::Checkbox;
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::DrawUi;
#[cfg(test)]
#[path = "delete_series_ui_tests.rs"]
@@ -3,8 +3,8 @@ mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DELETE_SERIES_BLOCKS};
use crate::ui::sonarr_ui::library::delete_series_ui::DeleteSeriesUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::delete_series_ui::DeleteSeriesUi;
#[test]
fn test_delete_series_ui_accepts() {
+32 -22
View File
@@ -1,16 +1,16 @@
use std::sync::atomic::Ordering;
use ratatui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::prelude::Layout;
use ratatui::widgets::ListItem;
use ratatui::Frame;
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::modals::EditSeriesModal;
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EDIT_SERIES_BLOCKS, SERIES_DETAILS_BLOCKS,
};
use crate::models::Route;
use crate::render_selectable_input_box;
use crate::ui::styles::ManagarrStyle;
@@ -20,7 +20,7 @@ use crate::ui::widgets::checkbox::Checkbox;
use crate::ui::widgets::input_box::InputBox;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::widgets::selectable_list::SelectableList;
use crate::ui::{draw_popup, DrawUi};
use crate::ui::{DrawUi, draw_popup};
use super::series_details_ui::SeriesDetailsUi;
@@ -41,10 +41,10 @@ impl DrawUi for EditSeriesUi {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) {
if let Route::Sonarr(active_sonarr_block, context_option) = app.get_current_route() {
if let Some(context) = context_option {
if SERIES_DETAILS_BLOCKS.contains(&context) {
draw_popup(f, app, SeriesDetailsUi::draw, Size::Large);
}
if let Some(context) = context_option
&& SERIES_DETAILS_BLOCKS.contains(&context)
{
draw_popup(f, app, SeriesDetailsUi::draw, Size::Large);
}
let draw_edit_series_prompt = |f: &mut Frame<'_>, app: &mut App<'_>, prompt_area: Rect| {
@@ -105,21 +105,31 @@ fn draw_edit_series_confirmation_prompt(f: &mut Frame<'_>, app: &mut App<'_>, ar
let selected_quality_profile = quality_profile_list.current_selection();
let selected_language_profile = language_profile_list.current_selection();
let [paragraph_area, monitored_area, season_folder_area, quality_profile_area, language_profile_area, series_type_area, path_area, tags_area, _, buttons_area] =
Layout::vertical([
Constraint::Length(6),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Fill(1),
Constraint::Length(3),
])
.margin(1)
.areas(area);
let [
paragraph_area,
monitored_area,
season_folder_area,
quality_profile_area,
language_profile_area,
series_type_area,
path_area,
tags_area,
_,
buttons_area,
] = Layout::vertical([
Constraint::Length(6),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Fill(1),
Constraint::Length(3),
])
.margin(1)
.areas(area);
let [save_area, cancel_area] =
Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
.areas(buttons_area);
@@ -3,8 +3,8 @@ mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_SERIES_BLOCKS};
use crate::ui::sonarr_ui::library::edit_series_ui::EditSeriesUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::edit_series_ui::EditSeriesUi;
#[test]
fn test_edit_series_ui_accepts() {
+89 -79
View File
@@ -1,9 +1,9 @@
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS};
use crate::models::sonarr_models::{
DownloadRecord, DownloadStatus, Episode, SonarrHistoryEventType, SonarrHistoryItem, SonarrRelease,
};
use crate::models::Route;
use crate::ui::sonarr_ui::sonarr_ui_utils::{
create_download_failed_history_event_details,
create_download_folder_imported_history_event_details,
@@ -21,14 +21,14 @@ use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::message::Message;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::{draw_popup, draw_tabs, DrawUi};
use crate::ui::{DrawUi, draw_popup, draw_tabs};
use crate::utils::convert_to_gb;
use chrono::Utc;
use ratatui::Frame;
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::text::{Line, Span, Text};
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
use ratatui::Frame;
use serde_json::Number;
#[cfg(test)]
@@ -47,76 +47,80 @@ impl DrawUi for EpisodeDetailsUi {
}
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) {
if let Some(season_details_modal) = app.data.sonarr_data.season_details_modal.as_ref() {
if season_details_modal.episode_details_modal.is_some() {
if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() {
let draw_episode_details_popup =
|f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| {
let content_area = draw_tabs(
f,
popup_area,
"Episode Details",
&app
.data
.sonarr_data
.season_details_modal
.as_ref()
.unwrap()
.episode_details_modal
.as_ref()
.unwrap()
.episode_details_tabs,
);
draw_episode_details_tabs(f, app, content_area);
if let Some(season_details_modal) = app.data.sonarr_data.season_details_modal.as_ref()
&& season_details_modal.episode_details_modal.is_some()
&& let Route::Sonarr(active_sonarr_block, _) = app.get_current_route()
{
let draw_episode_details_popup = |f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| {
let content_area = draw_tabs(
f,
popup_area,
"Episode Details",
&app
.data
.sonarr_data
.season_details_modal
.as_ref()
.unwrap()
.episode_details_modal
.as_ref()
.unwrap()
.episode_details_tabs,
);
draw_episode_details_tabs(f, app, content_area);
match active_sonarr_block {
ActiveSonarrBlock::AutomaticallySearchEpisodePrompt => {
let prompt = format!(
"Do you want to trigger an automatic search of your indexers for the episode: {}",
app.data.sonarr_data.season_details_modal.as_ref().unwrap().episodes.current_selection().title
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Automatic Episode Search")
.prompt(&prompt)
.yes_no_value(app.data.sonarr_data.prompt_confirm);
match active_sonarr_block {
ActiveSonarrBlock::AutomaticallySearchEpisodePrompt => {
let prompt = format!(
"Do you want to trigger an automatic search of your indexers for the episode: {}",
app
.data
.sonarr_data
.season_details_modal
.as_ref()
.unwrap()
.episodes
.current_selection()
.title
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Automatic Episode Search")
.prompt(&prompt)
.yes_no_value(app.data.sonarr_data.prompt_confirm);
f.render_widget(
Popup::new(confirmation_prompt).size(Size::MediumPrompt),
f.area(),
);
}
ActiveSonarrBlock::ManualEpisodeSearchConfirmPrompt => {
draw_manual_episode_search_confirm_prompt(f, app);
}
ActiveSonarrBlock::EpisodeHistoryDetails => {
draw_history_item_details_popup(f, app, popup_area);
}
_ => (),
}
};
draw_popup(f, app, draw_episode_details_popup, Size::Large);
f.render_widget(
Popup::new(confirmation_prompt).size(Size::MediumPrompt),
f.area(),
);
}
ActiveSonarrBlock::ManualEpisodeSearchConfirmPrompt => {
draw_manual_episode_search_confirm_prompt(f, app);
}
ActiveSonarrBlock::EpisodeHistoryDetails => {
draw_history_item_details_popup(f, app, popup_area);
}
_ => (),
}
}
};
draw_popup(f, app, draw_episode_details_popup, Size::Large);
}
}
}
pub fn draw_episode_details_tabs(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
if let Some(season_details_modal) = app.data.sonarr_data.season_details_modal.as_ref() {
if let Some(episode_details_modal) = season_details_modal.episode_details_modal.as_ref() {
if let Route::Sonarr(active_sonarr_block, _) = episode_details_modal
.episode_details_tabs
.get_active_route()
{
match active_sonarr_block {
ActiveSonarrBlock::EpisodeDetails => draw_episode_details(f, app, area),
ActiveSonarrBlock::EpisodeHistory => draw_episode_history_table(f, app, area),
ActiveSonarrBlock::EpisodeFile => draw_file_info(f, app, area),
ActiveSonarrBlock::ManualEpisodeSearch => draw_episode_releases(f, app, area),
_ => (),
}
}
if let Some(season_details_modal) = app.data.sonarr_data.season_details_modal.as_ref()
&& let Some(episode_details_modal) = season_details_modal.episode_details_modal.as_ref()
&& let Route::Sonarr(active_sonarr_block, _) = episode_details_modal
.episode_details_tabs
.get_active_route()
{
match active_sonarr_block {
ActiveSonarrBlock::EpisodeDetails => draw_episode_details(f, app, area),
ActiveSonarrBlock::EpisodeHistory => draw_episode_history_table(f, app, area),
ActiveSonarrBlock::EpisodeFile => draw_file_info(f, app, area),
ActiveSonarrBlock::ManualEpisodeSearch => draw_episode_releases(f, app, area),
_ => (),
}
}
}
@@ -197,16 +201,22 @@ fn draw_file_info(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
let file_info = episode_details_modal.file_details.to_owned();
let audio_details = episode_details_modal.audio_details.to_owned();
let video_details = episode_details_modal.video_details.to_owned();
let [file_details_title_area, file_details_area, audio_details_title_area, audio_details_area, video_details_title_area, video_details_area] =
Layout::vertical([
Constraint::Length(2),
Constraint::Length(5),
Constraint::Length(1),
Constraint::Length(6),
Constraint::Length(1),
Constraint::Length(7),
])
.areas(area);
let [
file_details_title_area,
file_details_area,
audio_details_title_area,
audio_details_area,
video_details_title_area,
video_details_area,
] = Layout::vertical([
Constraint::Length(2),
Constraint::Length(5),
Constraint::Length(1),
Constraint::Length(6),
Constraint::Length(1),
Constraint::Length(7),
])
.areas(area);
let file_details_title_paragraph =
Paragraph::new("File Details".bold()).block(layout_block_top_border());
@@ -593,10 +603,10 @@ fn style_from_status(download: Option<&DownloadRecord>, episode: &Episode) -> St
return Style::new().unmonitored_missing();
}
if let Some(air_date) = episode.air_date_utc.as_ref() {
if air_date > &Utc::now() {
return Style::new().unreleased();
}
if let Some(air_date) = episode.air_date_utc.as_ref()
&& air_date > &Utc::now()
{
return Style::new().unreleased();
}
return Style::new().missing();
@@ -3,8 +3,8 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS,
};
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
use strum::IntoEnumIterator;
#[test]
+4 -4
View File
@@ -1,15 +1,15 @@
#[cfg(test)]
mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, ADD_SERIES_BLOCKS, DELETE_SERIES_BLOCKS, EDIT_SERIES_BLOCKS,
ADD_SERIES_BLOCKS, ActiveSonarrBlock, DELETE_SERIES_BLOCKS, EDIT_SERIES_BLOCKS,
EPISODE_DETAILS_BLOCKS, SEASON_DETAILS_BLOCKS, SERIES_DETAILS_BLOCKS,
};
use crate::models::{
servarr_data::sonarr::sonarr_data::LIBRARY_BLOCKS, sonarr_models::SeriesStatus,
};
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::LibraryUi;
use crate::ui::styles::ManagarrStyle;
use crate::ui::DrawUi;
use pretty_assertions::assert_eq;
use ratatui::widgets::{Cell, Row};
use strum::IntoEnumIterator;
@@ -134,8 +134,8 @@ mod tests {
}
#[test]
fn test_decorate_row_with_style_unreleased_when_continuing_and_all_monitored_episodes_are_present(
) {
fn test_decorate_row_with_style_unreleased_when_continuing_and_all_monitored_episodes_are_present()
{
let seasons = vec![
Season {
monitored: false,
+3 -3
View File
@@ -2,9 +2,9 @@ use add_series_ui::AddSeriesUi;
use delete_series_ui::DeleteSeriesUi;
use edit_series_ui::EditSeriesUi;
use ratatui::{
Frame,
layout::{Constraint, Rect},
widgets::{Cell, Row},
Frame,
};
use series_details_ui::SeriesDetailsUi;
@@ -16,15 +16,15 @@ use crate::utils::convert_to_gb;
use crate::{
app::App,
models::{
Route,
servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, LIBRARY_BLOCKS},
sonarr_models::{Series, SeriesStatus},
Route,
},
ui::{
DrawUi,
styles::ManagarrStyle,
utils::{get_width_from_percentage, layout_block_top_border},
widgets::managarr_table::ManagarrTable,
DrawUi,
},
};
+92 -86
View File
@@ -1,9 +1,9 @@
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SEASON_DETAILS_BLOCKS};
use crate::models::sonarr_models::{
DownloadRecord, DownloadStatus, Episode, SonarrHistoryEventType, SonarrHistoryItem, SonarrRelease,
};
use crate::models::Route;
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
use crate::ui::sonarr_ui::sonarr_ui_utils::{
create_download_failed_history_event_details,
@@ -21,13 +21,13 @@ use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::message::Message;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::{draw_popup, draw_tabs, DrawUi};
use crate::ui::{DrawUi, draw_popup, draw_tabs};
use crate::utils::convert_to_gb;
use chrono::Utc;
use ratatui::Frame;
use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::prelude::{Line, Style, Stylize, Text};
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
use ratatui::Frame;
use serde_json::Number;
#[cfg(test)]
@@ -48,101 +48,107 @@ impl DrawUi for SeasonDetailsUi {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) {
let route = app.get_current_route();
if app.data.sonarr_data.season_details_modal.is_some() {
if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() {
let draw_season_details_popup = |f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| {
let content_area = draw_tabs(
f,
popup_area,
&format!(
"Season {} Details",
if app.data.sonarr_data.season_details_modal.is_some()
&& let Route::Sonarr(active_sonarr_block, _) = app.get_current_route()
{
let draw_season_details_popup = |f: &mut Frame<'_>, app: &mut App<'_>, popup_area: Rect| {
let content_area = draw_tabs(
f,
popup_area,
&format!(
"Season {} Details",
app
.data
.sonarr_data
.seasons
.current_selection()
.season_number
),
&app
.data
.sonarr_data
.season_details_modal
.as_ref()
.unwrap()
.season_details_tabs,
);
draw_season_details(f, app, content_area);
match active_sonarr_block {
ActiveSonarrBlock::AutomaticallySearchSeasonPrompt => {
let prompt = format!(
"Do you want to trigger an automatic search of your indexers for season packs for: {}",
app
.data
.sonarr_data
.seasons
.current_selection()
.season_number
),
&app
.data
.sonarr_data
.season_details_modal
.as_ref()
.unwrap()
.season_details_tabs,
);
draw_season_details(f, app, content_area);
.title
.as_ref()
.unwrap()
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Automatic Season Search")
.prompt(&prompt)
.yes_no_value(app.data.sonarr_data.prompt_confirm);
match active_sonarr_block {
ActiveSonarrBlock::AutomaticallySearchSeasonPrompt => {
let prompt = format!(
"Do you want to trigger an automatic search of your indexers for season packs for: {}",
app.data.sonarr_data.seasons.current_selection().title.as_ref().unwrap()
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Automatic Season Search")
.prompt(&prompt)
.yes_no_value(app.data.sonarr_data.prompt_confirm);
f.render_widget(
Popup::new(confirmation_prompt).size(Size::MediumPrompt),
f.area(),
);
}
ActiveSonarrBlock::DeleteEpisodeFilePrompt => {
let prompt = format!(
"Do you really want to delete this episode: \n{}?",
app
.data
.sonarr_data
.season_details_modal
.as_ref()
.unwrap()
.episodes
.current_selection()
.title
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Delete Episode")
.prompt(&prompt)
.yes_no_value(app.data.sonarr_data.prompt_confirm);
f.render_widget(
Popup::new(confirmation_prompt).size(Size::MediumPrompt),
f.area(),
);
}
ActiveSonarrBlock::ManualSeasonSearchConfirmPrompt => {
draw_manual_season_search_confirm_prompt(f, app);
}
ActiveSonarrBlock::SeasonHistoryDetails => {
draw_history_item_details_popup(f, app, popup_area);
}
_ => (),
f.render_widget(
Popup::new(confirmation_prompt).size(Size::MediumPrompt),
f.area(),
);
}
};
ActiveSonarrBlock::DeleteEpisodeFilePrompt => {
let prompt = format!(
"Do you really want to delete this episode: \n{}?",
app
.data
.sonarr_data
.season_details_modal
.as_ref()
.unwrap()
.episodes
.current_selection()
.title
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Delete Episode")
.prompt(&prompt)
.yes_no_value(app.data.sonarr_data.prompt_confirm);
draw_popup(f, app, draw_season_details_popup, Size::XLarge);
if EpisodeDetailsUi::accepts(route) {
EpisodeDetailsUi::draw(f, app, _area);
f.render_widget(
Popup::new(confirmation_prompt).size(Size::MediumPrompt),
f.area(),
);
}
ActiveSonarrBlock::ManualSeasonSearchConfirmPrompt => {
draw_manual_season_search_confirm_prompt(f, app);
}
ActiveSonarrBlock::SeasonHistoryDetails => {
draw_history_item_details_popup(f, app, popup_area);
}
_ => (),
}
};
draw_popup(f, app, draw_season_details_popup, Size::XLarge);
if EpisodeDetailsUi::accepts(route) {
EpisodeDetailsUi::draw(f, app, _area);
}
}
}
}
pub fn draw_season_details(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
if let Some(season_details_modal) = app.data.sonarr_data.season_details_modal.as_ref() {
if let Route::Sonarr(active_sonarr_block, _) =
if let Some(season_details_modal) = app.data.sonarr_data.season_details_modal.as_ref()
&& let Route::Sonarr(active_sonarr_block, _) =
season_details_modal.season_details_tabs.get_active_route()
{
match active_sonarr_block {
ActiveSonarrBlock::SeasonDetails => draw_episodes_table(f, app, area),
ActiveSonarrBlock::SeasonHistory => draw_season_history_table(f, app, area),
ActiveSonarrBlock::ManualSeasonSearch => draw_season_releases(f, app, area),
_ => (),
}
{
match active_sonarr_block {
ActiveSonarrBlock::SeasonDetails => draw_episodes_table(f, app, area),
ActiveSonarrBlock::SeasonHistory => draw_season_history_table(f, app, area),
ActiveSonarrBlock::ManualSeasonSearch => draw_season_releases(f, app, area),
_ => (),
}
}
}
@@ -588,10 +594,10 @@ fn decorate_with_row_style<'a>(
return row.unmonitored_missing();
}
if let Some(air_date) = episode.air_date_utc.as_ref() {
if air_date > &Utc::now() {
return row.unreleased();
}
if let Some(air_date) = episode.air_date_utc.as_ref()
&& air_date > &Utc::now()
{
return row.unreleased();
}
return row.missing();
@@ -5,8 +5,8 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS, SEASON_DETAILS_BLOCKS,
};
use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi;
#[test]
fn test_season_details_ui_accepts() {
@@ -1,18 +1,18 @@
use chrono::Utc;
use deunicode::deunicode;
use ratatui::Frame;
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
use ratatui::style::{Style, Stylize};
use ratatui::text::{Line, Text};
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
use ratatui::Frame;
use regex::Regex;
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SERIES_DETAILS_BLOCKS};
use crate::models::sonarr_models::{
Season, SeasonStatistics, SonarrHistoryEventType, SonarrHistoryItem,
};
use crate::models::Route;
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi;
use crate::ui::sonarr_ui::sonarr_ui_utils::{
@@ -31,7 +31,7 @@ use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::message::Message;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::{draw_popup, draw_tabs, DrawUi};
use crate::ui::{DrawUi, draw_popup, draw_tabs};
use crate::utils::convert_to_gb;
#[cfg(test)]
@@ -75,7 +75,8 @@ impl DrawUi for SeriesDetailsUi {
match active_sonarr_block {
ActiveSonarrBlock::AutomaticallySearchSeriesPrompt => {
let prompt = format!(
"Do you want to trigger an automatic search of your indexers for all monitored episode(s) for the series: {}", app.data.sonarr_data.series.current_selection().title
"Do you want to trigger an automatic search of your indexers for all monitored episode(s) for the series: {}",
app.data.sonarr_data.series.current_selection().title
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Automatic Series Search")
@@ -5,8 +5,8 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS, SEASON_DETAILS_BLOCKS, SERIES_DETAILS_BLOCKS,
};
use crate::ui::sonarr_ui::library::series_details_ui::SeriesDetailsUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::series_details_ui::SeriesDetailsUi;
#[test]
fn test_series_details_ui_accepts() {
+3 -4
View File
@@ -7,11 +7,11 @@ use history::HistoryUi;
use indexers::IndexersUi;
use library::LibraryUi;
use ratatui::{
Frame,
layout::{Constraint, Layout, Rect},
style::Stylize,
text::Text,
widgets::Paragraph,
Frame,
};
use root_folders::RootFoldersUi;
use system::SystemUi;
@@ -20,22 +20,21 @@ use crate::{
app::App,
logos::SONARR_LOGO,
models::{
Route,
servarr_data::sonarr::sonarr_data::SonarrData,
servarr_models::{DiskSpace, RootFolder},
sonarr_models::DownloadRecord,
Route,
},
utils::convert_to_gb,
};
use super::{
draw_tabs,
DrawUi, draw_tabs,
styles::ManagarrStyle,
utils::{
borderless_block, layout_block, line_gauge_with_label, line_gauge_with_title, title_block,
},
widgets::loading_block::LoadingBlock,
DrawUi,
};
mod blocklist;
+3 -3
View File
@@ -1,17 +1,17 @@
use ratatui::Frame;
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ROOT_FOLDERS_BLOCKS};
use crate::models::servarr_models::RootFolder;
use crate::models::Route;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::layout_block_top_border;
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::{draw_input_box_popup, draw_popup, DrawUi};
use crate::ui::{DrawUi, draw_input_box_popup, draw_popup};
use crate::utils::convert_to_gb;
#[cfg(test)]
@@ -3,8 +3,8 @@ mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ROOT_FOLDERS_BLOCKS};
use crate::ui::sonarr_ui::root_folders::RootFoldersUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::root_folders::RootFoldersUi;
#[test]
fn test_root_folders_ui_accepts() {
+1 -1
View File
@@ -4,7 +4,7 @@ mod tests {
use crate::{
models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock,
ui::{sonarr_ui::SonarrUi, DrawUi},
ui::{DrawUi, sonarr_ui::SonarrUi},
};
#[test]
+2 -2
View File
@@ -6,9 +6,9 @@ use ratatui::style::Style;
use ratatui::text::{Span, Text};
use ratatui::widgets::{Cell, Row};
use ratatui::{
Frame,
layout::{Constraint, Rect},
widgets::ListItem,
Frame,
};
use crate::app::App;
@@ -23,7 +23,7 @@ use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::selectable_list::SelectableList;
use crate::{
models::Route,
ui::{utils::title_block, DrawUi},
ui::{DrawUi, utils::title_block},
};
mod system_details_ui;
+4 -4
View File
@@ -1,14 +1,14 @@
use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::text::{Span, Text};
use ratatui::widgets::{Cell, ListItem, Paragraph, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::Route;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SYSTEM_DETAILS_BLOCKS};
use crate::models::sonarr_models::SonarrTask;
use crate::models::Route;
use crate::ui::sonarr_ui::system::{
draw_queued_events, extract_task_props, TASK_TABLE_CONSTRAINTS, TASK_TABLE_HEADERS,
TASK_TABLE_CONSTRAINTS, TASK_TABLE_HEADERS, draw_queued_events, extract_task_props,
};
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::{borderless_block, style_log_list_item, title_block};
@@ -17,7 +17,7 @@ use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::widgets::selectable_list::SelectableList;
use crate::ui::{draw_popup, DrawUi};
use crate::ui::{DrawUi, draw_popup};
#[cfg(test)]
#[path = "system_details_ui_tests.rs"]
@@ -5,8 +5,8 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, SYSTEM_DETAILS_BLOCKS,
};
use crate::ui::sonarr_ui::system::system_details_ui::SystemDetailsUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::system::system_details_ui::SystemDetailsUi;
#[test]
fn test_system_details_ui_accepts() {
+1 -1
View File
@@ -5,8 +5,8 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, SYSTEM_DETAILS_BLOCKS,
};
use crate::ui::sonarr_ui::system::SystemUi;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::system::SystemUi;
#[test]
fn test_system_ui_accepts() {