Skip to content

Commit fa1aa57

Browse files
bnjbvrpoljar
authored andcommitted
feat(sdk): add a room method to retrieve a list of threads
1 parent c3ed8b9 commit fa1aa57

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

crates/matrix-sdk/CHANGELOG.md

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

99
### Features
1010

11+
- `Room::list_threads()` is a new method to list all the threads in a room.
12+
1113
### Bug fixes
1214

1315
### Refactor

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

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ use std::fmt;
1717
use matrix_sdk_common::{debug::DebugStructExt as _, deserialized_responses::TimelineEvent};
1818
use ruma::{
1919
api::{
20-
client::{filter::RoomEventFilter, message::get_message_events},
20+
client::{
21+
filter::RoomEventFilter,
22+
message::get_message_events,
23+
threads::get_threads::{self, v1::IncludeThreads},
24+
},
2125
Direction,
2226
},
2327
assign,
@@ -174,3 +178,49 @@ pub struct EventWithContextResponse {
174178
/// membership events.
175179
pub state: Vec<Raw<AnyStateEvent>>,
176180
}
181+
182+
/// Options for [super::Room::list_threads].
183+
#[derive(Debug, Default)]
184+
pub struct ListThreadsOptions {
185+
/// An extra filter to select which threads should be returned.
186+
pub include_threads: IncludeThreads,
187+
188+
/// The token to start returning events from.
189+
///
190+
/// This token can be obtained from a [`ThreadRoots::prev_batch_token`]
191+
/// returned by a previous call to [`super::Room::list_threads()`].
192+
///
193+
/// If `from` isn't provided the homeserver shall return a list of thread
194+
/// roots from end of the timeline history.
195+
pub from: Option<String>,
196+
197+
/// The maximum number of events to return.
198+
///
199+
/// Default: 10.
200+
pub limit: Option<UInt>,
201+
}
202+
203+
impl ListThreadsOptions {
204+
/// Converts the thread options into a Ruma request.
205+
pub(super) fn into_request(self, room_id: &RoomId) -> get_threads::v1::Request {
206+
assign!(get_threads::v1::Request::new(room_id.to_owned()), {
207+
from: self.from,
208+
include: self.include_threads,
209+
limit: self.limit,
210+
})
211+
}
212+
}
213+
214+
/// The result of a [`super::Room::list_threads`] query.
215+
///
216+
/// This is a wrapper around the Ruma equivalent, with events decrypted if needs
217+
/// be.
218+
#[derive(Debug)]
219+
pub struct ThreadRoots {
220+
/// The events that are thread roots in the current batch.
221+
pub chunk: Vec<TimelineEvent>,
222+
223+
/// Token to paginate backwards in a subsequent query to
224+
/// [`super::Room::list_threads`].
225+
pub prev_batch_token: Option<String>,
226+
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use matrix_sdk_common::{
5454
executor::{spawn, JoinHandle},
5555
timeout::timeout,
5656
};
57+
use messages::{ListThreadsOptions, ThreadRoots};
5758
use mime::Mime;
5859
use reply::Reply;
5960
#[cfg(feature = "e2e-encryption")]
@@ -3544,6 +3545,27 @@ impl Room {
35443545
pub fn privacy_settings(&self) -> RoomPrivacySettings<'_> {
35453546
RoomPrivacySettings::new(&self.inner, &self.client)
35463547
}
3548+
3549+
/// Retrieve a list of all the threads for the current room.
3550+
///
3551+
/// Since this client-server API is paginated, the return type may include a
3552+
/// token used to resuming back-pagination into the list of results, in
3553+
/// [`ThreadRoots::prev_batch_token`]. This token can be fed back into
3554+
/// [`ListThreadsOptions::from`] to continue the pagination
3555+
/// from the previous position.
3556+
pub async fn list_threads(&self, opts: ListThreadsOptions) -> Result<ThreadRoots> {
3557+
let request = opts.into_request(self.room_id());
3558+
3559+
let response = self.client.send(request).await?;
3560+
3561+
let push_ctx = self.push_context().await?;
3562+
let chunk = join_all(
3563+
response.chunk.into_iter().map(|ev| self.try_decrypt_event(ev, push_ctx.as_ref())),
3564+
)
3565+
.await;
3566+
3567+
Ok(ThreadRoots { chunk, prev_batch_token: response.next_batch })
3568+
}
35473569
}
35483570

35493571
#[cfg(all(feature = "e2e-encryption", not(target_arch = "wasm32")))]
@@ -3872,6 +3894,7 @@ mod tests {
38723894
use super::ReportedContentScore;
38733895
use crate::{
38743896
config::RequestConfig,
3897+
room::messages::ListThreadsOptions,
38753898
test_utils::{client::mock_matrix_session, logged_in_client, mocks::MatrixMockServer},
38763899
Client,
38773900
};

0 commit comments

Comments
 (0)