By fetching it when the user gets close to the end of the backlog (rather than waiting for them to actually see the end)
90 lines
2.4 KiB
Rust
90 lines
2.4 KiB
Rust
/*
|
|
* Copyright (C) 2023 Valentin Lorentz
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License version 3,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
use std::collections::VecDeque;
|
|
use std::sync::Arc;
|
|
use std::sync::RwLock;
|
|
|
|
use matrix_sdk::async_trait;
|
|
use memuse::DynamicUsage;
|
|
use ratatui::text::Text;
|
|
use tokio::sync::mpsc::UnboundedReceiver;
|
|
use tracing_error::ErrorLayer;
|
|
use tracing_subscriber::prelude::*;
|
|
|
|
use super::{Buffer, BufferId, BufferItem, BufferItemContent};
|
|
use crate::widgets::Prerender;
|
|
|
|
/// Maximum number of log lines to be stored in memory
|
|
const MAX_MEM_LOG_LINES: usize = 1000;
|
|
|
|
pub struct LogBuffer {
|
|
lines: VecDeque<(String, Prerender)>,
|
|
receiver: UnboundedReceiver<String>,
|
|
}
|
|
|
|
impl LogBuffer {
|
|
pub fn new(receiver: UnboundedReceiver<String>) -> Self {
|
|
LogBuffer {
|
|
lines: VecDeque::new(),
|
|
receiver,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl DynamicUsage for LogBuffer {
|
|
fn dynamic_usage(&self) -> usize {
|
|
self.lines.dynamic_usage()
|
|
}
|
|
fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
|
|
self.lines.dynamic_usage_bounds()
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Buffer for LogBuffer {
|
|
fn short_name(&self) -> String {
|
|
"ratatrix".to_owned()
|
|
}
|
|
|
|
fn id(&self) -> BufferId {
|
|
BufferId::Log
|
|
}
|
|
|
|
async fn poll_updates(&mut self) {
|
|
let line = self
|
|
.receiver
|
|
.recv()
|
|
.await
|
|
.expect("LogBuffer's channel was closed");
|
|
if self.lines.len() >= MAX_MEM_LOG_LINES {
|
|
self.lines.pop_front();
|
|
}
|
|
self.lines.push_back((line, Prerender::new()));
|
|
}
|
|
|
|
fn content<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = BufferItem<'a>> + 'a> {
|
|
use ansi_to_tui::IntoText;
|
|
Box::new(self.lines.iter().rev().map(|(line, prerender)| BufferItem {
|
|
content: BufferItemContent::Text(line.clone().into_text().unwrap_or_else(|e| {
|
|
tracing::error!("Could not convert line from ANSI codes to ratatui: {}", e);
|
|
Text::raw(line)
|
|
})),
|
|
prerender,
|
|
}))
|
|
}
|
|
}
|