Skip to content

Commit

Permalink
Handle and parse the image protocol produced by a reply header.
Browse files Browse the repository at this point in the history
It was necessary to break out `Message::show_msg` from `MessageFormatter::push_in_reply`, due to the lifetime of the image protocol.
`Message::show_with_preview` now returns the image protocols of both the body and reply header.
`Scrollback::render` was updated to handle this.
  • Loading branch information
Andrew-Collins committed Oct 16, 2024
1 parent 9a9bdb4 commit 805e5dc
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
34 changes: 26 additions & 8 deletions src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,14 +712,13 @@ impl<'a> MessageFormatter<'a> {
fn push_in_reply(
&mut self,
msg: &'a Message,
mut replied: Text<'a>,
style: Style,
text: &mut Text<'a>,
info: &'a RoomInfo,
) {
let width = self.width();
let w = width.saturating_sub(2);
let shortcodes = self.settings.tunables.message_shortcode_display;
let (mut replied, _) = msg.show_msg(w, style, true, shortcodes);
let mut sender = msg.sender_span(info, self.settings);
let sender_width = UnicodeWidthStr::width(sender.content.as_ref());
let trailing = w.saturating_sub(sender_width + 1);
Expand Down Expand Up @@ -961,22 +960,41 @@ impl Message {
vwctx: &ViewportContext<MessageCursor>,
info: &'a RoomInfo,
settings: &'a ApplicationSettings,
) -> (Text<'a>, Option<(&dyn Protocol, u16, u16)>) {
) -> (Text<'a>, [Option<(&'a dyn Protocol, u16, u16)>; 2]) {

Check warning on line 963 in src/message/mod.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

[clippy] reported by reviewdog 🐶 warning: very complex type used. Consider factoring parts into `type` definitions --> src/message/mod.rs:963:10 | 963 | ) -> (Text<'a>, [Option<(&'a dyn Protocol, u16, u16)>; 2]) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity = note: `#[warn(clippy::type_complexity)]` on by default Raw Output: src/message/mod.rs:963:10:w:warning: very complex type used. Consider factoring parts into `type` definitions --> src/message/mod.rs:963:10 | 963 | ) -> (Text<'a>, [Option<(&'a dyn Protocol, u16, u16)>; 2]) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity = note: `#[warn(clippy::type_complexity)]` on by default __END__
let width = vwctx.get_width();

let style = self.get_render_style(selected, settings);
let mut fmt = self.get_render_format(prev, width, info, settings);
let mut text = Text::default();
let width = fmt.width();
let x_off = fmt.cols.user_gutter_width(settings);

Check warning on line 970 in src/message/mod.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

[clippy] reported by reviewdog 🐶 warning: unused variable: `x_off` --> src/message/mod.rs:970:13 | 970 | let x_off = fmt.cols.user_gutter_width(settings); | ^^^^^ help: if this is intentional, prefix it with an underscore: `_x_off` | = note: `#[warn(unused_variables)]` on by default Raw Output: src/message/mod.rs:970:13:w:warning: unused variable: `x_off` --> src/message/mod.rs:970:13 | 970 | let x_off = fmt.cols.user_gutter_width(settings); | ^^^^^ help: if this is intentional, prefix it with an underscore: `_x_off` | = note: `#[warn(unused_variables)]` on by default __END__
let date_flag = fmt.date.is_some();

// Show the message that this one replied to, if any.
let reply = self
.reply_to()
.or_else(|| self.thread_root())
.and_then(|e| info.get_event(&e));

let mut proto_reply = None;
if let Some(r) = &reply {
fmt.push_in_reply(r, style, &mut text, info);
// Get the text and image content of the reply header
let (msg, proto) =
r.show_msg(width, style, false, settings.tunables.message_shortcode_display);

// Determine the image offset of the reply header, taking into account the formatting
proto_reply = proto.map(|p| {
// Adjust y_off by 1 to account for username
let y_off = text.lines.len() as u16 + 1;
// Adjust x_off by 2 to account for the vertical line and indent
let x_off = fmt.cols.user_gutter_width(settings) + 2;
// Adjust y_off by 1 if a date was printed before the message to account for the extra line.
let y_off = if fmt.date.is_some() { y_off + 1 } else { y_off };
(p, x_off, y_off)
});

// Format the reply header and push it into the `Text` buffer
fmt.push_in_reply(r, msg, style, &mut text, info);
}

// Now show the message contents, and the inlined reply if we couldn't find it above.
Expand All @@ -988,11 +1006,11 @@ impl Message {
);

// Given our text so far, determine the image offset.
let proto = proto.map(|p| {
let proto_main = proto.map(|p| {
let y_off = text.lines.len() as u16;
let x_off = fmt.cols.user_gutter_width(settings);
// Adjust y_off by 1 if a date was printed before the message to account for the extra line.
let y_off = if fmt.date.is_some() { y_off + 1 } else { y_off };
let y_off = if date_flag { y_off + 1 } else { y_off };
(p, x_off, y_off)
});

Expand All @@ -1012,7 +1030,7 @@ impl Message {
fmt.push_thread_reply_count(thread.len(), &mut text);
}

(text, proto)
(text, [proto_main, proto_reply])
}

pub fn show<'a>(
Expand Down Expand Up @@ -1053,7 +1071,7 @@ impl Message {
},
ImageStatus::Loaded(backend) => {
proto = Some(backend.as_ref());
placeholder_frame(None, width, &backend.rect().into())
placeholder_frame(Some("Loading..."), width, &backend.rect().into())
},
ImageStatus::Error(err) => Some(format!("[Image error: {err}]\n")),
};
Expand Down
12 changes: 9 additions & 3 deletions src/windows/room/scrollback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1340,7 +1340,7 @@ impl<'a> StatefulWidget for Scrollback<'a> {

for (key, item) in thread.range(&corner_key..) {
let sel = key == cursor_key;
let (txt, mut msg_preview) =
let (txt, [mut msg_preview, mut reply_preview]) =
item.show_with_preview(prev, foc && sel, &state.viewctx, info, settings);

let incomplete_ok = !full || !sel;
Expand All @@ -1357,11 +1357,17 @@ impl<'a> StatefulWidget for Scrollback<'a> {
continue;
}

// Only take the preview into the matching row number.
// `reply` and `msg` previews are on rows,
// so an `or` works to pick the one that matches (if any)
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,
};
}
.or(match reply_preview {
Some((_, _, y)) if y as usize == row => reply_preview.take(),
_ => None,
});

lines.push((key, row, line, line_preview));
sawit |= sel;
Expand Down

0 comments on commit 805e5dc

Please sign in to comment.