feat(sdk): add a Client::joined_space_rooms method that allows retrieving the list of joined spaces.

This commit is contained in:
Stefan Ceriu
2025-08-21 10:09:17 +03:00
committed by Damir Jelić
parent b2fee72d79
commit 763314645b
5 changed files with 295 additions and 2 deletions
+1
View File
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
### Features
- Add a `Client::joined_space_rooms` method that allows retrieving the list of joined spaces.
- `Room::enable_encryption` and `Room::enable_encryption_with_state_event_encryption` will poll
the encryption state for up to 3 seconds, rather than checking once after a single sync has
completed.
+9
View File
@@ -1234,6 +1234,15 @@ impl Client {
self.rooms_filtered(RoomStateFilter::LEFT)
}
/// Returns the joined space rooms this client knows about.
pub fn joined_space_rooms(&self) -> Vec<Room> {
self.base_client()
.rooms_filtered(RoomStateFilter::JOINED)
.into_iter()
.flat_map(|room| room.is_space().then_some(Room::new(self.clone(), room)))
.collect()
}
/// Get a room with the given room id.
///
/// # Arguments
@@ -284,6 +284,7 @@ async fn test_invited_rooms() {
assert!(client.joined_rooms().is_empty());
assert!(client.left_rooms().is_empty());
assert!(!client.invited_rooms().is_empty());
assert!(client.joined_space_rooms().is_empty());
let room = client.get_room(room_id!("!696r7674:example.com")).unwrap();
assert_eq!(room.state(), RoomState::Invited);
@@ -300,11 +301,31 @@ async fn test_left_rooms() {
assert!(client.joined_rooms().is_empty());
assert!(!client.left_rooms().is_empty());
assert!(client.invited_rooms().is_empty());
assert!(client.joined_space_rooms().is_empty());
let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap();
assert_eq!(room.state(), RoomState::Left);
}
#[async_test]
async fn test_joined_space_rooms() {
let (client, server) = logged_in_client_with_server().await;
mock_sync(&server, &*test_json::JOIN_SPACE_SYNC, None).await;
let _response = client.sync_once(SyncSettings::default()).await.unwrap();
assert!(!client.joined_rooms().is_empty());
assert!(!client.joined_space_rooms().is_empty());
assert!(client.left_rooms().is_empty());
assert!(client.invited_rooms().is_empty());
let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap();
assert_eq!(room.state(), RoomState::Joined);
assert!(room.is_space());
}
#[async_test]
async fn test_whoami() {
let (client, server) = logged_in_client_with_server().await;
+2 -2
View File
@@ -25,8 +25,8 @@ pub use api_responses::{
};
pub use members::MEMBERS;
pub use sync::{
DEFAULT_SYNC_SUMMARY, INVITE_SYNC, LEAVE_SYNC, LEAVE_SYNC_EVENT, MORE_SYNC, MORE_SYNC_2, SYNC,
VOIP_SYNC,
DEFAULT_SYNC_SUMMARY, INVITE_SYNC, JOIN_SPACE_SYNC, LEAVE_SYNC, LEAVE_SYNC_EVENT, MORE_SYNC,
MORE_SYNC_2, SYNC, VOIP_SYNC,
};
pub use sync_events::{
ALIAS, ALIASES, ENCRYPTION, MEMBER, MEMBER_ADDITIONAL, MEMBER_BAN, MEMBER_INVITE, MEMBER_LEAVE,
@@ -1231,6 +1231,268 @@ pub static LEAVE_SYNC_EVENT: Lazy<JsonValue> = Lazy::new(|| {
})
});
pub static JOIN_SPACE_SYNC: Lazy<JsonValue> = Lazy::new(|| {
json!({
"device_one_time_keys_count": {},
"next_batch": "s526_47314_0_7_1_1_1_11444_1",
"device_lists": {
"changed": [
"@example:example.org"
],
"left": []
},
"account_data": {
"events": [
{
"content": {
"ignored_users": {
"@someone:example.org": {}
}
},
"type": "m.ignored_user_list"
}
]
},
"rooms": {
"invite": {},
"join": {
*DEFAULT_TEST_ROOM_ID: {
"summary": {},
"account_data": {
"events": [
{
"content": {
"event_id": "$someplace:example.org"
},
"room_id": "!roomid:room.com",
"type": "m.fully_read"
}
]
},
"ephemeral": {
"events": [
{
"content": {
"$151680659217152dPKjd:localhost": {
"m.read": {
"@example:localhost": {
"ts": 151680989
}
}
}
},
"room_id": *DEFAULT_TEST_ROOM_ID,
"type": "m.receipt"
},
]
},
"state": {
"events": [
{
"content": {
"join_rule": "public"
},
"event_id": "$15139375514WsgmR:localhost",
"origin_server_ts": 151393755000000_u64,
"sender": "@example:localhost",
"state_key": "",
"type": "m.room.join_rules",
"unsigned": {
"age": 7034220
}
},
{
"content": {
"avatar_url": null,
"displayname": "example",
"membership": "join"
},
"event_id": "$151800140517rfvjc:localhost",
"membership": "join",
"origin_server_ts": 151800140000000_u64,
"sender": "@example:localhost",
"state_key": "@example:localhost",
"type": "m.room.member",
"unsigned": {
"age": 2970366,
"replaces_state": "$151800111315tsynI:localhost"
}
},
{
"content": {
"history_visibility": "shared"
},
"event_id": "$15139375515VaJEY:localhost",
"origin_server_ts": 151393755000000_u64,
"sender": "@example:localhost",
"state_key": "",
"type": "m.room.history_visibility",
"unsigned": {
"age": 7034220
}
},
{
"content": {
"creator": "@example:localhost",
"type": "m.space"
},
"event_id": "$15139375510KUZHi:localhost",
"origin_server_ts": 151393755000000_u64,
"sender": "@example:localhost",
"state_key": "",
"type": "m.room.create",
"unsigned": {
"age": 703422
}
},
{
"content": {
"aliases": [
"#tutorial:localhost"
]
},
"event_id": "$15139375516NUgtD:localhost",
"origin_server_ts": 151393755000000_u64,
"sender": "@example:localhost",
"state_key": "localhost",
"type": "m.room.aliases",
"unsigned": {
"age": 703422
}
},
{
"content": {
"topic": "room topic"
},
"event_id": "$151957878228ssqrJ:localhost",
"origin_server_ts": 151957878000000_u64,
"sender": "@example:localhost",
"state_key": "",
"type": "m.room.topic",
"unsigned": {
"age": 1392989709,
"prev_content": {
"topic": "test"
},
"prev_sender": "@example:localhost",
"replaces_state": "$151957069225EVYKm:localhost"
}
},
{
"content": {
"ban": 50,
"events": {
"m.room.avatar": 50,
"m.room.canonical_alias": 50,
"m.room.history_visibility": 100,
"m.room.name": 50,
"m.room.power_levels": 100
},
"events_default": 0,
"invite": 0,
"kick": 50,
"redact": 50,
"state_default": 50,
"users": {
"@example:localhost": 100
},
"users_default": 0
},
"event_id": "$15139375512JaHAW:localhost",
"origin_server_ts": 151393755000000_u64,
"sender": "@example:localhost",
"state_key": "",
"type": "m.room.power_levels",
"unsigned": {
"age": 703422
}
},
{
"content": {
"alias": "#tutorial:localhost"
},
"event_id": "$15139375513VdeRF:localhost",
"origin_server_ts": 151393755000000_u64,
"sender": "@example:localhost",
"state_key": "",
"type": "m.room.canonical_alias",
"unsigned": {
"age": 703422
}
},
{
"content": {
"avatar_url": null,
"displayname": "example2",
"membership": "join"
},
"event_id": "$152034824468gOeNB:localhost",
"membership": "join",
"origin_server_ts": 152034824000000_u64,
"sender": "@example2:localhost",
"state_key": "@example2:localhost",
"type": "m.room.member",
"unsigned": {
"age": 623527289,
"prev_content": {
"membership": "leave"
},
"prev_sender": "@example:localhost",
"replaces_state": "$152034819067QWJxM:localhost"
}
},
]
},
"timeline": {
"events": [
{
"content": {
"body": "baba",
"format": "org.matrix.custom.html",
"formatted_body": "<strong>baba</strong>",
"msgtype": "m.text"
},
"event_id": "$152037280074GZeOm:localhost",
"origin_server_ts": 152037280000000_u64,
"sender": "@example:localhost",
"type": "m.room.message",
"unsigned": {
"age": 598971425
}
}
],
"limited": true,
"prev_batch": "t392-516_47314_0_7_1_1_1_11444_1"
},
"unread_notifications": {
"highlight_count": 0,
"notification_count": 11
}
}
},
"leave": {}
},
"to_device": {
"events": []
},
"presence": {
"events": [
{
"content": {
"avatar_url": "mxc://localhost/wefuiwegh8742w",
"currently_active": false,
"last_active_ago": 1,
"presence": "online",
"status_msg": "Making cupcakes"
},
"sender": "@example:localhost",
"type": "m.presence"
}
]
}
})
});
/// In the [`MIXED_SYNC`], the room id of the joined room.
pub static MIXED_JOINED_ROOM_ID: Lazy<&RoomId> =
Lazy::new(|| room_id!("!SVkFJHzfwvuaIEawgC:localhost"));