Skip to content

Commit d986437

Browse files
committed
timeline: add the ability to set a prefix for internal IDs
1 parent e4331ac commit d986437

File tree

7 files changed

+92
-25
lines changed

7 files changed

+92
-25
lines changed

bindings/matrix-sdk-ffi/src/room_list.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,9 +537,13 @@ impl RoomListItem {
537537
/// * `event_type_filter` - An optional [`TimelineEventTypeFilter`] to be
538538
/// used to filter timeline events besides the default timeline filter. If
539539
/// `None` is passed, only the default timeline filter will be used.
540+
/// * `internal_id_prefix` - An optional String that will be prepended to
541+
/// all the timeline item's internal IDs, making it possible to
542+
/// distinguish different timeline instances from each other.
540543
async fn init_timeline(
541544
&self,
542545
event_type_filter: Option<Arc<TimelineEventTypeFilter>>,
546+
internal_id_prefix: Option<String>,
543547
) -> Result<(), RoomListError> {
544548
let mut timeline_builder = self
545549
.inner
@@ -554,6 +558,10 @@ impl RoomListItem {
554558
});
555559
}
556560

561+
if let Some(internal_id_prefix) = internal_id_prefix {
562+
timeline_builder = timeline_builder.with_internal_id_prefix(internal_id_prefix);
563+
}
564+
557565
if let Some(utd_hook) = self.utd_hook.clone() {
558566
timeline_builder = timeline_builder.with_unable_to_decrypt_hook(utd_hook);
559567
}

crates/matrix-sdk-ui/src/timeline/builder.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ pub struct TimelineBuilder {
4545
/// An optional hook to call whenever we run into an unable-to-decrypt or a
4646
/// late-decryption event.
4747
unable_to_decrypt_hook: Option<Arc<UtdHookManager>>,
48+
49+
/// An optional prefix for internal IDs.
50+
internal_id_prefix: Option<String>,
4851
}
4952

5053
impl TimelineBuilder {
@@ -53,6 +56,7 @@ impl TimelineBuilder {
5356
room: room.clone(),
5457
settings: TimelineInnerSettings::default(),
5558
unable_to_decrypt_hook: None,
59+
internal_id_prefix: None,
5660
}
5761
}
5862

@@ -65,6 +69,15 @@ impl TimelineBuilder {
6569
self
6670
}
6771

72+
/// Sets the internal id prefix for this timeline.
73+
///
74+
/// The prefix will be prepended to any internal ID using when generating
75+
/// timeline IDs for this timeline.
76+
pub fn with_internal_id_prefix(mut self, prefix: String) -> Self {
77+
self.internal_id_prefix = Some(prefix);
78+
self
79+
}
80+
6881
/// Enable tracking of the fully-read marker and the read receipts on the
6982
/// timeline.
7083
pub fn track_read_marker_and_receipts(mut self) -> Self {
@@ -122,7 +135,7 @@ impl TimelineBuilder {
122135
)
123136
)]
124137
pub async fn build(self) -> event_cache::Result<Timeline> {
125-
let Self { room, settings, unable_to_decrypt_hook } = self;
138+
let Self { room, settings, unable_to_decrypt_hook, internal_id_prefix } = self;
126139

127140
let client = room.client();
128141
let event_cache = client.event_cache();
@@ -135,7 +148,8 @@ impl TimelineBuilder {
135148

136149
let has_events = !events.is_empty();
137150

138-
let inner = TimelineInner::new(room, unable_to_decrypt_hook).with_settings(settings);
151+
let inner = TimelineInner::new(room, internal_id_prefix, unable_to_decrypt_hook)
152+
.with_settings(settings);
139153

140154
inner.replace_with_initial_events(events).await;
141155

crates/matrix-sdk-ui/src/timeline/day_dividers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ mod tests {
573573
let mut items = ObservableVector::new();
574574
let mut txn = items.transaction();
575575

576-
let mut meta = TimelineInnerMetadata::new(ruma::RoomVersionId::V11, None);
576+
let mut meta = TimelineInnerMetadata::new(ruma::RoomVersionId::V11, None, None);
577577

578578
let timestamp = MilliSecondsSinceUnixEpoch(uint!(42));
579579
let timestamp_next_day =
@@ -607,7 +607,7 @@ mod tests {
607607
let mut items = ObservableVector::new();
608608
let mut txn = items.transaction();
609609

610-
let mut meta = TimelineInnerMetadata::new(ruma::RoomVersionId::V11, None);
610+
let mut meta = TimelineInnerMetadata::new(ruma::RoomVersionId::V11, None, None);
611611

612612
let timestamp = MilliSecondsSinceUnixEpoch(uint!(42));
613613
let timestamp_next_day =

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,14 @@ pub fn default_event_filter(event: &AnySyncTimelineEvent, room_version: &RoomVer
213213
impl<P: RoomDataProvider> TimelineInner<P> {
214214
pub(super) fn new(
215215
room_data_provider: P,
216+
internal_id_prefix: Option<String>,
216217
unable_to_decrypt_hook: Option<Arc<UtdHookManager>>,
217218
) -> Self {
218-
let state =
219-
TimelineInnerState::new(room_data_provider.room_version(), unable_to_decrypt_hook);
219+
let state = TimelineInnerState::new(
220+
room_data_provider.room_version(),
221+
internal_id_prefix,
222+
unable_to_decrypt_hook,
223+
);
220224
Self {
221225
state: Arc::new(RwLock::new(state)),
222226
room_data_provider,

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,19 @@ pub(in crate::timeline) struct TimelineInnerState {
7474
impl TimelineInnerState {
7575
pub(super) fn new(
7676
room_version: RoomVersionId,
77+
internal_id_prefix: Option<String>,
7778
unable_to_decrypt_hook: Option<Arc<UtdHookManager>>,
7879
) -> Self {
7980
Self {
8081
// Upstream default capacity is currently 16, which is making
8182
// sliding-sync tests with 20 events lag. This should still be
8283
// small enough.
8384
items: ObservableVector::with_capacity(32),
84-
meta: TimelineInnerMetadata::new(room_version, unable_to_decrypt_hook),
85+
meta: TimelineInnerMetadata::new(
86+
room_version,
87+
internal_id_prefix,
88+
unable_to_decrypt_hook,
89+
),
8590
}
8691
}
8792

@@ -678,6 +683,10 @@ pub(in crate::timeline) struct TimelineInnerMetadata {
678683
/// remote echoes.
679684
next_internal_id: u64,
680685

686+
/// An optional prefix for internal IDs, defined during construction of the
687+
/// timeline.
688+
internal_id_prefix: Option<String>,
689+
681690
pub reactions: Reactions,
682691
pub poll_pending_events: PollPendingEvents,
683692
pub fully_read_event: Option<OwnedEventId>,
@@ -707,6 +716,7 @@ pub(in crate::timeline) struct TimelineInnerMetadata {
707716
impl TimelineInnerMetadata {
708717
pub(crate) fn new(
709718
room_version: RoomVersionId,
719+
internal_id_prefix: Option<String>,
710720
unable_to_decrypt_hook: Option<Arc<UtdHookManager>>,
711721
) -> Self {
712722
Self {
@@ -723,6 +733,7 @@ impl TimelineInnerMetadata {
723733
in_flight_reaction: Default::default(),
724734
room_version,
725735
unable_to_decrypt_hook,
736+
internal_id_prefix,
726737
}
727738
}
728739

@@ -760,7 +771,8 @@ impl TimelineInnerMetadata {
760771
pub fn next_internal_id(&mut self) -> String {
761772
let val = self.next_internal_id;
762773
self.next_internal_id += 1;
763-
format!("{val}")
774+
let prefix = self.internal_id_prefix.as_deref().unwrap_or("");
775+
format!("{prefix}{val}")
764776
}
765777

766778
/// Returns a new timeline item with a fresh internal id.

crates/matrix-sdk-ui/src/timeline/tests/basic.rs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -268,21 +268,10 @@ async fn test_dedup_pagination() {
268268
async fn test_dedup_initial() {
269269
let timeline = TestTimeline::new();
270270

271-
let event_a = SyncTimelineEvent::new(
272-
timeline
273-
.event_builder
274-
.make_sync_message_event(*ALICE, RoomMessageEventContent::text_plain("A")),
275-
);
276-
let event_b = SyncTimelineEvent::new(
277-
timeline
278-
.event_builder
279-
.make_sync_message_event(*BOB, RoomMessageEventContent::text_plain("B")),
280-
);
281-
let event_c = SyncTimelineEvent::new(
282-
timeline
283-
.event_builder
284-
.make_sync_message_event(*CAROL, RoomMessageEventContent::text_plain("C")),
285-
);
271+
let factory = EventFactory::new();
272+
let event_a = factory.text_msg("A").sender(*ALICE).into_sync();
273+
let event_b = factory.text_msg("B").sender(*BOB).into_sync();
274+
let event_c = factory.text_msg("C").sender(*CAROL).into_sync();
286275

287276
timeline
288277
.inner
@@ -322,6 +311,39 @@ async fn test_dedup_initial() {
322311
assert_eq!(timeline_items[0].unique_id(), "3");
323312
}
324313

314+
#[async_test]
315+
async fn test_internal_id_prefix() {
316+
let timeline = TestTimeline::with_internal_id_prefix("le_prefix_".to_owned());
317+
318+
let factory = EventFactory::new();
319+
let ev_a = factory.text_msg("A").sender(*ALICE).into_sync();
320+
let ev_b = factory.text_msg("B").sender(*BOB).into_sync();
321+
let ev_c = factory.text_msg("C").sender(*CAROL).into_sync();
322+
323+
timeline
324+
.inner
325+
.add_events_at(vec![ev_a, ev_b, ev_c], TimelineEnd::Back { from_cache: false })
326+
.await;
327+
328+
let timeline_items = timeline.inner.items().await;
329+
assert_eq!(timeline_items.len(), 4);
330+
331+
assert!(timeline_items[0].is_day_divider());
332+
assert_eq!(timeline_items[0].unique_id(), "le_prefix_3");
333+
334+
let event1 = &timeline_items[1];
335+
assert_eq!(event1.as_event().unwrap().sender(), *ALICE);
336+
assert_eq!(event1.unique_id(), "le_prefix_0");
337+
338+
let event2 = &timeline_items[2];
339+
assert_eq!(event2.as_event().unwrap().sender(), *BOB);
340+
assert_eq!(event2.unique_id(), "le_prefix_1");
341+
342+
let event3 = &timeline_items[3];
343+
assert_eq!(event3.as_event().unwrap().sender(), *CAROL);
344+
assert_eq!(event3.unique_id(), "le_prefix_2");
345+
}
346+
325347
#[async_test]
326348
async fn test_sanitized() {
327349
let timeline = TestTimeline::new();

crates/matrix-sdk-ui/src/timeline/tests/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,23 @@ impl TestTimeline {
7979
Self::with_room_data_provider(TestRoomDataProvider::default())
8080
}
8181

82+
fn with_internal_id_prefix(prefix: String) -> Self {
83+
Self {
84+
inner: TimelineInner::new(TestRoomDataProvider::default(), Some(prefix), None),
85+
event_builder: EventBuilder::new(),
86+
}
87+
}
88+
8289
fn with_room_data_provider(room_data_provider: TestRoomDataProvider) -> Self {
8390
Self {
84-
inner: TimelineInner::new(room_data_provider, None),
91+
inner: TimelineInner::new(room_data_provider, None, None),
8592
event_builder: EventBuilder::new(),
8693
}
8794
}
8895

8996
fn with_unable_to_decrypt_hook(hook: Arc<UtdHookManager>) -> Self {
9097
Self {
91-
inner: TimelineInner::new(TestRoomDataProvider::default(), Some(hook)),
98+
inner: TimelineInner::new(TestRoomDataProvider::default(), None, Some(hook)),
9299
event_builder: EventBuilder::new(),
93100
}
94101
}

0 commit comments

Comments
 (0)