diff --git a/src/app/app_tests.rs b/src/app/app_tests.rs index aea2490..1707ea4 100644 --- a/src/app/app_tests.rs +++ b/src/app/app_tests.rs @@ -5,6 +5,7 @@ mod tests { use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use serde_json::Value; use serial_test::serial; + use std::time::{Duration, Instant}; use tokio::sync::mpsc; use crate::app::{App, AppConfig, Data, ServarrConfig, interpolate_env_vars}; @@ -80,7 +81,7 @@ mod tests { assert_eq!(app.server_tabs.index, 0); assert_eq!(app.server_tabs.tabs, expected_tab_routes); assert_eq!(app.tick_until_poll, 400); - assert_eq!(app.ticks_until_scroll, 64); + assert_eq!(app.scroll_interval, Duration::from_millis(100)); assert_eq!(app.tick_count, 0); assert_eq!(app.ui_scroll_tick_count, 0); assert!(!app.is_loading); @@ -101,7 +102,7 @@ mod tests { assert_eq!(app.error, HorizontallyScrollableText::default()); assert_eq!(app.server_tabs.index, 0); assert_eq!(app.tick_until_poll, 400); - assert_eq!(app.ticks_until_scroll, 64); + assert_eq!(app.scroll_interval, Duration::from_millis(100)); assert_eq!(app.tick_count, 0); assert!(!app.is_loading); assert!(!app.is_routing); @@ -247,22 +248,23 @@ mod tests { #[test] fn test_on_ui_scroll_tick() { let mut app = App { - ticks_until_scroll: 1, + scroll_interval: Duration::ZERO, ..App::default() }; + // Zero interval: elapsed() >= scroll_interval is always true, so every + // call should signal "scroll now" (ui_scroll_tick_count == 0) + app.on_ui_scroll_tick(); 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, 0); + // Long interval with a fresh timestamp: should signal "not yet" (count == 1) + app.scroll_interval = Duration::from_secs(60); + app.last_scroll = Instant::now(); + 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] diff --git a/src/app/mod.rs b/src/app/mod.rs index fc0b234..79ac588 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -7,6 +7,7 @@ use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::PathBuf; +use std::time::{Duration, Instant}; use std::{fs, process}; use tokio::sync::mpsc::Sender; use tokio_util::sync::CancellationToken; @@ -41,7 +42,8 @@ pub struct App<'a> { pub error: HorizontallyScrollableText, pub notification: Option, pub tick_until_poll: u64, - pub ticks_until_scroll: u64, + pub scroll_interval: Duration, + pub last_scroll: Instant, pub tick_count: u64, pub ui_scroll_tick_count: u64, pub is_routing: bool, @@ -171,10 +173,11 @@ impl App<'_> { } pub fn on_ui_scroll_tick(&mut self) { - if self.ui_scroll_tick_count == self.ticks_until_scroll { + if self.last_scroll.elapsed() >= self.scroll_interval { self.ui_scroll_tick_count = 0; + self.last_scroll = Instant::now(); } else { - self.ui_scroll_tick_count += 1; + self.ui_scroll_tick_count = 1; } } @@ -260,7 +263,8 @@ impl Default for App<'_> { is_first_render: true, server_tabs: TabState::new(Vec::new()), tick_until_poll: 400, - ticks_until_scroll: 64, + scroll_interval: Duration::from_millis(100), + last_scroll: Instant::now(), tick_count: 0, ui_scroll_tick_count: 0, is_loading: false, diff --git a/src/main.rs b/src/main.rs index db4888f..a40173f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -276,12 +276,12 @@ async fn start_ui( let input_events = Events::new(); - { - let mut app = app.lock().await; - terminal.draw(|f| ui(f, &mut app))?; - } - loop { + { + let mut app = app.lock().await; + terminal.draw(|f| ui(f, &mut app))?; + } + match input_events.next()? { Some(InputEvent::KeyEvent(key)) => { let mut app = app.lock().await; @@ -291,13 +291,11 @@ async fn start_ui( } handlers::handle_events(key, &mut app); - terminal.draw(|f| ui(f, &mut app))?; } Some(InputEvent::Tick) => { let mut app = app.lock().await; app.on_tick().await; - terminal.draw(|f| ui(f, &mut app))?; } None => break, }