xfy 12a91e3b8e 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
2026-06-11 14:34:36 +08:00

61 lines
1.7 KiB
Rust

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>,
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 item in merged {
match item {
MergedComment::Approved(comment) => rsx! {
CommentItem { comment, post_id }
},
MergedComment::Pending(comment) => rsx! {
PendingCommentItem { comment, post_id }
},
}
}
}
}
}