feat(comments): merge approved and pending comments in CommentList

- Accept both comments and pending props
- Merge into chronologically sorted list
- Route to CommentItem or PendingCommentItem per item type
This commit is contained in:
xfy 2026-06-11 14:34:36 +08:00
parent 9e658662cb
commit 12a91e3b8e

View File

@ -1,14 +1,59 @@
use dioxus::prelude::*;
use crate::models::comment::PublicComment;
use crate::hooks::comment_storage::PendingComment;
use crate::components::comments::item::CommentItem;
use crate::components::comments::pending_item::PendingCommentItem;
enum MergedComment {
Approved(PublicComment),
Pending(PendingComment),
}
fn merge_comments(
approved: Vec<PublicComment>,
pending: Vec<PendingComment>,
) -> Vec<MergedComment> {
let mut merged: Vec<MergedComment> = approved
.into_iter()
.map(MergedComment::Approved)
.chain(pending.into_iter().map(MergedComment::Pending))
.collect();
merged.sort_by(|a, b| {
let time_a = match a {
MergedComment::Approved(c) => c.created_at_iso.as_str(),
MergedComment::Pending(c) => c.created_at.as_str(),
};
let time_b = match b {
MergedComment::Approved(c) => c.created_at_iso.as_str(),
MergedComment::Pending(c) => c.created_at.as_str(),
};
time_a.cmp(time_b)
});
merged
}
#[component]
pub fn CommentList(comments: Vec<PublicComment>, post_id: i32) -> Element {
pub fn CommentList(
comments: Vec<PublicComment>,
pending: Vec<PendingComment>,
post_id: i32,
) -> Element {
let merged = merge_comments(comments, pending);
rsx! {
div { class: "space-y-0 divide-y divide-gray-100 dark:divide-[#2a2a2a]",
for comment in comments {
CommentItem { comment, post_id }
for item in merged {
match item {
MergedComment::Approved(comment) => rsx! {
CommentItem { comment, post_id }
},
MergedComment::Pending(comment) => rsx! {
PendingCommentItem { comment, post_id }
},
}
}
}
}