Commit 9b9b16982dca
tarball3 files changed+139-0
@@ -213,6 +213,23 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> {
213213
self.clear();214214
}215215
216
+ VectorDiff::Reset { values: events } => {217
+ recycled_timeline_ids.clear();218
+ self.clear();219
+ for event in events {220
+ self.handle_remote_event(221
+ event,222
+ TimelineItemPosition::End { origin },223
+ room_data_provider,224
+ settings,225
+ &mut date_divider_adjuster,226
+ &mut cached_profiles,227
+ None,228
+ )229
+ .await;230
+ }231
+ }232
+216233
v => unimplemented!("{v:?}"),217234
}218235
}@@ -429,6 +446,18 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> {
429446
// place.430447
}431448
449
+ VectorDiff::Reset { values: events } => {450
+ for event in events {451
+ self.handle_remote_aggregation(452
+ event,453
+ TimelineItemPosition::End { origin },454
+ room_data_provider,455
+ &mut date_divider_adjuster,456
+ )457
+ .await;458
+ }459
+ }460
+432461
v => unimplemented!("{v:?}"),433462
}434463
}@@ -56,6 +56,7 @@ mod queue;
5656
mod reactions;5757
mod read_receipts;5858
mod redecryption;59
+mod reseed;5960
mod replies;6061
mod subscribe;6162
mod thread;@@ -0,0 +1,109 @@
1
+use std::time::Duration;2
+3
+use assert_matches::assert_matches;4
+use futures_util::StreamExt;5
+use matrix_sdk::test_utils::mocks::MatrixMockServer;6
+use matrix_sdk_test::{ALICE, JoinedRoomBuilder, async_test, event_factory::EventFactory};7
+use matrix_sdk_ui::timeline::{EventSendState, RoomExt};8
+use ruma::{event_id, events::room::message::RoomMessageEventContent, room_id};9
+use tokio::time::timeout;10
+11
+#[async_test]12
+async fn test_timeline_survives_room_cache_reseed() {13
+ let server = MatrixMockServer::new().await;14
+ let client = server.client_builder().build().await;15
+ client.send_queue().set_enabled(false).await;16
+17
+ server.mock_room_state_encryption().plain().mount().await;18
+19
+ let room_id = room_id!("!a98sd12bjh:example.org");20
+ let room = server.sync_joined_room(&client, room_id).await;21
+ let timeline = room.timeline().await.unwrap();22
+ let (_, mut timeline_stream) = timeline.subscribe().await;23
+ let event_factory = EventFactory::new().room(room_id);24
+25
+ let old_event_id = event_id!("$before_reseed");26
+ server27
+ .sync_room(28
+ &client,29
+ JoinedRoomBuilder::new(room_id).add_timeline_event(30
+ event_factory.text_msg("old history").sender(&ALICE).event_id(old_event_id),31
+ ),32
+ )33
+ .await;34
+35
+ timeout(Duration::from_secs(5), async {36
+ loop {37
+ let items = timeline.items().await;38
+ if items.iter().any(|item| {39
+ item.as_event().is_some_and(|event| event.event_id() == Some(old_event_id))40
+ }) {41
+ break;42
+ }43
+ assert!(timeline_stream.next().await.is_some());44
+ }45
+ })46
+ .await47
+ .unwrap();48
+49
+ timeline.send(RoomMessageEventContent::text_plain("pending local echo").into()).await.unwrap();50
+51
+ timeout(Duration::from_secs(5), async {52
+ loop {53
+ let items = timeline.items().await;54
+ if items.iter().any(|item| {55
+ item.as_event().is_some_and(|event| {56
+ event57
+ .content()58
+ .as_message()59
+ .is_some_and(|message| message.body() == "pending local echo")60
+ })61
+ }) {62
+ break;63
+ }64
+ assert!(timeline_stream.next().await.is_some());65
+ }66
+ })67
+ .await68
+ .unwrap();69
+70
+ let new_event_id = event_id!("$after_reseed");71
+ let new_event =72
+ event_factory.text_msg("recent history").sender(&ALICE).event_id(new_event_id).into_event();73
+ let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap();74
+ room_event_cache75
+ .reseed(vec![new_event], Some("older".into()))76
+ .await77
+ .unwrap();78
+79
+ timeout(Duration::from_secs(5), async {80
+ loop {81
+ let items = timeline.items().await;82
+ if items.iter().any(|item| {83
+ item.as_event().is_some_and(|event| event.event_id() == Some(new_event_id))84
+ }) {85
+ break;86
+ }87
+ assert!(timeline_stream.next().await.is_some());88
+ }89
+ })90
+ .await91
+ .unwrap();92
+93
+ let items = timeline.items().await;94
+ assert!(!items.iter().any(|item| {95
+ item.as_event().is_some_and(|event| event.event_id() == Some(old_event_id))96
+ }));97
+98
+ let local_echo = items99
+ .iter()100
+ .filter_map(|item| item.as_event())101
+ .find(|event| {102
+ event103
+ .content()104
+ .as_message()105
+ .is_some_and(|message| message.body() == "pending local echo")106
+ })107
+ .unwrap();108
+ assert_matches!(local_echo.send_state(), Some(EventSendState::NotSentYet { .. }));109
+}