Skip to content

Commit d0048e7

Browse files
jmartinespbnjbvr
authored andcommitted
chore(room_preview): Add knocking action to the RoomPreviewActions too
1 parent 736f4d4 commit d0048e7

File tree

16 files changed

+313
-202
lines changed

16 files changed

+313
-202
lines changed

bindings/matrix-sdk-ffi/src/client.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::{
22
collections::HashMap,
33
fmt::Debug,
44
mem::ManuallyDrop,
5-
ops::Deref,
65
path::Path,
76
sync::{Arc, RwLock},
87
};
@@ -1028,7 +1027,7 @@ impl Client {
10281027
&self,
10291028
room_id: String,
10301029
via_servers: Vec<String>,
1031-
) -> Result<RoomPreview, ClientError> {
1030+
) -> Result<Arc<RoomPreview>, ClientError> {
10321031
let room_id = RoomId::parse(&room_id).context("room_id is not a valid room id")?;
10331032

10341033
let via_servers = via_servers
@@ -1042,16 +1041,15 @@ impl Client {
10421041
let room_id: &RoomId = &room_id;
10431042

10441043
let sdk_room_preview = self.inner.get_room_preview(room_id.into(), via_servers).await?;
1045-
let client = (*self.inner.deref()).clone();
10461044

1047-
RoomPreview::try_from_sdk(sdk_room_preview, client)
1045+
Ok(Arc::new(RoomPreview::from_sdk(sdk_room_preview)))
10481046
}
10491047

10501048
/// Given a room alias, get the preview of a room, to interact with it.
10511049
pub async fn get_room_preview_from_room_alias(
10521050
&self,
10531051
room_alias: String,
1054-
) -> Result<RoomPreview, ClientError> {
1052+
) -> Result<Arc<RoomPreview>, ClientError> {
10551053
let room_alias =
10561054
RoomAliasId::parse(&room_alias).context("room_alias is not a valid room alias")?;
10571055

@@ -1060,9 +1058,8 @@ impl Client {
10601058
let room_alias: &RoomAliasId = &room_alias;
10611059

10621060
let sdk_room_preview = self.inner.get_room_preview(room_alias.into(), Vec::new()).await?;
1063-
let client = (*self.inner.deref()).clone();
10641061

1065-
RoomPreview::try_from_sdk(sdk_room_preview, client)
1062+
Ok(Arc::new(RoomPreview::from_sdk(sdk_room_preview)))
10661063
}
10671064

10681065
/// Waits until an at least partially synced room is received, and returns
@@ -1807,7 +1804,7 @@ impl From<OidcPrompt> for SdkOidcPrompt {
18071804
}
18081805

18091806
/// The rule used for users wishing to join this room.
1810-
#[derive(uniffi::Enum)]
1807+
#[derive(Debug, Clone, uniffi::Enum)]
18111808
pub enum JoinRule {
18121809
/// Anyone can join the room without any prior action.
18131810
Public,
@@ -1836,7 +1833,7 @@ pub enum JoinRule {
18361833
}
18371834

18381835
/// An allow rule which defines a condition that allows joining a room.
1839-
#[derive(uniffi::Enum)]
1836+
#[derive(Debug, Clone, uniffi::Enum)]
18401837
pub enum AllowRule {
18411838
/// Only a member of the `room_id` Room can join the one this rule is used
18421839
/// in.

bindings/matrix-sdk-ffi/src/error.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use std::{collections::HashMap, fmt, fmt::Display};
22

33
use matrix_sdk::{
44
encryption::CryptoStoreError, event_cache::EventCacheError, oidc::OidcError, reqwest,
5-
room::edit::EditError, send_queue::RoomSendQueueError, HttpError, IdParseError,
6-
NotificationSettingsError as SdkNotificationSettingsError,
5+
room::edit::EditError, room_preview::WrongRoomPreviewState, send_queue::RoomSendQueueError,
6+
HttpError, IdParseError, NotificationSettingsError as SdkNotificationSettingsError,
77
QueueWedgeError as SdkQueueWedgeError, StoreError,
88
};
99
use matrix_sdk_ui::{encryption_sync_service, notification_client, sync_service, timeline};
1010
use uniffi::UnexpectedUniFFICallbackError;
11-
use matrix_sdk::room_preview::RoomPreviewError;
11+
1212
use crate::room_list::RoomListError;
1313

1414
#[derive(Debug, thiserror::Error)]
@@ -155,8 +155,8 @@ impl From<RoomSendQueueError> for ClientError {
155155
}
156156
}
157157

158-
impl From<RoomPreviewError> for ClientError {
159-
fn from(e: RoomSendQueueError) -> Self {
158+
impl From<WrongRoomPreviewState> for ClientError {
159+
fn from(e: WrongRoomPreviewState) -> Self {
160160
Self::new(e)
161161
}
162162
}

bindings/matrix-sdk-ffi/src/room.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use crate::{
4545
TaskHandle,
4646
};
4747

48-
#[derive(Debug, uniffi::Enum)]
48+
#[derive(Debug, Clone, uniffi::Enum)]
4949
pub enum Membership {
5050
Invited,
5151
Joined,

bindings/matrix-sdk-ffi/src/room_list.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ use matrix_sdk_ui::{
1616
timeline::default_event_filter,
1717
unable_to_decrypt_hook::UtdHookManager,
1818
};
19-
use ruma::{
20-
IdParseError, OwnedRoomOrAliasId, OwnedServerName, RoomAliasId, RoomOrAliasId, ServerName,
21-
};
19+
use ruma::{OwnedRoomOrAliasId, OwnedServerName, ServerName};
2220
use tokio::sync::RwLock;
2321

2422
use crate::{
@@ -595,10 +593,10 @@ impl RoomListItem {
595593
Ok(Arc::new(Room::new(self.inner.inner_room().clone())))
596594
}
597595

598-
/// Builds a `RoomPreview` from a room list item. This is intended for rooms
599-
/// with [`Membership::Invite`] or [`Membership::Knocked`],
596+
/// Builds a `RoomPreview` from a room list item. This is intended for
597+
/// invited or knocked rooms.
600598
///
601-
/// An error will be returned if the room is a state other than invited
599+
/// An error will be returned if the room is in a state other than invited
602600
/// or knocked.
603601
async fn preview_room(&self, via: Vec<String>) -> Result<Arc<RoomPreview>, ClientError> {
604602
let membership = self.membership();
@@ -624,7 +622,7 @@ impl RoomListItem {
624622
};
625623

626624
let room_preview = client.get_room_preview(&room_or_alias_id, server_names).await?;
627-
Ok(Arc::new(RoomPreview::try_from_sdk(room_preview, client)))
625+
Ok(Arc::new(RoomPreview::from_sdk(room_preview)))
628626
}
629627

630628
/// Build a full `Room` FFI object, filling its associated timeline.
Lines changed: 44 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,48 @@
1-
use matrix_sdk::{
2-
room_preview::{
3-
JoinRoomPreviewAction as SdkJoinRoomPreviewAction, LeaveRoomPreviewAction as SdkLeaveRoomPreviewAction, RoomPreview as SdkRoomPreview,
4-
RoomPreviewActions,
5-
},
6-
Client, RoomState,
7-
};
1+
use std::sync::Arc;
2+
3+
use matrix_sdk::room_preview::RoomPreview as SdkRoomPreview;
84
use ruma::space::SpaceRoomJoinRule;
95

106
use crate::{client::JoinRule, error::ClientError, room::Membership};
117

12-
#[derive(uniffi::Record)]
13-
pub struct RoomPreview {
14-
pub info: RoomPreviewInfo,
15-
pub room_preview_actions: RoomPreviewActions,
16-
pub(crate) sdk_info: matrix_sdk::room_preview::RoomPreview,
17-
}
18-
19-
#[derive(uniffi::Enum)]
20-
pub enum RoomPreviewAction {
21-
Invited { join: JoinRoomPreviewAction, leave: LeaveRoomPreviewAction },
22-
Knocked { leave: LeaveRoomPreviewAction },
23-
}
24-
8+
/// A room preview for a room. It's intended to be used to represent rooms that
9+
/// aren't joined yet.
2510
#[derive(uniffi::Object)]
26-
pub struct JoinRoomPreviewAction {
27-
inner: SdkJoinRoomPreviewAction,
11+
pub struct RoomPreview {
12+
inner: Arc<SdkRoomPreview>,
2813
}
2914

3015
#[matrix_sdk_ffi_macros::export]
31-
impl JoinRoomPreviewAction {
32-
async fn run(&self) {
33-
self.inner.run().unwrap()
16+
impl RoomPreview {
17+
/// Returns the room info the preview contains.
18+
pub fn info(&self) -> RoomPreviewInfo {
19+
let info = &self.inner;
20+
RoomPreviewInfo {
21+
room_id: info.room_id.to_string(),
22+
canonical_alias: info.canonical_alias.as_ref().map(|alias| alias.to_string()),
23+
name: info.name.clone(),
24+
topic: info.topic.clone(),
25+
avatar_url: info.avatar_url.as_ref().map(|url| url.to_string()),
26+
num_joined_members: info.num_joined_members,
27+
room_type: info.room_type.as_ref().map(|room_type| room_type.to_string()),
28+
is_history_world_readable: info.is_world_readable,
29+
membership: info.state.map(|state| state.into()),
30+
join_rule: info.join_rule.clone().into(),
31+
}
3432
}
35-
}
3633

37-
impl From<matrix_sdk::room_preview::RoomPreviewActions> for RoomPreviewAction {
38-
fn from(actions: RoomPreviewActions) -> Self {
39-
match actions {
40-
RoomPreviewActions::Invited { join, leave } => Self::Invited { join, leave },
41-
RoomPreviewActions::Knocked { leave } => Self::Knocked { leave },
42-
}
34+
/// Leave the room if the room preview state is either joined, invited or
35+
/// knocked.
36+
///
37+
/// Will return an error otherwise.
38+
pub async fn leave(&self) -> Result<(), ClientError> {
39+
self.inner.leave().await.map_err(Into::into)
4340
}
4441
}
4542

46-
struct
47-
4843
impl RoomPreview {
49-
pub(crate) fn try_from_sdk(info: SdkRoomPreview, client: Client) -> Result<Self, ClientError> {
50-
let info = RoomPreviewInfo {
51-
room_id: info.room_id.to_string(),
52-
canonical_alias: info.canonical_alias.map(|alias| alias.to_string()),
53-
name: info.name,
54-
topic: info.topic,
55-
avatar_url: info.avatar_url.map(|url| url.to_string()),
56-
num_joined_members: info.num_joined_members,
57-
room_type: info.room_type.map(|room_type| room_type.to_string()),
58-
is_history_world_readable: info.is_world_readable,
59-
membership: info.state.map(|state| state.into()).unwrap_or_else(|| Membership::Left),
60-
join_rule: info.join_rule.into(),
61-
};
62-
63-
let room_preview_actions = match info.membership {
64-
Membership::Invited => RoomPreviewActions::Invited {
65-
join: JoinRoomPreviewAction::new(client.clone()),
66-
leave: LeaveRoomPreviewAction::new(client.clone()),
67-
},
68-
Membership::Knocked => {
69-
RoomPreviewActions::Knocked { leave: LeaveRoomPreviewAction::new(client.clone()) }
70-
}
71-
_ => {
72-
return Err(ClientError::new(format!(
73-
"The room preview had membership {:?} instead of Invited or Knocked.",
74-
info.membership
75-
)))
76-
}
77-
};
78-
Ok(Self { info, room_preview_actions })
44+
pub(crate) fn from_sdk(room_preview: SdkRoomPreview) -> Self {
45+
Self { inner: Arc::new(room_preview) }
7946
}
8047
}
8148

@@ -98,23 +65,28 @@ pub struct RoomPreviewInfo {
9865
pub room_type: Option<String>,
9966
/// Is the history world-readable for this room?
10067
pub is_history_world_readable: bool,
101-
/// Is the room joined by the current user?
102-
pub membership: Membership,
103-
/// is the join rule public for this room?
68+
/// The membership state for the current user, if known.
69+
pub membership: Option<Membership>,
70+
/// The join rule for this room (private, public, knock, etc.).
10471
pub join_rule: JoinRule,
10572
}
10673

10774
impl From<SpaceRoomJoinRule> for JoinRule {
10875
fn from(join_rule: SpaceRoomJoinRule) -> Self {
10976
match join_rule {
110-
SpaceRoomJoinRule::Public => JoinRule::Public,
111-
SpaceRoomJoinRule::Private => JoinRule::Private,
11277
SpaceRoomJoinRule::Invite => JoinRule::Invite,
11378
SpaceRoomJoinRule::Knock => JoinRule::Knock,
114-
SpaceRoomJoinRule::KnockRestricted => JoinRule::KnockRestricted { rules: Vec::new() },
79+
SpaceRoomJoinRule::Private => JoinRule::Private,
11580
SpaceRoomJoinRule::Restricted => JoinRule::Restricted { rules: Vec::new() },
116-
// For the `_Custom` case, assume it's private
117-
_ => JoinRule::Private,
81+
SpaceRoomJoinRule::KnockRestricted => JoinRule::KnockRestricted { rules: Vec::new() },
82+
SpaceRoomJoinRule::Public => JoinRule::Public,
83+
_ => {
84+
// Since we have no way to get the _Custom contents, assume it's private.
85+
// Warning! If new join rules are introduced we may be mapping wrong values
86+
// here, but there's no way to match
87+
// `SpaceRoomJoinRule::_Custom(_)` and have an exhaustive match.
88+
JoinRule::Private
89+
}
11890
}
11991
}
12092
}

crates/matrix-sdk-base/src/rooms/normal.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,6 @@ impl RoomSummary {
186186
/// Enum keeping track in which state the room is, e.g. if our own user is
187187
/// joined, RoomState::Invited, or has left the room.
188188
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
189-
#[cfg(feature = "uniffi")]
190-
#[derive(uniffi::Enum)]
191189
pub enum RoomState {
192190
/// The room is in a joined state.
193191
Joined,

crates/matrix-sdk-base/src/sync.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::{collections::BTreeMap, fmt};
1919
use matrix_sdk_common::{debug::DebugRawEvent, deserialized_responses::SyncTimelineEvent};
2020
use ruma::{
2121
api::client::sync::sync_events::{
22-
v3::{InvitedRoom as InvitedRoomUpdate, KnockedRoom},
22+
v3::{InvitedRoom as InvitedRoomUpdate, KnockedRoom as KnockedRoomUpdate},
2323
UnreadNotificationsCount as RumaUnreadNotificationsCount,
2424
},
2525
events::{
@@ -78,7 +78,7 @@ pub struct RoomUpdates {
7878
/// The rooms that the user has been invited to.
7979
pub invite: BTreeMap<OwnedRoomId, InvitedRoomUpdate>,
8080
/// The rooms that the user has knocked on.
81-
pub knocked: BTreeMap<OwnedRoomId, KnockedRoom>,
81+
pub knocked: BTreeMap<OwnedRoomId, KnockedRoomUpdate>,
8282
}
8383

8484
impl RoomUpdates {
@@ -254,7 +254,7 @@ impl<'a> fmt::Debug for DebugInvitedRoomUpdates<'a> {
254254
}
255255
}
256256

257-
struct DebugKnockedRoomUpdates<'a>(&'a BTreeMap<OwnedRoomId, KnockedRoom>);
257+
struct DebugKnockedRoomUpdates<'a>(&'a BTreeMap<OwnedRoomId, KnockedRoomUpdate>);
258258

259259
#[cfg(not(tarpaulin_include))]
260260
impl<'a> fmt::Debug for DebugKnockedRoomUpdates<'a> {

crates/matrix-sdk/src/client/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use ruma::{
5454
},
5555
filter::{create_filter::v3::Request as FilterUploadRequest, FilterDefinition},
5656
knock::knock_room,
57-
membership::{join_room_by_id, join_room_by_id_or_alias},
57+
membership::{join_room_by_id, join_room_by_id_or_alias, leave_room},
5858
room::create_room,
5959
session::login::v3::DiscoveryInfo,
6060
sync::sync_events,
@@ -1208,6 +1208,13 @@ impl Client {
12081208
Ok(Room::new(self.clone(), base_room))
12091209
}
12101210

1211+
/// Leave a room given its `RoomId`.
1212+
pub async fn leave_room(&self, room_id: &RoomId) -> Result<()> {
1213+
let request = leave_room::v3::Request::new(room_id.to_owned());
1214+
self.send(request, None).await?;
1215+
self.base_client().room_left(room_id).await.map_err(Into::into)
1216+
}
1217+
12111218
/// Search the homeserver's directory of public rooms.
12121219
///
12131220
/// Sends a request to "_matrix/client/r0/publicRooms", returns

crates/matrix-sdk/src/error.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ use serde_json::Error as JsonError;
4545
use thiserror::Error;
4646
use url::ParseError as UrlParseError;
4747

48-
use crate::{event_cache::EventCacheError, store_locks::LockStoreError};
48+
use crate::{
49+
event_cache::EventCacheError, room_preview::WrongRoomPreviewState, store_locks::LockStoreError,
50+
};
4951

5052
/// Result type of the matrix-sdk.
5153
pub type Result<T, E = Error> = std::result::Result<T, E>;
@@ -348,6 +350,12 @@ pub enum Error {
348350
#[error("wrong room state: {0}")]
349351
WrongRoomState(WrongRoomState),
350352

353+
/// Attempted to call a method on a room preview that requires the user to
354+
/// have a specific membership state in the room, but the membership
355+
/// state is different or none.
356+
#[error("wrong room state: {0}")]
357+
WrongRoomPreviewState(WrongRoomPreviewState),
358+
351359
/// Session callbacks have been set multiple times.
352360
#[error("session callbacks have been set multiple times")]
353361
MultipleSessionCallbacks,

crates/matrix-sdk/src/room/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use ruma::{
4747
membership::{
4848
ban_user, forget_room, get_member_events,
4949
invite_user::{self, v3::InvitationRecipient},
50-
join_room_by_id, kick_user, leave_room, unban_user, Invite3pid,
50+
kick_user, leave_room, unban_user, Invite3pid,
5151
},
5252
message::send_message_event,
5353
read_marker::set_read_marker,

0 commit comments

Comments
 (0)