matrix_sdk_ffi/
room_info.rs
1use std::collections::HashMap;
2
3use matrix_sdk::{EncryptionState, 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 encryption_state: EncryptionState,
18 creator: Option<String>,
19 display_name: Option<String>,
22 raw_name: Option<String>,
24 topic: Option<String>,
25 avatar_url: Option<String>,
26 is_direct: bool,
27 is_public: bool,
28 is_space: bool,
29 is_tombstoned: bool,
30 is_favourite: bool,
31 canonical_alias: Option<String>,
32 alternative_aliases: Vec<String>,
33 membership: Membership,
34 inviter: Option<RoomMember>,
40 heroes: Vec<RoomHero>,
41 active_members_count: u64,
42 invited_members_count: u64,
43 joined_members_count: u64,
44 user_power_levels: HashMap<String, i64>,
45 highlight_count: u64,
46 notification_count: u64,
47 cached_user_defined_notification_mode: Option<RoomNotificationMode>,
48 has_room_call: bool,
49 active_room_call_participants: Vec<String>,
50 is_marked_unread: bool,
52 num_unread_messages: u64,
55 num_unread_notifications: u64,
58 num_unread_mentions: u64,
61 pinned_event_ids: Vec<String>,
63 join_rule: Option<JoinRule>,
65 history_visibility: RoomHistoryVisibility,
67}
68
69impl RoomInfo {
70 pub(crate) async fn new(room: &matrix_sdk::Room) -> Result<Self, ClientError> {
71 let unread_notification_counts = room.unread_notification_counts();
72
73 let power_levels_map = room.users_with_power_levels().await;
74 let mut user_power_levels = HashMap::<String, i64>::new();
75 for (id, level) in power_levels_map.iter() {
76 user_power_levels.insert(id.to_string(), *level);
77 }
78 let pinned_event_ids =
79 room.pinned_event_ids().unwrap_or_default().iter().map(|id| id.to_string()).collect();
80
81 let join_rule = room.join_rule().try_into();
82 if let Err(e) = &join_rule {
83 warn!("Failed to parse join rule: {:?}", e);
84 }
85
86 Ok(Self {
87 id: room.room_id().to_string(),
88 encryption_state: room.encryption_state(),
89 creator: room.creator().as_ref().map(ToString::to_string),
90 display_name: room.cached_display_name().map(|name| name.to_string()),
91 raw_name: room.name(),
92 topic: room.topic(),
93 avatar_url: room.avatar_url().map(Into::into),
94 is_direct: room.is_direct().await?,
95 is_public: room.is_public(),
96 is_space: room.is_space(),
97 is_tombstoned: room.is_tombstoned(),
98 is_favourite: room.is_favourite(),
99 canonical_alias: room.canonical_alias().map(Into::into),
100 alternative_aliases: room.alt_aliases().into_iter().map(Into::into).collect(),
101 membership: room.state().into(),
102 inviter: match room.state() {
103 RoomState::Invited => room
104 .invite_details()
105 .await
106 .ok()
107 .and_then(|details| details.inviter)
108 .map(TryInto::try_into)
109 .transpose()
110 .ok()
111 .flatten(),
112 _ => None,
113 },
114 heroes: room.heroes().into_iter().map(Into::into).collect(),
115 active_members_count: room.active_members_count(),
116 invited_members_count: room.invited_members_count(),
117 joined_members_count: room.joined_members_count(),
118 user_power_levels,
119 highlight_count: unread_notification_counts.highlight_count,
120 notification_count: unread_notification_counts.notification_count,
121 cached_user_defined_notification_mode: room
122 .cached_user_defined_notification_mode()
123 .map(Into::into),
124 has_room_call: room.has_active_room_call(),
125 active_room_call_participants: room
126 .active_room_call_participants()
127 .iter()
128 .map(|u| u.to_string())
129 .collect(),
130 is_marked_unread: room.is_marked_unread(),
131 num_unread_messages: room.num_unread_messages(),
132 num_unread_notifications: room.num_unread_notifications(),
133 num_unread_mentions: room.num_unread_mentions(),
134 pinned_event_ids,
135 join_rule: join_rule.ok(),
136 history_visibility: room.history_visibility_or_default().try_into()?,
137 })
138 }
139}