diff --git a/src/app/app_tests.rs b/src/app/app_tests.rs index 1707ea4..ffefe31 100644 --- a/src/app/app_tests.rs +++ b/src/app/app_tests.rs @@ -83,7 +83,7 @@ mod tests { assert_eq!(app.tick_until_poll, 400); 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.should_text_scroll); assert!(!app.is_loading); assert!(!app.is_routing); assert!(!app.should_refresh); @@ -252,19 +252,16 @@ mod tests { ..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!(app.should_text_scroll); app.on_ui_scroll_tick(); - assert_eq!(app.ui_scroll_tick_count, 0); + assert!(app.should_text_scroll); - // 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!(!app.should_text_scroll); } #[tokio::test] diff --git a/src/app/mod.rs b/src/app/mod.rs index 79ac588..a660243 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -45,7 +45,7 @@ pub struct App<'a> { pub scroll_interval: Duration, pub last_scroll: Instant, pub tick_count: u64, - pub ui_scroll_tick_count: u64, + pub should_text_scroll: bool, pub is_routing: bool, pub is_loading: bool, pub should_refresh: bool, @@ -174,10 +174,10 @@ impl App<'_> { pub fn on_ui_scroll_tick(&mut self) { if self.last_scroll.elapsed() >= self.scroll_interval { - self.ui_scroll_tick_count = 0; + self.should_text_scroll = true; self.last_scroll = Instant::now(); } else { - self.ui_scroll_tick_count = 1; + self.should_text_scroll = false; } } @@ -266,7 +266,7 @@ impl Default for App<'_> { scroll_interval: Duration::from_millis(100), last_scroll: Instant::now(), tick_count: 0, - ui_scroll_tick_count: 0, + should_text_scroll: false, is_loading: false, is_routing: false, should_refresh: false, diff --git a/src/event/input_event.rs b/src/event/input_event.rs index 39e87e0..1dfa0a3 100644 --- a/src/event/input_event.rs +++ b/src/event/input_event.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use std::env; use std::sync::mpsc; use std::sync::mpsc::Receiver; use std::thread; @@ -21,22 +20,10 @@ pub struct Events { const DEFAULT_TICK_RATE_MS: u64 = 50; -fn configured_tick_rate_ms_from(raw: Option<&str>) -> u64 { - raw - .and_then(|value| value.parse::().ok()) - .filter(|ms| *ms > 0) - .unwrap_or(DEFAULT_TICK_RATE_MS) -} - -fn configured_tick_rate_ms() -> u64 { - let raw = env::var("MANAGARR_TICK_RATE_MS").ok(); - configured_tick_rate_ms_from(raw.as_deref()) -} - impl Events { pub fn new() -> Self { let (tx, rx) = mpsc::channel(); - let tick_rate: Duration = Duration::from_millis(configured_tick_rate_ms()); + let tick_rate: Duration = Duration::from_millis(DEFAULT_TICK_RATE_MS); thread::spawn(move || { let mut last_tick = Instant::now(); @@ -80,16 +67,5 @@ mod tests { #[test] fn defaults_to_original_tick_rate() { assert_eq!(DEFAULT_TICK_RATE_MS, 50); - assert_eq!(configured_tick_rate_ms_from(None), 50); - } - - #[test] - fn parses_positive_tick_rates_and_rejects_invalid_values() { - assert_eq!(configured_tick_rate_ms_from(Some("250")), 250); - assert_eq!(configured_tick_rate_ms_from(Some("0")), DEFAULT_TICK_RATE_MS); - assert_eq!( - configured_tick_rate_ms_from(Some("abc")), - DEFAULT_TICK_RATE_MS - ); } } diff --git a/src/network/mod.rs b/src/network/mod.rs index c275a2c..f74ba3b 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -6,8 +6,6 @@ use async_trait::async_trait; use lidarr_network::LidarrEvent; use log::{debug, error, warn}; use regex::Regex; - -static WHITESPACE_RE: OnceLock = OnceLock::new(); use reqwest::{Client, RequestBuilder}; use serde::Serialize; use serde::de::DeserializeOwned; @@ -35,6 +33,8 @@ mod network_tests; #[cfg(test)] pub mod servarr_test_utils; +static WHITESPACE_RE: OnceLock = OnceLock::new(); + #[cfg_attr(test, automock)] #[async_trait] pub trait NetworkTrait { diff --git a/src/ui/lidarr_ui/downloads/mod.rs b/src/ui/lidarr_ui/downloads/mod.rs index 2e0ed1f..004606d 100644 --- a/src/ui/lidarr_ui/downloads/mod.rs +++ b/src/ui/lidarr_ui/downloads/mod.rs @@ -88,7 +88,7 @@ fn draw_downloads(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { output_path.as_ref().unwrap().scroll_left_or_reset( get_width_from_percentage(area, 18), current_selection == *download_record, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); } diff --git a/src/ui/lidarr_ui/history/mod.rs b/src/ui/lidarr_ui/history/mod.rs index fb6b8a8..45c26ca 100644 --- a/src/ui/lidarr_ui/history/mod.rs +++ b/src/ui/lidarr_ui/history/mod.rs @@ -60,7 +60,7 @@ fn draw_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 50), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ diff --git a/src/ui/lidarr_ui/indexers/test_all_indexers_ui.rs b/src/ui/lidarr_ui/indexers/test_all_indexers_ui.rs index 6a3b30e..b78a74a 100644 --- a/src/ui/lidarr_ui/indexers/test_all_indexers_ui.rs +++ b/src/ui/lidarr_ui/indexers/test_all_indexers_ui.rs @@ -46,7 +46,7 @@ fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, are result.validation_failures.scroll_left_or_reset( get_width_from_percentage(area, 86), *result == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let pass_fail = if result.is_valid { "+" } else { "x" }; let row = Row::new(vec![ diff --git a/src/ui/lidarr_ui/library/add_artist_ui.rs b/src/ui/lidarr_ui/library/add_artist_ui.rs index bb9ab21..7867130 100644 --- a/src/ui/lidarr_ui/library/add_artist_ui.rs +++ b/src/ui/lidarr_ui/library/add_artist_ui.rs @@ -112,7 +112,7 @@ fn draw_add_artist_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { artist.artist_name.scroll_left_or_reset( get_width_from_percentage(area, 27), *artist == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ diff --git a/src/ui/lidarr_ui/library/album_details_ui.rs b/src/ui/lidarr_ui/library/album_details_ui.rs index 964ee8c..86e7899 100644 --- a/src/ui/lidarr_ui/library/album_details_ui.rs +++ b/src/ui/lidarr_ui/library/album_details_ui.rs @@ -250,7 +250,7 @@ fn draw_album_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ @@ -345,7 +345,7 @@ fn draw_album_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { get_width_from_percentage(area, 35), current_selection == *release && active_lidarr_block != ActiveLidarrBlock::ManualAlbumSearchConfirmPrompt, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let size = convert_to_gb(*size); let rejected_str = if *rejected { "⛔" } else { "" }; diff --git a/src/ui/lidarr_ui/library/artist_details_ui.rs b/src/ui/lidarr_ui/library/artist_details_ui.rs index 939fea4..952bfc1 100644 --- a/src/ui/lidarr_ui/library/artist_details_ui.rs +++ b/src/ui/lidarr_ui/library/artist_details_ui.rs @@ -271,7 +271,7 @@ fn draw_albums_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { album.title.scroll_left_or_reset( get_width_from_percentage(area, 33), *album == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let monitored = if album.monitored { "🏷" } else { "" }; let album_type = album.album_type.clone().unwrap_or_default(); @@ -376,7 +376,7 @@ fn draw_artist_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ @@ -490,7 +490,7 @@ fn draw_artist_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { get_width_from_percentage(area, 35), current_selection == *release && active_lidarr_block != ActiveLidarrBlock::ManualArtistSearchConfirmPrompt, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let size = convert_to_gb(*size); let rejected_str = if *rejected { "⛔" } else { "" }; diff --git a/src/ui/lidarr_ui/library/mod.rs b/src/ui/lidarr_ui/library/mod.rs index 449a4f9..4f981aa 100644 --- a/src/ui/lidarr_ui/library/mod.rs +++ b/src/ui/lidarr_ui/library/mod.rs @@ -96,7 +96,7 @@ fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { artist.artist_name.scroll_left_or_reset( get_width_from_percentage(area, 25), *artist == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let monitored = if artist.monitored { "🏷" } else { "" }; let artist_type = artist.artist_type.clone().unwrap_or_default(); diff --git a/src/ui/lidarr_ui/library/track_details_ui.rs b/src/ui/lidarr_ui/library/track_details_ui.rs index cf330cc..f9c3d72 100644 --- a/src/ui/lidarr_ui/library/track_details_ui.rs +++ b/src/ui/lidarr_ui/library/track_details_ui.rs @@ -158,7 +158,7 @@ fn draw_track_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 502a7c1..17bc5a7 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -139,7 +139,7 @@ fn draw_error(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { app .error - .scroll_left_or_reset(area.width as usize, true, app.ui_scroll_tick_count == 0); + .scroll_left_or_reset(area.width as usize, true, app.should_text_scroll); let paragraph = Paragraph::new(Text::from(app.error.to_string().failure())) .block(block) diff --git a/src/ui/radarr_ui/blocklist/mod.rs b/src/ui/radarr_ui/blocklist/mod.rs index 3fb243b..1101e45 100644 --- a/src/ui/radarr_ui/blocklist/mod.rs +++ b/src/ui/radarr_ui/blocklist/mod.rs @@ -96,7 +96,7 @@ fn draw_blocklist_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { movie.title.scroll_left_or_reset( get_width_from_percentage(area, 20), current_selection == *blocklist_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let languages_string = languages diff --git a/src/ui/radarr_ui/collections/collection_details_ui.rs b/src/ui/radarr_ui/collections/collection_details_ui.rs index 3daeaa4..f0bf0d4 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui.rs @@ -90,7 +90,7 @@ pub fn draw_collection_details(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) movie.title.scroll_left_or_reset( get_width_from_percentage(table_area, 20), current_selection == *movie, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let (hours, minutes) = convert_runtime(movie.runtime); let imdb_rating = movie diff --git a/src/ui/radarr_ui/collections/mod.rs b/src/ui/radarr_ui/collections/mod.rs index 63ed8a8..870a123 100644 --- a/src/ui/radarr_ui/collections/mod.rs +++ b/src/ui/radarr_ui/collections/mod.rs @@ -70,7 +70,7 @@ pub(super) fn draw_collections(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) collection.title.scroll_left_or_reset( get_width_from_percentage(area, 25), *collection == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let monitored = if collection.monitored { "🏷" } else { "" }; let search_on_add = if collection.search_on_add { diff --git a/src/ui/radarr_ui/downloads/mod.rs b/src/ui/radarr_ui/downloads/mod.rs index 2e52d7b..af14789 100644 --- a/src/ui/radarr_ui/downloads/mod.rs +++ b/src/ui/radarr_ui/downloads/mod.rs @@ -87,7 +87,7 @@ fn draw_downloads(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { output_path.as_ref().unwrap().scroll_left_or_reset( get_width_from_percentage(area, 18), current_selection == *download_record, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); } diff --git a/src/ui/radarr_ui/history/mod.rs b/src/ui/radarr_ui/history/mod.rs index 797ee58..5ac566f 100644 --- a/src/ui/radarr_ui/history/mod.rs +++ b/src/ui/radarr_ui/history/mod.rs @@ -61,7 +61,7 @@ fn draw_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ diff --git a/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs b/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs index 3fc509d..12bc402 100644 --- a/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs +++ b/src/ui/radarr_ui/indexers/test_all_indexers_ui.rs @@ -47,7 +47,7 @@ fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, are result.validation_failures.scroll_left_or_reset( get_width_from_percentage(area, 86), *result == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let pass_fail = if result.is_valid { "✔" } else { "❌" }; let row = Row::new(vec![ diff --git a/src/ui/radarr_ui/library/add_movie_ui.rs b/src/ui/radarr_ui/library/add_movie_ui.rs index f3afa39..fa24913 100644 --- a/src/ui/radarr_ui/library/add_movie_ui.rs +++ b/src/ui/radarr_ui/library/add_movie_ui.rs @@ -141,7 +141,7 @@ fn draw_add_movie_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { movie.title.scroll_left_or_reset( get_width_from_percentage(area, 27), *movie == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ diff --git a/src/ui/radarr_ui/library/mod.rs b/src/ui/radarr_ui/library/mod.rs index 2ba46ae..0b1af8d 100644 --- a/src/ui/radarr_ui/library/mod.rs +++ b/src/ui/radarr_ui/library/mod.rs @@ -90,7 +90,7 @@ fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { movie.title.scroll_left_or_reset( get_width_from_percentage(area, 27), *movie == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let monitored = if movie.monitored { "🏷" } else { "" }; let studio = movie.studio.clone().unwrap_or_default(); diff --git a/src/ui/radarr_ui/library/movie_details_ui.rs b/src/ui/radarr_ui/library/movie_details_ui.rs index e36ecad..bd2c41f 100644 --- a/src/ui/radarr_ui/library/movie_details_ui.rs +++ b/src/ui/radarr_ui/library/movie_details_ui.rs @@ -250,7 +250,7 @@ fn draw_movie_history(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { movie_history_item.source_title.scroll_left_or_reset( get_width_from_percentage(area, 34), current_selection == *movie_history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ @@ -402,7 +402,7 @@ fn draw_movie_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { get_width_from_percentage(area, 30), current_selection == *release && current_route != ActiveRadarrBlock::ManualSearchConfirmPrompt.into(), - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let size = convert_to_gb(*size); let rejected_str = if *rejected { "⛔" } else { "" }; diff --git a/src/ui/sonarr_ui/downloads/mod.rs b/src/ui/sonarr_ui/downloads/mod.rs index 5706bd4..bf46b5b 100644 --- a/src/ui/sonarr_ui/downloads/mod.rs +++ b/src/ui/sonarr_ui/downloads/mod.rs @@ -88,7 +88,7 @@ fn draw_downloads(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { output_path.as_ref().unwrap().scroll_left_or_reset( get_width_from_percentage(area, 18), current_selection == *download_record, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); } diff --git a/src/ui/sonarr_ui/history/mod.rs b/src/ui/sonarr_ui/history/mod.rs index b37bf8c..8e6a24a 100644 --- a/src/ui/sonarr_ui/history/mod.rs +++ b/src/ui/sonarr_ui/history/mod.rs @@ -61,7 +61,7 @@ fn draw_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ diff --git a/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs b/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs index bc02ed8..6a3c164 100644 --- a/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs +++ b/src/ui/sonarr_ui/indexers/test_all_indexers_ui.rs @@ -46,7 +46,7 @@ fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, are result.validation_failures.scroll_left_or_reset( get_width_from_percentage(area, 86), *result == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let pass_fail = if result.is_valid { "✔" } else { "❌" }; let row = Row::new(vec![ diff --git a/src/ui/sonarr_ui/library/add_series_ui.rs b/src/ui/sonarr_ui/library/add_series_ui.rs index 942cb8e..5836f01 100644 --- a/src/ui/sonarr_ui/library/add_series_ui.rs +++ b/src/ui/sonarr_ui/library/add_series_ui.rs @@ -121,7 +121,7 @@ fn draw_add_series_search(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { series.title.scroll_left_or_reset( get_width_from_percentage(area, 27), *series == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ diff --git a/src/ui/sonarr_ui/library/episode_details_ui.rs b/src/ui/sonarr_ui/library/episode_details_ui.rs index 3d78a26..c1776e1 100644 --- a/src/ui/sonarr_ui/library/episode_details_ui.rs +++ b/src/ui/sonarr_ui/library/episode_details_ui.rs @@ -279,7 +279,7 @@ fn draw_episode_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ @@ -414,7 +414,7 @@ fn draw_episode_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { get_width_from_percentage(area, 30), current_selection == *release && active_sonarr_block != ActiveSonarrBlock::ManualEpisodeSearchConfirmPrompt, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let size = convert_to_gb(*size); let rejected_str = if *rejected { "⛔" } else { "" }; diff --git a/src/ui/sonarr_ui/library/mod.rs b/src/ui/sonarr_ui/library/mod.rs index 19569ef..2cef864 100644 --- a/src/ui/sonarr_ui/library/mod.rs +++ b/src/ui/sonarr_ui/library/mod.rs @@ -95,7 +95,7 @@ fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { series.title.scroll_left_or_reset( get_width_from_percentage(area, 23), *series == current_selection, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let monitored = if series.monitored { "🏷" } else { "" }; let certification = series.certification.clone().unwrap_or_default(); diff --git a/src/ui/sonarr_ui/library/season_details_ui.rs b/src/ui/sonarr_ui/library/season_details_ui.rs index f77caad..92926a3 100644 --- a/src/ui/sonarr_ui/library/season_details_ui.rs +++ b/src/ui/sonarr_ui/library/season_details_ui.rs @@ -266,7 +266,7 @@ fn draw_season_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![ @@ -377,7 +377,7 @@ fn draw_season_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { get_width_from_percentage(area, 30), current_selection == *release && active_sonarr_block != ActiveSonarrBlock::ManualSeasonSearchConfirmPrompt, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); let size = convert_to_gb(*size); let rejected_str = if *rejected { "⛔" } else { "" }; diff --git a/src/ui/sonarr_ui/library/series_details_ui.rs b/src/ui/sonarr_ui/library/series_details_ui.rs index 37dce9b..3958763 100644 --- a/src/ui/sonarr_ui/library/series_details_ui.rs +++ b/src/ui/sonarr_ui/library/series_details_ui.rs @@ -314,7 +314,7 @@ fn draw_series_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { source_title.scroll_left_or_reset( get_width_from_percentage(area, 40), current_selection == *history_item, - app.ui_scroll_tick_count == 0, + app.should_text_scroll, ); Row::new(vec![