From bd99c5e72b18618db0cb3ab6d680d34a246ef11b Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 4 Sep 2023 15:54:56 +0200 Subject: [PATCH] ui: Transfer reply details from old to new item when receiving dup event --- .../src/timeline/event_handler.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/matrix-sdk-ui/src/timeline/event_handler.rs b/crates/matrix-sdk-ui/src/timeline/event_handler.rs index 688190466..acf729e5a 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_handler.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_handler.rs @@ -936,6 +936,8 @@ impl<'a> TimelineEventHandler<'a> { // TODO: Check whether anything is different about the // old and new item? + transfer_details(&mut item, &old_item); + let old_item_id = old_item.internal_id; if idx == self.state.items.len() - 1 @@ -1135,6 +1137,24 @@ impl<'a> TimelineEventHandler<'a> { } } +/// Transfer `TimelineDetails` that weren't available on the original item and +/// have been fetched separately (only `reply_to` for now) from `old_item` to +/// `item`, given two items for an event that was re-received. +/// +/// `old_item` *should* always be a local echo usually, but with the sliding +/// sync proxy, we often re-receive remote events that aren't remote echoes. +fn transfer_details(item: &mut EventTimelineItem, old_item: &EventTimelineItem) { + let TimelineItemContent::Message(msg) = &mut item.content else { return }; + let TimelineItemContent::Message(old_msg) = &old_item.content else { return }; + + let Some(in_reply_to) = &mut msg.in_reply_to else { return }; + let Some(old_in_reply_to) = &old_msg.in_reply_to else { return }; + + if matches!(&in_reply_to.event, TimelineDetails::Unavailable) { + in_reply_to.event = old_in_reply_to.event.clone(); + } +} + pub(crate) fn update_read_marker( items: &mut ObservableVector>, fully_read_event: Option<&EventId>,