'use client'; import { useState, useRef } from 'react'; import { Plus, ArrowUp, Upload } from 'lucide-react'; import { ModelSelector } from './ModelSelector'; import { ToolsDropdown } from './ToolsDropdown'; import { FilePreviewList } from './FilePreviewList'; import { useFileUpload } from '@/hooks/useFileUpload'; import { cn } from '@/lib/utils'; import type { Model, Tool } from '@/types'; import type { UploadFile } from '@/types/file-upload'; interface ChatInputProps { models: Model[]; selectedModel: Model; onModelSelect: (model: Model) => void; tools: Tool[]; onToolToggle: (toolId: string) => void; onEnableAllTools: (enabled: boolean) => void; onSend: (message: string, files?: UploadFile[]) => void; placeholder?: string; className?: string; } export function ChatInput({ models, selectedModel, onModelSelect, tools, onToolToggle, onEnableAllTools, onSend, placeholder = 'How can I help you today?', className, }: ChatInputProps) { const [message, setMessage] = useState(''); const fileInputRef = useRef(null); // 使用文件上传 Hook const { files, isDragging, addFiles, removeFile, clearFiles, handleDragEnter, handleDragLeave, handleDragOver, handleDrop, handlePaste, } = useFileUpload(); const handleSend = () => { if (message.trim() || files.length > 0) { onSend(message, files.length > 0 ? files : undefined); setMessage(''); clearFiles(); } }; const handleKeyDown = (e: React.KeyboardEvent) => { // 检查是否正在使用输入法组合(如中文输入法选词时按回车) // isComposing 为 true 时,表示用户正在用输入法选词,此时不应发送消息 if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { e.preventDefault(); handleSend(); } }; // 处理文件选择 const handleFileSelect = (e: React.ChangeEvent) => { const selectedFiles = e.target.files; if (selectedFiles && selectedFiles.length > 0) { addFiles(selectedFiles); } // 重置 input 以允许重复选择同一文件 if (fileInputRef.current) { fileInputRef.current.value = ''; } }; // 打开文件选择对话框 const openFileDialog = () => { fileInputRef.current?.click(); }; return (
{/* 拖拽覆盖层 */} {isDragging && (

释放以添加文件

支持图片、PDF、文档等格式

)} {/* 文件预览区域 */} {files.length > 0 && (
)} {/* 第一行:输入区域 */}
setMessage(e.target.value)} onKeyDown={handleKeyDown} onPaste={handlePaste} placeholder={files.length > 0 ? '添加描述(可选)...' : placeholder} className="w-full border-none outline-none text-[var(--color-text-primary)] bg-transparent py-2 placeholder:text-[var(--color-text-placeholder)]" />
{/* 第二行:功能按钮区域 */}
{/* 左侧按钮 */}
{/* 添加附件 */} {/* 隐藏的文件输入 */} {/* 工具下拉 */}
{/* 右侧按钮 */}
{/* 模型选择器 */} {/* 发送按钮 */}
{/* 提示文字 */}

可拖拽文件到此处或使用 Ctrl+V 粘贴图片

); }