"use client"; import type { UseChatHelpers } from "@ai-sdk/react"; import { type Dispatch, type SetStateAction, useCallback, useEffect, useRef, useState, } from "react"; import type { ChatMessage, Attachment } from "@/lib/types"; import { getTextFromMessage } from "@/lib/utils"; import { Button } from "./ui/button"; import { Textarea } from "./ui/textarea"; import { PreviewAttachment } from "./preview-attachment"; export type MessageEditorProps = { message: ChatMessage; setMode: Dispatch>; setMessages: UseChatHelpers["setMessages"]; regenerate: UseChatHelpers["regenerate"]; sendMessage: UseChatHelpers["sendMessage"]; }; export function MessageEditor({ message, setMode, setMessages, regenerate, sendMessage, }: MessageEditorProps) { const [isSubmitting, setIsSubmitting] = useState(false); const [draftContent, setDraftContent] = useState( getTextFromMessage(message) ); // 🆕 管理可编辑的附件列表 const [attachments, setAttachments] = useState(() => { // 从消息的 parts 中提取图片附件 return message.parts .filter((part): part is Extract => part.type === "file" && 'mediaType' in part && typeof part.mediaType === 'string' && part.mediaType.startsWith("image/") ) .map((part) => ({ url: part.url, name: part.filename ?? part.url.split("/").pop() ?? "image", contentType: part.mediaType ?? "image/jpeg", })); }); const textareaRef = useRef(null); const adjustHeight = useCallback(() => { if (textareaRef.current) { textareaRef.current.style.height = "auto"; textareaRef.current.style.height = `${textareaRef.current.scrollHeight + 2}px`; } }, []); useEffect(() => { if (textareaRef.current) { adjustHeight(); } }, [adjustHeight]); const handleInput = (event: React.ChangeEvent) => { setDraftContent(event.target.value); adjustHeight(); }; return (
{/* 🆕 显示附件列表(可删除)*/} {attachments.length > 0 && (
{attachments.map((attachment, index) => ( { setAttachments((prev) => prev.filter((_, i) => i !== index)); }} /> ))}
)}