2024-07-16 08:05:25 +00:00
|
|
|
use axum::extract::State;
|
2025-04-04 03:30:13 +00:00
|
|
|
use conduwuit::{
|
2025-06-04 00:11:09 +01:00
|
|
|
Result, at, debug_warn,
|
2025-04-26 08:24:47 +00:00
|
|
|
matrix::{
|
|
|
|
|
Event,
|
|
|
|
|
pdu::{PduCount, PduEvent},
|
|
|
|
|
},
|
2025-04-04 03:30:13 +00:00
|
|
|
};
|
2024-08-08 17:18:30 +00:00
|
|
|
use futures::StreamExt;
|
2026-04-12 10:48:31 -04:00
|
|
|
use ruma::{api::client::threads::get_threads, assign, uint};
|
2023-06-25 19:31:40 +02:00
|
|
|
|
2025-09-07 18:06:11 -04:00
|
|
|
use crate::Ruma;
|
2023-06-25 19:31:40 +02:00
|
|
|
|
|
|
|
|
/// # `GET /_matrix/client/r0/rooms/{roomId}/threads`
|
2024-07-16 08:05:25 +00:00
|
|
|
pub(crate) async fn get_threads_route(
|
2024-12-15 00:05:47 -05:00
|
|
|
State(services): State<crate::State>,
|
|
|
|
|
ref body: Ruma<get_threads::v1::Request>,
|
2024-07-16 08:05:25 +00:00
|
|
|
) -> Result<get_threads::v1::Response> {
|
2023-06-25 19:31:40 +02:00
|
|
|
// Use limit or else 10, with maximum 100
|
2024-03-25 17:05:11 -04:00
|
|
|
let limit = body
|
|
|
|
|
.limit
|
2024-05-04 09:45:37 -04:00
|
|
|
.unwrap_or_else(|| uint!(10))
|
|
|
|
|
.try_into()
|
2024-03-25 17:05:11 -04:00
|
|
|
.unwrap_or(10)
|
|
|
|
|
.min(100);
|
2023-06-25 19:31:40 +02:00
|
|
|
|
2024-11-02 06:12:54 +00:00
|
|
|
let from: PduCount = body
|
|
|
|
|
.from
|
|
|
|
|
.as_deref()
|
2025-09-07 18:06:11 -04:00
|
|
|
.map(str::parse)
|
2024-11-02 06:12:54 +00:00
|
|
|
.transpose()?
|
|
|
|
|
.unwrap_or_else(PduCount::max);
|
2023-06-25 19:31:40 +02:00
|
|
|
|
2024-11-02 06:12:54 +00:00
|
|
|
let threads: Vec<(PduCount, PduEvent)> = services
|
2023-06-25 19:31:40 +02:00
|
|
|
.rooms
|
|
|
|
|
.threads
|
2026-05-26 13:28:23 -04:00
|
|
|
.threads_until(body.identity.sender_user(), &body.room_id, from, &body.include)
|
2024-08-08 17:18:30 +00:00
|
|
|
.await?
|
2023-06-25 19:31:40 +02:00
|
|
|
.take(limit)
|
2024-08-08 17:18:30 +00:00
|
|
|
.filter_map(|(count, pdu)| async move {
|
2024-07-16 08:05:25 +00:00
|
|
|
services
|
2023-06-25 19:31:40 +02:00
|
|
|
.rooms
|
|
|
|
|
.state_accessor
|
2026-05-26 13:28:23 -04:00
|
|
|
.user_can_see_event(body.identity.sender_user(), &body.room_id, &pdu.event_id)
|
2024-08-08 17:18:30 +00:00
|
|
|
.await
|
|
|
|
|
.then_some((count, pdu))
|
2023-06-25 19:31:40 +02:00
|
|
|
})
|
2025-06-04 00:11:09 +01:00
|
|
|
.then(|(count, mut pdu)| async move {
|
|
|
|
|
if let Err(e) = services
|
|
|
|
|
.rooms
|
|
|
|
|
.pdu_metadata
|
2026-05-26 13:28:23 -04:00
|
|
|
.add_bundled_aggregations_to_pdu(body.identity.sender_user(), &mut pdu)
|
2025-06-04 00:11:09 +01:00
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
debug_warn!("Failed to add bundled aggregations to thread: {e}");
|
|
|
|
|
}
|
|
|
|
|
(count, pdu)
|
|
|
|
|
})
|
2024-08-08 17:18:30 +00:00
|
|
|
.collect()
|
|
|
|
|
.await;
|
2023-06-25 19:31:40 +02:00
|
|
|
|
2026-04-12 10:48:31 -04:00
|
|
|
let next_batch = threads
|
|
|
|
|
.last()
|
|
|
|
|
.filter(|_| threads.len() >= limit)
|
|
|
|
|
.map(at!(0))
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(ToString::to_string);
|
2024-11-02 06:12:54 +00:00
|
|
|
|
2026-04-12 10:48:31 -04:00
|
|
|
let chunk = threads
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(at!(1))
|
|
|
|
|
.map(Event::into_format)
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
Ok(assign!(get_threads::v1::Response::new(chunk), { next_batch }))
|
2023-06-25 19:31:40 +02:00
|
|
|
}
|