matrix_sdk_ffi/
room_info.rs

1use std::collections::HashMap;
2
3use matrix_sdk::RoomState;
4use tracing::warn;
5
6use crate::{
7    client::JoinRule,
8    error::ClientError,
9    notification_settings::RoomNotificationMode,
10    room::{Membership, RoomHero, RoomHistoryVisibility},
11    room_member::RoomMember,
12};
13
14#[derive(uniffi::Record)]
15pub struct RoomInfo {
16    id: String,
17    creator: Option<String>,
18    /// The room's name from the room state event if received from sync, or one
19    /// that's been computed otherwise.
20    display_name: Option<String>,
21    /// Room name as defined by the room state event only.
22    raw_name: Option<String>,
23    topic: Option<String>,
24    avatar_url: Option<String>,
25    is_direct: bool,
26    is_public: bool,
27    is_space: bool,
28    is_tombstoned: bool,
29    is_favourite: bool,
30    canonical_alias: Option<String>,
31    alternative_aliases: Vec<String>,
32    membership: Membership,
33    /// Member who invited the current user to a room that's in the invited
34    /// state.
35    ///
36    /// Can be missing if the room membership invite event is missing from the
37    /// store.
38    inviter: Option<RoomMember>,
39    heroes: Vec<RoomHero>,
40    active_members_count: u64,
41    invited_members_count: u64,
42    joined_members_count: u64,
43    user_power_levels: HashMap<String, i64>,
44    highlight_count: u64,
45    notification_count: u64,
46    cached_user_defined_notification_mode: Option<RoomNotificationMode>,
47    has_room_call: bool,
48    active_room_call_participants: Vec<String>,
49    /// Whether this room has been explicitly marked as unread
50    is_marked_unread: bool,
51    /// "Interesting" messages received in that room, independently of the
52    /// notification settings.
53    num_unread_messages: u64,
54    /// Events that will notify the user, according to their
55    /// notification settings.
56    num_unread_notifications: u64,
57    /// Events causing mentions/highlights for the user, according to their
58    /// notification settings.
59    num_unread_mentions: u64,
60    /// The currently pinned event ids.
61    pinned_event_ids: Vec<String>,
62    /// The join rule for this room, if known.
63    join_rule: Option<JoinRule>,
64    /// The history visibility for this room, if known.
65    history_visibility: RoomHistoryVisibility,
66}
67
68impl RoomInfo {
69    pub(crate) async fn new(room: &matrix_sdk::Room) -> Result<Self, ClientError> {
70        let unread_notification_counts = room.unread_notification_counts();
71
72        let power_levels_map = room.users_with_power_levels().await;
73        let mut user_power_levels = HashMap::<String, i64>::new();
74        for (id, level) in power_levels_map.iter() {
75            user_power_levels.insert(id.to_string(), *level);
76        }
77        let pinned_event_ids =
78            room.pinned_event_ids().unwrap_or_default().iter().map(|id| id.to_string()).collect();
79
80        let join_rule = room.join_rule().try_into();
81        if let Err(e) = &join_rule {
82            warn!("Failed to parse join rule: {:?}", e);
83        }
84
85        Ok(Self {
86            id: room.room_id().to_string(),
87            creator: room.creator().as_ref().map(ToString::to_string),
88            display_name: room.cached_display_name().map(|name| name.to_string()),
89            raw_name: room.name(),
90            topic: room.topic(),
91            avatar_url: room.avatar_url().map(Into::into),
92            is_direct: room.is_direct().await?,
93            is_public: room.is_public(),
94            is_space: room.is_space(),
95            is_tombstoned: room.is_tombstoned(),
96            is_favourite: room.is_favourite(),
97            canonical_alias: room.canonical_alias().map(Into::into),
98            alternative_aliases: room.alt_aliases().into_iter().map(Into::into).collect(),
99            membership: room.state().into(),
100            inviter: match room.state() {
101                RoomState::Invited => room
102                    .invite_details()
103                    .await
104                    .ok()
105                    .and_then(|details| details.inviter)
106                    .map(TryInto::try_into)
107                    .transpose()
108                    .ok()
109                    .flatten(),
110                _ => None,
111            },
112            heroes: room.heroes().into_iter().map(Into::into).collect(),
113            active_members_count: room.active_members_count(),
114            invited_members_count: room.invited_members_count(),
115            joined_members_count: room.joined_members_count(),
116            user_power_levels,
117            highlight_count: unread_notification_counts.highlight_count,
118            notification_count: unread_notification_counts.notification_count,
119            cached_user_defined_notification_mode: room
120                .cached_user_defined_notification_mode()
121                .map(Into::into),
122            has_room_call: room.has_active_room_call(),
123            active_room_call_participants: room
124                .active_room_call_participants()
125                .iter()
126                .map(|u| u.to_string())
127                .collect(),
128            is_marked_unread: room.is_marked_unread(),
129            num_unread_messages: room.num_unread_messages(),
130            num_unread_notifications: room.num_unread_notifications(),
131            num_unread_mentions: room.num_unread_mentions(),
132            pinned_event_ids,
133            join_rule: join_rule.ok(),
134            history_visibility: room.history_visibility_or_default().try_into()?,
135        })
136    }
137}