60 lines
1.6 KiB
Rust
60 lines
1.6 KiB
Rust
use axum::Json;
|
|
use axum::extract::{Path, Query, State};
|
|
use axum::response::IntoResponse;
|
|
use serde::Deserialize;
|
|
use tracing::error;
|
|
use validator::Validate;
|
|
|
|
use crate::state::AppState;
|
|
use crate::web::context::UserContext;
|
|
use crate::web::entity::message::Message;
|
|
use crate::{entity, web};
|
|
|
|
#[derive(Debug, Deserialize, Validate)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct PageParams {
|
|
#[serde(default = "limit_default")]
|
|
#[validate(range(min = 1, max = 100))]
|
|
pub limit: u32,
|
|
#[serde(default)]
|
|
pub before: Option<entity::message::Id>,
|
|
}
|
|
|
|
fn limit_default() -> u32 {
|
|
50
|
|
}
|
|
|
|
pub async fn page(
|
|
State(state): State<AppState>,
|
|
context: UserContext,
|
|
Path(channel_id): Path<entity::channel::Id>,
|
|
Query(params): Query<PageParams>,
|
|
) -> web::Result<impl IntoResponse> {
|
|
// TODO: check permissions
|
|
match params.validate() {
|
|
Ok(_) => {},
|
|
Err(e) => return Err(web::error::ClientError::ValidationFailed(e).into()),
|
|
};
|
|
|
|
let messages_futures = state
|
|
.database
|
|
.select_channel_messages_paginated(channel_id, params.before, params.limit as i64)
|
|
.await?
|
|
.into_iter()
|
|
.map(|message| async {
|
|
let attachments = state
|
|
.database
|
|
.select_message_attachments(message.id)
|
|
.await?
|
|
.into_iter()
|
|
.map(web::entity::file::File::from)
|
|
.collect::<Vec<_>>();
|
|
|
|
Ok::<_, web::Error>(Message::from_message_with_attachments(message, attachments))
|
|
});
|
|
|
|
let messages = futures::future::try_join_all(messages_futures).await?;
|
|
|
|
Ok(Json(messages))
|
|
}
|