diff --git a/benchmarks/benches/timeline.rs b/benchmarks/benches/timeline.rs index 3a657d9c0..cf600297d 100644 --- a/benchmarks/benches/timeline.rs +++ b/benchmarks/benches/timeline.rs @@ -1,7 +1,7 @@ use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use matrix_sdk::test_utils::mocks::MatrixMockServer; use matrix_sdk_test::{JoinedRoomBuilder, StateTestEvent, event_factory::EventFactory}; -use matrix_sdk_ui::timeline::TimelineBuilder; +use matrix_sdk_ui::timeline::{TimelineBuilder, TimelineReadReceiptTracking}; use ruma::{ EventId, events::room::message::RoomMessageEventContentWithoutRelation, owned_room_id, owned_user_id, @@ -103,7 +103,7 @@ pub fn create_timeline_with_initial_events(c: &mut Criterion) { |b| { b.to_async(&runtime).iter(|| async { let timeline = TimelineBuilder::new(&room) - .track_read_marker_and_receipts() + .track_read_marker_and_receipts(TimelineReadReceiptTracking::AllEvents) .build() .await .expect("Could not create timeline"); diff --git a/bindings/matrix-sdk-ffi/CHANGELOG.md b/bindings/matrix-sdk-ffi/CHANGELOG.md index 8b1dea096..3ac20991b 100644 --- a/bindings/matrix-sdk-ffi/CHANGELOG.md +++ b/bindings/matrix-sdk-ffi/CHANGELOG.md @@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file. ### Breaking changes +- `TimelineConfiguration::track_read_receipts`'s type is now an enum to allow tracking to be enabled for all events + (like before) or only for message-like events (which prevents read receipts from being placed on state events). + ([#5900](https://github.com/matrix-org/matrix-rust-sdk/pull/5900)) - `Client::reset_server_info()` has been split into `reset_supported_versions()` and `reset_well_known()`. ([#5910](https://github.com/matrix-org/matrix-rust-sdk/pull/5910)) diff --git a/bindings/matrix-sdk-ffi/src/room/mod.rs b/bindings/matrix-sdk-ffi/src/room/mod.rs index c10d09516..a7d6211b4 100644 --- a/bindings/matrix-sdk-ffi/src/room/mod.rs +++ b/bindings/matrix-sdk-ffi/src/room/mod.rs @@ -234,11 +234,7 @@ impl Room { builder = builder .with_focus(configuration.focus.try_into()?) .with_date_divider_mode(configuration.date_divider_mode.into()) - .state_events_can_show_read_receipts(configuration.state_events_can_show_read_receipts); - - if configuration.track_read_receipts { - builder = builder.track_read_marker_and_receipts(); - } + .track_read_marker_and_receipts(configuration.track_read_receipts); match configuration.filter { TimelineFilter::All => { diff --git a/bindings/matrix-sdk-ffi/src/timeline/configuration.rs b/bindings/matrix-sdk-ffi/src/timeline/configuration.rs index 808741023..795b1b019 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/configuration.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/configuration.rs @@ -1,6 +1,9 @@ use std::sync::Arc; -use matrix_sdk_ui::timeline::event_type_filter::TimelineEventTypeFilter as InnerTimelineEventTypeFilter; +use matrix_sdk_ui::timeline::{ + event_type_filter::TimelineEventTypeFilter as InnerTimelineEventTypeFilter, + TimelineReadReceiptTracking, +}; use ruma::{ events::{AnySyncTimelineEvent, TimelineEventType}, EventId, @@ -164,9 +167,6 @@ pub struct TimelineConfiguration { /// How should we filter out events from the timeline? pub filter: TimelineFilter, - /// Can read receipts be shown on state events or only on messages? - pub state_events_can_show_read_receipts: bool, - /// An optional String that will be prepended to /// all the timeline item's internal IDs, making it possible to /// distinguish different timeline instances from each other. @@ -176,11 +176,11 @@ pub struct TimelineConfiguration { pub date_divider_mode: DateDividerMode, /// Should the read receipts and read markers be tracked for the timeline - /// items in this instance? + /// items in this instance and on which event types? /// /// As this has a non negligible performance impact, make sure to enable it /// only when you need it. - pub track_read_receipts: bool, + pub track_read_receipts: TimelineReadReceiptTracking, /// Whether this timeline instance should report UTDs through the client's /// delegate. diff --git a/crates/matrix-sdk-ui/CHANGELOG.md b/crates/matrix-sdk-ui/CHANGELOG.md index 703a10f3d..2476de8da 100644 --- a/crates/matrix-sdk-ui/CHANGELOG.md +++ b/crates/matrix-sdk-ui/CHANGELOG.md @@ -6,6 +6,13 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - ReleaseDate +### Features + +- [**breaking**] `TimelineBuilder::track_read_marker_and_receipts` now takes a parameter to allow tracking to be enabled + for all events (like before) or only for message-like events (which prevents read receipts from being placed on state + events). + ([#5900](https://github.com/matrix-org/matrix-rust-sdk/pull/5900)) + ## [0.15.0] - 2025-11-27 ### Features diff --git a/crates/matrix-sdk-ui/src/timeline/builder.rs b/crates/matrix-sdk-ui/src/timeline/builder.rs index 4fccd710a..c431c4622 100644 --- a/crates/matrix-sdk-ui/src/timeline/builder.rs +++ b/crates/matrix-sdk-ui/src/timeline/builder.rs @@ -25,6 +25,7 @@ use super::{ }; use crate::{ timeline::{ + TimelineReadReceiptTracking, controller::spawn_crypto_tasks, tasks::{ pinned_events_task, room_event_cache_updates_task, room_send_queue_update_task, @@ -91,17 +92,17 @@ impl TimelineBuilder { self } - /// Chose when to insert the date separators, either in between each day + /// Choose when to insert the date separators, either in between each day /// or each month. pub fn with_date_divider_mode(mut self, mode: DateDividerMode) -> Self { self.settings.date_divider_mode = mode; self } - /// Enable tracking of the fully-read marker and the read receipts on the - /// timeline. - pub fn track_read_marker_and_receipts(mut self) -> Self { - self.settings.track_read_receipts = true; + /// Choose whether to enable tracking of the fully-read marker and the read + /// receipts and on which event types. + pub fn track_read_marker_and_receipts(mut self, tracking: TimelineReadReceiptTracking) -> Self { + self.settings.track_read_receipts = tracking; self } @@ -141,11 +142,6 @@ impl TimelineBuilder { self } - pub fn state_events_can_show_read_receipts(mut self, show: bool) -> Self { - self.settings.state_events_can_show_read_receipts = show; - self - } - /// Whether to add events that failed to deserialize to the timeline. /// /// Defaults to `true`. @@ -159,7 +155,7 @@ impl TimelineBuilder { skip(self), fields( room_id = ?self.room.room_id(), - track_read_receipts = self.settings.track_read_receipts, + track_read_receipts = ?self.settings.track_read_receipts, ) )] pub async fn build(self) -> Result { diff --git a/crates/matrix-sdk-ui/src/timeline/controller/mod.rs b/crates/matrix-sdk-ui/src/timeline/controller/mod.rs index cc721ec7d..29148a04c 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/mod.rs @@ -61,7 +61,8 @@ pub(super) use self::{ use super::{ DateDividerMode, EmbeddedEvent, Error, EventSendState, EventTimelineItem, InReplyToDetails, MediaUploadProgress, PaginationError, Profile, TimelineDetails, TimelineEventItemId, - TimelineFocus, TimelineItem, TimelineItemContent, TimelineItemKind, VirtualTimelineItem, + TimelineFocus, TimelineItem, TimelineItemContent, TimelineItemKind, + TimelineReadReceiptTracking, VirtualTimelineItem, algorithms::{rfind_event_by_id, rfind_event_item}, event_item::{ReactionStatus, RemoteEventOrigin}, item::TimelineUniqueId, @@ -265,11 +266,9 @@ pub(super) struct TimelineController { #[derive(Clone)] pub(super) struct TimelineSettings { - /// Should the read receipts and read markers be handled? - pub(super) track_read_receipts: bool, - - /// Whether state events can show read receipts. - pub(super) state_events_can_show_read_receipts: bool, + /// Should the read receipts and read markers be handled and on which event + /// types? + pub(super) track_read_receipts: TimelineReadReceiptTracking, /// Event filter that controls what's rendered as a timeline item (and thus /// what can carry read receipts). @@ -287,7 +286,6 @@ impl fmt::Debug for TimelineSettings { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TimelineSettings") .field("track_read_receipts", &self.track_read_receipts) - .field("state_events_can_show_read_receipts", &self.state_events_can_show_read_receipts) .field("add_failed_to_parse", &self.add_failed_to_parse) .finish_non_exhaustive() } @@ -296,8 +294,7 @@ impl fmt::Debug for TimelineSettings { impl Default for TimelineSettings { fn default() -> Self { Self { - track_read_receipts: false, - state_events_can_show_read_receipts: true, + track_read_receipts: TimelineReadReceiptTracking::Disabled, event_filter: Arc::new(default_event_filter), add_failed_to_parse: true, date_divider_mode: DateDividerMode::Daily, @@ -986,8 +983,8 @@ impl TimelineController

{ { let mut state = self.state.write().await; - let track_read_markers = self.settings.track_read_receipts; - if track_read_markers { + let track_read_markers = &self.settings.track_read_receipts; + if track_read_markers.is_enabled() { state.populate_initial_user_receipt(&self.room_data_provider, ReceiptType::Read).await; state .populate_initial_user_receipt(&self.room_data_provider, ReceiptType::ReadPrivate) @@ -1011,7 +1008,7 @@ impl TimelineController

{ .await; } - if track_read_markers { + if track_read_markers.is_enabled() { if let Some(fully_read_event_id) = self.room_data_provider.load_fully_read_marker().await { diff --git a/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs b/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs index 25f590616..5e9609e4b 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs @@ -33,7 +33,8 @@ use super::{ event_item::RemoteEventOrigin, traits::RoomDataProvider, }, - ObservableItems, ObservableItemsTransaction, TimelineMetadata, TimelineSettings, + ObservableItems, ObservableItemsTransaction, TimelineMetadata, TimelineReadReceiptTracking, + TimelineSettings, metadata::EventMeta, }; use crate::timeline::{ @@ -468,8 +469,12 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> { event: &AnySyncTimelineEvent, ) -> bool { match event { - AnySyncTimelineEvent::State(_) => settings.state_events_can_show_read_receipts, - AnySyncTimelineEvent::MessageLike(_) => true, + AnySyncTimelineEvent::State(_) => { + settings.track_read_receipts == TimelineReadReceiptTracking::AllEvents + } + AnySyncTimelineEvent::MessageLike(_) => { + settings.track_read_receipts != TimelineReadReceiptTracking::Disabled + } } } @@ -735,7 +740,7 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> { sender, sender_profile, timestamp, - read_receipts: if settings.track_read_receipts + read_receipts: if settings.track_read_receipts.is_enabled() && should_add && can_show_read_receipts { @@ -920,7 +925,7 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> { event.visible = event_meta.visible; event.can_show_read_receipts = event_meta.can_show_read_receipts; - if settings.track_read_receipts { + if settings.track_read_receipts.is_enabled() { // Since the event's visibility changed, we need to update the read // receipts of the previous visible event. self.maybe_update_read_receipts_of_prev_event(&event_meta.event_id); @@ -929,7 +934,7 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> { } } - if settings.track_read_receipts + if settings.track_read_receipts.is_enabled() && matches!( position, TimelineItemPosition::Start { .. } diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index 8e4f407f1..034cea9bb 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -1103,3 +1103,26 @@ impl TryFrom for matrix_sdk::attachment::GalleryItemInfo { }) } } + +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] +/// The level of read receipt tracking for the timeline. +pub enum TimelineReadReceiptTracking { + /// Track read receipts for all events. + AllEvents, + /// Track read receipts only for message-like events. + MessageLikeEvents, + /// Disable read receipt tracking. + Disabled, +} + +impl TimelineReadReceiptTracking { + /// Whether or not read receipt tracking is enabled. + pub fn is_enabled(&self) -> bool { + match self { + TimelineReadReceiptTracking::AllEvents => true, + TimelineReadReceiptTracking::MessageLikeEvents => true, + TimelineReadReceiptTracking::Disabled => false, + } + } +} diff --git a/crates/matrix-sdk-ui/src/timeline/tests/basic.rs b/crates/matrix-sdk-ui/src/timeline/tests/basic.rs index bf8caf395..40c17d764 100644 --- a/crates/matrix-sdk-ui/src/timeline/tests/basic.rs +++ b/crates/matrix-sdk-ui/src/timeline/tests/basic.rs @@ -42,7 +42,7 @@ use stream_assert::{assert_next_matches, assert_pending}; use super::TestTimeline; use crate::timeline::{ MembershipChange, MsgLikeContent, MsgLikeKind, RoomExt, TimelineDetails, TimelineFocus, - TimelineItemContent, TimelineItemKind, VirtualTimelineItem, + TimelineItemContent, TimelineItemKind, TimelineReadReceiptTracking, VirtualTimelineItem, controller::TimelineSettings, event_item::{AnyOtherFullStateEventContent, RemoteEventOrigin}, tests::{ReadReceiptMap, TestRoomDataProvider, TestTimelineBuilder}, @@ -99,8 +99,7 @@ async fn test_replace_with_initial_events_and_read_marker() { .with_initial_user_receipts(receipts), ) .settings(TimelineSettings { - track_read_receipts: true, - state_events_can_show_read_receipts: true, + track_read_receipts: TimelineReadReceiptTracking::AllEvents, ..Default::default() }) .build(); @@ -527,7 +526,7 @@ async fn test_latest_event_id_in_main_timeline() { let timeline = room .timeline_builder() .with_focus(TimelineFocus::Live { hide_threaded_events: true }) - .track_read_marker_and_receipts() + .track_read_marker_and_receipts(TimelineReadReceiptTracking::AllEvents) .build() .await .expect("Could not build live timeline"); diff --git a/crates/matrix-sdk-ui/src/timeline/tests/echo.rs b/crates/matrix-sdk-ui/src/timeline/tests/echo.rs index 9afd42774..77351f26c 100644 --- a/crates/matrix-sdk-ui/src/timeline/tests/echo.rs +++ b/crates/matrix-sdk-ui/src/timeline/tests/echo.rs @@ -28,6 +28,7 @@ use stream_assert::{assert_next_matches, assert_pending}; use super::TestTimeline; use crate::timeline::{ + TimelineReadReceiptTracking, controller::TimelineSettings, event_item::{EventSendState, RemoteEventOrigin}, tests::{TestRoomDataProvider, TestTimelineBuilder}, @@ -240,8 +241,7 @@ async fn test_no_read_marker_with_local_echo() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_fully_read_marker(event_id.to_owned())) .settings(TimelineSettings { - track_read_receipts: true, - state_events_can_show_read_receipts: true, + track_read_receipts: TimelineReadReceiptTracking::AllEvents, ..Default::default() }) .build(); diff --git a/crates/matrix-sdk-ui/src/timeline/tests/event_filter.rs b/crates/matrix-sdk-ui/src/timeline/tests/event_filter.rs index f8bd669eb..e7fef6b30 100644 --- a/crates/matrix-sdk-ui/src/timeline/tests/event_filter.rs +++ b/crates/matrix-sdk-ui/src/timeline/tests/event_filter.rs @@ -97,11 +97,7 @@ async fn test_default_filter() { #[async_test] async fn test_filter_always_false() { let timeline = TestTimelineBuilder::new() - .settings(TimelineSettings { - event_filter: Arc::new(|_, _| false), - state_events_can_show_read_receipts: true, - ..Default::default() - }) + .settings(TimelineSettings { event_filter: Arc::new(|_, _| false), ..Default::default() }) .build(); let f = &timeline.factory; diff --git a/crates/matrix-sdk-ui/src/timeline/tests/read_receipts.rs b/crates/matrix-sdk-ui/src/timeline/tests/read_receipts.rs index 479098977..bd268dd9c 100644 --- a/crates/matrix-sdk-ui/src/timeline/tests/read_receipts.rs +++ b/crates/matrix-sdk-ui/src/timeline/tests/read_receipts.rs @@ -35,7 +35,7 @@ use stream_assert::{assert_next_matches, assert_pending}; use super::{ReadReceiptMap, TestRoomDataProvider}; use crate::timeline::{ - MsgLikeContent, MsgLikeKind, RoomExt, TimelineFocus, + MsgLikeContent, MsgLikeKind, RoomExt, TimelineFocus, TimelineReadReceiptTracking, controller::TimelineSettings, tests::{TestTimelineBuilder, encryption::get_client}, }; @@ -52,7 +52,10 @@ fn filter_notice(ev: &AnySyncTimelineEvent, _rules: &RoomVersionRules) -> bool { #[async_test] async fn test_read_receipts_updates_on_live_events() { let timeline = TestTimelineBuilder::new() - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); let mut stream = timeline.subscribe().await; @@ -114,7 +117,10 @@ async fn test_read_receipts_updates_on_live_events() { #[async_test] async fn test_read_receipts_updates_on_back_paginated_events() { let timeline = TestTimelineBuilder::new() - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); let room_id = room_id!("!room:localhost"); @@ -153,7 +159,7 @@ async fn test_read_receipts_updates_on_back_paginated_events() { async fn test_read_receipts_updates_on_filtered_events() { let timeline = TestTimelineBuilder::new() .settings(TimelineSettings { - track_read_receipts: true, + track_read_receipts: TimelineReadReceiptTracking::AllEvents, event_filter: Arc::new(filter_notice), ..Default::default() }) @@ -254,7 +260,7 @@ async fn test_read_receipts_updates_on_filtered_events_with_stored() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_initial_user_receipts(initial_user_receipts)) .settings(TimelineSettings { - track_read_receipts: true, + track_read_receipts: TimelineReadReceiptTracking::AllEvents, event_filter: Arc::new(filter_notice), ..Default::default() }) @@ -324,7 +330,7 @@ async fn test_read_receipts_updates_on_back_paginated_filtered_events() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_initial_user_receipts(initial_user_receipts)) .settings(TimelineSettings { - track_read_receipts: true, + track_read_receipts: TimelineReadReceiptTracking::AllEvents, event_filter: Arc::new(filter_notice), ..Default::default() }) @@ -420,7 +426,7 @@ async fn test_read_receipts_updates_on_message_decryption() { let timeline = room .timeline_builder() .event_filter(filter_text_msg) - .track_read_marker_and_receipts() + .track_read_marker_and_receipts(TimelineReadReceiptTracking::AllEvents) .build() .await .unwrap(); @@ -537,7 +543,10 @@ async fn test_initial_public_unthreaded_receipt() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_initial_user_receipts(initial_user_receipts)) - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); let (receipt_event_id, _) = timeline.controller.latest_user_read_receipt(*ALICE).await.unwrap(); @@ -562,7 +571,10 @@ async fn test_initial_public_main_thread_receipt() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_initial_user_receipts(initial_user_receipts)) - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); let (receipt_event_id, _) = timeline.controller.latest_user_read_receipt(*ALICE).await.unwrap(); @@ -587,7 +599,10 @@ async fn test_initial_private_unthreaded_receipt() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_initial_user_receipts(initial_user_receipts)) - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); let (receipt_event_id, _) = timeline.controller.latest_user_read_receipt(*ALICE).await.unwrap(); @@ -612,7 +627,10 @@ async fn test_initial_private_main_thread_receipt() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_initial_user_receipts(initial_user_receipts)) - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); let (receipt_event_id, _) = timeline.controller.latest_user_read_receipt(*ALICE).await.unwrap(); @@ -626,7 +644,10 @@ async fn test_clear_read_receipts() { let event_b_id = event_id!("$event_b"); let timeline = TestTimelineBuilder::new() - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); let f = &timeline.factory; @@ -706,7 +727,10 @@ async fn test_implicit_read_receipt_before_explicit_read_receipt() { let timeline = TestTimelineBuilder::new() .provider(TestRoomDataProvider::default().with_initial_user_receipts(initial_user_receipts)) - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); // Check that the receipts are at the correct place. @@ -768,7 +792,10 @@ async fn test_threaded_latest_user_read_receipt() { let timeline = TestTimelineBuilder::new() .focus(TimelineFocus::Thread { root_event_id: thread_root }) - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .build(); // Sanity check: no read receipts before any events. @@ -839,7 +866,10 @@ async fn test_threaded_latest_user_read_receipt() { #[async_test] async fn test_unthreaded_client_updates_threaded_read_receipts() { let timeline = TestTimelineBuilder::new() - .settings(TimelineSettings { track_read_receipts: true, ..Default::default() }) + .settings(TimelineSettings { + track_read_receipts: TimelineReadReceiptTracking::AllEvents, + ..Default::default() + }) .focus(TimelineFocus::Live { hide_threaded_events: true }) .build(); let mut stream = timeline.subscribe().await; diff --git a/crates/matrix-sdk-ui/src/timeline/traits.rs b/crates/matrix-sdk-ui/src/timeline/traits.rs index be6261a24..cd94a0ca7 100644 --- a/crates/matrix-sdk-ui/src/timeline/traits.rs +++ b/crates/matrix-sdk-ui/src/timeline/traits.rs @@ -37,7 +37,8 @@ use tracing::error; use super::{EventTimelineItem, Profile, RedactError, TimelineBuilder}; use crate::timeline::{ - self, Timeline, latest_event::LatestEventValue, pinned_events_loader::PinnedEventsRoom, + self, Timeline, TimelineReadReceiptTracking, latest_event::LatestEventValue, + pinned_events_loader::PinnedEventsRoom, }; pub trait RoomExt { @@ -77,7 +78,8 @@ impl RoomExt for Room { } fn timeline_builder(&self) -> TimelineBuilder { - TimelineBuilder::new(self).track_read_marker_and_receipts() + TimelineBuilder::new(self) + .track_read_marker_and_receipts(TimelineReadReceiptTracking::AllEvents) } async fn latest_event_item(&self) -> Option { diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs b/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs index 8a87d4cf9..6d32af400 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs @@ -24,7 +24,9 @@ use matrix_sdk::{ test_utils::logged_in_client_with_server, }; use matrix_sdk_test::{async_test, mocks::mock_encryption_state}; -use matrix_sdk_ui::timeline::{TimelineBuilder, TimelineItem, TimelineItemKind}; +use matrix_sdk_ui::timeline::{ + TimelineBuilder, TimelineItem, TimelineItemKind, TimelineReadReceiptTracking, +}; use ruma::{RoomId, room_id, user_id}; use serde_json::json; use wiremock::{Match, Mock, MockServer, Request, ResponseTemplate, http::Method}; @@ -404,7 +406,10 @@ async fn timeline_test_helper( anyhow::anyhow!("Room {room_id} not found in client. Can't provide a timeline for it") })?; - let timeline = TimelineBuilder::new(&sdk_room).track_read_marker_and_receipts().build().await?; + let timeline = TimelineBuilder::new(&sdk_room) + .track_read_marker_and_receipts(TimelineReadReceiptTracking::AllEvents) + .build() + .await?; Ok(timeline.subscribe().await) } diff --git a/labs/multiverse/src/widgets/room_view/mod.rs b/labs/multiverse/src/widgets/room_view/mod.rs index fd24e6f9d..d2c9d3729 100644 --- a/labs/multiverse/src/widgets/room_view/mod.rs +++ b/labs/multiverse/src/widgets/room_view/mod.rs @@ -16,7 +16,7 @@ use matrix_sdk::{ }; use matrix_sdk_ui::{ Timeline, - timeline::{TimelineBuilder, TimelineFocus, TimelineItem}, + timeline::{TimelineBuilder, TimelineFocus, TimelineItem, TimelineReadReceiptTracking}, }; use ratatui::{prelude::*, widgets::*}; use tokio::{spawn, sync::OnceCell, task::JoinHandle}; @@ -152,7 +152,7 @@ impl RoomView { let task = spawn(async move { let timeline = TimelineBuilder::new(&r) .with_focus(TimelineFocus::Thread { root_event_id: cloned_root }) - .track_read_marker_and_receipts() + .track_read_marker_and_receipts(TimelineReadReceiptTracking::AllEvents) .build() .await .unwrap();