diff --git a/src/lib.rs b/src/lib.rs index 128cb3f..10004b8 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,8 +54,8 @@ pub fn check_page( ext = "html", source = "{% import \"./macros/post.html\" as post %}{% call post::post(board, post, post.thread.is_some()) %}" )] -pub struct PostTemplate { - tcx: TemplateCtx, - post: Post, - board: Board, +pub struct PostTemplate<'a> { + tcx: &'a TemplateCtx, + board: &'a Board, + post: &'a Post, } diff --git a/src/live_hub.rs b/src/live_hub.rs index dce249d..a080cee 100644 --- a/src/live_hub.rs +++ b/src/live_hub.rs @@ -7,7 +7,8 @@ use uuid::Uuid; use crate::{ db::models::{Board, Post}, - web::tcx::TemplateCtx, PostTemplate, + web::tcx::TemplateCtx, + PostTemplate, }; #[derive(Message)] @@ -144,12 +145,12 @@ impl Handler for LiveHub { tcx.update_yous(&mut self.cache).ok(); - let post = post.clone(); + let tcx = &tcx; + let board = &board; + let post = &post; let id = post.id; - let tcx = tcx.clone(); - let board = board.clone(); - let html = PostTemplate { tcx, post, board } + let html = PostTemplate { tcx, board, post } .render() .unwrap_or_default(); @@ -175,9 +176,11 @@ impl Handler for LiveHub { }; let id = post.id; - let tcx = tcx.clone(); + let tcx = &tcx; + let board = &board; + let post = &post; - let html = PostTemplate { tcx, post, board } + let html = PostTemplate { tcx, board, post } .render() .unwrap_or_default(); @@ -213,10 +216,10 @@ impl Handler for LiveHub { tcx.update_yous(&mut self.cache).ok(); - let post = post.clone(); let id = post.id; - let tcx = tcx.clone(); - let board = board.clone(); + let tcx = &tcx; + let board = &board; + let post = &post; let html = PostTemplate { tcx, post, board } .render() diff --git a/src/main.rs b/src/main.rs index 026e881..b98dda2 100755 --- a/src/main.rs +++ b/src/main.rs @@ -73,7 +73,7 @@ async fn run() -> Result<(), Error> { .service(web::news::news) .service(web::overboard::overboard) .service(web::overboard_catalog::overboard_catalog) - .service(web::post_json::post_json) + .service(web::thread_json::thread_json) .service(web::thread::thread) .service(web::actions::appeal_ban::appeal_ban) .service(web::actions::create_post::create_post) diff --git a/src/web/mod.rs b/src/web/mod.rs index 3eb6b22..dcc8cbe 100755 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -11,7 +11,7 @@ pub mod logout; pub mod news; pub mod overboard; pub mod overboard_catalog; -pub mod post_json; +pub mod thread_json; pub mod staff; pub mod tcx; pub mod thread; diff --git a/src/web/post_json.rs b/src/web/post_json.rs deleted file mode 100644 index 7155f12..0000000 --- a/src/web/post_json.rs +++ /dev/null @@ -1,47 +0,0 @@ -use actix_web::{ - get, - web::{Data, Json, Path}, - HttpRequest, -}; -use askama::Template; -use serde::Serialize; - -use crate::{ - ctx::Ctx, - db::models::{Board, Post}, - error::NekrochanError, - web::tcx::TemplateCtx, - PostTemplate, -}; - -#[derive(Serialize)] -pub struct PostJsonResponse { - pub html: String, -} - -#[get("/post-json/{board}/{id}")] -pub async fn post_json( - ctx: Data, - req: HttpRequest, - path: Path<(String, i64)>, -) -> Result, NekrochanError> { - let (board, id) = path.into_inner(); - - let tcx = TemplateCtx::new(&ctx, &req).await?; - - 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))?; - - let html = PostTemplate { tcx, board, post } - .render() - .unwrap_or_default(); - - let res = PostJsonResponse { html }; - - Ok(Json(res)) -} diff --git a/src/web/thread_json.rs b/src/web/thread_json.rs new file mode 100644 index 0000000..4846eaf --- /dev/null +++ b/src/web/thread_json.rs @@ -0,0 +1,58 @@ +use actix_web::{ + get, + web::{Data, Json, Path}, + HttpRequest, +}; +use askama::Template; +use std::{collections::HashMap, vec}; + +use crate::{ + ctx::Ctx, + db::models::{Board, Post}, + error::NekrochanError, + web::tcx::TemplateCtx, + PostTemplate, +}; + +#[get("/thread-json/{board}/{id}")] +pub async fn thread_json( + ctx: Data, + req: HttpRequest, + path: Path<(String, i64)>, +) -> Result>, NekrochanError> { + let (board, id) = path.into_inner(); + + let tcx = TemplateCtx::new(&ctx, &req).await?; + + let board = Board::read(&ctx, board.clone()) + .await? + .ok_or(NekrochanError::BoardNotFound(board))?; + + let thread = Post::read(&ctx, board.id.clone(), id) + .await? + .ok_or(NekrochanError::PostNotFound(board.id.clone(), id))?; + + if thread.thread.is_some() { + return Err(NekrochanError::IsReplyError); + } + + let mut res = HashMap::new(); + + let replies = thread.read_replies(&ctx).await?; + let posts = vec![vec![thread], replies].concat(); + + for post in posts { + let id = post.id; + let tcx = &tcx; + let board = &board; + let post = &post; + + let html = PostTemplate { tcx, board, post } + .render() + .unwrap_or_default(); + + res.insert(id, html); + } + + Ok(Json(res)) +} diff --git a/static/js/hover.js b/static/js/hover.js index 1cec516..6e29970 100644 --- a/static/js/hover.js +++ b/static/js/hover.js @@ -20,7 +20,7 @@ $(function () { setup_events($(".quote")); function setup_events(elements) { - elements.on("mouseenter", function (event) { + elements.on("mouseover", function (event) { toggle_hover($(this), event); }); @@ -36,34 +36,35 @@ $(function () { } function toggle_hover(quote, event) { - hovering = event.type === "mouseenter"; + hovering = event.type === "mouseover"; - let path_segments = quote.prop("pathname").split("/"); - let board = path_segments[2]; - let id = quote.prop("hash").slice(1); - - let post = $(`#${id}[data-board="${board}"]`); - - if (post.length > 0) { - if (post.isInViewport()) { - post.toggleClass("highlighted", hovering); - return; - } - - if (hovering) { - create_preview(post.clone(), event.clientX, event.clientY); - return; - } - } - - if ($("#preview").length > 0 && !hovering) { + if ($("#preview").length !== 0 && !hovering) { remove_preview(); return; } - let html = cache[`${board}/${id}`]; + let path_segments = quote.prop("pathname").split("/"); + let board = path_segments[2]; + let thread = path_segments[3]; + let id = quote.prop("hash").slice(1); - if (html) { + let post = $(`#${id}[data-board="${board}"]`); + + if (post.length !== 0 && post.isInViewport()) { + post.toggleClass("highlighted", hovering); + return; + } + + if (post.length !== 0 && hovering) { + create_preview(post.clone(), event.clientX, event.clientY); + return; + } + + let html; + let cached_thread = cache[`${board}/${thread}`]; + + if (cached_thread) { + html = cached_thread[id]; post = $($.parseHTML(html)); create_preview(post, event.clientX, event.clientY); return; @@ -72,15 +73,13 @@ $(function () { quote.css("cursor", "wait"); try { - $.get(`/post-json/${board}/${id}`, function (data) { + $.get(`/thread-json/${board}/${thread}`, function (data) { quote.css("cursor", ""); - - html = data.html; - cache[`${board}/${id}`] = html; + cache[`${board}/${thread}`] = data; + html = data[id]; post = $($.parseHTML(html)); - if (hovering) - create_preview(post, event.clientX, event.clientY); + create_preview(post, event.clientX, event.clientY); }); } catch (e) { quote.css("cursor", ""); @@ -93,6 +92,10 @@ $(function () { } function create_preview(preview, x, y) { + if (!hovering) { + return; + } + preview.attr("id", "preview"); preview.addClass("box"); preview.removeClass("highlighted"); @@ -100,7 +103,7 @@ $(function () { let existing = $("#preview"); - if (existing.length > 0) { + if (existing.length !== 0) { existing.replaceWith(preview); } else { preview.appendTo("body");