76 lines
2.0 KiB
Rust
76 lines
2.0 KiB
Rust
use axum::Json;
|
|
use axum::extract::State;
|
|
use axum::response::IntoResponse;
|
|
use axum_extra::extract::WithRejection;
|
|
use serde::Deserialize;
|
|
use validator::Validate;
|
|
|
|
use crate::state::AppState;
|
|
use crate::web::context::UserContext;
|
|
use crate::web::entity::user::PartialUser;
|
|
use crate::web::route::user::channel::RecipientChannel;
|
|
use crate::web::ws;
|
|
use crate::{entity, web};
|
|
|
|
#[derive(Debug, Validate, Deserialize)]
|
|
pub struct CreatePayload {
|
|
#[validate(length(min = 1, max = 32))]
|
|
recipients: Vec<entity::user::Id>,
|
|
}
|
|
|
|
pub async fn create(
|
|
State(state): State<AppState>,
|
|
context: UserContext,
|
|
WithRejection(Json(payload), _): WithRejection<Json<CreatePayload>, web::Error>,
|
|
) -> web::Result<impl IntoResponse> {
|
|
match payload.validate() {
|
|
Ok(_) => {},
|
|
Err(err) => {
|
|
return Err(web::error::ClientError::ValidationFailed(err).into());
|
|
},
|
|
}
|
|
|
|
let channel_id = match payload.recipients.len() {
|
|
1 => {
|
|
let recipient = payload.recipients[0];
|
|
state
|
|
.database
|
|
.procedure_create_dm_channel(context.user_id, recipient)
|
|
.await?
|
|
},
|
|
_ => {
|
|
state
|
|
.database
|
|
.procedure_create_group_channel(context.user_id, &payload.recipients)
|
|
.await?
|
|
},
|
|
};
|
|
|
|
let channel = state.database.select_channel_by_id(channel_id).await?;
|
|
|
|
let recipients = state
|
|
.database
|
|
.select_channel_recipients(channel_id)
|
|
.await?
|
|
.unwrap_or_default()
|
|
.into_iter()
|
|
.map(|user| user.id)
|
|
.collect::<Vec<_>>();
|
|
|
|
let recipient_channels = RecipientChannel {
|
|
channel: channel.clone(),
|
|
recipients: recipients.clone(),
|
|
};
|
|
|
|
ws::gateway::util::send_message_channel(
|
|
state,
|
|
channel_id,
|
|
ws::gateway::event::Event::AddDmChannel {
|
|
channel,
|
|
recipients,
|
|
},
|
|
);
|
|
|
|
Ok(Json(recipient_channels))
|
|
}
|