63 řádky
1.4 KiB
Rust
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)
|
||
|
}
|