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, req: HttpRequest, path: Path<(String, i64, i64)>, stream: Payload, ) -> Result { 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) }