matrix_sdk_ui/spaces/
room.rs

1// Copyright 2025 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for that specific language governing permissions and
13// limitations under the License.
14
15use matrix_sdk::{Room, RoomHero, RoomState};
16use ruma::{
17    OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId,
18    events::room::{guest_access::GuestAccess, history_visibility::HistoryVisibility},
19    room::{JoinRuleSummary, RoomSummary, RoomType},
20};
21
22/// Structure representing a room in a space and aggregated information
23/// relevant to the UI layer.
24#[derive(Debug, Clone, PartialEq)]
25pub struct SpaceRoom {
26    /// The ID of the room.
27    pub room_id: OwnedRoomId,
28    /// The canonical alias of the room, if any.
29    pub canonical_alias: Option<OwnedRoomAliasId>,
30    /// The name of the room, if any.
31    pub name: Option<String>,
32    /// The topic of the room, if any.
33    pub topic: Option<String>,
34    /// The URL for the room's avatar, if one is set.
35    pub avatar_url: Option<OwnedMxcUri>,
36    /// The type of room from `m.room.create`, if any.
37    pub room_type: Option<RoomType>,
38    /// The number of members joined to the room.
39    pub num_joined_members: u64,
40    /// The join rule of the room.
41    pub join_rule: Option<JoinRuleSummary>,
42    /// Whether the room may be viewed by users without joining.
43    pub world_readable: Option<bool>,
44    /// Whether guest users may join the room and participate in it.
45    pub guest_can_join: bool,
46
47    /// The number of children room this has, if a space.
48    pub children_count: u64,
49    /// Whether this room is joined, left etc.
50    pub state: Option<RoomState>,
51    /// A list of room members considered to be heroes.
52    pub heroes: Option<Vec<RoomHero>>,
53}
54
55impl SpaceRoom {
56    /// Build a `SpaceRoom` from a `RoomSummary` received from the /hierarchy
57    /// endpoint.
58    pub(crate) fn new_from_summary(
59        summary: &RoomSummary,
60        known_room: Option<Room>,
61        children_count: u64,
62    ) -> Self {
63        Self {
64            room_id: summary.room_id.clone(),
65            canonical_alias: summary.canonical_alias.clone(),
66            name: summary.name.clone(),
67            topic: summary.topic.clone(),
68            avatar_url: summary.avatar_url.clone(),
69            room_type: summary.room_type.clone(),
70            num_joined_members: summary.num_joined_members.into(),
71            join_rule: Some(summary.join_rule.clone()),
72            world_readable: Some(summary.world_readable),
73            guest_can_join: summary.guest_can_join,
74            children_count,
75            state: known_room.as_ref().map(|r| r.state()),
76            heroes: known_room.map(|r| r.heroes()),
77        }
78    }
79
80    /// Build a `SpaceRoom` from a room already known to this client.
81    pub(crate) fn new_from_known(known_room: Room, children_count: u64) -> Self {
82        let room_info = known_room.clone_info();
83
84        Self {
85            room_id: room_info.room_id().to_owned(),
86            canonical_alias: room_info.canonical_alias().map(ToOwned::to_owned),
87            name: room_info.name().map(ToOwned::to_owned),
88            topic: room_info.topic().map(ToOwned::to_owned),
89            avatar_url: room_info.avatar_url().map(ToOwned::to_owned),
90            room_type: room_info.room_type().cloned(),
91            num_joined_members: known_room.joined_members_count(),
92            join_rule: room_info.join_rule().cloned().map(Into::into),
93            world_readable: room_info
94                .history_visibility()
95                .map(|vis| *vis == HistoryVisibility::WorldReadable),
96            guest_can_join: known_room.guest_access() == GuestAccess::CanJoin,
97            children_count,
98            state: Some(known_room.state()),
99            heroes: Some(room_info.heroes().to_vec()),
100        }
101    }
102}