implement local room preview
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
e257512aa7
commit
2f2cebe84d
|
@ -0,0 +1,72 @@
|
||||||
|
use axum::extract::State;
|
||||||
|
use conduit::{at, utils::BoolExt, Err, Result};
|
||||||
|
use futures::StreamExt;
|
||||||
|
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 limit = LIMIT_MAX;
|
||||||
|
let events: Vec<_> = services
|
||||||
|
.rooms
|
||||||
|
.timeline
|
||||||
|
.pdus_rev(None, room_id, None)
|
||||||
|
.await?
|
||||||
|
.take(limit)
|
||||||
|
.collect()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let state: Vec<_> = services
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.room_state_full_pdus(room_id)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(|pdu| pdu.to_state_event())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
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(|pdu| pdu.to_room_event())
|
||||||
|
.collect(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Response {
|
||||||
|
room_id: room_id.to_owned(),
|
||||||
|
account_data: None,
|
||||||
|
state: state.into(),
|
||||||
|
messages: messages.chunk.is_empty().or_some(messages),
|
||||||
|
visibility: services.rooms.directory.visibility(room_id).await.into(),
|
||||||
|
membership: services
|
||||||
|
.rooms
|
||||||
|
.state_cache
|
||||||
|
.user_membership(body.sender_user(), room_id)
|
||||||
|
.await,
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
mod aliases;
|
mod aliases;
|
||||||
mod create;
|
mod create;
|
||||||
mod event;
|
mod event;
|
||||||
|
mod initial_sync;
|
||||||
mod upgrade;
|
mod upgrade;
|
||||||
|
|
||||||
pub(crate) use self::{
|
pub(crate) use self::{
|
||||||
aliases::get_room_aliases_route, create::create_room_route, event::get_room_event_route,
|
aliases::get_room_aliases_route, create::create_room_route, event::get_room_event_route,
|
||||||
upgrade::upgrade_room_route,
|
initial_sync::room_initial_sync_route, upgrade::upgrade_room_route,
|
||||||
};
|
};
|
||||||
|
|
|
@ -183,8 +183,7 @@ pub fn build(router: Router<State>, server: &Server) -> Router<State> {
|
||||||
.ruma_route(&client::well_known_support)
|
.ruma_route(&client::well_known_support)
|
||||||
.ruma_route(&client::well_known_client)
|
.ruma_route(&client::well_known_client)
|
||||||
.route("/_conduwuit/server_version", get(client::conduwuit_server_version))
|
.route("/_conduwuit/server_version", get(client::conduwuit_server_version))
|
||||||
.route("/_matrix/client/r0/rooms/:room_id/initialSync", get(initial_sync))
|
.ruma_route(&client::room_initial_sync_route)
|
||||||
.route("/_matrix/client/v3/rooms/:room_id/initialSync", get(initial_sync))
|
|
||||||
.route("/client/server.json", get(client::syncv3_client_server_json));
|
.route("/client/server.json", get(client::syncv3_client_server_json));
|
||||||
|
|
||||||
if config.allow_federation {
|
if config.allow_federation {
|
||||||
|
@ -285,10 +284,6 @@ async fn redirect_legacy_preview(uri: Uri) -> impl IntoResponse {
|
||||||
Redirect::temporary(&uri)
|
Redirect::temporary(&uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn initial_sync(_uri: Uri) -> impl IntoResponse {
|
|
||||||
err!(Request(GuestAccessForbidden("Guest access not implemented")))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn legacy_media_disabled() -> impl IntoResponse { err!(Request(Forbidden("Unauthenticated media is disabled."))) }
|
async fn legacy_media_disabled() -> impl IntoResponse { err!(Request(Forbidden("Unauthenticated media is disabled."))) }
|
||||||
|
|
||||||
async fn federation_disabled() -> impl IntoResponse { err!(Request(Forbidden("Federation is disabled."))) }
|
async fn federation_disabled() -> impl IntoResponse { err!(Request(Forbidden("Federation is disabled."))) }
|
||||||
|
|
Loading…
Reference in New Issue