nekrochan/src/web/live.rs

63 řádky
1.4 KiB
Rust

use actix_web::{
get,
web::{Data, Path, Payload},
HttpRequest, HttpResponse,
};
use actix_web_actors::ws;
use uuid::Uuid;
use crate::{
ctx::Ctx,
db::models::{Board, Post},
error::NekrochanError,
live_hub::TargetedPostCreatedMessage,
live_session::LiveSession,
web::tcx::TemplateCtx,
};
#[get("/live/{board}/{id}/{last}")]
pub async fn live(
ctx: Data<Ctx>,
req: HttpRequest,
path: Path<(String, i64, i64)>,
stream: Payload,
) -> Result<HttpResponse, NekrochanError> {
let (board, id, last) = path.into_inner();
let board = Board::read(&ctx, board.clone())
.await?
.ok_or(NekrochanError::BoardNotFound(board))?;
let post = Post::read(&ctx, board.id.clone(), id)
.await?
.ok_or(NekrochanError::PostNotFound(board.id.clone(), id))?;
if post.thread.is_some() {
return Err(NekrochanError::IsReplyError);
}
let uuid = Uuid::new_v4();
let thread = (board.id, id);
let tcx = TemplateCtx::new(&ctx, &req).await?;
let hub = ctx.hub();
let ws = LiveSession {
uuid,
thread,
tcx,
hub,
};
let res = ws::start(ws, &req, stream)?;
let new_replies = post.read_replies_after(&ctx, last).await?;
for post in new_replies {
ctx.hub()
.send(TargetedPostCreatedMessage { uuid, post })
.await?;
}
Ok(res)
}