import React from "react"; import { formatDistanceToNow } from "date-fns"; import { MessageSquare, Trash2, Reply } from "lucide-react"; import type { AnnotationItem, UserProfile } from "../../types"; import { getAvatarUrl } from "../../api/client"; import { clsx } from "clsx"; interface ReplyListProps { replies: AnnotationItem[]; rootUri: string; user: UserProfile | null; onReply: (reply: AnnotationItem) => void; onDelete: (reply: AnnotationItem) => void; isInline?: boolean; } interface ReplyItemProps { reply: AnnotationItem & { children?: AnnotationItem[] }; depth: number; user: UserProfile | null; onReply: (reply: AnnotationItem) => void; onDelete: (reply: AnnotationItem) => void; isInline: boolean; } const ReplyItem: React.FC = ({ reply, depth = 0, user, onReply, onDelete, isInline, }) => { const author = reply.author || reply.creator || {}; const isReplyOwner = user?.did && author.did === user.did; if (!author.handle && !author.did) return null; return (
0 && "ml-4 pl-3 border-l-2 border-surface-200 dark:border-surface-700", )} > {isInline ? ( <> {getAvatarUrl(author.did, author.avatar) ? ( 0 ? "w-6 h-6" : "w-7 h-7", )} /> ) : (
0 ? "w-6 h-6 text-[10px]" : "w-7 h-7 text-xs", )} > {(author.displayName || author.handle || "?")[0]?.toUpperCase()}
)}
0 ? "text-xs" : "text-sm", )} > {author.displayName || author.handle} {reply.createdAt ? formatDistanceToNow(new Date(reply.createdAt), { addSuffix: false, }) : ""}
{isReplyOwner && ( )}

0 ? "text-sm" : "text-sm", )} > {reply.text || reply.body?.value}

) : (
{getAvatarUrl(author.did, author.avatar) ? ( ) : (
{(author.displayName || author.handle || "?")[0]?.toUpperCase()}
)}
{author.displayName || author.handle}
{reply.createdAt ? formatDistanceToNow(new Date(reply.createdAt), { addSuffix: false, }) : ""}

{reply.text || reply.body?.value}

{isReplyOwner && ( )}
)}
{reply.children && reply.children.length > 0 && (
{reply.children.map((child) => ( ))}
)}
); }; export default function ReplyList({ replies, rootUri, user, onReply, onDelete, isInline = false, }: ReplyListProps) { if (!replies || replies.length === 0) { return (

No replies yet

); } const buildReplyTree = () => { const replyMap: Record< string, AnnotationItem & { children: AnnotationItem[] } > = {}; const rootReplies: (AnnotationItem & { children: AnnotationItem[] })[] = []; replies.forEach((r) => { replyMap[r.uri || r.id || ""] = { ...r, children: [] }; }); replies.forEach((r) => { const parentUri = r.reply?.parent?.uri || r.parentUri; if (parentUri === rootUri || !parentUri || !replyMap[parentUri]) { rootReplies.push(replyMap[r.uri || r.id || ""]); } else { replyMap[parentUri].children.push(replyMap[r.uri || r.id || ""]); } }); return rootReplies; }; const replyTree = buildReplyTree(); return (
{replyTree.map((reply) => ( ))}
); }