feat: Improved overall UI responsiveness
This commit is contained in:
+24
-2
@@ -7,12 +7,12 @@ mod tests {
|
|||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
use crate::app::{App, AppConfig, Data, ServarrConfig, interpolate_env_vars};
|
use crate::app::{interpolate_env_vars, App, AppConfig, Data, ServarrConfig};
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData};
|
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData};
|
||||||
use crate::models::{HorizontallyScrollableText, TabRoute};
|
use crate::models::{HorizontallyScrollableText, TabRoute};
|
||||||
use crate::network::NetworkEvent;
|
|
||||||
use crate::network::radarr_network::RadarrEvent;
|
use crate::network::radarr_network::RadarrEvent;
|
||||||
|
use crate::network::NetworkEvent;
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -80,6 +80,7 @@ mod tests {
|
|||||||
assert_eq!(app.tick_until_poll, 400);
|
assert_eq!(app.tick_until_poll, 400);
|
||||||
assert_eq!(app.ticks_until_scroll, 4);
|
assert_eq!(app.ticks_until_scroll, 4);
|
||||||
assert_eq!(app.tick_count, 0);
|
assert_eq!(app.tick_count, 0);
|
||||||
|
assert_eq!(app.ui_scroll_tick_count, 0);
|
||||||
assert!(!app.is_loading);
|
assert!(!app.is_loading);
|
||||||
assert!(!app.is_routing);
|
assert!(!app.is_routing);
|
||||||
assert!(!app.should_refresh);
|
assert!(!app.should_refresh);
|
||||||
@@ -240,6 +241,27 @@ mod tests {
|
|||||||
assert_eq!(app.tick_count, 0);
|
assert_eq!(app.tick_count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_on_ui_scroll_tick() {
|
||||||
|
let mut app = App {
|
||||||
|
ticks_until_scroll: 1,
|
||||||
|
..App::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(app.ui_scroll_tick_count, 0);
|
||||||
|
assert_eq!(app.tick_count, 0);
|
||||||
|
|
||||||
|
app.on_ui_scroll_tick();
|
||||||
|
|
||||||
|
assert_eq!(app.ui_scroll_tick_count, 1);
|
||||||
|
assert_eq!(app.tick_count, 0);
|
||||||
|
|
||||||
|
app.on_ui_scroll_tick();
|
||||||
|
|
||||||
|
assert_eq!(app.ui_scroll_tick_count, 0);
|
||||||
|
assert_eq!(app.tick_count, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_on_tick_first_render() {
|
async fn test_on_tick_first_render() {
|
||||||
let (sync_network_tx, mut sync_network_rx) = mpsc::channel::<NetworkEvent>(500);
|
let (sync_network_tx, mut sync_network_rx) = mpsc::channel::<NetworkEvent>(500);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ pub struct App<'a> {
|
|||||||
pub tick_until_poll: u64,
|
pub tick_until_poll: u64,
|
||||||
pub ticks_until_scroll: u64,
|
pub ticks_until_scroll: u64,
|
||||||
pub tick_count: u64,
|
pub tick_count: u64,
|
||||||
|
pub ui_scroll_tick_count: u64,
|
||||||
pub is_routing: bool,
|
pub is_routing: bool,
|
||||||
pub is_loading: bool,
|
pub is_loading: bool,
|
||||||
pub should_refresh: bool,
|
pub should_refresh: bool,
|
||||||
@@ -145,6 +146,14 @@ impl App<'_> {
|
|||||||
self.tick_count = 0;
|
self.tick_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_ui_scroll_tick(&mut self) {
|
||||||
|
if self.ui_scroll_tick_count == self.ticks_until_scroll {
|
||||||
|
self.ui_scroll_tick_count = 0;
|
||||||
|
} else {
|
||||||
|
self.ui_scroll_tick_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.reset_tick_count();
|
self.reset_tick_count();
|
||||||
@@ -227,6 +236,7 @@ impl Default for App<'_> {
|
|||||||
tick_until_poll: 400,
|
tick_until_poll: 400,
|
||||||
ticks_until_scroll: 4,
|
ticks_until_scroll: 4,
|
||||||
tick_count: 0,
|
tick_count: 0,
|
||||||
|
ui_scroll_tick_count: 0,
|
||||||
is_loading: false,
|
is_loading: false,
|
||||||
is_routing: false,
|
is_routing: false,
|
||||||
should_refresh: false,
|
should_refresh: false,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use anyhow::Result;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@@ -49,7 +50,10 @@ impl Events {
|
|||||||
Events { rx }
|
Events { rx }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&self) -> Result<InputEvent<Key>, mpsc::RecvError> {
|
pub fn next(&self) -> Result<Option<InputEvent<Key>>> {
|
||||||
self.rx.recv()
|
match self.rx.try_recv() {
|
||||||
|
Ok(event) => Ok(Some(event)),
|
||||||
|
_ => Ok(None),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-10
@@ -3,37 +3,39 @@
|
|||||||
extern crate assertables;
|
extern crate assertables;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::{CommandFactory, Parser, crate_authors, crate_description, crate_name, crate_version};
|
use clap::{crate_authors, crate_description, crate_name, crate_version, CommandFactory, Parser};
|
||||||
use clap_complete::generate;
|
use clap_complete::generate;
|
||||||
use crossterm::execute;
|
use crossterm::execute;
|
||||||
use crossterm::terminal::{
|
use crossterm::terminal::{
|
||||||
EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode,
|
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
|
||||||
};
|
};
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use network::NetworkTrait;
|
use network::NetworkTrait;
|
||||||
use ratatui::Terminal;
|
|
||||||
use ratatui::backend::CrosstermBackend;
|
use ratatui::backend::CrosstermBackend;
|
||||||
|
use ratatui::Terminal;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use std::panic::PanicHookInfo;
|
use std::panic::PanicHookInfo;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::time::sleep;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
use std::{io, panic, process};
|
use std::{io, panic, process};
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
use tokio::sync::mpsc::Receiver;
|
use tokio::sync::mpsc::Receiver;
|
||||||
use tokio::sync::{Mutex, mpsc};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use utils::{
|
use utils::{
|
||||||
build_network_client, load_config, start_cli_no_spinner, start_cli_with_spinner, tail_logs,
|
build_network_client, load_config, start_cli_no_spinner, start_cli_with_spinner, tail_logs,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::app::{App, log_and_print_error};
|
use crate::app::{log_and_print_error, App};
|
||||||
use crate::cli::Command;
|
use crate::cli::Command;
|
||||||
use crate::event::Key;
|
|
||||||
use crate::event::input_event::{Events, InputEvent};
|
use crate::event::input_event::{Events, InputEvent};
|
||||||
|
use crate::event::Key;
|
||||||
use crate::network::{Network, NetworkEvent};
|
use crate::network::{Network, NetworkEvent};
|
||||||
use crate::ui::theme::{Theme, ThemeDefinitionsWrapper};
|
use crate::ui::theme::{Theme, ThemeDefinitionsWrapper};
|
||||||
use crate::ui::{THEME, ui};
|
use crate::ui::{ui, THEME};
|
||||||
use crate::utils::load_theme_config;
|
use crate::utils::load_theme_config;
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
@@ -249,7 +251,7 @@ async fn start_ui(
|
|||||||
terminal.draw(|f| ui(f, &mut app))?;
|
terminal.draw(|f| ui(f, &mut app))?;
|
||||||
|
|
||||||
match input_events.next()? {
|
match input_events.next()? {
|
||||||
InputEvent::KeyEvent(key) => {
|
Some(InputEvent::KeyEvent(key)) => {
|
||||||
if key == Key::Char('q') && !app.ignore_special_keys_for_textbox_input {
|
if key == Key::Char('q') && !app.ignore_special_keys_for_textbox_input {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -257,8 +259,11 @@ async fn start_ui(
|
|||||||
handlers::handle_events(key, &mut app);
|
handlers::handle_events(key, &mut app);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputEvent::Tick => app.on_tick().await,
|
Some(InputEvent::Tick) => app.on_tick().await,
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = sleep(Duration::from_millis(16)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
terminal.show_cursor()?;
|
terminal.show_cursor()?;
|
||||||
|
|||||||
+5
-6
@@ -1,7 +1,6 @@
|
|||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Flex, Layout, Rect};
|
use ratatui::layout::{Constraint, Flex, Layout, Rect};
|
||||||
use ratatui::style::{Style, Stylize};
|
use ratatui::style::{Style, Stylize};
|
||||||
use ratatui::text::{Line, Text};
|
use ratatui::text::{Line, Text};
|
||||||
@@ -9,6 +8,7 @@ use ratatui::widgets::Paragraph;
|
|||||||
use ratatui::widgets::Tabs;
|
use ratatui::widgets::Tabs;
|
||||||
use ratatui::widgets::Wrap;
|
use ratatui::widgets::Wrap;
|
||||||
use ratatui::widgets::{Clear, Row};
|
use ratatui::widgets::{Clear, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
use sonarr_ui::SonarrUi;
|
use sonarr_ui::SonarrUi;
|
||||||
use utils::layout_block;
|
use utils::layout_block;
|
||||||
|
|
||||||
@@ -52,6 +52,7 @@ pub trait DrawUi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(f: &mut Frame<'_>, app: &mut App<'_>) {
|
pub fn ui(f: &mut Frame<'_>, app: &mut App<'_>) {
|
||||||
|
app.on_ui_scroll_tick();
|
||||||
f.render_widget(background_block(), f.area());
|
f.render_widget(background_block(), f.area());
|
||||||
let [header_area, context_area, table_area] = if !app.error.text.is_empty() {
|
let [header_area, context_area, table_area] = if !app.error.text.is_empty() {
|
||||||
let [header_area, error_area, context_area, table_area] = Layout::vertical([
|
let [header_area, error_area, context_area, table_area] = Layout::vertical([
|
||||||
@@ -124,11 +125,9 @@ fn draw_error(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
.failure()
|
.failure()
|
||||||
.bold();
|
.bold();
|
||||||
|
|
||||||
app.error.scroll_left_or_reset(
|
app
|
||||||
area.width as usize,
|
.error
|
||||||
true,
|
.scroll_left_or_reset(area.width as usize, true, app.ui_scroll_tick_count == 0);
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
|
||||||
);
|
|
||||||
|
|
||||||
let paragraph = Paragraph::new(Text::from(app.error.to_string().failure()))
|
let paragraph = Paragraph::new(Text::from(app.error.to_string().failure()))
|
||||||
.block(block)
|
.block(block)
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::radarr_models::BlocklistItem;
|
use crate::models::radarr_models::BlocklistItem;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS};
|
||||||
use crate::ui::DrawUi;
|
use crate::models::Route;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
||||||
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::message::Message;
|
use crate::ui::widgets::message::Message;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
use ratatui::Frame;
|
use crate::ui::DrawUi;
|
||||||
use ratatui::layout::{Alignment, Constraint, Rect};
|
use ratatui::layout::{Alignment, Constraint, Rect};
|
||||||
use ratatui::style::{Style, Stylize};
|
use ratatui::style::{Style, Stylize};
|
||||||
use ratatui::text::{Line, Text};
|
use ratatui::text::{Line, Text};
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "blocklist_ui_tests.rs"]
|
#[path = "blocklist_ui_tests.rs"]
|
||||||
@@ -96,7 +96,7 @@ fn draw_blocklist_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
movie.title.scroll_left_or_reset(
|
movie.title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 20),
|
get_width_from_percentage(area, 20),
|
||||||
current_selection == *blocklist_item,
|
current_selection == *blocklist_item,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
let languages_string = languages
|
let languages_string = languages
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Flex, Layout, Rect};
|
use ratatui::layout::{Constraint, Flex, Layout, Rect};
|
||||||
use ratatui::style::Stylize;
|
use ratatui::style::Stylize;
|
||||||
use ratatui::text::{Line, Text};
|
use ratatui::text::{Line, Text};
|
||||||
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::radarr_models::CollectionMovie;
|
use crate::models::radarr_models::CollectionMovie;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{
|
use crate::models::servarr_data::radarr::radarr_data::{
|
||||||
ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS,
|
ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS,
|
||||||
};
|
};
|
||||||
|
use crate::models::Route;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
borderless_block, get_width_from_percentage, layout_block_top_border_with_title, title_block,
|
borderless_block, get_width_from_percentage, layout_block_top_border_with_title, title_block,
|
||||||
@@ -17,7 +17,7 @@ use crate::ui::utils::{
|
|||||||
};
|
};
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::Size;
|
use crate::ui::widgets::popup::Size;
|
||||||
use crate::ui::{DrawUi, draw_popup};
|
use crate::ui::{draw_popup, DrawUi};
|
||||||
use crate::utils::convert_runtime;
|
use crate::utils::convert_runtime;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -90,7 +90,7 @@ pub fn draw_collection_details(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect)
|
|||||||
movie.title.scroll_left_or_reset(
|
movie.title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(table_area, 20),
|
get_width_from_percentage(table_area, 20),
|
||||||
current_selection == *movie,
|
current_selection == *movie,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let (hours, minutes) = convert_runtime(movie.runtime);
|
let (hours, minutes) = convert_runtime(movie.runtime);
|
||||||
let imdb_rating = movie
|
let imdb_rating = movie
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Rect};
|
use ratatui::layout::{Constraint, Rect};
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::radarr_models::Collection;
|
use crate::models::radarr_models::Collection;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, COLLECTIONS_BLOCKS};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, COLLECTIONS_BLOCKS};
|
||||||
use crate::ui::DrawUi;
|
use crate::models::Route;
|
||||||
use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi;
|
use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi;
|
||||||
use crate::ui::radarr_ui::collections::edit_collection_ui::EditCollectionUi;
|
use crate::ui::radarr_ui::collections::edit_collection_ui::EditCollectionUi;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
@@ -14,6 +13,7 @@ use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
|||||||
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
|
use crate::ui::DrawUi;
|
||||||
|
|
||||||
mod collection_details_ui;
|
mod collection_details_ui;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -70,7 +70,7 @@ pub(super) fn draw_collections(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect)
|
|||||||
collection.title.scroll_left_or_reset(
|
collection.title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 25),
|
get_width_from_percentage(area, 25),
|
||||||
*collection == current_selection,
|
*collection == current_selection,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let monitored = if collection.monitored { "🏷" } else { "" };
|
let monitored = if collection.monitored { "🏷" } else { "" };
|
||||||
let search_on_add = if collection.search_on_add {
|
let search_on_add = if collection.search_on_add {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Rect};
|
use ratatui::layout::{Constraint, Rect};
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::radarr_models::DownloadRecord;
|
use crate::models::radarr_models::DownloadRecord;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS};
|
||||||
use crate::models::{HorizontallyScrollableText, Route};
|
use crate::models::{HorizontallyScrollableText, Route};
|
||||||
use crate::ui::DrawUi;
|
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
||||||
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
|
use crate::ui::DrawUi;
|
||||||
use crate::utils::convert_to_gb;
|
use crate::utils::convert_to_gb;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -87,7 +87,7 @@ fn draw_downloads(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
output_path.as_ref().unwrap().scroll_left_or_reset(
|
output_path.as_ref().unwrap().scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 18),
|
get_width_from_percentage(area, 18),
|
||||||
current_selection == *download_record,
|
current_selection == *download_record,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::servarr_data::modals::IndexerTestResultModalItem;
|
use crate::models::servarr_data::modals::IndexerTestResultModalItem;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||||
|
use crate::models::Route;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{get_width_from_percentage, title_block};
|
use crate::ui::utils::{get_width_from_percentage, title_block};
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::Size;
|
use crate::ui::widgets::popup::Size;
|
||||||
use crate::ui::{DrawUi, draw_popup};
|
use crate::ui::{draw_popup, DrawUi};
|
||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Rect};
|
use ratatui::layout::{Constraint, Rect};
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "test_all_indexers_ui_tests.rs"]
|
#[path = "test_all_indexers_ui_tests.rs"]
|
||||||
@@ -45,7 +45,7 @@ fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, are
|
|||||||
result.validation_failures.scroll_left_or_reset(
|
result.validation_failures.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 86),
|
get_width_from_percentage(area, 86),
|
||||||
*result == current_selection,
|
*result == current_selection,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let pass_fail = if result.is_valid { "✔" } else { "❌" };
|
let pass_fail = if result.is_valid { "✔" } else { "❌" };
|
||||||
let row = Row::new(vec![
|
let row = Row::new(vec![
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Layout, Rect};
|
use ratatui::layout::{Constraint, Layout, Rect};
|
||||||
use ratatui::widgets::{Cell, ListItem, Row};
|
use ratatui::widgets::{Cell, ListItem, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::radarr_models::AddMovieSearchResult;
|
use crate::models::radarr_models::AddMovieSearchResult;
|
||||||
use crate::models::servarr_data::radarr::modals::AddMovieModal;
|
use crate::models::servarr_data::radarr::modals::AddMovieModal;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ADD_MOVIE_BLOCKS, ActiveRadarrBlock};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS};
|
||||||
|
use crate::models::Route;
|
||||||
use crate::ui::radarr_ui::collections::CollectionsUi;
|
use crate::ui::radarr_ui::collections::CollectionsUi;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
@@ -19,9 +19,9 @@ use crate::ui::widgets::managarr_table::ManagarrTable;
|
|||||||
use crate::ui::widgets::message::Message;
|
use crate::ui::widgets::message::Message;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
use crate::ui::widgets::selectable_list::SelectableList;
|
use crate::ui::widgets::selectable_list::SelectableList;
|
||||||
use crate::ui::{DrawUi, draw_popup};
|
use crate::ui::{draw_popup, DrawUi};
|
||||||
use crate::utils::convert_runtime;
|
use crate::utils::convert_runtime;
|
||||||
use crate::{App, render_selectable_input_box};
|
use crate::{render_selectable_input_box, App};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "add_movie_ui_tests.rs"]
|
#[path = "add_movie_ui_tests.rs"]
|
||||||
@@ -139,7 +139,7 @@ fn draw_add_movie_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
movie.title.scroll_left_or_reset(
|
movie.title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 27),
|
get_width_from_percentage(area, 27),
|
||||||
*movie == current_selection,
|
*movie == current_selection,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
@@ -307,27 +307,19 @@ fn draw_confirmation_prompt(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
|
|
||||||
f.render_widget(title_block_centered(&title), area);
|
f.render_widget(title_block_centered(&title), area);
|
||||||
|
|
||||||
let [
|
let [paragraph_area, root_folder_area, monitor_area, min_availability_area, quality_profile_area, tags_area, _, buttons_area] =
|
||||||
paragraph_area,
|
Layout::vertical([
|
||||||
root_folder_area,
|
Constraint::Length(6),
|
||||||
monitor_area,
|
Constraint::Length(3),
|
||||||
min_availability_area,
|
Constraint::Length(3),
|
||||||
quality_profile_area,
|
Constraint::Length(3),
|
||||||
tags_area,
|
Constraint::Length(3),
|
||||||
_,
|
Constraint::Length(3),
|
||||||
buttons_area,
|
Constraint::Fill(1),
|
||||||
] = Layout::vertical([
|
Constraint::Length(3),
|
||||||
Constraint::Length(6),
|
])
|
||||||
Constraint::Length(3),
|
.margin(1)
|
||||||
Constraint::Length(3),
|
.areas(area);
|
||||||
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);
|
let prompt_paragraph = layout_paragraph_borderless(&prompt);
|
||||||
f.render_widget(prompt_paragraph, paragraph_area);
|
f.render_widget(prompt_paragraph, paragraph_area);
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Rect};
|
use ratatui::layout::{Constraint, Rect};
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::radarr_models::Movie;
|
use crate::models::radarr_models::Movie;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, LIBRARY_BLOCKS};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, LIBRARY_BLOCKS};
|
||||||
use crate::ui::DrawUi;
|
use crate::models::Route;
|
||||||
use crate::ui::radarr_ui::decorate_with_row_style;
|
use crate::ui::radarr_ui::decorate_with_row_style;
|
||||||
use crate::ui::radarr_ui::library::add_movie_ui::AddMovieUi;
|
use crate::ui::radarr_ui::library::add_movie_ui::AddMovieUi;
|
||||||
use crate::ui::radarr_ui::library::delete_movie_ui::DeleteMovieUi;
|
use crate::ui::radarr_ui::library::delete_movie_ui::DeleteMovieUi;
|
||||||
@@ -16,6 +15,7 @@ use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
|||||||
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
|
use crate::ui::DrawUi;
|
||||||
use crate::utils::{convert_runtime, convert_to_gb};
|
use crate::utils::{convert_runtime, convert_to_gb};
|
||||||
|
|
||||||
mod add_movie_ui;
|
mod add_movie_ui;
|
||||||
@@ -90,7 +90,7 @@ fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
movie.title.scroll_left_or_reset(
|
movie.title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 27),
|
get_width_from_percentage(area, 27),
|
||||||
*movie == current_selection,
|
*movie == current_selection,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let monitored = if movie.monitored { "🏷" } else { "" };
|
let monitored = if movie.monitored { "🏷" } else { "" };
|
||||||
let studio = movie.studio.clone().unwrap_or_default();
|
let studio = movie.studio.clone().unwrap_or_default();
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Layout, Rect};
|
use ratatui::layout::{Constraint, Layout, Rect};
|
||||||
use ratatui::style::{Style, Stylize};
|
use ratatui::style::{Style, Stylize};
|
||||||
use ratatui::text::{Line, Span, Text};
|
use ratatui::text::{Line, Span, Text};
|
||||||
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
||||||
|
use ratatui::Frame;
|
||||||
use serde_json::Number;
|
use serde_json::Number;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::radarr_models::{Credit, MovieHistoryItem, RadarrRelease};
|
use crate::models::radarr_models::{Credit, MovieHistoryItem, RadarrRelease};
|
||||||
use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
|
use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS};
|
||||||
|
use crate::models::Route;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
borderless_block, decorate_peer_style, get_width_from_percentage, layout_block_bottom_border,
|
borderless_block, decorate_peer_style, get_width_from_percentage, layout_block_bottom_border,
|
||||||
@@ -21,7 +21,7 @@ use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
|||||||
use crate::ui::widgets::loading_block::LoadingBlock;
|
use crate::ui::widgets::loading_block::LoadingBlock;
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
use crate::ui::{DrawUi, draw_popup, draw_tabs};
|
use crate::ui::{draw_popup, draw_tabs, DrawUi};
|
||||||
use crate::utils::convert_to_gb;
|
use crate::utils::convert_to_gb;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -116,22 +116,16 @@ fn draw_file_info(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
|
|||||||
let file_info = movie_details_modal.file_details.to_owned();
|
let file_info = movie_details_modal.file_details.to_owned();
|
||||||
let audio_details = movie_details_modal.audio_details.to_owned();
|
let audio_details = movie_details_modal.audio_details.to_owned();
|
||||||
let video_details = movie_details_modal.video_details.to_owned();
|
let video_details = movie_details_modal.video_details.to_owned();
|
||||||
let [
|
let [file_details_title_area, file_details_area, audio_details_title_area, audio_details_area, video_details_title_area, video_details_area] =
|
||||||
file_details_title_area,
|
Layout::vertical([
|
||||||
file_details_area,
|
Constraint::Length(2),
|
||||||
audio_details_title_area,
|
Constraint::Length(5),
|
||||||
audio_details_area,
|
Constraint::Length(1),
|
||||||
video_details_title_area,
|
Constraint::Length(6),
|
||||||
video_details_area,
|
Constraint::Length(1),
|
||||||
] = Layout::vertical([
|
Constraint::Length(7),
|
||||||
Constraint::Length(2),
|
])
|
||||||
Constraint::Length(5),
|
.areas(area);
|
||||||
Constraint::Length(1),
|
|
||||||
Constraint::Length(6),
|
|
||||||
Constraint::Length(1),
|
|
||||||
Constraint::Length(7),
|
|
||||||
])
|
|
||||||
.areas(area);
|
|
||||||
|
|
||||||
let file_details_title_paragraph =
|
let file_details_title_paragraph =
|
||||||
Paragraph::new("File Details".bold()).block(layout_block_top_border());
|
Paragraph::new("File Details".bold()).block(layout_block_top_border());
|
||||||
@@ -246,7 +240,7 @@ fn draw_movie_history(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
movie_history_item.source_title.scroll_left_or_reset(
|
movie_history_item.source_title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 34),
|
get_width_from_percentage(area, 34),
|
||||||
current_selection == *movie_history_item,
|
current_selection == *movie_history_item,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
@@ -398,7 +392,7 @@ fn draw_movie_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
get_width_from_percentage(area, 30),
|
get_width_from_percentage(area, 30),
|
||||||
current_selection == *release
|
current_selection == *release
|
||||||
&& current_route != ActiveRadarrBlock::ManualSearchConfirmPrompt.into(),
|
&& current_route != ActiveRadarrBlock::ManualSearchConfirmPrompt.into(),
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let size = convert_to_gb(*size);
|
let size = convert_to_gb(*size);
|
||||||
let rejected_str = if *rejected { "⛔" } else { "" };
|
let rejected_str = if *rejected { "⛔" } else { "" };
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Rect};
|
use ratatui::layout::{Constraint, Rect};
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS};
|
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS};
|
||||||
use crate::models::sonarr_models::DownloadRecord;
|
use crate::models::sonarr_models::DownloadRecord;
|
||||||
use crate::models::{HorizontallyScrollableText, Route};
|
use crate::models::{HorizontallyScrollableText, Route};
|
||||||
use crate::ui::DrawUi;
|
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
||||||
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
|
use crate::ui::DrawUi;
|
||||||
use crate::utils::convert_f64_to_gb;
|
use crate::utils::convert_f64_to_gb;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -88,7 +88,7 @@ fn draw_downloads(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
output_path.as_ref().unwrap().scroll_left_or_reset(
|
output_path.as_ref().unwrap().scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 18),
|
get_width_from_percentage(area, 18),
|
||||||
current_selection == *download_record,
|
current_selection == *download_record,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS};
|
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS};
|
||||||
use crate::models::servarr_models::Language;
|
use crate::models::servarr_models::Language;
|
||||||
use crate::models::sonarr_models::{SonarrHistoryEventType, SonarrHistoryItem};
|
use crate::models::sonarr_models::{SonarrHistoryEventType, SonarrHistoryItem};
|
||||||
use crate::ui::DrawUi;
|
use crate::models::Route;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
use crate::ui::utils::{get_width_from_percentage, layout_block_top_border};
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::message::Message;
|
use crate::ui::widgets::message::Message;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
use ratatui::Frame;
|
use crate::ui::DrawUi;
|
||||||
use ratatui::layout::{Alignment, Constraint, Rect};
|
use ratatui::layout::{Alignment, Constraint, Rect};
|
||||||
use ratatui::style::Style;
|
use ratatui::style::Style;
|
||||||
use ratatui::text::Text;
|
use ratatui::text::Text;
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use super::sonarr_ui_utils::{
|
use super::sonarr_ui_utils::{
|
||||||
create_download_failed_history_event_details,
|
create_download_failed_history_event_details,
|
||||||
@@ -69,7 +69,7 @@ fn draw_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
source_title.scroll_left_or_reset(
|
source_title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 40),
|
get_width_from_percentage(area, 40),
|
||||||
current_selection == *history_item,
|
current_selection == *history_item,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::servarr_data::modals::IndexerTestResultModalItem;
|
use crate::models::servarr_data::modals::IndexerTestResultModalItem;
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
||||||
|
use crate::models::Route;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{get_width_from_percentage, title_block};
|
use crate::ui::utils::{get_width_from_percentage, title_block};
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::popup::Size;
|
use crate::ui::widgets::popup::Size;
|
||||||
use crate::ui::{DrawUi, draw_popup};
|
use crate::ui::{draw_popup, DrawUi};
|
||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Rect};
|
use ratatui::layout::{Constraint, Rect};
|
||||||
use ratatui::widgets::{Cell, Row};
|
use ratatui::widgets::{Cell, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "test_all_indexers_ui_tests.rs"]
|
#[path = "test_all_indexers_ui_tests.rs"]
|
||||||
@@ -44,7 +44,7 @@ fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, are
|
|||||||
result.validation_failures.scroll_left_or_reset(
|
result.validation_failures.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 86),
|
get_width_from_percentage(area, 86),
|
||||||
*result == current_selection,
|
*result == current_selection,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let pass_fail = if result.is_valid { "✔" } else { "❌" };
|
let pass_fail = if result.is_valid { "✔" } else { "❌" };
|
||||||
let row = Row::new(vec![
|
let row = Row::new(vec![
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Constraint, Layout, Rect};
|
use ratatui::layout::{Constraint, Layout, Rect};
|
||||||
use ratatui::widgets::{Cell, ListItem, Row};
|
use ratatui::widgets::{Cell, ListItem, Row};
|
||||||
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::servarr_data::sonarr::modals::AddSeriesModal;
|
use crate::models::servarr_data::sonarr::modals::AddSeriesModal;
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::{ADD_SERIES_BLOCKS, ActiveSonarrBlock};
|
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ADD_SERIES_BLOCKS};
|
||||||
use crate::models::sonarr_models::AddSeriesSearchResult;
|
use crate::models::sonarr_models::AddSeriesSearchResult;
|
||||||
|
use crate::models::Route;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
get_width_from_percentage, layout_block, layout_paragraph_borderless, title_block_centered,
|
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::message::Message;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
use crate::ui::widgets::selectable_list::SelectableList;
|
use crate::ui::widgets::selectable_list::SelectableList;
|
||||||
use crate::ui::{DrawUi, draw_popup};
|
use crate::ui::{draw_popup, DrawUi};
|
||||||
use crate::{App, render_selectable_input_box};
|
use crate::{render_selectable_input_box, App};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "add_series_ui_tests.rs"]
|
#[path = "add_series_ui_tests.rs"]
|
||||||
@@ -119,7 +119,7 @@ fn draw_add_series_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
series.title.scroll_left_or_reset(
|
series.title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 27),
|
get_width_from_percentage(area, 27),
|
||||||
*series == current_selection,
|
*series == current_selection,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
@@ -276,31 +276,21 @@ fn draw_confirmation_prompt(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
|
|
||||||
f.render_widget(title_block_centered(&title), area);
|
f.render_widget(title_block_centered(&title), area);
|
||||||
|
|
||||||
let [
|
let [paragraph_area, root_folder_area, monitor_area, quality_profile_area, language_profile_area, series_type_area, season_folder_area, tags_area, _, buttons_area] =
|
||||||
paragraph_area,
|
Layout::vertical([
|
||||||
root_folder_area,
|
Constraint::Length(6),
|
||||||
monitor_area,
|
Constraint::Length(3),
|
||||||
quality_profile_area,
|
Constraint::Length(3),
|
||||||
language_profile_area,
|
Constraint::Length(3),
|
||||||
series_type_area,
|
Constraint::Length(3),
|
||||||
season_folder_area,
|
Constraint::Length(3),
|
||||||
tags_area,
|
Constraint::Length(3),
|
||||||
_,
|
Constraint::Length(3),
|
||||||
buttons_area,
|
Constraint::Fill(1),
|
||||||
] = Layout::vertical([
|
Constraint::Length(3),
|
||||||
Constraint::Length(6),
|
])
|
||||||
Constraint::Length(3),
|
.margin(1)
|
||||||
Constraint::Length(3),
|
.areas(area);
|
||||||
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);
|
let prompt_paragraph = layout_paragraph_borderless(&prompt);
|
||||||
f.render_widget(prompt_paragraph, paragraph_area);
|
f.render_widget(prompt_paragraph, paragraph_area);
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ fn draw_episode_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect)
|
|||||||
source_title.scroll_left_or_reset(
|
source_title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 40),
|
get_width_from_percentage(area, 40),
|
||||||
current_selection == *history_item,
|
current_selection == *history_item,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
@@ -431,7 +431,7 @@ fn draw_episode_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
get_width_from_percentage(area, 30),
|
get_width_from_percentage(area, 30),
|
||||||
current_selection == *release
|
current_selection == *release
|
||||||
&& active_sonarr_block != ActiveSonarrBlock::ManualEpisodeSearchConfirmPrompt,
|
&& active_sonarr_block != ActiveSonarrBlock::ManualEpisodeSearchConfirmPrompt,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let size = convert_to_gb(*size);
|
let size = convert_to_gb(*size);
|
||||||
let rejected_str = if *rejected { "⛔" } else { "" };
|
let rejected_str = if *rejected { "⛔" } else { "" };
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ use add_series_ui::AddSeriesUi;
|
|||||||
use delete_series_ui::DeleteSeriesUi;
|
use delete_series_ui::DeleteSeriesUi;
|
||||||
use edit_series_ui::EditSeriesUi;
|
use edit_series_ui::EditSeriesUi;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
Frame,
|
|
||||||
layout::{Constraint, Rect},
|
layout::{Constraint, Rect},
|
||||||
widgets::{Cell, Row},
|
widgets::{Cell, Row},
|
||||||
|
Frame,
|
||||||
};
|
};
|
||||||
use series_details_ui::SeriesDetailsUi;
|
use series_details_ui::SeriesDetailsUi;
|
||||||
|
|
||||||
@@ -16,15 +16,15 @@ use crate::utils::convert_to_gb;
|
|||||||
use crate::{
|
use crate::{
|
||||||
app::App,
|
app::App,
|
||||||
models::{
|
models::{
|
||||||
Route,
|
|
||||||
servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, LIBRARY_BLOCKS},
|
servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, LIBRARY_BLOCKS},
|
||||||
sonarr_models::{Series, SeriesStatus},
|
sonarr_models::{Series, SeriesStatus},
|
||||||
|
Route,
|
||||||
},
|
},
|
||||||
ui::{
|
ui::{
|
||||||
DrawUi,
|
|
||||||
styles::ManagarrStyle,
|
styles::ManagarrStyle,
|
||||||
utils::{get_width_from_percentage, layout_block_top_border},
|
utils::{get_width_from_percentage, layout_block_top_border},
|
||||||
widgets::managarr_table::ManagarrTable,
|
widgets::managarr_table::ManagarrTable,
|
||||||
|
DrawUi,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
series.title.scroll_left_or_reset(
|
series.title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 23),
|
get_width_from_percentage(area, 23),
|
||||||
*series == current_selection,
|
*series == current_selection,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let monitored = if series.monitored { "🏷" } else { "" };
|
let monitored = if series.monitored { "🏷" } else { "" };
|
||||||
let certification = series.certification.clone().unwrap_or_default();
|
let certification = series.certification.clone().unwrap_or_default();
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ fn draw_season_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
source_title.scroll_left_or_reset(
|
source_title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 40),
|
get_width_from_percentage(area, 40),
|
||||||
current_selection == *history_item,
|
current_selection == *history_item,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
@@ -382,7 +382,7 @@ fn draw_season_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
get_width_from_percentage(area, 30),
|
get_width_from_percentage(area, 30),
|
||||||
current_selection == *release
|
current_selection == *release
|
||||||
&& active_sonarr_block != ActiveSonarrBlock::ManualSeasonSearchConfirmPrompt,
|
&& active_sonarr_block != ActiveSonarrBlock::ManualSeasonSearchConfirmPrompt,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
let size = convert_to_gb(*size);
|
let size = convert_to_gb(*size);
|
||||||
let rejected_str = if *rejected { "⛔" } else { "" };
|
let rejected_str = if *rejected { "⛔" } else { "" };
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use deunicode::deunicode;
|
use deunicode::deunicode;
|
||||||
use ratatui::Frame;
|
|
||||||
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
||||||
use ratatui::style::{Style, Stylize};
|
use ratatui::style::{Style, Stylize};
|
||||||
use ratatui::text::{Line, Text};
|
use ratatui::text::{Line, Text};
|
||||||
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
||||||
|
use ratatui::Frame;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SERIES_DETAILS_BLOCKS};
|
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SERIES_DETAILS_BLOCKS};
|
||||||
use crate::models::sonarr_models::{
|
use crate::models::sonarr_models::{
|
||||||
Season, SeasonStatistics, SonarrHistoryEventType, SonarrHistoryItem,
|
Season, SeasonStatistics, SonarrHistoryEventType, SonarrHistoryItem,
|
||||||
};
|
};
|
||||||
|
use crate::models::Route;
|
||||||
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
|
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::library::season_details_ui::SeasonDetailsUi;
|
||||||
use crate::ui::sonarr_ui::sonarr_ui_utils::{
|
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::managarr_table::ManagarrTable;
|
||||||
use crate::ui::widgets::message::Message;
|
use crate::ui::widgets::message::Message;
|
||||||
use crate::ui::widgets::popup::{Popup, Size};
|
use crate::ui::widgets::popup::{Popup, Size};
|
||||||
use crate::ui::{DrawUi, draw_popup, draw_tabs};
|
use crate::ui::{draw_popup, draw_tabs, DrawUi};
|
||||||
use crate::utils::convert_to_gb;
|
use crate::utils::convert_to_gb;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -315,7 +315,7 @@ fn draw_series_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
|||||||
source_title.scroll_left_or_reset(
|
source_title.scroll_left_or_reset(
|
||||||
get_width_from_percentage(area, 40),
|
get_width_from_percentage(area, 40),
|
||||||
current_selection == *history_item,
|
current_selection == *history_item,
|
||||||
app.tick_count.is_multiple_of(app.ticks_until_scroll),
|
app.ui_scroll_tick_count == 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
|
|||||||
Reference in New Issue
Block a user