"use client"; import { Card, CardContent, CardFooter, CardHeader, } from "@/components/ui/card"; import { UserAvatar } from "./user-avatar"; import { Me, Thought } from "@/lib/api"; import { deleteThought } from "@/app/actions/thoughts"; import { format, formatDistanceToNow } from "date-fns"; import { useAuth } from "@/hooks/use-auth"; import { useState } from "react"; import { toast } from "sonner"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Button } from "@/components/ui/button"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { CornerUpLeft, MessageSquare, MoreHorizontal, Trash2, } from "lucide-react"; import { ThoughtForm } from "@/components/thought-form"; import { MovieCard } from "@/components/movie-card"; import Link from "next/link"; import { cn, profileHref } from "@/lib/utils"; interface ThoughtCardProps { thought: Thought; currentUser: Me | null; isReply?: boolean; } function renderWithHashtags(content: string) { return content.split(/(#\w+)/g).map((part, i) => /^#\w+$/.test(part) ? ( {part} ) : ( part ) ); } export function ThoughtCard({ thought, currentUser, isReply = false, }: ThoughtCardProps) { const { author } = thought; const [isAlertOpen, setIsAlertOpen] = useState(false); const [isReplyOpen, setIsReplyOpen] = useState(false); const [deletingState, setDeletingState] = useState<"idle" | "shaking" | "fading">("idle"); const { token } = useAuth(); const timeAgo = formatDistanceToNow(new Date(thought.createdAt), { addSuffix: true, }); const isAuthor = currentUser?.username === thought.author.username; const meta = thought.noteExtensions as Record | null | undefined; if (meta?.movieTitle) { return ( [0]["meta"]} author={thought.author} createdAt={new Date(thought.createdAt)} /> ); } const handleDelete = async () => { setIsAlertOpen(false); setDeletingState("shaking"); await new Promise((r) => setTimeout(r, 450)); setDeletingState("fading"); await new Promise((r) => setTimeout(r, 300)); try { await deleteThought(thought.id); toast.success("Thought deleted."); } catch (error) { console.error("Failed to delete thought:", error); setDeletingState("idle"); toast.error("Failed to delete thought."); } }; return ( <> {thought.replyToId && isReply && ( Replying to{" "} parent thought )} {!thought.replyToId && thought.replyToUrl && ( Replying to{" "} original post ↗ )} {author.displayName || author.username} {!author.local && ( {author.username.startsWith("@") ? author.username : `@${author.username}`} {author.username.split("@").filter(Boolean).at(-1)} )} {timeAgo} {isAuthor && ( setIsAlertOpen(true)} > Delete )} View {thought.author.local ? ( {renderWithHashtags(thought.content)} ) : ( 📎 Media attachment — not supported', }} /> )} {(thought.mood || (meta?.mood as string | undefined)) && ( feeling {thought.mood || (meta?.mood as string)} )} {token && ( setIsReplyOpen(!isReplyOpen)} > Reply )} {isReplyOpen && ( setIsReplyOpen(false)} currentUser={currentUser} /> )} Are you sure? This action cannot be undone. This will permanently delete your thought. Cancel Delete > ); }
{renderWithHashtags(thought.content)}
feeling {thought.mood || (meta?.mood as string)}