Skip to content

Commit

Permalink
Merge pull request #3550 from Hywan/fix-ui-timeline-duplicated-events
Browse files Browse the repository at this point in the history
fix(ui): Change the behaviour when a duplicated event is received by the `Timeline`
  • Loading branch information
Hywan authored Jun 13, 2024
2 parents de5d805 + d46e658 commit 868e821
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
48 changes: 38 additions & 10 deletions crates/matrix-sdk-ui/src/timeline/inner/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,9 @@ impl TimelineInnerStateTransaction<'_> {
timestamp: Some(event.origin_server_ts()),
visible: false,
};
self.add_event(event_meta, position, room_data_provider, settings).await;
let _event_added_or_updated = self
.add_or_update_event(event_meta, position, room_data_provider, settings)
.await;

return HandleEventResult::default();
}
Expand All @@ -526,7 +528,9 @@ impl TimelineInnerStateTransaction<'_> {
timestamp,
visible: false,
};
self.add_event(event_meta, position, room_data_provider, settings).await;
let _event_added_or_updated = self
.add_or_update_event(event_meta, position, room_data_provider, settings)
.await;
}

return HandleEventResult::default();
Expand All @@ -543,7 +547,15 @@ impl TimelineInnerStateTransaction<'_> {
timestamp: Some(timestamp),
visible: should_add,
};
self.add_event(event_meta, position, room_data_provider, settings).await;

let event_added_or_updated =
self.add_or_update_event(event_meta, position, room_data_provider, settings).await;

// If the event has not been added or updated, it's because it's a duplicated
// event. Let's return early.
if !event_added_or_updated {
return HandleEventResult::default();
}

let sender_profile = room_data_provider.profile_from_user_id(&sender).await;
let ctx = TimelineEventContext {
Expand Down Expand Up @@ -637,23 +649,37 @@ impl TimelineInnerStateTransaction<'_> {
items.commit();
}

async fn add_event<P: RoomDataProvider>(
/// Add or update an event in the [`TimelineInnerMeta::all_events`]
/// collection.
///
/// This method also adjusts read receipt if needed.
///
/// It returns `true` if the event has been added or updated, `false`
/// otherwise. The latter happens if the event already exists, i.e. if
/// an existing event is requested to be added.
async fn add_or_update_event<P: RoomDataProvider>(
&mut self,
event_meta: FullEventMeta<'_>,
position: TimelineItemPosition,
room_data_provider: &P,
settings: &TimelineInnerSettings,
) {
) -> bool {
// Detect if an event already exists in [`TimelineInnerMeta::all_events`]
fn event_already_exists(new_event_id: &EventId, all_events: &VecDeque<EventMeta>) -> bool {
all_events.iter().any(|EventMeta { event_id, .. }| event_id == new_event_id)
}

match position {
TimelineItemPosition::Start { .. } => {
if event_already_exists(event_meta.event_id, &self.meta.all_events) {
return false;
}

self.meta.all_events.push_front(event_meta.base_meta())
}
TimelineItemPosition::End { .. } => {
// Handle duplicated event.
if let Some(pos) =
self.meta.all_events.iter().position(|ev| ev.event_id == event_meta.event_id)
{
self.meta.all_events.remove(pos);
if event_already_exists(event_meta.event_id, &self.meta.all_events) {
return false;
}

self.meta.all_events.push_back(event_meta.base_meta());
Expand Down Expand Up @@ -686,6 +712,8 @@ impl TimelineInnerStateTransaction<'_> {

self.maybe_add_implicit_read_receipt(event_meta);
}

true
}

fn adjust_day_dividers(&mut self, mut adjuster: DayDividerAdjuster) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,10 +416,6 @@ async fn test_timeline_duplicated_events() -> Result<()> {
assert_timeline_stream! {
[timeline_stream]
update[3] "$x3:bar.org";
update[1] "$x1:bar.org";
remove[1];
append "$x1:bar.org";
update[3] "$x1:bar.org";
append "$x4:bar.org";
};
}
Expand Down

0 comments on commit 868e821

Please sign in to comment.