From af390328b58ccbbf0fb7687e8f6b4aa090676800 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 16 Sep 2024 12:01:14 +0200 Subject: [PATCH] Revert "chore(ui,ffi): Remove the `RoomList::entries` method." This reverts commit 98a3a0b3c4c6905a20cb5ddfc3a063020d530c59. --- bindings/matrix-sdk-ffi/src/room_list.rs | 27 ++++++ .../src/room_list_service/mod.rs | 6 +- .../src/room_list_service/room_list.rs | 12 ++- .../tests/integration/room_list_service.rs | 90 +++++++++++++++++++ 4 files changed, 125 insertions(+), 10 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index 1d24c547f25..48a6c100397 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -182,6 +182,33 @@ impl RoomList { }) } + fn entries(&self, listener: Box) -> Arc { + let this = self.inner.clone(); + let utd_hook = self.room_list_service.utd_hook.clone(); + + Arc::new(TaskHandle::new(RUNTIME.spawn(async move { + let (entries, entries_stream) = this.entries(); + + pin_mut!(entries_stream); + + listener.on_update(vec![RoomListEntriesUpdate::Append { + values: entries + .into_iter() + .map(|room| Arc::new(RoomListItem::from(room, utd_hook.clone()))) + .collect(), + }]); + + while let Some(diffs) = entries_stream.next().await { + listener.on_update( + diffs + .into_iter() + .map(|diff| RoomListEntriesUpdate::from(diff, utd_hook.clone())) + .collect(), + ); + } + }))) + } + fn entries_with_dynamic_adapters( self: Arc, page_size: u32, diff --git a/crates/matrix-sdk-ui/src/room_list_service/mod.rs b/crates/matrix-sdk-ui/src/room_list_service/mod.rs index 3f10f066774..1b5a57a3a96 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/mod.rs @@ -44,9 +44,9 @@ //! fluid user experience for a Matrix client. //! //! [`RoomListService::all_rooms`] provides a way to get a [`RoomList`] for all -//! the rooms. From that, calling [`RoomList::entries_with_dynamic_adapters`] -//! provides a way to get a stream of rooms. This stream is sorted, can be -//! filtered, and the filter can be changed over time. +//! the rooms. From that, calling [`RoomList::entries`] provides a way to get a +//! stream of room list entry. This stream can be filtered, and the filter can +//! be changed over time. //! //! [`RoomListService::state`] provides a way to get a stream of the state //! machine's state, which can be pretty helpful for the client app. diff --git a/crates/matrix-sdk-ui/src/room_list_service/room_list.rs b/crates/matrix-sdk-ui/src/room_list_service/room_list.rs index 6f9686bbf00..de7b4870270 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/room_list.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/room_list.rs @@ -115,8 +115,8 @@ impl RoomList { self.loading_state.subscribe() } - /// Get a stream of rooms. - fn entries(&self) -> (Vector, impl Stream>> + '_) { + /// Get all previous rooms, in addition to a [`Stream`] to rooms' updates. + pub fn entries(&self) -> (Vector, impl Stream>> + '_) { let (rooms, stream) = self.client.rooms_stream(); let map_room = |room| Room::new(room, &self.sliding_sync); @@ -127,11 +127,9 @@ impl RoomList { ) } - /// Get a configurable stream of rooms. - /// - /// It's possible to provide a filter that will filter out room list - /// entries, and that it's also possible to “paginate” over the entries by - /// `page_size`. The rooms are also sorted. + /// Similar to [`Self::entries`] except that it's possible to provide a + /// filter that will filter out room list entries, and that it's also + /// possible to “paginate” over the entries by `page_size`. /// /// The returned stream will only start yielding diffs once a filter is set /// through the returned [`RoomListDynamicEntriesController`]. For every diff --git a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs index 25ba17d6b66..b37ec389f9c 100644 --- a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs @@ -1167,6 +1167,96 @@ async fn test_loading_states() -> Result<(), Error> { Ok(()) } +#[async_test] +async fn test_entries_stream() -> Result<(), Error> { + let (_, server, room_list) = new_room_list_service().await?; + + let sync = room_list.sync(); + pin_mut!(sync); + + let all_rooms = room_list.all_rooms().await?; + + let (previous_entries, entries_stream) = all_rooms.entries(); + pin_mut!(entries_stream); + + sync_then_assert_request_and_fake_response! { + [server, room_list, sync] + states = Init => SettingUp, + assert request >= { + "lists": { + ALL_ROOMS: { + "ranges": [[0, 19]], + }, + }, + }, + respond with = { + "pos": "0", + "lists": { + ALL_ROOMS: { + "count": 10, + }, + }, + "rooms": { + "!r0:bar.org": { + "initial": true, + "timeline": [], + }, + "!r1:bar.org": { + "initial": true, + "timeline": [], + }, + "!r2:bar.org": { + "initial": true, + "timeline": [], + }, + }, + }, + }; + + assert!(previous_entries.is_empty()); + assert_entries_batch! { + [entries_stream] + push back [ "!r0:bar.org" ]; + push back [ "!r1:bar.org" ]; + push back [ "!r2:bar.org" ]; + end; + }; + + sync_then_assert_request_and_fake_response! { + [server, room_list, sync] + states = SettingUp => Running, + assert request >= { + "lists": { + ALL_ROOMS: { + "ranges": [[0, 9]], + }, + }, + }, + respond with = { + "pos": "1", + "lists": { + ALL_ROOMS: { + "count": 9, + }, + }, + "rooms": { + "!r3:bar.org": { + "initial": true, + "timeline": [], + }, + }, + }, + }; + + assert_entries_batch! { + [entries_stream] + push back [ "!r3:bar.org" ]; + end; + }; + + Ok(()) +} + #[async_test] async fn test_dynamic_entries_stream() -> Result<(), Error> { let (client, server, room_list) = new_room_list_service().await?;