test: Updated Rust edition to 2024 and refactored network module tests to be more idiomatic
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user