Skip to content

Commit 868e821

Browse files
authored
Merge pull request #3550 from Hywan/fix-ui-timeline-duplicated-events
fix(ui): Change the behaviour when a duplicated event is received by the `Timeline`
2 parents de5d805 + d46e658 commit 868e821

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

crates/matrix-sdk-ui/src/timeline/inner/state.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,9 @@ impl TimelineInnerStateTransaction<'_> {
501501
timestamp: Some(event.origin_server_ts()),
502502
visible: false,
503503
};
504-
self.add_event(event_meta, position, room_data_provider, settings).await;
504+
let _event_added_or_updated = self
505+
.add_or_update_event(event_meta, position, room_data_provider, settings)
506+
.await;
505507

506508
return HandleEventResult::default();
507509
}
@@ -526,7 +528,9 @@ impl TimelineInnerStateTransaction<'_> {
526528
timestamp,
527529
visible: false,
528530
};
529-
self.add_event(event_meta, position, room_data_provider, settings).await;
531+
let _event_added_or_updated = self
532+
.add_or_update_event(event_meta, position, room_data_provider, settings)
533+
.await;
530534
}
531535

532536
return HandleEventResult::default();
@@ -543,7 +547,15 @@ impl TimelineInnerStateTransaction<'_> {
543547
timestamp: Some(timestamp),
544548
visible: should_add,
545549
};
546-
self.add_event(event_meta, position, room_data_provider, settings).await;
550+
551+
let event_added_or_updated =
552+
self.add_or_update_event(event_meta, position, room_data_provider, settings).await;
553+
554+
// If the event has not been added or updated, it's because it's a duplicated
555+
// event. Let's return early.
556+
if !event_added_or_updated {
557+
return HandleEventResult::default();
558+
}
547559

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

640-
async fn add_event<P: RoomDataProvider>(
652+
/// Add or update an event in the [`TimelineInnerMeta::all_events`]
653+
/// collection.
654+
///
655+
/// This method also adjusts read receipt if needed.
656+
///
657+
/// It returns `true` if the event has been added or updated, `false`
658+
/// otherwise. The latter happens if the event already exists, i.e. if
659+
/// an existing event is requested to be added.
660+
async fn add_or_update_event<P: RoomDataProvider>(
641661
&mut self,
642662
event_meta: FullEventMeta<'_>,
643663
position: TimelineItemPosition,
644664
room_data_provider: &P,
645665
settings: &TimelineInnerSettings,
646-
) {
666+
) -> bool {
667+
// Detect if an event already exists in [`TimelineInnerMeta::all_events`]
668+
fn event_already_exists(new_event_id: &EventId, all_events: &VecDeque<EventMeta>) -> bool {
669+
all_events.iter().any(|EventMeta { event_id, .. }| event_id == new_event_id)
670+
}
671+
647672
match position {
648673
TimelineItemPosition::Start { .. } => {
674+
if event_already_exists(event_meta.event_id, &self.meta.all_events) {
675+
return false;
676+
}
677+
649678
self.meta.all_events.push_front(event_meta.base_meta())
650679
}
651680
TimelineItemPosition::End { .. } => {
652-
// Handle duplicated event.
653-
if let Some(pos) =
654-
self.meta.all_events.iter().position(|ev| ev.event_id == event_meta.event_id)
655-
{
656-
self.meta.all_events.remove(pos);
681+
if event_already_exists(event_meta.event_id, &self.meta.all_events) {
682+
return false;
657683
}
658684

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

687713
self.maybe_add_implicit_read_receipt(event_meta);
688714
}
715+
716+
true
689717
}
690718

691719
fn adjust_day_dividers(&mut self, mut adjuster: DayDividerAdjuster) {

crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,6 @@ async fn test_timeline_duplicated_events() -> Result<()> {
416416
assert_timeline_stream! {
417417
[timeline_stream]
418418
update[3] "$x3:bar.org";
419-
update[1] "$x1:bar.org";
420-
remove[1];
421-
append "$x1:bar.org";
422-
update[3] "$x1:bar.org";
423419
append "$x4:bar.org";
424420
};
425421
}

0 commit comments

Comments
 (0)