testing
This commit is contained in:
Generated
+120
-8
@@ -41,6 +41,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anpa"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4d032745fe46100dbcb28ee6e30f12c4b148786f8889e07cd0a3445eeb54970f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.21"
|
version = "0.6.21"
|
||||||
@@ -217,6 +223,31 @@ dependencies = [
|
|||||||
"objc2",
|
"objc2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bon"
|
||||||
|
version = "3.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebeb9aaf9329dff6ceb65c689ca3db33dbf15f324909c60e4e5eef5701ce31b1"
|
||||||
|
dependencies = [
|
||||||
|
"bon-macros",
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bon-macros"
|
||||||
|
version = "3.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77e9d642a7e3a318e37c2c9427b5a6a48aa1ad55dcd986f3034ab2239045a645"
|
||||||
|
dependencies = [
|
||||||
|
"darling 0.21.3",
|
||||||
|
"ident_case",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.12.1"
|
version = "1.12.1"
|
||||||
@@ -376,6 +407,20 @@ dependencies = [
|
|||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "compact_str"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
|
||||||
|
dependencies = [
|
||||||
|
"castaway",
|
||||||
|
"cfg-if",
|
||||||
|
"itoa",
|
||||||
|
"rustversion",
|
||||||
|
"ryu",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "confy"
|
name = "confy"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@@ -459,8 +504,18 @@ version = "0.20.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
|
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core 0.20.11",
|
||||||
"darling_macro",
|
"darling_macro 0.20.11",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.21.3",
|
||||||
|
"darling_macro 0.21.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -477,13 +532,38 @@ dependencies = [
|
|||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_macro"
|
name = "darling_macro"
|
||||||
version = "0.20.11"
|
version = "0.20.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core 0.20.11",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.21.3",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
@@ -536,7 +616,7 @@ version = "0.1.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae5c625eda104c228c06ecaf988d1c60e542176bd7a490e60eeda3493244c0c9"
|
checksum = "ae5c625eda104c228c06ecaf988d1c60e542176bd7a490e60eeda3493244c0c9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling 0.20.11",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
@@ -664,7 +744,7 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "583f1f514d2754010ff71ed6853068cacbe43cc142cc076aa1b871d9754efc48"
|
checksum = "583f1f514d2754010ff71ed6853068cacbe43cc142cc076aa1b871d9754efc48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling 0.20.11",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
@@ -673,7 +753,7 @@ dependencies = [
|
|||||||
name = "enum_display_style_derive"
|
name = "enum_display_style_derive"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling 0.20.11",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
@@ -1249,7 +1329,7 @@ version = "0.3.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6778b0196eefee7df739db78758e5cf9b37412268bfa5650bfeed028aed20d9c"
|
checksum = "6778b0196eefee7df739db78758e5cf9b37412268bfa5650bfeed028aed20d9c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling 0.20.11",
|
||||||
"indoc",
|
"indoc",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1454,6 +1534,7 @@ dependencies = [
|
|||||||
"serial_test",
|
"serial_test",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
|
"tachyonfx",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
@@ -1477,6 +1558,12 @@ version = "2.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "micromath"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@@ -2005,6 +2092,16 @@ dependencies = [
|
|||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
@@ -2109,7 +2206,7 @@ checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cassowary",
|
"cassowary",
|
||||||
"compact_str",
|
"compact_str 0.8.1",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"indoc",
|
"indoc",
|
||||||
"instability",
|
"instability",
|
||||||
@@ -2704,6 +2801,21 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tachyonfx"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de9d53c5afe979f7de9d5ba856c9829b118d6aca6335750201f1ada46bc198e2"
|
||||||
|
dependencies = [
|
||||||
|
"anpa",
|
||||||
|
"bon",
|
||||||
|
"compact_str 0.9.0",
|
||||||
|
"micromath",
|
||||||
|
"ratatui",
|
||||||
|
"thiserror 2.0.17",
|
||||||
|
"unicode-width 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.23.0"
|
version = "3.23.0"
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ openssl = { version = "0.10.70", features = ["vendored"] }
|
|||||||
veil = "0.2.0"
|
veil = "0.2.0"
|
||||||
validate_theme_derive = "0.1.0"
|
validate_theme_derive = "0.1.0"
|
||||||
enum_display_style_derive = "0.1.0"
|
enum_display_style_derive = "0.1.0"
|
||||||
|
tachyonfx = { version = "0.21.0", features = ["sendable"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_cmd = "2.0.16"
|
assert_cmd = "2.0.16"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{fs, process};
|
use std::{fs, process};
|
||||||
|
use tachyonfx::{Duration, EffectManager};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use veil::Redact;
|
use veil::Redact;
|
||||||
@@ -40,6 +41,9 @@ pub struct App<'a> {
|
|||||||
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 ui_scroll_tick_count: u64,
|
||||||
|
pub last_tick: Duration,
|
||||||
|
pub effects: EffectManager<()>,
|
||||||
|
pub has_active_effect: bool,
|
||||||
pub is_routing: bool,
|
pub is_routing: bool,
|
||||||
pub is_loading: bool,
|
pub is_loading: bool,
|
||||||
pub should_refresh: bool,
|
pub should_refresh: bool,
|
||||||
@@ -189,6 +193,7 @@ impl App<'_> {
|
|||||||
pub fn push_navigation_stack(&mut self, route: Route) {
|
pub fn push_navigation_stack(&mut self, route: Route) {
|
||||||
self.navigation_stack.push(route);
|
self.navigation_stack.push(route);
|
||||||
self.is_routing = true;
|
self.is_routing = true;
|
||||||
|
self.has_active_effect = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_navigation_stack(&mut self) {
|
pub fn pop_navigation_stack(&mut self) {
|
||||||
@@ -237,6 +242,9 @@ impl Default for App<'_> {
|
|||||||
ticks_until_scroll: 4,
|
ticks_until_scroll: 4,
|
||||||
tick_count: 0,
|
tick_count: 0,
|
||||||
ui_scroll_tick_count: 0,
|
ui_scroll_tick_count: 0,
|
||||||
|
last_tick: Duration::ZERO,
|
||||||
|
effects: EffectManager::default(),
|
||||||
|
has_active_effect: false,
|
||||||
is_loading: false,
|
is_loading: false,
|
||||||
is_routing: false,
|
is_routing: false,
|
||||||
should_refresh: false,
|
should_refresh: false,
|
||||||
|
|||||||
+12
-9
@@ -3,37 +3,38 @@
|
|||||||
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 std::time::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;
|
||||||
@@ -242,9 +243,12 @@ async fn start_ui(
|
|||||||
terminal.hide_cursor()?;
|
terminal.hide_cursor()?;
|
||||||
|
|
||||||
let input_events = Events::new();
|
let input_events = Events::new();
|
||||||
|
let mut last_frame_instant = Instant::now();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut app = app.lock().await;
|
let mut app = app.lock().await;
|
||||||
|
app.last_tick = last_frame_instant.elapsed().into();
|
||||||
|
last_frame_instant = Instant::now();
|
||||||
|
|
||||||
terminal.draw(|f| ui(f, &mut app))?;
|
terminal.draw(|f| ui(f, &mut app))?;
|
||||||
|
|
||||||
@@ -256,7 +260,6 @@ async fn start_ui(
|
|||||||
|
|
||||||
handlers::handle_events(key, &mut app);
|
handlers::handle_events(key, &mut app);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(InputEvent::Tick) => app.on_tick().await,
|
Some(InputEvent::Tick) => app.on_tick().await,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ pub fn ui(f: &mut Frame<'_>, app: &mut App<'_>) {
|
|||||||
if app.keymapping_table.is_some() {
|
if app.keymapping_table.is_some() {
|
||||||
draw_help_popup(f, app);
|
draw_help_popup(f, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let area = f.area();
|
||||||
|
app
|
||||||
|
.effects
|
||||||
|
.process_effects(app.last_tick, f.buffer_mut(), area);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_header_row(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
fn draw_header_row(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -64,7 +64,9 @@ impl DrawUi for LibraryUi {
|
|||||||
.yes_no_value(app.data.radarr_data.prompt_confirm);
|
.yes_no_value(app.data.radarr_data.prompt_confirm);
|
||||||
|
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Popup::new(confirmation_prompt).size(Size::MediumPrompt),
|
Popup::new(confirmation_prompt)
|
||||||
|
.size(Size::MediumPrompt)
|
||||||
|
.app(app),
|
||||||
f.area(),
|
f.area(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -154,5 +154,6 @@ fn draw_history_item_details_popup(f: &mut Frame<'_>, app: &mut App<'_>) {
|
|||||||
.style(Style::new().secondary())
|
.style(Style::new().secondary())
|
||||||
.alignment(Alignment::Left);
|
.alignment(Alignment::Left);
|
||||||
|
|
||||||
f.render_widget(Popup::new(message).size(Size::NarrowMessage), f.area());
|
let widget = Popup::new(message).size(Size::NarrowMessage).app(app);
|
||||||
|
f.render_widget(widget, f.area());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,33 @@
|
|||||||
|
use crate::app::App;
|
||||||
use crate::ui::styles::ManagarrStyle;
|
use crate::ui::styles::ManagarrStyle;
|
||||||
|
use derive_setters::Setters;
|
||||||
use ratatui::buffer::Buffer;
|
use ratatui::buffer::Buffer;
|
||||||
use ratatui::layout::Rect;
|
use ratatui::layout::Rect;
|
||||||
use ratatui::prelude::Text;
|
use ratatui::prelude::Text;
|
||||||
|
use ratatui::style::Style;
|
||||||
use ratatui::widgets::{Block, Paragraph, Widget};
|
use ratatui::widgets::{Block, Paragraph, Widget};
|
||||||
|
use tachyonfx::pattern::SweepPattern;
|
||||||
|
use tachyonfx::{fx, Interpolation};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "loading_block_tests.rs"]
|
#[path = "loading_block_tests.rs"]
|
||||||
mod loading_block_tests;
|
mod loading_block_tests;
|
||||||
|
|
||||||
pub struct LoadingBlock<'a> {
|
#[derive(Setters)]
|
||||||
|
pub struct LoadingBlock<'a, 'b> {
|
||||||
is_loading: bool,
|
is_loading: bool,
|
||||||
block: Block<'a>,
|
block: Block<'a>,
|
||||||
|
#[setters(strip_option)]
|
||||||
|
app: Option<&'a mut App<'b>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LoadingBlock<'a> {
|
impl<'a, 'b> LoadingBlock<'a, 'b> {
|
||||||
pub fn new(is_loading: bool, block: Block<'a>) -> Self {
|
pub fn new(is_loading: bool, block: Block<'a>) -> Self {
|
||||||
Self { is_loading, block }
|
Self {
|
||||||
|
is_loading,
|
||||||
|
block,
|
||||||
|
app: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_loading_block(self, area: Rect, buf: &mut Buffer) {
|
fn render_loading_block(self, area: Rect, buf: &mut Buffer) {
|
||||||
@@ -27,10 +39,20 @@ impl<'a> LoadingBlock<'a> {
|
|||||||
} else {
|
} else {
|
||||||
self.block.render(area, buf);
|
self.block.render(area, buf);
|
||||||
}
|
}
|
||||||
|
if let Some(app) = self.app
|
||||||
|
&& !app.has_active_effect {
|
||||||
|
let color = Style::new().failure().fg.expect("primary fg color is unset");
|
||||||
|
let fx =
|
||||||
|
fx::repeating(fx::paint_fg(color, 1000)
|
||||||
|
.with_pattern(SweepPattern::left_to_right(10))
|
||||||
|
.with_area(area));
|
||||||
|
app.effects.add_effect(fx);
|
||||||
|
app.has_active_effect = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for LoadingBlock<'_> {
|
impl Widget for LoadingBlock<'_, '_> {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
self.render_loading_block(area, buf);
|
self.render_loading_block(area, buf);
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-13
@@ -1,7 +1,10 @@
|
|||||||
|
use crate::app::App;
|
||||||
use crate::ui::utils::{background_block, centered_rect};
|
use crate::ui::utils::{background_block, centered_rect};
|
||||||
|
use derive_setters::Setters;
|
||||||
use ratatui::buffer::Buffer;
|
use ratatui::buffer::Buffer;
|
||||||
use ratatui::layout::{Constraint, Layout, Rect};
|
use ratatui::layout::{Constraint, Layout, Rect};
|
||||||
use ratatui::widgets::{Block, Clear, Widget};
|
use ratatui::widgets::{Block, Clear, Widget};
|
||||||
|
use tachyonfx::{fx, Interpolation};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "popup_tests.rs"]
|
#[path = "popup_tests.rs"]
|
||||||
@@ -49,15 +52,25 @@ impl Size {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Popup<'a, T: Widget> {
|
#[derive(Setters)]
|
||||||
|
pub struct Popup<'a, 'b, T: Widget> {
|
||||||
|
#[setters(skip)]
|
||||||
widget: T,
|
widget: T,
|
||||||
margin: u16,
|
margin: u16,
|
||||||
|
#[setters(skip)]
|
||||||
percent_x: u16,
|
percent_x: u16,
|
||||||
|
#[setters(skip)]
|
||||||
percent_y: u16,
|
percent_y: u16,
|
||||||
|
#[setters(strip_option)]
|
||||||
block: Option<Block<'a>>,
|
block: Option<Block<'a>>,
|
||||||
|
#[setters(strip_option)]
|
||||||
|
app: Option<&'a mut App<'b>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Widget> Popup<'a, T> {
|
impl<T> Popup<'_, '_, T>
|
||||||
|
where
|
||||||
|
T: Widget,
|
||||||
|
{
|
||||||
pub fn new(widget: T) -> Self {
|
pub fn new(widget: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
widget,
|
widget,
|
||||||
@@ -65,6 +78,7 @@ impl<'a, T: Widget> Popup<'a, T> {
|
|||||||
percent_y: 0,
|
percent_y: 0,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
block: None,
|
block: None,
|
||||||
|
app: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,16 +95,6 @@ impl<'a, T: Widget> Popup<'a, T> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block(mut self, block: Block<'a>) -> Self {
|
|
||||||
self.block = Some(block);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn margin(mut self, margin: u16) -> Self {
|
|
||||||
self.margin = margin;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_popup(self, area: Rect, buf: &mut Buffer) {
|
fn render_popup(self, area: Rect, buf: &mut Buffer) {
|
||||||
let mut popup_area = centered_rect(self.percent_x, self.percent_y, area);
|
let mut popup_area = centered_rect(self.percent_x, self.percent_y, area);
|
||||||
let height = if popup_area.height < 3 {
|
let height = if popup_area.height < 3 {
|
||||||
@@ -114,10 +118,19 @@ impl<'a, T: Widget> Popup<'a, T> {
|
|||||||
.areas(popup_area);
|
.areas(popup_area);
|
||||||
|
|
||||||
self.widget.render(content_area, buf);
|
self.widget.render(content_area, buf);
|
||||||
|
if let Some(app) = self.app
|
||||||
|
&& !app.has_active_effect {
|
||||||
|
let timer = (100, Interpolation::Linear);
|
||||||
|
let fx =
|
||||||
|
fx::coalesce(timer)
|
||||||
|
.with_area(content_area);
|
||||||
|
app.effects.add_effect(fx);
|
||||||
|
app.has_active_effect = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Widget> Widget for Popup<'_, T> {
|
impl<T: Widget> Widget for Popup<'_, '_, T> {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
self.render_popup(area, buf);
|
self.render_popup(area, buf);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user