diff --git a/src/components/comments/section.rs b/src/components/comments/section.rs index 8cfd77b..de0570e 100644 --- a/src/components/comments/section.rs +++ b/src/components/comments/section.rs @@ -1,21 +1,50 @@ use dioxus::prelude::*; -use crate::api::comments::{get_comments, CommentTreeResponse}; +use crate::api::comments::{check_pending_status, get_comments, CommentTreeResponse}; use crate::components::comments::form::CommentForm; use crate::components::comments::list::CommentList; use crate::components::skeletons::comment_skeleton::CommentListSkeleton; +use crate::hooks::comment_storage::{self, PendingComment}; #[derive(Clone, Copy)] pub struct CommentContext { pub active_reply: Signal>, pub refresh_trigger: Signal, + pub pending_comments: Signal>, } #[component] pub fn CommentSection(post_id: i32) -> Element { - let ctx = use_context_provider(|| CommentContext { - active_reply: Signal::new(None), - refresh_trigger: Signal::new(false), + let ctx = use_context_provider(|| { + let pending: Vec = comment_storage::load_pending_comments(post_id); + comment_storage::prune_all_expired(); + + CommentContext { + active_reply: Signal::new(None), + refresh_trigger: Signal::new(false), + pending_comments: Signal::new(pending), + } + }); + + use_future(move || { + let pending = ctx.pending_comments; + async move { + let ids: Vec = pending().iter().map(|c| c.id).collect(); + if ids.is_empty() { + return; + } + if let Ok(statuses) = check_pending_status(ids).await { + let to_remove: Vec = statuses + .into_iter() + .filter(|s| s.status != "pending") + .map(|s| s.id) + .collect(); + if !to_remove.is_empty() { + comment_storage::remove_pending_ids(post_id, &to_remove); + pending.write().retain(|c| !to_remove.contains(&c.id)); + } + } + } }); let comments_resource = use_server_future(move || { @@ -27,21 +56,28 @@ pub fn CommentSection(post_id: i32) -> Element { match data.as_ref().map(|r| r.as_ref()) { Some(Ok(CommentTreeResponse { comments, count })) => { - let count = *count; + let approved_count = *count; + let pending_count = ctx.pending_comments.read().len() as i64; + let total_count = approved_count + pending_count; + let has_any = approved_count > 0 || pending_count > 0; rsx! { div { class: "space-y-8", h2 { class: "text-xl font-bold text-paper-primary", - "评论区 ({count})" + "评论区 ({total_count})" } CommentForm { post_id, parent_id: None } - if comments.is_empty() { + if !has_any { p { class: "text-paper-tertiary text-center py-8", "暂无评论,成为第一个评论的人吧!" } } else { - CommentList { comments: comments.clone(), post_id } + CommentList { + comments: comments.clone(), + pending: ctx.pending_comments.read().clone(), + post_id, + } } } }