mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
b61010da47
Add support for the m.replace and m.reference bundled aggregations. This should fix plenty of subtle client issues. Threads are not included in the new code as they have historically been written to the database. Replacing the old system would result in issues when switching away from continuwuity, so saved for later. Some TODOs have been left re event visibility and ignored users. These should be OK for now, though.
98 lines
2.1 KiB
Rust
98 lines
2.1 KiB
Rust
use axum::extract::State;
|
|
use conduwuit::{
|
|
Err, Event, Result, at, debug_warn,
|
|
utils::{BoolExt, stream::TryTools},
|
|
};
|
|
use futures::{FutureExt, TryStreamExt, future::try_join4};
|
|
use ruma::api::client::room::initial_sync::v3::{PaginationChunk, Request, Response};
|
|
|
|
use crate::Ruma;
|
|
|
|
const LIMIT_MAX: usize = 100;
|
|
|
|
pub(crate) async fn room_initial_sync_route(
|
|
State(services): State<crate::State>,
|
|
body: Ruma<Request>,
|
|
) -> Result<Response> {
|
|
let room_id = &body.room_id;
|
|
|
|
if !services
|
|
.rooms
|
|
.state_accessor
|
|
.user_can_see_state_events(body.sender_user(), room_id)
|
|
.await
|
|
{
|
|
return Err!(Request(Forbidden("No room preview available.")));
|
|
}
|
|
|
|
let membership = services
|
|
.rooms
|
|
.state_cache
|
|
.user_membership(body.sender_user(), room_id)
|
|
.map(Ok);
|
|
|
|
let visibility = services.rooms.directory.visibility(room_id).map(Ok);
|
|
|
|
let state = services
|
|
.rooms
|
|
.state_accessor
|
|
.room_state_full_pdus(room_id)
|
|
.map_ok(Event::into_format)
|
|
.try_collect::<Vec<_>>();
|
|
|
|
// Events are returned in body
|
|
|
|
let limit = LIMIT_MAX;
|
|
let events = services
|
|
.rooms
|
|
.timeline
|
|
.pdus_rev(room_id, None)
|
|
.try_take(limit)
|
|
.and_then(async |mut pdu| {
|
|
pdu.1.set_unsigned(body.sender_user.as_deref());
|
|
if let Some(sender_user) = body.sender_user.as_deref() {
|
|
if let Err(e) = services
|
|
.rooms
|
|
.pdu_metadata
|
|
.add_bundled_aggregations_to_pdu(sender_user, &mut pdu.1)
|
|
.await
|
|
{
|
|
debug_warn!("Failed to add bundled aggregations: {e}");
|
|
}
|
|
}
|
|
Ok(pdu)
|
|
})
|
|
.try_collect::<Vec<_>>();
|
|
|
|
let (membership, visibility, state, events) =
|
|
try_join4(membership, visibility, state, events)
|
|
.boxed()
|
|
.await?;
|
|
|
|
let messages = PaginationChunk {
|
|
start: events.last().map(at!(0)).as_ref().map(ToString::to_string),
|
|
|
|
end: events
|
|
.first()
|
|
.map(at!(0))
|
|
.as_ref()
|
|
.map(ToString::to_string)
|
|
.unwrap_or_default(),
|
|
|
|
chunk: events
|
|
.into_iter()
|
|
.map(at!(1))
|
|
.map(Event::into_format)
|
|
.collect(),
|
|
};
|
|
|
|
Ok(Response {
|
|
room_id: room_id.to_owned(),
|
|
account_data: None,
|
|
state: state.into(),
|
|
messages: messages.chunk.is_empty().or_some(messages),
|
|
visibility: visibility.into(),
|
|
membership,
|
|
})
|
|
}
|