feat(sdk): Add TimelineStart virtual timeline item
This commit is contained in:
committed by
Jonas Platte
parent
237edcd747
commit
9b3bf5a4fa
@@ -160,6 +160,7 @@ impl TimelineItem {
|
||||
}
|
||||
Item::Virtual(VItem::ReadMarker) => Some(VirtualTimelineItem::ReadMarker),
|
||||
Item::Virtual(VItem::LoadingIndicator) => Some(VirtualTimelineItem::LoadingIndicator),
|
||||
Item::Virtual(VItem::TimelineStart) => Some(VirtualTimelineItem::TimelineStart),
|
||||
Item::Event(_) => None,
|
||||
}
|
||||
}
|
||||
@@ -596,6 +597,12 @@ pub enum VirtualTimelineItem {
|
||||
|
||||
/// A loading indicator for a pagination request.
|
||||
LoadingIndicator,
|
||||
|
||||
/// The beginning of the visible timeline.
|
||||
///
|
||||
/// There might be earlier events the user is not allowed to see due to
|
||||
/// history visibility.
|
||||
TimelineStart,
|
||||
}
|
||||
|
||||
#[extension_trait]
|
||||
|
||||
@@ -525,7 +525,10 @@ impl<'a, 'i> TimelineEventHandler<'a, 'i> {
|
||||
// divider at position 1 and the new event at 2 rather than 0 and 1.
|
||||
let offset =
|
||||
match self.timeline_items.first().and_then(|item| item.as_virtual()) {
|
||||
Some(VirtualTimelineItem::LoadingIndicator) => 1,
|
||||
Some(
|
||||
VirtualTimelineItem::LoadingIndicator
|
||||
| VirtualTimelineItem::TimelineStart,
|
||||
) => 1,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
|
||||
@@ -156,15 +156,19 @@ impl TimelineInner {
|
||||
lock.insert_cloned(0, Arc::new(TimelineItem::loading_indicator()));
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub(super) fn remove_loading_indicator(&self) {
|
||||
#[instrument(skip(self))]
|
||||
pub(super) fn remove_loading_indicator(&self, more_messages: bool) {
|
||||
let mut lock = self.items.lock_mut();
|
||||
if !lock.first().map_or(false, |item| item.is_loading_indicator()) {
|
||||
warn!("There is no loading indicator");
|
||||
return;
|
||||
}
|
||||
|
||||
lock.remove(0);
|
||||
if more_messages {
|
||||
lock.remove(0);
|
||||
} else {
|
||||
lock.set_cloned(0, Arc::new(TimelineItem::timeline_start()))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) async fn handle_fully_read(&self, raw: Raw<FullyReadEvent>) {
|
||||
|
||||
@@ -182,8 +182,9 @@ impl Timeline {
|
||||
num_updates += self.inner.handle_back_paginated_event(room_ev, own_user_id).await;
|
||||
}
|
||||
|
||||
self.inner.remove_loading_indicator();
|
||||
let outcome = PaginationOutcome { more_messages: messages.end.is_some(), num_updates };
|
||||
let more_messages = messages.end.is_some();
|
||||
self.inner.remove_loading_indicator(more_messages);
|
||||
let outcome = PaginationOutcome { more_messages, num_updates };
|
||||
*start_lock = messages.end;
|
||||
|
||||
Ok(outcome)
|
||||
@@ -343,6 +344,10 @@ impl TimelineItem {
|
||||
Self::Virtual(VirtualTimelineItem::LoadingIndicator)
|
||||
}
|
||||
|
||||
fn timeline_start() -> Self {
|
||||
Self::Virtual(VirtualTimelineItem::TimelineStart)
|
||||
}
|
||||
|
||||
fn is_read_marker(&self) -> bool {
|
||||
matches!(self, Self::Virtual(VirtualTimelineItem::ReadMarker))
|
||||
}
|
||||
|
||||
@@ -34,4 +34,10 @@ pub enum VirtualTimelineItem {
|
||||
|
||||
/// A loading indicator for a pagination request.
|
||||
LoadingIndicator,
|
||||
|
||||
/// The beginning of the visible timeline.
|
||||
///
|
||||
/// There might be earlier events the user is not allowed to see due to
|
||||
/// history visibility.
|
||||
TimelineStart,
|
||||
}
|
||||
|
||||
@@ -260,6 +260,7 @@ async fn back_pagination() {
|
||||
.await;
|
||||
|
||||
timeline.paginate_backwards(uint!(10)).await.unwrap();
|
||||
server.reset().await;
|
||||
|
||||
let loading = assert_matches!(
|
||||
timeline_stream.next().await,
|
||||
@@ -297,6 +298,34 @@ async fn back_pagination() {
|
||||
|
||||
// Removal of the loading indicator
|
||||
assert_matches!(timeline_stream.next().await, Some(VecDiff::RemoveAt { index: 0 }));
|
||||
|
||||
Mock::given(method("GET"))
|
||||
.and(path_regex(r"^/_matrix/client/r0/rooms/.*/messages$"))
|
||||
.and(header("authorization", "Bearer 1234"))
|
||||
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
|
||||
// Usually there would be a few events here, but we just want to test
|
||||
// that the timeline start item is added when there is no end token
|
||||
"chunk": [],
|
||||
"start": "t47409-4357353_219380_26003_2269"
|
||||
})))
|
||||
.expect(1)
|
||||
.named("messages_batch_1")
|
||||
.mount(&server)
|
||||
.await;
|
||||
|
||||
timeline.paginate_backwards(uint!(10)).await.unwrap();
|
||||
|
||||
let loading = assert_matches!(
|
||||
timeline_stream.next().await,
|
||||
Some(VecDiff::InsertAt { index: 0, value }) => value
|
||||
);
|
||||
assert_matches!(loading.as_virtual().unwrap(), VirtualTimelineItem::LoadingIndicator);
|
||||
|
||||
let loading = assert_matches!(
|
||||
timeline_stream.next().await,
|
||||
Some(VecDiff::UpdateAt { index: 0, value }) => value
|
||||
);
|
||||
assert_matches!(loading.as_virtual().unwrap(), VirtualTimelineItem::TimelineStart);
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
|
||||
Reference in New Issue
Block a user