-
Notifications
You must be signed in to change notification settings - Fork 254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(room): add RequestToJoinRoom
subscriptions
#4338
base: main
Are you sure you want to change the base?
Changes from all commits
3428799
7d13224
40c3aff
39fed6b
af7b68d
e3cd7cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
use std::{collections::HashMap, pin::pin, sync::Arc}; | ||
|
||
use anyhow::{Context, Result}; | ||
use futures_util::StreamExt; | ||
use futures_util::{pin_mut, StreamExt}; | ||
use matrix_sdk::{ | ||
crypto::LocalTrust, | ||
event_cache::paginator::PaginatorError, | ||
|
@@ -840,6 +840,108 @@ impl Room { | |
|
||
Ok(()) | ||
} | ||
|
||
/// Subscribes to requests to join this room, using a `listener` to be | ||
/// notified of the changes. | ||
/// | ||
/// The current requests to join the room will be emitted immediately | ||
/// when subscribing, along with a [`TaskHandle`] to cancel the | ||
/// subscription. | ||
pub async fn subscribe_to_requests_to_join( | ||
self: Arc<Self>, | ||
listener: Box<dyn RequestsToJoinListener>, | ||
) -> Result<Arc<TaskHandle>, ClientError> { | ||
let stream = self.inner.subscribe_to_requests_to_join().await?; | ||
|
||
let handle = Arc::new(TaskHandle::new(RUNTIME.spawn(async move { | ||
pin_mut!(stream); | ||
while let Some(requests) = stream.next().await { | ||
listener.call(requests.into_iter().map(Into::into).collect()); | ||
} | ||
}))); | ||
|
||
Ok(handle) | ||
} | ||
} | ||
|
||
impl From<matrix_sdk::room::request_to_join::RequestToJoinRoom> for RequestToJoin { | ||
fn from(request: matrix_sdk::room::request_to_join::RequestToJoinRoom) -> Self { | ||
Self { | ||
event_id: request.event_id.to_string(), | ||
user_id: request.member_info.user_id.to_string(), | ||
room_id: request.room_id().to_string(), | ||
display_name: request.member_info.display_name.clone(), | ||
avatar_url: request.member_info.avatar_url.as_ref().map(|url| url.to_string()), | ||
reason: request.member_info.reason.clone(), | ||
timestamp: request.timestamp.map(|ts| ts.into()), | ||
is_seen: request.is_seen, | ||
actions: Arc::new(RequestToJoinActions { inner: request }), | ||
} | ||
} | ||
} | ||
|
||
/// A listener for receiving new requests to a join a room. | ||
#[matrix_sdk_ffi_macros::export(callback_interface)] | ||
pub trait RequestsToJoinListener: Send + Sync { | ||
fn call(&self, requests_to_join: Vec<RequestToJoin>); | ||
} | ||
|
||
/// An FFI representation of a request to join a room. | ||
#[derive(Debug, Clone, uniffi::Record)] | ||
pub struct RequestToJoin { | ||
/// The event id of the event that contains the `knock` membership change. | ||
pub event_id: String, | ||
/// The user id of the user who's requesting to join the room. | ||
pub user_id: String, | ||
/// The room id of the room whose access was requested. | ||
pub room_id: String, | ||
/// The optional display name of the user who's requesting to join the room. | ||
pub display_name: Option<String>, | ||
/// The optional avatar url of the user who's requesting to join the room. | ||
pub avatar_url: Option<String>, | ||
/// An optional reason why the user wants join the room. | ||
pub reason: Option<String>, | ||
/// The timestamp when this request was created. | ||
pub timestamp: Option<u64>, | ||
/// Whether the request to join has been marked as `seen` so it can be | ||
/// filtered by the client. | ||
pub is_seen: bool, | ||
/// A set of actions to perform for this request to join. | ||
pub actions: Arc<RequestToJoinActions>, | ||
} | ||
|
||
/// A set of actions to perform for a request to join. | ||
#[derive(Debug, Clone, uniffi::Object)] | ||
pub struct RequestToJoinActions { | ||
inner: matrix_sdk::room::request_to_join::RequestToJoinRoom, | ||
} | ||
|
||
#[matrix_sdk_ffi_macros::export] | ||
impl RequestToJoinActions { | ||
/// Accepts the request to join by inviting the user to the room. | ||
pub async fn accept(&self) -> Result<(), ClientError> { | ||
self.inner.accept().await.map_err(Into::into) | ||
} | ||
|
||
/// Declines the request to join by kicking the user from the room with an | ||
/// optional reason. | ||
pub async fn decline(&self, reason: Option<String>) -> Result<(), ClientError> { | ||
self.inner.decline(reason.as_deref()).await.map_err(Into::into) | ||
} | ||
|
||
/// Declines the request to join by banning the user from the room with an | ||
/// optional reason. | ||
pub async fn decline_and_ban(&self, reason: Option<String>) -> Result<(), ClientError> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we want a separate ban action, and let the user chain? in the case the user doesn't have the right for both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean kick, then ban? Can we ban a user who already left the room? Also, I'd expect the UI to not display the component that triggers this action rather than controlling trying to workaround the issue here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry I'm stupid. :D
This comment was marked as resolved.
Sorry, something went wrong. |
||
self.inner.decline_and_ban(reason.as_deref()).await.map_err(Into::into) | ||
} | ||
|
||
/// Marks the request as 'seen'. | ||
/// | ||
/// **IMPORTANT**: this won't update the current reference to this request, | ||
/// a new one with the updated value should be emitted instead. | ||
pub async fn mark_as_seen(&self) -> Result<(), ClientError> { | ||
self.inner.clone().mark_as_seen().await.map_err(Into::into) | ||
} | ||
} | ||
|
||
/// Generates a `matrix.to` permalink to the given room alias. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing
mark_as_seen
?