task(ui): Support VectorDiff::Insert in TimelineStateTransaction::handle_remote_events_with_diffs.

This patch updates
`TimelineStateTransaction::handle_remote_events_with_diffs` to support
`VectorDiff::Insert`.
This commit is contained in:
Ivan Enderlin
2024-12-10 09:38:03 +01:00
parent b25fd830ec
commit 409fccb709
2 changed files with 78 additions and 4 deletions

View File

@@ -485,6 +485,17 @@ impl TimelineStateTransaction<'_> {
.await;
}
VectorDiff::Insert { index: event_index, value: event } => {
self.handle_remote_event(
event,
TimelineItemPosition::At { event_index, origin },
room_data_provider,
settings,
&mut day_divider_adjuster,
)
.await;
}
VectorDiff::Clear => {
self.clear();
}
@@ -550,7 +561,8 @@ impl TimelineStateTransaction<'_> {
// Retrieve the origin of the event.
let origin = match position {
TimelineItemPosition::End { origin }
| TimelineItemPosition::Start { origin } => origin,
| TimelineItemPosition::Start { origin }
| TimelineItemPosition::At { origin, .. } => origin,
TimelineItemPosition::UpdateDecrypted { timeline_item_index: idx } => self
.items
@@ -826,6 +838,10 @@ impl TimelineStateTransaction<'_> {
self.items.push_back_remote_event(event_meta.base_meta());
}
TimelineItemPosition::At { event_index, .. } => {
self.items.insert_remote_event(event_index, event_meta.base_meta());
}
TimelineItemPosition::UpdateDecrypted { .. } => {
if let Some(event) =
self.items.get_remote_event_by_event_id_mut(event_meta.event_id)
@@ -846,7 +862,9 @@ impl TimelineStateTransaction<'_> {
if settings.track_read_receipts
&& matches!(
position,
TimelineItemPosition::Start { .. } | TimelineItemPosition::End { .. }
TimelineItemPosition::Start { .. }
| TimelineItemPosition::End { .. }
| TimelineItemPosition::At { .. }
)
{
self.load_read_receipts_for_event(event_meta.event_id, room_data_provider).await;

View File

@@ -290,6 +290,15 @@ pub(super) enum TimelineItemPosition {
origin: RemoteEventOrigin,
},
/// One item is inserted to the timeline.
At {
/// Where to insert the remote event.
event_index: usize,
/// The origin of the new item.
origin: RemoteEventOrigin,
},
/// A single item is updated, after it's been successfully decrypted.
///
/// This happens when an item that was a UTD must be replaced with the
@@ -595,7 +604,9 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
replacement: PendingEdit,
) {
match position {
TimelineItemPosition::Start { .. } | TimelineItemPosition::UpdateDecrypted { .. } => {
TimelineItemPosition::Start { .. }
| TimelineItemPosition::At { .. }
| TimelineItemPosition::UpdateDecrypted { .. } => {
// Only insert the edit if there wasn't any other edit
// before.
//
@@ -1039,7 +1050,8 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
Flow::Remote { event_id, raw_event, position, txn_id, encryption_info, .. } => {
let origin = match *position {
TimelineItemPosition::Start { origin }
| TimelineItemPosition::End { origin } => origin,
| TimelineItemPosition::End { origin }
| TimelineItemPosition::At { origin, .. } => origin,
// For updates, reuse the origin of the encrypted event.
TimelineItemPosition::UpdateDecrypted { timeline_item_index: idx } => self
@@ -1108,6 +1120,50 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
self.items.push_front(item, Some(0));
}
Flow::Remote { position: TimelineItemPosition::At { event_index, .. }, .. } => {
let all_remote_events = self.items.all_remote_events();
let event_index = *event_index;
// Look for the closest `timeline_item_index` at the left of `event_index`.
let timeline_item_index = all_remote_events
.range(0..=event_index)
.rev()
.find_map(|event_meta| event_meta.timeline_item_index)
// The new `timeline_item_index` is the previous + 1.
.map(|timeline_item_index| timeline_item_index + 1);
// No index? Look for the closest `timeline_item_index` at the right of
// `event_index`.
let timeline_item_index = timeline_item_index.or_else(|| {
all_remote_events
.range(event_index + 1..)
.find_map(|event_meta| event_meta.timeline_item_index)
});
// Still no index? Well, it means there is no existing `timeline_item_index`
// so we are inserting at the last non-local item position as a fallback.
let timeline_item_index = timeline_item_index.unwrap_or_else(|| {
self.items
.iter()
.enumerate()
.rev()
.find_map(|(timeline_item_index, timeline_item)| {
(!timeline_item.as_event()?.is_local_echo())
.then_some(timeline_item_index + 1)
})
.unwrap_or(0)
});
trace!(
?event_index,
?timeline_item_index,
"Adding new remote timeline at specific event index"
);
let item = self.meta.new_timeline_item(item);
self.items.insert(timeline_item_index, item, Some(event_index));
}
Flow::Remote {
position: TimelineItemPosition::End { .. }, txn_id, event_id, ..
} => {