Skip to content

Commit aee686e

Browse files
committed
feat(sdk): add support for threads subscription CRUD (msc4306)
This doesn't store the subscriptions locally, nor does it implement the automatic thread subscription.
1 parent bb1c284 commit aee686e

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "184d4f85b201bc1e932a8344d7
7676
"unstable-msc4171",
7777
"unstable-msc4278",
7878
"unstable-msc4286",
79+
"unstable-msc4306"
7980
] }
8081
ruma-common = { git = "https://github.com/ruma/ruma", rev = "184d4f85b201bc1e932a8344d78575e826f31efa" }
8182
sentry = "0.36.0"

crates/matrix-sdk/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ All notable changes to this project will be documented in this file.
88

99
### Features
1010

11+
- Add experimental support for
12+
[MSC4306](https://github.com/matrix-org/matrix-spec-proposals/pull/4306), with the
13+
`Room::fetch_thread_subscription()`, `Room::subscribe_thread()` and `Room::unsubscribe_thread()`
14+
methods.
15+
([#5442](https://github.com/matrix-org/matrix-rust-sdk/pull/5442))
1116
- [**breaking**] `RoomMemberRole` has a new `Creator` variant, that
1217
differentiates room creators with infinite power levels, as introduced in room
1318
version 12.

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

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ use ruma::{
7878
room::{get_room_event, report_content, report_room},
7979
state::{get_state_event_for_key, send_state_event},
8080
tag::{create_tag, delete_tag},
81+
threads::{get_thread_subscription, subscribe_thread, unsubscribe_thread},
8182
typing::create_typing_event::{self, v3::Typing},
8283
},
8384
assign,
@@ -3645,6 +3646,101 @@ impl Room {
36453646
) -> Result<Relations> {
36463647
opts.send(self, event_id).await
36473648
}
3649+
3650+
/// Subscribe to a given thread in this room.
3651+
///
3652+
/// This will subscribe the user to the thread, so that they will receive
3653+
/// notifications for that thread specifically.
3654+
///
3655+
/// # Arguments
3656+
///
3657+
/// - `thread_root`: The ID of the thread root event to subscribe to.
3658+
/// - `automatic`: Whether the subscription was made automatically by a
3659+
/// client, not by manual user choice. If there was a previous automatic
3660+
/// subscription, and that's set to `true` (i.e. we're now subscribing
3661+
/// manually), the subscription will be overridden to a manual one
3662+
/// instead.
3663+
///
3664+
/// # Returns
3665+
///
3666+
/// - A 404 error if the event isn't known, or isn't a thread root.
3667+
/// - An `Ok` result if the subscription was successful.
3668+
pub async fn subscribe_thread(&self, thread_root: OwnedEventId, automatic: bool) -> Result<()> {
3669+
self.client
3670+
.send(subscribe_thread::unstable::Request::new(
3671+
self.room_id().to_owned(),
3672+
thread_root,
3673+
automatic,
3674+
))
3675+
.await?;
3676+
Ok(())
3677+
}
3678+
3679+
/// Unsubscribe from a given thread in this room.
3680+
///
3681+
/// # Arguments
3682+
///
3683+
/// - `thread_root`: The ID of the thread root event to unsubscribe to.
3684+
///
3685+
/// # Returns
3686+
///
3687+
/// - An `Ok` result if the unsubscription was successful, or the thread was
3688+
/// already unsubscribed.
3689+
/// - A 404 error if the event isn't known, or isn't a thread root.
3690+
pub async fn unsubscribe_thread(&self, thread_root: OwnedEventId) -> Result<()> {
3691+
self.client
3692+
.send(unsubscribe_thread::unstable::Request::new(
3693+
self.room_id().to_owned(),
3694+
thread_root,
3695+
))
3696+
.await?;
3697+
Ok(())
3698+
}
3699+
3700+
/// Return the current thread subscription for the given thread root in this
3701+
/// room.
3702+
///
3703+
/// # Arguments
3704+
///
3705+
/// - `thread_root`: The ID of the thread root event to get the subscription
3706+
/// for.
3707+
///
3708+
/// # Returns
3709+
///
3710+
/// - An `Ok` result with `Some(ThreadSubscription)` if the subscription
3711+
/// exists.
3712+
/// - An `Ok` result with `None` if the subscription does not exist, or the
3713+
/// event couldn't be found, or the event isn't a thread.
3714+
/// - An error if the request fails for any other reason, such as a network
3715+
/// error.
3716+
pub async fn fetch_thread_subscription(
3717+
&self,
3718+
thread_root: OwnedEventId,
3719+
) -> Result<Option<ThreadSubscription>> {
3720+
let result = self
3721+
.client
3722+
.send(get_thread_subscription::unstable::Request::new(
3723+
self.room_id().to_owned(),
3724+
thread_root,
3725+
))
3726+
.await;
3727+
3728+
match result {
3729+
Ok(response) => Ok(Some(ThreadSubscription { automatic: response.automatic })),
3730+
Err(http_error) => match http_error.as_client_api_error() {
3731+
Some(error) if error.status_code == StatusCode::NOT_FOUND => Ok(None),
3732+
_ => Err(http_error.into()),
3733+
},
3734+
}
3735+
}
3736+
}
3737+
3738+
/// Status of a thread subscription.
3739+
#[derive(Debug, Clone, Copy)]
3740+
pub struct ThreadSubscription {
3741+
/// Whether the subscription was made automatically by a client, not by
3742+
/// manual user choice.
3743+
pub automatic: bool,
36483744
}
36493745

36503746
#[cfg(feature = "e2e-encryption")]

0 commit comments

Comments
 (0)