Skip to content

Commit 86e2c74

Browse files
committed
Return only top level joined rooms from SpaceService::joined_spaces and its reactive counterpart.
1 parent 45d074b commit 86e2c74

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed

bindings/matrix-sdk-ffi/src/client.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,11 +1262,7 @@ impl Client {
12621262
}
12631263

12641264
pub async fn spaces_service(&self) -> Arc<SpaceService> {
1265-
// This method doesn't need to be async but if its not the FFI layer panics
1266-
// with "there is no no reactor running, must be called from the context
1267-
// of a Tokio 1.x runtime" error because the undelying constructor spawns
1268-
// an async task.
1269-
let inner = UISpaceService::new((*self.inner).clone());
1265+
let inner = UISpaceService::new((*self.inner).clone()).await;
12701266
Arc::new(SpaceService::new(inner))
12711267
}
12721268

crates/matrix-sdk-ui/src/spaces/mod.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
//! See [`SpaceService`] for details.
1818
1919
use eyeball::{SharedObservable, Subscriber};
20+
use futures_util::pin_mut;
2021
use matrix_sdk::Client;
2122
use ruma::OwnedRoomId;
2223
use tokio::task::JoinHandle;
24+
use tokio_stream::StreamExt;
2325
use tracing::error;
2426

2527
pub use crate::spaces::{room::SpaceServiceRoom, room_list::SpaceServiceRoomList};
@@ -42,10 +44,10 @@ impl Drop for SpaceService {
4244
}
4345

4446
impl SpaceService {
45-
pub fn new(client: Client) -> Self {
47+
pub async fn new(client: Client) -> Self {
4648
let joined_spaces = SharedObservable::new(Vec::new());
4749

48-
joined_spaces.set(Self::joined_spaces_for(&client));
50+
joined_spaces.set(Self::joined_spaces_for(&client).await);
4951

5052
let client_clone = client.clone();
5153
let joined_spaces_clone = joined_spaces.clone();
@@ -57,7 +59,7 @@ impl SpaceService {
5759
loop {
5860
match all_room_updates_receiver.recv().await {
5961
Ok(_) => {
60-
let new_spaces = Self::joined_spaces_for(&client_clone);
62+
let new_spaces = Self::joined_spaces_for(&client_clone).await;
6163
if new_spaces != joined_spaces_clone.get() {
6264
joined_spaces_clone.set(new_spaces);
6365
}
@@ -84,13 +86,29 @@ impl SpaceService {
8486
SpaceServiceRoomList::new(self.client.clone(), space_id)
8587
}
8688

87-
fn joined_spaces_for(client: &Client) -> Vec<SpaceServiceRoom> {
88-
client
89+
async fn joined_spaces_for(client: &Client) -> Vec<SpaceServiceRoom> {
90+
let joined_spaces = client
8991
.joined_rooms()
9092
.into_iter()
9193
.filter_map(|room| if room.is_space() { Some(room) } else { None })
92-
.map(SpaceServiceRoom::new_from_known)
93-
.collect::<Vec<_>>()
94+
.collect::<Vec<_>>();
95+
96+
let top_level_spaces: Vec<SpaceServiceRoom> = tokio_stream::iter(joined_spaces)
97+
.then(|room| async move {
98+
let ok = if let Ok(parents) = room.parent_spaces().await {
99+
pin_mut!(parents);
100+
parents.any(|p| p.is_ok()).await == false
101+
} else {
102+
false
103+
};
104+
(room, ok)
105+
})
106+
.filter(|(_, ok)| *ok)
107+
.map(|(x, _)| SpaceServiceRoom::new_from_known(x))
108+
.collect()
109+
.await;
110+
111+
top_level_spaces
94112
}
95113
}
96114

@@ -115,7 +133,7 @@ mod tests {
115133
let server = MatrixMockServer::new().await;
116134
let client = server.client_builder().build().await;
117135
let user_id = client.user_id().unwrap();
118-
let space_service = SpaceService::new(client.clone());
136+
let space_service = SpaceService::new(client.clone()).await;
119137
let factory = EventFactory::new();
120138

121139
server.mock_room_state_encryption().plain().mount().await;
@@ -181,10 +199,10 @@ mod tests {
181199
)
182200
.await;
183201

184-
// All joined
202+
// Only the parent space is returned
185203
assert_eq!(
186204
space_service.joined_spaces().iter().map(|s| s.room_id.to_owned()).collect::<Vec<_>>(),
187-
vec![child_space_id_1, child_space_id_2, parent_space_id]
205+
vec![parent_space_id]
188206
);
189207

190208
let parent_space = client.get_room(parent_space_id).unwrap();
@@ -246,7 +264,7 @@ mod tests {
246264
// Build the `SpaceService` and expect the room to show up with no updates
247265
// pending
248266

249-
let space_service = SpaceService::new(client.clone());
267+
let space_service = SpaceService::new(client.clone()).await;
250268

251269
let joined_spaces_subscriber = space_service.subscribe_to_joined_spaces();
252270
pin_mut!(joined_spaces_subscriber);

crates/matrix-sdk-ui/src/spaces/room_list.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ mod tests {
148148
async fn test_room_list_pagination() {
149149
let server = MatrixMockServer::new().await;
150150
let client = server.client_builder().build().await;
151-
let space_service = SpaceService::new(client.clone());
151+
let space_service = SpaceService::new(client.clone()).await;
152152

153153
server.mock_room_state_encryption().plain().mount().await;
154154

0 commit comments

Comments
 (0)