mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-13 02:25:51 -04:00
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:
@@ -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;
|
||||
|
||||
@@ -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, ..
|
||||
} => {
|
||||
|
||||
Reference in New Issue
Block a user