Skip to main content

yggdrasil/components/comments/
pending_item.rs

1//! 待审核评论项组件
2//!
3//! 展示用户刚提交、尚未通过审核的评论占位项,
4//! 视觉上使用较低的透明度并标注"审核中"状态。
5
6use leptos::prelude::*;
7
8use crate::components::comments::card::CommentCardShell;
9use crate::utils::comment_storage::{render_pending_content, PendingComment};
10use crate::utils::time::format_relative_time_iso;
11
12/// 待审核评论项组件。
13///
14/// Props:
15/// - `comment`:待审核评论数据
16/// - `post_id`:所属文章 ID(当前未使用,保留用于未来扩展)
17///
18/// 展示内容包括:作者头像/链接、基于创建时间动态计算的相对时间、审核中徽章、Markdown 渲染内容。
19/// 孤儿评论深度会被修正为 0。
20#[component]
21pub fn PendingCommentItem(comment: PendingComment, post_id: i32) -> impl IntoView {
22    let _ = post_id;
23    // 孤儿评论(parent_id 为 None 但 depth > 0)按顶层展示
24    let depth = if comment.parent_id.is_none() && comment.depth > 0 {
25        0
26    } else {
27        comment.depth
28    };
29
30    let content_html = render_pending_content(&comment.content_md);
31    // 基于创建时间实时计算相对时间,避免"刚刚"永久显示。
32    let relative_time = format_relative_time_iso(&comment.created_at);
33
34    let author_element = match &comment.author_url {
35        Some(url) if !url.is_empty() => view! {
36            <a class="comment-author" href=url.clone() rel="nofollow noopener" target="_blank">
37                {comment.author_name.clone()}
38            </a>
39        }
40        .into_any(),
41        _ => view! { <span class="comment-author">{comment.author_name.clone()}</span> }.into_any(),
42    };
43
44    let status_badge = view! {
45        <span
46            class="comment-badge is-pending"
47            title="刚提交的评论只有你自己能看到,审核通过后对所有人显示。"
48        >
49            "审核中"
50        </span>
51    }
52    .into_any();
53
54    let timestamp = view! {
55        <time class="comment-time" datetime=comment.created_at.clone() title=comment.created_at.clone()>
56            {relative_time}
57        </time>
58    }
59    .into_any();
60
61    view! {
62        <CommentCardShell
63            depth=depth
64            muted=true
65            avatar_url=comment.avatar_url.clone()
66            author_name=comment.author_name.clone()
67            author_element=author_element
68            author_badge=().into_any()
69            timestamp=timestamp
70            status_badge=status_badge
71            content_html=content_html
72        />
73    }
74}