import React, { useRef, useState, useEffect } from "react"; import { Image as ImageIcon, Send, Trash2, ArrowUp } from "lucide-react"; import { MessageBlock } from "./types"; import { useUploadFile } from "@/app/service/domain/service"; interface InputBarProps { onSend: (blocks: MessageBlock[], videoId?: string) => void; setVideoPreview?: (url: string, id: string) => void; initialVideoUrl?: string; initialVideoId?: string; } export function InputBar({ onSend, setVideoPreview, initialVideoUrl, initialVideoId }: InputBarProps) { const [text, setText] = useState(""); const [isUploading, setIsUploading] = useState(false); const [uploadProgress, setUploadProgress] = useState(0); const [imageUrl, setImageUrl] = useState(null); const [videoUrl, setVideoUrl] = useState(initialVideoUrl || null); const [videoId, setVideoId] = useState(initialVideoId || null); const [isMultiline, setIsMultiline] = useState(false); const textareaRef = useRef(null); const { uploadFile } = useUploadFile(); const adjustHeight = () => { const textarea = textareaRef.current; if (textarea) { textarea.style.height = 'auto'; const newHeight = Math.min(Math.max(textarea.scrollHeight, 48), 120); textarea.style.height = `${newHeight}px`; // 检查是否超过一行(48px 是单行高度) setIsMultiline(newHeight > 48); } }; // 监听初始视频 URL 和 ID 的变化 useEffect(() => { if (initialVideoUrl && initialVideoId) { setVideoUrl(initialVideoUrl); setVideoId(initialVideoId); } }, [initialVideoUrl, initialVideoId]); // 监听文本变化和组件挂载时调整高度 useEffect(() => { adjustHeight(); }, [text]); const handleSend = () => { const blocks: MessageBlock[] = []; if (text.trim()) blocks.push({ type: "text" as const, text: text.trim() }); if (imageUrl) blocks.push({ type: "image" as const, url: imageUrl }); if (videoUrl) blocks.push({ type: "video" as const, url: videoUrl }); if (!blocks.length) return; onSend(blocks, videoId || undefined); setText(""); setImageUrl(null); if (videoUrl && videoId && setVideoPreview) { setVideoPreview(videoUrl, videoId); } setVideoUrl(null); setVideoId(null); }; const handleFileUpload = async (file: File) => { try { setIsUploading(true); const url = await uploadFile(file, (progress) => { setUploadProgress(progress); }); // 如果已经有视频,先保存视频状态 const prevVideoUrl = videoUrl; const prevVideoId = videoId; setImageUrl(url); // 恢复视频状态 if (prevVideoUrl && prevVideoId) { setVideoUrl(prevVideoUrl); setVideoId(prevVideoId); } } catch (error) { console.error("上传失败:", error); // 可以添加错误提示 } finally { setIsUploading(false); setUploadProgress(0); } }; const onFileChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; // 保存对 input 元素的引用 const inputElement = e.currentTarget; if (file) { if (!file.type.startsWith('image/')) { alert('请选择图片文件'); inputElement.value = ""; // 重置 input return; } await handleFileUpload(file); // 使用保存的引用重置 input inputElement.value = ""; } }; const removeImage = () => { setImageUrl(null); }; return (
{/* 媒体预览 */}
{/* 图片预览 */} {imageUrl && (
预览图
)} {/* 视频预览 */} {videoUrl && (
)}
{/* 上传进度 */} {isUploading && (
)}
{/* 图片上传按钮 - 单行时显示在左侧,多行时显示在底部 */} {!isMultiline && ( )} {/* 文本输入 */}