Commit 0e081dee5e28
tarball2 files changed+39-3
@@ -404,14 +404,24 @@ async fn fetch_side(
404404
if backwards {405405
events.reverse();406406
}407
- let (values, highlights) = events.into_iter().unzip();407
+ let (values, highlights): (Vec<_>, _) = events.into_iter().unzip();408
+ let token = page_token(backwards, &values, messages.end);408409
Ok(Side {409410
values,410411
highlights,411
- token: messages.end,412
+ token,412413
})413414
}414415
416
+/// going back, a page that reaches the room's creation or comes back empty is the start, even417
+/// when the server still hands out a token after it, as continuwuity does418
+fn page_token(backwards: bool, values: &[Value], end: Option<String>) -> Option<String> {419
+ let created = values420
+ .iter()421
+ .any(|value| value.get("type").and_then(Value::as_str) == Some("m.room.create"));422
+ end.filter(|_| !(backwards && (values.is_empty() || created)))423
+}424
+415425
/// a search hit as event context would show it, `values` its original and then its latest edit416426
pub(crate) async fn preview(417427
room: &Room,@@ -613,3 +623,26 @@ fn validate_limit(limit: u16) -> Result<(), Error> {
613623
Ok(())614624
}615625
}626
+627
+#[cfg(test)]628
+mod tests {629
+ use serde_json::json;630
+631
+ use super::page_token;632
+633
+ #[test]634
+ fn going_back_past_creation_or_an_empty_page_is_the_start() {635
+ let token = || Some("more".to_owned());636
+ let message = json!({ "type": "m.room.message" });637
+ let create = json!({ "type": "m.room.create" });638
+ assert_eq!(page_token(true, &[message.clone()], token()), token());639
+ assert_eq!(640
+ page_token(true, &[message.clone(), create.clone()], token()),641
+ None642
+ );643
+ assert_eq!(page_token(true, &[], token()), None);644
+ assert_eq!(page_token(true, &[message.clone()], None), None);645
+ assert_eq!(page_token(false, &[], token()), token());646
+ assert_eq!(page_token(false, &[create], token()), token());647
+ }648
+}@@ -733,7 +733,10 @@ async fn event_context_uses_independent_direction_limits_and_saved_mention_conte
733733
.await734734
.unwrap();735735
let context = &session.context;736
- assert_eq!(context.start_token.as_deref(), Some("manual-before-next"));736
+ assert_eq!(737
+ context.start_token, None,738
+ "an empty page going back is the start"739
+ );737740
assert_eq!(context.end_token.as_deref(), Some("manual-after-next"));738741
handle739742
.close_event_context(&session.context_id)