mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-13 02:25:51 -04:00
refactor(ui): Timeline receives pagination events as VectorDiffs!
This patch allows the paginated events of a `Timeline` to be received via `RoomEventCacheUpdate::UpdateTimelineEvents` as `VectorDiff`s.
This commit is contained in:
@@ -124,7 +124,7 @@ pub(super) struct TimelineController<P: RoomDataProvider = Room> {
|
||||
pub(crate) room_data_provider: P,
|
||||
|
||||
/// Settings applied to this timeline.
|
||||
settings: TimelineSettings,
|
||||
pub(super) settings: TimelineSettings,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
@@ -77,12 +77,16 @@ impl super::Timeline {
|
||||
let num_events = events.len();
|
||||
trace!("Back-pagination succeeded with {num_events} events");
|
||||
|
||||
// TODO(hywan): Remove, and let spread events via
|
||||
// `matrix_sdk::event_cache::RoomEventCacheUpdate` from
|
||||
// `matrix_sdk::event_cache::RoomPagination::run_backwards`.
|
||||
self.controller
|
||||
.add_events_at(events.into_iter(), TimelineNewItemPosition::Start { origin: RemoteEventOrigin::Pagination })
|
||||
.await;
|
||||
// If `TimelineSettings::vectordiffs_as_inputs` is enabled,
|
||||
// we don't need to add events manually: everything we need
|
||||
// is to let the `EventCache` receive the events from this
|
||||
// pagination, and emit its updates as `VectorDiff`s, which
|
||||
// will be handled by the `Timeline` naturally.
|
||||
if !self.controller.settings.vectordiffs_as_inputs {
|
||||
self.controller
|
||||
.add_events_at(events.into_iter(), TimelineNewItemPosition::Start { origin: RemoteEventOrigin::Pagination })
|
||||
.await;
|
||||
}
|
||||
|
||||
if num_events == 0 && !reached_start {
|
||||
// As an exceptional contract: if there were no events in the response,
|
||||
|
||||
@@ -28,7 +28,7 @@ use super::{
|
||||
events::{Gap, RoomEvents},
|
||||
RoomEventCacheInner,
|
||||
},
|
||||
BackPaginationOutcome, Result,
|
||||
BackPaginationOutcome, EventsOrigin, Result, RoomEventCacheUpdate,
|
||||
};
|
||||
|
||||
/// An API object to run pagination queries on a [`super::RoomEventCache`].
|
||||
@@ -227,6 +227,15 @@ impl RoomPagination {
|
||||
debug!("not storing previous batch token, because we deduplicated all new back-paginated events");
|
||||
}
|
||||
|
||||
let sync_timeline_events_diffs = room_events.updates_as_vector_diffs();
|
||||
|
||||
if !sync_timeline_events_diffs.is_empty() {
|
||||
let _ = self.inner.sender.send(RoomEventCacheUpdate::UpdateTimelineEvents {
|
||||
diffs: sync_timeline_events_diffs,
|
||||
origin: EventsOrigin::Sync,
|
||||
});
|
||||
}
|
||||
|
||||
BackPaginationOutcome { events, reached_start }
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -281,6 +281,9 @@ async fn test_backpaginate_once() {
|
||||
assert_event_matches_msg(&events[1], "hello");
|
||||
assert_eq!(events.len(), 2);
|
||||
|
||||
let next = room_stream.recv().now_or_never();
|
||||
assert_matches!(next, Some(Ok(RoomEventCacheUpdate::UpdateTimelineEvents { .. })));
|
||||
|
||||
let next = room_stream.recv().now_or_never();
|
||||
assert_matches!(next, None);
|
||||
}
|
||||
@@ -400,6 +403,14 @@ async fn test_backpaginate_many_times_with_many_iterations() {
|
||||
assert_event_matches_msg(&events[3], "heyo");
|
||||
assert_eq!(events.len(), 4);
|
||||
|
||||
// First iteration.
|
||||
let next = room_stream.recv().now_or_never();
|
||||
assert_matches!(next, Some(Ok(RoomEventCacheUpdate::UpdateTimelineEvents { .. })));
|
||||
|
||||
// Second iteration.
|
||||
let next = room_stream.recv().now_or_never();
|
||||
assert_matches!(next, Some(Ok(RoomEventCacheUpdate::UpdateTimelineEvents { .. })));
|
||||
|
||||
assert!(room_stream.is_empty());
|
||||
}
|
||||
|
||||
@@ -523,6 +534,14 @@ async fn test_backpaginate_many_times_with_one_iteration() {
|
||||
assert_event_matches_msg(&events[3], "heyo");
|
||||
assert_eq!(events.len(), 4);
|
||||
|
||||
// First pagination.
|
||||
let next = room_stream.recv().now_or_never();
|
||||
assert_matches!(next, Some(Ok(RoomEventCacheUpdate::UpdateTimelineEvents { .. })));
|
||||
|
||||
// Second pagination.
|
||||
let next = room_stream.recv().now_or_never();
|
||||
assert_matches!(next, Some(Ok(RoomEventCacheUpdate::UpdateTimelineEvents { .. })));
|
||||
|
||||
assert!(room_stream.is_empty());
|
||||
}
|
||||
|
||||
@@ -680,7 +699,7 @@ async fn test_backpaginating_without_token() {
|
||||
let room = server.sync_joined_room(&client, room_id).await;
|
||||
let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap();
|
||||
|
||||
let (events, room_stream) = room_event_cache.subscribe().await.unwrap();
|
||||
let (events, mut room_stream) = room_event_cache.subscribe().await.unwrap();
|
||||
|
||||
assert!(events.is_empty());
|
||||
assert!(room_stream.is_empty());
|
||||
@@ -712,6 +731,9 @@ async fn test_backpaginating_without_token() {
|
||||
assert_event_matches_msg(&events[0], "hi");
|
||||
assert_eq!(events.len(), 1);
|
||||
|
||||
let next = room_stream.recv().now_or_never();
|
||||
assert_matches!(next, Some(Ok(RoomEventCacheUpdate::UpdateTimelineEvents { .. })));
|
||||
|
||||
assert!(room_stream.is_empty());
|
||||
}
|
||||
|
||||
@@ -772,6 +794,7 @@ async fn test_limited_timeline_resets_pagination() {
|
||||
server.sync_room(&client, JoinedRoomBuilder::new(room_id).set_timeline_limited()).await;
|
||||
|
||||
// We receive an update about the limited timeline.
|
||||
assert_let_timeout!(Ok(RoomEventCacheUpdate::UpdateTimelineEvents { .. }) = room_stream.recv());
|
||||
assert_let_timeout!(Ok(RoomEventCacheUpdate::Clear) = room_stream.recv());
|
||||
|
||||
// The paginator state is reset: status set to Initial, hasn't hit the timeline
|
||||
|
||||
Reference in New Issue
Block a user