Skip to content

Commit d0b9bbc

Browse files
committed
featui): Timeline::subscribe() supports lazy backwards pagination.
This patch updates the pagination mechanism of the `Timeline` to support lazy backwards pagination. `Timeline::paginate_backwards` already does different things whether the timeline focus is live or focused. When it's live, the method will first try to paginate backwards lazily, by adjusting the `count` value of the `Skip` stream used by the `Timeline::subscribe` method. If there is not enough items to provide, the greedy pagination will run.
1 parent bb524f0 commit d0b9bbc

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

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

+23-2
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,28 @@ impl<P: RoomDataProvider> TimelineController<P> {
410410
}
411411
}
412412

413-
/// Run a backward pagination (in focused mode) and append the results to
413+
/// Run a lazy backwards pagination (in live mode).
414+
///
415+
/// It adjusts the `count` value of the `Skip` higher-order stream so that
416+
/// more items are pushed front in the timeline.
417+
///
418+
/// If no more items are available (i.e. if the `count` is zero), this
419+
/// method returns `Some(needs)` where `needs` is the number of events that
420+
/// must be unlazily backwards paginated.
421+
pub(super) async fn live_lazy_paginate_backwards(&self, num_events: u16) -> Option<usize> {
422+
let state = self.state.read().await;
423+
424+
let (count, needs) = state
425+
.meta
426+
.subscriber_skip_count
427+
.compute_next_when_paginating_backwards(num_events.into());
428+
429+
state.meta.subscriber_skip_count.update(count, &state.timeline_focus);
430+
431+
needs
432+
}
433+
434+
/// Run a backwards pagination (in focused mode) and append the results to
414435
/// the timeline.
415436
///
416437
/// Returns whether we hit the start of the timeline.
@@ -439,7 +460,7 @@ impl<P: RoomDataProvider> TimelineController<P> {
439460
Ok(hit_end_of_timeline)
440461
}
441462

442-
/// Run a forward pagination (in focused mode) and append the results to
463+
/// Run a forwards pagination (in focused mode) and append the results to
443464
/// the timeline.
444465
///
445466
/// Returns whether we hit the end of the timeline.

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub(in crate::timeline) struct TimelineState {
5858
pub meta: TimelineMetadata,
5959

6060
/// The kind of focus of this timeline.
61-
timeline_focus: TimelineFocusKind,
61+
pub timeline_focus: TimelineFocusKind,
6262
}
6363

6464
impl TimelineState {
@@ -100,6 +100,7 @@ impl TimelineState {
100100
let previous_number_of_items = self.items.len();
101101

102102
let mut transaction = self.transaction();
103+
// Apply the diffs.
103104
transaction.handle_remote_events_with_diffs(diffs, origin, room_data, settings).await;
104105
transaction.commit();
105106

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,21 @@ impl super::Timeline {
3232
///
3333
/// Returns whether we hit the start of the timeline.
3434
#[instrument(skip_all, fields(room_id = ?self.room().room_id()))]
35-
pub async fn paginate_backwards(&self, num_events: u16) -> Result<bool, Error> {
35+
pub async fn paginate_backwards(&self, mut num_events: u16) -> Result<bool, Error> {
3636
if self.controller.is_live().await {
37+
match self.controller.live_lazy_paginate_backwards(num_events).await {
38+
Some(needed_num_events) => {
39+
num_events = needed_num_events.try_into().expect(
40+
"failed to cast `needed_num_events` (`usize`) into `num_events` (`usize`)",
41+
);
42+
}
43+
None => {
44+
// TODO: returning `false` is not true everytime, we need a way to know if
45+
// lazy-loading has reached the end of the timeline.
46+
return Ok(false);
47+
}
48+
}
49+
3750
Ok(self.live_paginate_backwards(num_events).await?)
3851
} else {
3952
Ok(self.controller.focused_paginate_backwards(num_events).await?)

0 commit comments

Comments
 (0)