matrix_sdk_ffi/
room_preview.rs1use anyhow::Context as _;
2use matrix_sdk::{room_preview::RoomPreview as SdkRoomPreview, Client};
3use ruma::room::{JoinRuleSummary, RoomType as RumaRoomType};
4
5use crate::{
6 client::{AllowRule, JoinRule},
7 error::ClientError,
8 room::{Membership, RoomHero},
9 room_member::{RoomMember, RoomMemberWithSenderInfo},
10 utils::AsyncRuntimeDropped,
11};
12
13#[derive(uniffi::Object)]
16pub struct RoomPreview {
17 inner: SdkRoomPreview,
18 client: AsyncRuntimeDropped<Client>,
19}
20
21#[matrix_sdk_ffi_macros::export]
22impl RoomPreview {
23 pub fn info(&self) -> RoomPreviewInfo {
25 let info = &self.inner;
26 RoomPreviewInfo {
27 room_id: info.room_id.to_string(),
28 canonical_alias: info.canonical_alias.as_ref().map(|alias| alias.to_string()),
29 name: info.name.clone(),
30 topic: info.topic.clone(),
31 avatar_url: info.avatar_url.as_ref().map(|url| url.to_string()),
32 num_joined_members: info.num_joined_members,
33 num_active_members: info.num_active_members,
34 room_type: info.room_type.clone().into(),
35 is_history_world_readable: info.is_world_readable,
36 membership: info.state.map(|state| state.into()),
37 join_rule: info.join_rule.clone().map(Into::into),
38 is_direct: info.is_direct,
39 heroes: info
40 .heroes
41 .as_ref()
42 .map(|heroes| heroes.iter().map(|h| h.to_owned().into()).collect()),
43 }
44 }
45
46 pub async fn leave(&self) -> Result<(), ClientError> {
54 let room =
55 self.client.get_room(&self.inner.room_id).context("missing room for a room preview")?;
56
57 Ok(room.leave().await?)
58 }
59
60 pub async fn inviter(&self) -> Option<RoomMember> {
62 let room = self.client.get_room(&self.inner.room_id)?;
63 let invite_details = room.invite_details().await.ok()?;
64 invite_details.inviter.and_then(|m| m.try_into().ok())
65 }
66
67 pub async fn forget(&self) -> Result<(), ClientError> {
69 let room =
70 self.client.get_room(&self.inner.room_id).context("missing room for a room preview")?;
71 room.forget().await?;
72 Ok(())
73 }
74
75 pub async fn own_membership_details(&self) -> Option<RoomMemberWithSenderInfo> {
77 let room = self.client.get_room(&self.inner.room_id)?;
78 room.member_with_sender_info(self.client.user_id()?).await.ok()?.try_into().ok()
79 }
80}
81
82impl RoomPreview {
83 pub(crate) fn new(client: AsyncRuntimeDropped<Client>, inner: SdkRoomPreview) -> Self {
84 Self { client, inner }
85 }
86}
87
88#[derive(uniffi::Record)]
90pub struct RoomPreviewInfo {
91 pub room_id: String,
93 pub canonical_alias: Option<String>,
95 pub name: Option<String>,
97 pub topic: Option<String>,
99 pub avatar_url: Option<String>,
101 pub num_joined_members: u64,
103 pub num_active_members: Option<u64>,
105 pub room_type: RoomType,
107 pub is_history_world_readable: Option<bool>,
109 pub membership: Option<Membership>,
111 pub join_rule: Option<JoinRule>,
113 pub is_direct: Option<bool>,
115 pub heroes: Option<Vec<RoomHero>>,
117}
118
119impl From<JoinRuleSummary> for JoinRule {
120 fn from(join_rule: JoinRuleSummary) -> Self {
121 match join_rule {
122 JoinRuleSummary::Invite => JoinRule::Invite,
123 JoinRuleSummary::Knock => JoinRule::Knock,
124 JoinRuleSummary::Private => JoinRule::Private,
125 JoinRuleSummary::Restricted(summary) => JoinRule::Restricted {
126 rules: summary
127 .allowed_room_ids
128 .iter()
129 .map(|room_id| AllowRule::RoomMembership { room_id: room_id.to_string() })
130 .collect(),
131 },
132 JoinRuleSummary::KnockRestricted(summary) => JoinRule::KnockRestricted {
133 rules: summary
134 .allowed_room_ids
135 .iter()
136 .map(|room_id| AllowRule::RoomMembership { room_id: room_id.to_string() })
137 .collect(),
138 },
139 JoinRuleSummary::Public => JoinRule::Public,
140 _ => JoinRule::Custom { repr: join_rule.as_str().to_owned() },
141 }
142 }
143}
144
145#[derive(Debug, Clone, uniffi::Enum)]
147pub enum RoomType {
148 Room,
150 Space,
152 Custom { value: String },
154}
155
156impl From<Option<RumaRoomType>> for RoomType {
157 fn from(value: Option<RumaRoomType>) -> Self {
158 match value {
159 Some(RumaRoomType::Space) => RoomType::Space,
160 Some(RumaRoomType::_Custom(_)) => RoomType::Custom {
161 value: value.unwrap().to_string(),
163 },
164 _ => RoomType::Room,
165 }
166 }
167}