"use client"; import { useRef, useState, useEffect } from "react"; import { ArrowUp, Loader2 } from "lucide-react"; import { ContentEditor, type ContentEditorRef } from "@/features/editor"; import { FileUploadButton } from "@/components/common/file-upload-button"; import { ActorAvatar } from "@/components/common/actor-avatar"; import { useFileUpload } from "@/shared/hooks/use-file-upload"; import { cn } from "@/lib/utils"; // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- interface ReplyInputProps { issueId: string; placeholder?: string; avatarType: string; avatarId: string; onSubmit: (content: string, attachmentIds?: string[]) => Promise; size?: "sm" | "default"; } // --------------------------------------------------------------------------- // ReplyInput // --------------------------------------------------------------------------- function ReplyInput({ issueId, placeholder = "Leave a reply...", avatarType, avatarId, onSubmit, size = "default", }: ReplyInputProps) { const editorRef = useRef(null); const measureRef = useRef(null); const [isEmpty, setIsEmpty] = useState(true); const [isExpanded, setIsExpanded] = useState(false); const [submitting, setSubmitting] = useState(false); const [attachmentIds, setAttachmentIds] = useState([]); const { uploadWithToast } = useFileUpload(); useEffect(() => { const el = measureRef.current; if (!el) return; const observer = new ResizeObserver((entries) => { const entry = entries[0]; if (entry) setIsExpanded(entry.contentRect.height > 32); }); observer.observe(el); return () => observer.disconnect(); }, []); const handleUpload = async (file: File) => { const result = await uploadWithToast(file, { issueId }); if (result) { setAttachmentIds((prev) => [...prev, result.id]); } return result; }; const handleSubmit = async () => { const content = editorRef.current?.getMarkdown()?.replace(/(\n\s*)+$/, "").trim(); if (!content || submitting) return; setSubmitting(true); try { await onSubmit(content, attachmentIds.length > 0 ? attachmentIds : undefined); editorRef.current?.clearContent(); setIsEmpty(true); setAttachmentIds([]); } finally { setSubmitting(false); } }; const avatarSize = size === "sm" ? 22 : 28; return (
setIsEmpty(!md.trim())} onSubmit={handleSubmit} onUploadFile={handleUpload} debounceMs={100} />
editorRef.current?.uploadFile(file)} />
); } export { ReplyInput, type ReplyInputProps };