yggdrasil/api/comments/
read.rs1use crate::api::comments::types::*;
7use crate::api::error::ApiError;
8use leptos::prelude::*;
9
10#[server(GetComments, endpoint = "get_comments", input = leptos::server_fn::codec::Json)]
14pub async fn get_comments(post_id: i32) -> Result<CommentTreeResponse, ApiError> {
15 #[cfg(feature = "server")]
16 {
17 use crate::api::comments::helpers::row_to_public_comment;
18 use crate::api::error::AppError;
19 use crate::cache;
20 use crate::db::pool::get_conn;
21
22 if let Some(cached) = cache::get_comments_by_post(post_id).await {
23 let count = cached.len() as i64;
24 return Ok(CommentTreeResponse {
25 comments: cached,
26 count,
27 });
28 }
29
30 let client = get_conn().await.map_err(AppError::db_conn)?;
31
32 let rows = client
33 .query(
34 "SELECT c.id, c.parent_id, c.depth, c.author_name, c.author_email, c.author_url, c.content_html, c.created_at, \
35 c.user_id, u.display_name AS user_display_name, u.avatar_url AS user_avatar \
36 FROM comments c \
37 LEFT JOIN users u ON c.user_id = u.id \
38 WHERE c.post_id = $1 AND c.status = 'approved' AND c.deleted_at IS NULL \
39 AND EXISTS (SELECT 1 FROM posts p WHERE p.id = $1 AND p.status = 'published' AND p.deleted_at IS NULL) \
40 ORDER BY c.id ASC \
41 LIMIT 200",
42 &[&post_id],
43 )
44 .await
45 .map_err(AppError::query)?;
46
47 let comments: Vec<_> = rows.iter().map(row_to_public_comment).collect();
48 let count = comments.len() as i64;
49
50 cache::set_comments_by_post(post_id, comments.clone()).await;
51
52 Ok(CommentTreeResponse { comments, count })
53 }
54 #[cfg(not(feature = "server"))]
55 unreachable!()
56}