import { useMemo, useState } from 'react'; import { X } from 'lucide-react'; import { Link } from 'react-router-dom'; import { nip19 } from 'nostr-tools'; import type { NostrEvent } from '@nostrify/nostrify'; import { Dialog, DialogContent, DialogTitle, } from '@/components/ui/dialog'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { NoteContent } from '@/components/NoteContent'; import { ComposeBox } from '@/components/ComposeBox'; import { ProfilePreview } from '@/components/ExternalContentHeader'; import { useAuthor } from '@/hooks/useAuthor'; import { genUserName } from '@/lib/genUserName'; import { VerifiedNip05Text } from '@/components/Nip05Badge'; import { timeAgo } from '@/lib/timeAgo'; import { cn } from '@/lib/utils'; interface ReplyComposeModalProps { /** The event being replied to, or a URL for commenting on external content. When `null`, the modal acts as a "New post" composer. */ event?: NostrEvent | URL | null; /** The event being quoted (for quote posts). */ quotedEvent?: NostrEvent | null; open: boolean; onOpenChange: (open: boolean) => void; /** Called after a post is successfully published. */ onSuccess?: () => void; /** Pre-filled content for the compose box. */ initialContent?: string; /** Override the modal title. */ title?: string; /** Override the compose box placeholder text. */ placeholder?: string; } /** Extracts image URLs from note content. */ function extractImages(content: string): string[] { const urlRegex = /https?:\/\/[^\s]+\.(jpg|jpeg|png|gif|webp|svg)(\?[^\s]*)?/gi; return content.match(urlRegex) || []; } export function ReplyComposeModal({ event, quotedEvent, open, onOpenChange, onSuccess, initialContent, title: titleOverride, placeholder: placeholderOverride }: ReplyComposeModalProps) { const isUrl = event instanceof URL; const isReply = !!event; const isQuote = !!quotedEvent; const [previewMode, setPreviewMode] = useState(false); const [hasPreviewableContent, setHasPreviewableContent] = useState(false); const isProfileRoot = !isUrl && event instanceof Object && 'kind' in event && event.kind === 0; const title = titleOverride ?? (isUrl ? 'New comment' : isProfileRoot ? 'Comment on profile' : isReply ? 'Reply to post' : isQuote ? 'Quote post' : 'New post'); const placeholder = placeholderOverride ?? (isUrl ? 'Write a comment...' : isReply ? "What's on your mind?" : isQuote ? 'Add a comment...' : "What's happening?"); return ( ); } /** Compact embedded preview of the post being replied to. */ function EmbeddedPost({ event }: { event: NostrEvent }) { // Kind 0 (profile) โ show a profile card instead of trying to render the raw JSON content if (event.kind === 0) { return (