From d79f5d7527df16153ee8be2c4158bb26baf9c6c7 Mon Sep 17 00:00:00 2001 From: Val Lorentz Date: Wed, 22 Nov 2023 16:51:29 +0100 Subject: [PATCH] Make history-related constants configurable --- src/app.rs | 5 +++-- src/buffers/room.rs | 18 +++++++++++++++--- src/components/backlog.rs | 11 +++++++---- src/components/buflist.rs | 6 ++++-- src/components/home.rs | 5 +++-- src/config.rs | 9 +++++++++ src/default_config.toml | 17 +++++++++++++++++ tests/components/backlog.rs | 3 ++- 8 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/app.rs b/src/app.rs index 25d4db1..fb631a5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -39,7 +39,7 @@ use crate::{ }; pub struct App { - pub config: Config, + pub config: Arc, pub clients: NonEmpty, pub commands: RataCommands, pub tick_rate: f64, @@ -120,6 +120,7 @@ impl App { } let clients = NonEmpty::collect(clients).expect("map on NonEmpty returned empty vec"); + let config = Arc::new(config); let home = Home::new(config.clone()); let fps = FpsCounter::default(); let mode = Mode::Home; @@ -398,7 +399,7 @@ impl App { ) { futures::future::join_all( rooms - .map(|(client, room)| RoomBuffer::new(client, room)) + .map(|(client, room)| RoomBuffer::new(self.config.clone(), client, room)) .map(|fut| fut.map(|res| res.expect("Failed to create RoomBuffer at startup"))), ) .await diff --git a/src/buffers/room.rs b/src/buffers/room.rs index 30b702f..3e96e20 100644 --- a/src/buffers/room.rs +++ b/src/buffers/room.rs @@ -47,6 +47,7 @@ use sorted_vec::SortedVec; use tokio::sync::oneshot; use super::{Buffer, BufferId, BufferItem, BufferItemContent, BufferSortKey, FullyReadStatus}; +use crate::config::Config; use crate::widgets::Prerender; /// Like [`BufferItemContent`] but owned. @@ -368,6 +369,8 @@ impl SingleClientRoomBuffer { } pub struct RoomBuffer { + config: Arc, + room_id: OwnedRoomId, computed_roominfo: Option, @@ -400,8 +403,13 @@ impl DynamicUsage for RoomBuffer { } impl RoomBuffer { - pub async fn new(initial_client: Client, room_id: OwnedRoomId) -> Result { + pub async fn new( + config: Arc, + initial_client: Client, + room_id: OwnedRoomId, + ) -> Result { let mut self_ = RoomBuffer { + config, room_id, computed_roominfo: None, update_roominfo_rx: None, @@ -674,8 +682,12 @@ impl Buffer for RoomBuffer { // * we already backfilled a lot so we don't exhaust the available memory // * we already reached an unread message, in which case it's pointless to // backfill as we already know there are unread messages. - if buf.items.len() < 1000 { - buf.back_pagination_request.fetch_max(50, Ordering::Relaxed); + if buf.items.len() < self.config.history.max_prefetch_unread + && self.config.history.prefetch_unread > 0 + { + buf + .back_pagination_request + .fetch_max(self.config.history.prefetch_unread, Ordering::Relaxed); } } } diff --git a/src/components/backlog.rs b/src/components/backlog.rs index 6c3cd95..2e89d0e 100644 --- a/src/components/backlog.rs +++ b/src/components/backlog.rs @@ -15,6 +15,7 @@ */ use std::ops::DerefMut; +use std::sync::Arc; use color_eyre::eyre::{Result, WrapErr}; use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; @@ -41,7 +42,7 @@ struct ScrollPosition { #[derive(Debug)] pub struct Backlog { - config: Config, + config: Arc, /// Used to compute scroll on PageUp/PageDown when configured to a percentage. last_height: u16, scroll_position: Option, @@ -97,8 +98,10 @@ impl Component for Backlog { // We are reaching the end of the backlog we have locally, ask the buffer to fetch // more if it can - if undrawn_widgets_at_top <= 100 { - active_buffer.request_back_pagination(200); + if undrawn_widgets_at_top <= self.config.history.min_prefetch + && self.config.history.prefetch > 0 + { + active_buffer.request_back_pagination(self.config.history.prefetch); } Ok(()) @@ -106,7 +109,7 @@ impl Component for Backlog { } impl Backlog { - pub fn new(config: Config) -> Self { + pub fn new(config: Arc) -> Self { Backlog { config, last_height: 30, // Arbitrary default, only useful when user scrolls before first render diff --git a/src/components/buflist.rs b/src/components/buflist.rs index 9a6d575..d2f7518 100644 --- a/src/components/buflist.rs +++ b/src/components/buflist.rs @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +use std::sync::Arc; + use color_eyre::eyre::{Result, WrapErr}; use crossterm::event::{MouseEvent, MouseEventKind}; use ratatui::{prelude::*, widgets::*}; @@ -29,14 +31,14 @@ use crate::{ pub struct Buflist { command_tx: Option>, - config: Config, + config: Arc, /// Updated by [`draw`], used by [`handle_mouse_events`] to find which buffer was clicked. last_area: Option, last_num_buffers: Option, } impl Buflist { - pub fn new(config: Config) -> Self { + pub fn new(config: Arc) -> Self { Buflist { command_tx: None, config, diff --git a/src/components/home.rs b/src/components/home.rs index b0849c2..aabec48 100644 --- a/src/components/home.rs +++ b/src/components/home.rs @@ -14,6 +14,7 @@ * along with this program. If not, see . */ +use std::sync::Arc; use std::{collections::HashMap, time::Duration}; use color_eyre::eyre::{Result, WrapErr}; @@ -32,14 +33,14 @@ use crate::{ pub struct Home { command_tx: Option>, - config: Config, + config: Arc, buflist: Buflist, backlog: Backlog, textarea: TextArea<'static>, } impl Home { - pub fn new(config: Config) -> Self { + pub fn new(config: Arc) -> Self { let mut self_ = Home { command_tx: None, buflist: Buflist::new(config.clone()), diff --git a/src/config.rs b/src/config.rs index a28eb96..7e16db9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -102,6 +102,14 @@ impl<'de> Visitor<'de> for ScrollAmountVisitor { } } +#[derive(Clone, Debug, Deserialize)] +pub struct HistoryConfig { + pub prefetch_unread: u16, + pub max_prefetch_unread: usize, + pub min_prefetch: usize, + pub prefetch: u16, +} + #[derive(Clone, Debug, Deserialize)] pub struct MouseConfig { pub enable: bool, @@ -149,6 +157,7 @@ pub struct Config { #[serde(default, flatten)] pub config: AppConfig, pub accounts: nonempty::NonEmpty, + pub history: HistoryConfig, #[serde(default)] pub keybindings: KeyBindings, pub keyboard: KeyboardConfig, diff --git a/src/default_config.toml b/src/default_config.toml index 9947270..0d3eebf 100644 --- a/src/default_config.toml +++ b/src/default_config.toml @@ -14,6 +14,23 @@ scroll_page = "50%" [mouse] enable = true +[history] +# When there are unread events in a room, how many past events should be fetched +# at once to check whether there are unread messages (as opposed to non-message +# events), to find if the room should colored with style.buflist.unread_message or +# style.buflist.unread_event +prefetch_unread = 50 +# When do stop iteratively fetching pages of size $prefetch_unread when no unread +# messages are found +max_prefetch_unread = 1000 + +# How many older events to keep above the screen in case the user hits PageUp later. +# Set to 0 to only fetch when the user reaches an unfetched message. +min_prefetch = 100 +# When getting close to the oldest event we know about, how many events should be +# fetched at once +prefetch = 200 + # Configuration for the list of rooms on the right. [layout.buflist] # How long room names can be before being truncated. diff --git a/tests/components/backlog.rs b/tests/components/backlog.rs index f0139e7..96ef5e8 100644 --- a/tests/components/backlog.rs +++ b/tests/components/backlog.rs @@ -14,6 +14,7 @@ * along with this program. If not, see . */ +use std::sync::Arc; use std::path::PathBuf; use color_eyre::eyre::WrapErr; @@ -29,7 +30,7 @@ fn config() -> Config { std::env::set_var("RATATRIX_CONFIG", PathBuf::from(".config/")); let c = Config::new(); std::env::remove_var("RATATRIX_CONFIG"); - c.unwrap() + Arc::new(c.unwrap()) } fn rect(x: u16, y: u16, width: u16, height: u16) -> Rect {