Fetch backlog more eagerly

By fetching it when the user gets close to the end of the backlog (rather than
waiting for them to actually see the end)
This commit is contained in:
2023-11-11 10:59:19 +01:00
parent b1d98c0da0
commit 29d69a2bc0
4 changed files with 25 additions and 28 deletions

View File

@ -76,21 +76,14 @@ impl Buffer for LogBuffer {
self.lines.push_back((line, Prerender::new()));
}
fn content<'a>(&'a self) -> Box<dyn Iterator<Item = BufferItem<'a>> + 'a> {
fn content<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = BufferItem<'a>> + 'a> {
use ansi_to_tui::IntoText;
let (slice1, slice2) = self.lines.as_slices();
Box::new(
slice1
.into_iter()
.chain(slice2.into_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,
}),
)
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,
}))
}
}

View File

@ -62,7 +62,7 @@ pub trait Buffer: Send + Sync + memuse::DynamicUsage {
}
/// Returns if there are any updates to apply.
async fn poll_updates(&mut self);
fn content<'a>(&'a self) -> Box<dyn Iterator<Item = BufferItem<'a>> + 'a>;
fn content<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = BufferItem<'a>> + 'a>;
/// Called when the user is being showned the oldest items this buffer returned.
///
/// This should return immediately, not waiting for anything to be loaded.

View File

@ -521,7 +521,7 @@ impl Buffer for RoomBuffer {
}
}
fn content<'a>(&'a self) -> Box<dyn Iterator<Item = BufferItem<'a>> + 'a> {
fn content<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = BufferItem<'a>> + 'a> {
// TODO: merge buffers, etc.
Box::new(
self

View File

@ -68,11 +68,12 @@ impl Component for Backlog {
) -> Result<()> {
let active_buffer = buffers.active_buffer();
let items = active_buffer.content();
let unused_top_lines = self.draw_items(frame.buffer_mut(), area, items)?;
let undrawn_widgets_at_top = self.draw_items(frame.buffer_mut(), area, items)?;
// There is empty room on screen, ask the buffer to fetch more backlog if it can
if unused_top_lines > 0 {
active_buffer.request_back_pagination(100);
// 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);
}
Ok(())
@ -101,13 +102,14 @@ impl Backlog {
}
}
/// Returns how many lines are unused at the top of the area.
/// Returns how many items were not drawn because they are too high up the backlog
/// (ie. older than the currently displayed items)
pub fn draw_items<'a>(
&mut self,
frame_buffer: &mut Buffer,
area: Rect,
mut items: impl Iterator<Item = BufferItem<'a>>,
) -> Result<u16> {
mut items: impl ExactSizeIterator<Item = BufferItem<'a>>,
) -> Result<usize> {
let block = Block::new().borders(Borders::ALL);
let mut text_area = block.inner(area);
block.render(area, frame_buffer);
@ -163,11 +165,12 @@ impl Backlog {
}
if text_area.height == 0 {
// No more room to display other paragraphs, stop now
return Ok(0);
return Ok(items.len());
}
// Render other widgets
for item in items {
let total_items = items.len();
for (drawn_items, item) in items.enumerate() {
let height = match item.prerender.0.lock().unwrap().deref_mut() {
Some(PrerenderInner {
key,
@ -244,11 +247,12 @@ impl Backlog {
text_area.height = text_area.height.saturating_sub(height); // Remove lines at the bottom used by this paragraph
if text_area.height == 0 {
// No more room to display other paragraphs, stop now
return Ok(0);
return Ok(total_items - drawn_items - 1);
}
}
Ok(text_area.height)
// Loop ended on its own, meaning we ran out if items
Ok(0)
}
}