Add support for previewing images in room scrollback (#108)

This commit is contained in:
Benjamin Grosse 2023-11-16 08:36:22 -08:00 committed by GitHub
parent 974775b29b
commit 221faa828d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 588 additions and 29 deletions

View file

@ -1,6 +1,7 @@
//! Message scrollback
use std::collections::HashSet;
use ratatui_image::FixedImage;
use regex::Regex;
use matrix_sdk::ruma::OwnedRoomId;
@ -1264,6 +1265,7 @@ impl<'a> StatefulWidget for Scrollback<'a> {
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let info = self.store.application.rooms.get_or_default(state.room_id.clone());
let settings = &self.store.application.settings;
let picker = &self.store.application.picker;
let area = if state.cursor.timestamp.is_some() {
render_jump_to_recent(area, buf, self.focused)
} else {
@ -1307,7 +1309,11 @@ impl<'a> StatefulWidget for Scrollback<'a> {
let sel = key == cursor_key;
let txt = item.show(prev, foc && sel, &state.viewctx, info, settings);
prev = Some(item);
let mut msg_preview = if picker.is_some() {
item.line_preview(prev, &state.viewctx, info)
} else {
None
};
let incomplete_ok = !full || !sel;
@ -1323,9 +1329,17 @@ impl<'a> StatefulWidget for Scrollback<'a> {
continue;
}
lines.push((key, row, line));
let line_preview = match msg_preview {
// Only take the preview into the matching row number.
Some((_, _, y)) if y as usize == row => msg_preview.take(),
_ => None,
};
lines.push((key, row, line, line_preview));
sawit |= sel;
}
prev = Some(item);
}
if lines.len() > height {
@ -1333,7 +1347,7 @@ impl<'a> StatefulWidget for Scrollback<'a> {
let _ = lines.drain(..n);
}
if let Some(((ts, event_id), row, _)) = lines.first() {
if let Some(((ts, event_id), row, _, _)) = lines.first() {
state.viewctx.corner.timestamp = Some((*ts, event_id.clone()));
state.viewctx.corner.text_row = *row;
}
@ -1341,11 +1355,27 @@ impl<'a> StatefulWidget for Scrollback<'a> {
let mut y = area.top();
let x = area.left();
for (_, _, txt) in lines.into_iter() {
let mut image_previews = vec![];
for ((_, _), _, txt, line_preview) in lines.into_iter() {
let _ = buf.set_line(x, y, &txt, area.width);
if let Some((backend, msg_x, _)) = line_preview {
image_previews.push((x + msg_x, y, backend));
}
y += 1;
}
// Render image previews after all text lines have been drawn, as the render might draw below the current
// line.
for (x, y, backend) in image_previews {
let image_widget = FixedImage::new(backend);
let mut rect = backend.rect();
rect.x = x;
rect.y = y;
// Don't render outside of scrollback area
if rect.bottom() <= area.bottom() && rect.right() <= area.right() {
image_widget.render(rect, buf);
}
}
if self.room_focused &&
settings.tunables.read_receipt_send &&