From f99defff9850dc4dede0d14a6a31ecc32f0f23a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 14 Nov 2024 11:26:03 +0100 Subject: [PATCH 1/3] feat(ffi): add `is_direct` and `fn inviter` to `RoomPreview` --- bindings/matrix-sdk-ffi/src/room_preview.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bindings/matrix-sdk-ffi/src/room_preview.rs b/bindings/matrix-sdk-ffi/src/room_preview.rs index 505081fc52..14237d2544 100644 --- a/bindings/matrix-sdk-ffi/src/room_preview.rs +++ b/bindings/matrix-sdk-ffi/src/room_preview.rs @@ -3,6 +3,7 @@ use matrix_sdk::{room_preview::RoomPreview as SdkRoomPreview, Client}; use ruma::space::SpaceRoomJoinRule; use tracing::warn; +use crate::room_member::RoomMember; use crate::{client::JoinRule, error::ClientError, room::Membership, utils::AsyncRuntimeDropped}; /// A room preview for a room. It's intended to be used to represent rooms that @@ -33,6 +34,7 @@ impl RoomPreview { .clone() .try_into() .map_err(|_| anyhow::anyhow!("unhandled SpaceRoomJoinRule kind"))?, + is_direct: info.is_direct, }) } @@ -45,6 +47,13 @@ impl RoomPreview { self.client.get_room(&self.inner.room_id).context("missing room for a room preview")?; room.leave().await.map_err(Into::into) } + + /// Get the user who created the invite, if any. + pub async fn inviter(&self) -> Option { + let room = self.client.get_room(&self.inner.room_id)?; + let invite_details = room.invite_details().await.ok()?; + invite_details.inviter.and_then(|m| m.try_into().ok()) + } } impl RoomPreview { @@ -76,6 +85,8 @@ pub struct RoomPreviewInfo { pub membership: Option, /// The join rule for this room (private, public, knock, etc.). pub join_rule: JoinRule, + /// Whether the room is direct or not, if known. + pub is_direct: Option, } impl TryFrom for JoinRule { From aae67908f343432796366bf5aae865d64263c105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 14 Nov 2024 11:58:42 +0100 Subject: [PATCH 2/3] feat(ffi): add `RoomPreviewInfo::num_active_members` --- bindings/matrix-sdk-ffi/src/room_preview.rs | 3 +++ crates/matrix-sdk/src/room_preview.rs | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/bindings/matrix-sdk-ffi/src/room_preview.rs b/bindings/matrix-sdk-ffi/src/room_preview.rs index 14237d2544..5de8e5981c 100644 --- a/bindings/matrix-sdk-ffi/src/room_preview.rs +++ b/bindings/matrix-sdk-ffi/src/room_preview.rs @@ -27,6 +27,7 @@ impl RoomPreview { avatar_url: info.avatar_url.as_ref().map(|url| url.to_string()), num_joined_members: info.num_joined_members, room_type: info.room_type.as_ref().map(|room_type| room_type.to_string()), + num_active_members: info.num_active_members, is_history_world_readable: info.is_world_readable, membership: info.state.map(|state| state.into()), join_rule: info @@ -77,6 +78,8 @@ pub struct RoomPreviewInfo { pub avatar_url: Option, /// The number of joined members. pub num_joined_members: u64, + /// The number of active members, if known (joined + invited). + pub num_active_members: Option, /// The room type (space, custom) or nothing, if it's a regular room. pub room_type: Option, /// Is the history world-readable for this room? diff --git a/crates/matrix-sdk/src/room_preview.rs b/crates/matrix-sdk/src/room_preview.rs index c102b6225f..3cccf952ea 100644 --- a/crates/matrix-sdk/src/room_preview.rs +++ b/crates/matrix-sdk/src/room_preview.rs @@ -55,6 +55,9 @@ pub struct RoomPreview { /// The number of joined members. pub num_joined_members: u64, + /// The number of active members, if known (joined + invited). + pub num_active_members: Option, + /// The room type (space, custom) or nothing, if it's a regular room. pub room_type: Option, @@ -83,6 +86,7 @@ impl RoomPreview { room_info: RoomInfo, is_direct: Option, num_joined_members: u64, + num_active_members: Option, state: Option, ) -> Self { RoomPreview { @@ -107,6 +111,7 @@ impl RoomPreview { }, is_world_readable: *room_info.history_visibility() == HistoryVisibility::WorldReadable, num_joined_members, + num_active_members, state, is_direct, } @@ -121,6 +126,7 @@ impl RoomPreview { room.clone_info(), is_direct, room.joined_members_count(), + Some(room.active_members_count()), Some(room.state()), ) } @@ -178,6 +184,8 @@ impl RoomPreview { response.membership.map(|membership| RoomState::from(&membership)) }; + let num_active_members = cached_room.as_ref().map(|r| r.active_members_count()); + let is_direct = if let Some(cached_room) = cached_room { cached_room.is_direct().await.ok() } else { @@ -191,6 +199,7 @@ impl RoomPreview { topic: response.topic, avatar_url: response.avatar_url, num_joined_members: response.num_joined_members.into(), + num_active_members, room_type: response.room_type, join_rule: response.join_rule, is_world_readable: response.world_readable, @@ -238,8 +247,15 @@ impl RoomPreview { let room = client.get_room(room_id); let state = room.as_ref().map(|room| room.state()); + let num_active_members = room.as_ref().map(|r| r.active_members_count()); let is_direct = if let Some(room) = room { room.is_direct().await.ok() } else { None }; - Ok(Self::from_room_info(room_info, is_direct, num_joined_members, state)) + Ok(Self::from_room_info( + room_info, + is_direct, + num_joined_members, + num_active_members, + state, + )) } } From 086f5b16691148c3cf6874604b0766a02925c578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 14 Nov 2024 11:59:10 +0100 Subject: [PATCH 3/3] feat(ffi): make `RoomPreviewInfo::room_type` an enum, not an optional String --- bindings/matrix-sdk-ffi/src/room_preview.rs | 36 ++++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/room_preview.rs b/bindings/matrix-sdk-ffi/src/room_preview.rs index 5de8e5981c..3a3e08cb86 100644 --- a/bindings/matrix-sdk-ffi/src/room_preview.rs +++ b/bindings/matrix-sdk-ffi/src/room_preview.rs @@ -1,10 +1,12 @@ use anyhow::Context as _; use matrix_sdk::{room_preview::RoomPreview as SdkRoomPreview, Client}; -use ruma::space::SpaceRoomJoinRule; +use ruma::{room::RoomType as RumaRoomType, space::SpaceRoomJoinRule}; use tracing::warn; -use crate::room_member::RoomMember; -use crate::{client::JoinRule, error::ClientError, room::Membership, utils::AsyncRuntimeDropped}; +use crate::{ + client::JoinRule, error::ClientError, room::Membership, room_member::RoomMember, + utils::AsyncRuntimeDropped, +}; /// A room preview for a room. It's intended to be used to represent rooms that /// aren't joined yet. @@ -26,8 +28,8 @@ impl RoomPreview { topic: info.topic.clone(), avatar_url: info.avatar_url.as_ref().map(|url| url.to_string()), num_joined_members: info.num_joined_members, - room_type: info.room_type.as_ref().map(|room_type| room_type.to_string()), num_active_members: info.num_active_members, + room_type: info.room_type.as_ref().into(), is_history_world_readable: info.is_world_readable, membership: info.state.map(|state| state.into()), join_rule: info @@ -81,7 +83,7 @@ pub struct RoomPreviewInfo { /// The number of active members, if known (joined + invited). pub num_active_members: Option, /// The room type (space, custom) or nothing, if it's a regular room. - pub room_type: Option, + pub room_type: RoomType, /// Is the history world-readable for this room? pub is_history_world_readable: bool, /// The membership state for the current user, if known. @@ -111,3 +113,27 @@ impl TryFrom for JoinRule { }) } } + +/// The type of room for a [`RoomPreviewInfo`]. +#[derive(Debug, Clone, uniffi::Enum)] +pub enum RoomType { + /// It's a plain chat room. + Room, + /// It's a space that can group several rooms. + Space, + /// It's a custom implementation. + Custom { value: String }, +} + +impl From> for RoomType { + fn from(value: Option<&RumaRoomType>) -> Self { + match value { + Some(RumaRoomType::Space) => RoomType::Space, + Some(RumaRoomType::_Custom(_)) => RoomType::Custom { + // SAFETY: this was checked in the match branch above + value: value.unwrap().to_string(), + }, + _ => RoomType::Room, + } + } +}