"use client"; import CommentForm from "./comment-form"; import Comment from "./comment"; import { Drawer, DrawerContent, DrawerTitle, DrawerTrigger } from "ui/drawer"; import { useMemo, useRef, useState } from "react"; import { CornerDownRightIcon, MessagesSquareIcon, XIcon } from "lucide-react"; import { Button } from "ui/button"; import useSWR, { mutate } from "swr"; import { fetcher, truncateString } from "lib/utils"; import { ChatExportCommentWithUser } from "app-types/chat-export"; import { Avatar, AvatarFallback, AvatarImage } from "ui/avatar"; import { Skeleton } from "ui/skeleton"; import { authClient } from "auth/client"; import { notify } from "lib/notify"; import { useRouter } from "next/navigation"; function deepReplyCount(comment: ChatExportCommentWithUser): number { if (comment.replies?.length) { return comment.replies.reduce((acc, reply) => { return acc + deepReplyCount(reply); }, 1); } return 1; // original comment } export default function Comments({ id, children, defaultComments, }: { id: string; children?: React.ReactNode; defaultComments: ChatExportCommentWithUser[]; }) { const { data: session, isPending } = authClient.useSession(); const isLoggedIn = !!session?.user?.id; const [open, setOpen] = useState(false); const scrollRef = useRef(null); const [replyTo, setReplyTo] = useState( null, ); const router = useRouter(); const { data, isLoading } = useSWR( isLoggedIn ? `/api/export/${id}/comments` : null, fetcher, { fallbackData: defaultComments, revalidateOnMount: false, }, ); const trigger = useMemo(() => { if (children) return children; const commentCount = data?.length ? data.map(deepReplyCount).reduce((acc, count) => acc + count, 0) : 0; return ( ); }, [children, data, isPending]); const handleOpenChange = (open: boolean) => { if (!isLoggedIn) { notify .confirm({ title: "Sign in required", description: "You need to sign in to view comments. Would you like to go to the sign-in page?", }) .then((answer) => { if (answer) { router.push("/sign-in"); } }); } else { setOpen(open); } }; const handleReplySubmit = async () => { setReplyTo(null); await mutate(`/api/export/${id}/comments`); if (scrollRef.current) { scrollRef.current.scrollTo({ top: scrollRef.current.scrollHeight, behavior: "smooth", }); } }; return ( {trigger} Comments
{isLoading ? ( <> ) : data?.length === 0 ? (

Be the first to comment!

) : ( data?.map((comment) => ( setReplyTo(comment)} /> )) )}
{replyTo && (
{replyTo.authorName?.[0]?.toUpperCase()} Replying to {truncateString(replyTo.authorName, 8)} {" "} setReplyTo(null)} />
)}
); }