Skip to content

Commit 92c582a

Browse files
committed
feat(room): add a new function that will only subscribe to a thread if needed
1 parent 8848aa3 commit 92c582a

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,6 +3740,23 @@ impl Room {
37403740
}
37413741
}
37423742

3743+
/// Subscribe to a thread if needed, based on a current subscription to it.
3744+
///
3745+
/// This is like [`Self::subscribe_thread`], but it first checks if the user
3746+
/// has already subscribed to a thread, so as to minimize sending
3747+
/// unnecessary subscriptions which would be ignored by the server.
3748+
pub async fn subscribe_thread_if_needed(
3749+
&self,
3750+
thread_root: &EventId,
3751+
automatic: Option<OwnedEventId>,
3752+
) -> Result<()> {
3753+
if self.load_or_fetch_thread_subscription(thread_root).await?.is_some() {
3754+
// We already have a subscription, so there's no need to send a new one.
3755+
return Ok(());
3756+
}
3757+
self.subscribe_thread(thread_root.to_owned(), automatic).await
3758+
}
3759+
37433760
/// Unsubscribe from a given thread in this room.
37443761
///
37453762
/// # Arguments
@@ -3821,6 +3838,20 @@ impl Room {
38213838

38223839
Ok(subscription)
38233840
}
3841+
3842+
/// Return the current thread subscription for the given thread root in this
3843+
/// room, by getting it from storage if possible, or fetching it from
3844+
/// network otherwise.
3845+
///
3846+
/// See also [`Self::fetch_thread_subscription`] for the exact semantics of
3847+
/// this method.
3848+
pub async fn load_or_fetch_thread_subscription(
3849+
&self,
3850+
thread_root: &EventId,
3851+
) -> Result<Option<ThreadSubscription>> {
3852+
// A bit of a lie at the moment, since thread subscriptions are not sync'd yet.
3853+
self.fetch_thread_subscription(thread_root.to_owned()).await
3854+
}
38243855
}
38253856

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

crates/matrix-sdk/tests/integration/room/thread.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,72 @@ async fn test_subscribe_thread() {
7979
assert_matches!(subscription, None);
8080
}
8181

82+
#[async_test]
83+
async fn test_subscribe_thread_if_needed() {
84+
let server = MatrixMockServer::new().await;
85+
let client = server.client_builder().build().await;
86+
87+
let room_id = room_id!("!test:example.org");
88+
let room = server.sync_joined_room(&client, room_id).await;
89+
90+
// The function `subscribe_thread_if_needed` will automatically subscribe to the
91+
// thread, if there's no prior manual subscription, whether the new
92+
// subscription is automatic or not.
93+
for (root_id, automatic) in [
94+
(owned_event_id!("$root"), None),
95+
(owned_event_id!("$woot"), Some(owned_event_id!("$woot"))),
96+
] {
97+
server
98+
.mock_put_thread_subscription()
99+
.match_room_id(room_id.to_owned())
100+
.match_thread_id(root_id.clone())
101+
.ok()
102+
.mock_once()
103+
.mount()
104+
.await;
105+
106+
room.subscribe_thread_if_needed(&root_id, automatic).await.unwrap();
107+
}
108+
109+
// The function `subscribe_thread_if_needed` is a no-op, if there's a previous
110+
// automatic subscription, whether the new subscription is automatic or not.
111+
for (root_id, automatic) in [
112+
(owned_event_id!("$foot"), None),
113+
(owned_event_id!("$toot"), Some(owned_event_id!("$toot"))),
114+
] {
115+
server
116+
.mock_get_thread_subscription()
117+
.match_room_id(room_id.to_owned())
118+
.match_thread_id(root_id.clone())
119+
.ok(true)
120+
.mock_once()
121+
.mount()
122+
.await;
123+
124+
room.subscribe_thread_if_needed(&root_id, automatic).await.unwrap();
125+
}
126+
127+
// The function `subscribe_thread_if_needed` is a no-op if there's a prior
128+
// manual subscription, whether the new subscription is automatic or not.
129+
for (root_id, automatic) in [
130+
(owned_event_id!("$root"), None),
131+
(owned_event_id!("$woot"), Some(owned_event_id!("$woot"))),
132+
] {
133+
server
134+
.mock_get_thread_subscription()
135+
.match_room_id(room_id.to_owned())
136+
.match_thread_id(root_id.clone())
137+
.ok(false)
138+
.mock_once()
139+
.mount()
140+
.await;
141+
142+
// No-op! (The PUT endpoint hasn't been mocked, so this would result in a 404 if
143+
// it were trying to hit it.)
144+
room.subscribe_thread_if_needed(&root_id, automatic).await.unwrap();
145+
}
146+
}
147+
82148
#[async_test]
83149
async fn test_thread_push_rule_is_triggered_for_subscribed_threads() {
84150
// This test checks that the evaluation of push rules for threads will correctly

0 commit comments

Comments
 (0)