diff --git a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx index 07f2976a3e..5c1acab130 100644 --- a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx +++ b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx @@ -521,8 +521,6 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = async (event: ClipboardEvent) => { return await PasteService.handlePaste( event, - isVisionModel(model), - isGenerateImageModel(model), supportedExts, setFiles, setText, @@ -533,7 +531,7 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = t ) }, - [model, pasteLongTextAsFile, pasteLongTextThreshold, resizeTextArea, supportedExts, t, text] + [pasteLongTextAsFile, pasteLongTextThreshold, resizeTextArea, supportedExts, t, text] ) const handleDragOver = (e: React.DragEvent) => { diff --git a/src/renderer/src/pages/home/Messages/MessageEditor.tsx b/src/renderer/src/pages/home/Messages/MessageEditor.tsx index a2b6119c39..b70077b54e 100644 --- a/src/renderer/src/pages/home/Messages/MessageEditor.tsx +++ b/src/renderer/src/pages/home/Messages/MessageEditor.tsx @@ -41,14 +41,58 @@ const MessageBlockEditor: FC = ({ message, topicId, onSave, onResend, onC const [isFileDragging, setIsFileDragging] = useState(false) const { assistant } = useAssistant(message.assistantId) const model = assistant.model || assistant.defaultModel - const isVision = useMemo(() => isVisionModel(model), [model]) - const supportExts = useMemo(() => [...textExts, ...documentExts, ...(isVision ? imageExts : [])], [isVision]) const { pasteLongTextThreshold, fontSize, sendMessageShortcut, enableSpellCheck } = useSettings() const { t } = useTranslation() const textareaRef = useRef(null) const attachmentButtonRef = useRef(null) const isUserMessage = message.role === 'user' + const topicMessages = useAppSelector((state) => selectMessagesForTopic(state, topicId)) + + const couldAddImageFile = useMemo(() => { + const relatedAssistantMessages = topicMessages.filter((m) => m.askId === message.id && m.role === 'assistant') + if (relatedAssistantMessages.length === 0) { + // 无关联消息时fallback到助手模型 + return isVisionModel(model) + } + return relatedAssistantMessages.every((m) => { + if (m.model) { + return isVisionModel(m.model) || isGenerateImageModel(m.model) + } else { + // 若消息关联不存在的模型,视为其支持视觉 + return true + } + }) + }, [message.id, model, topicMessages]) + + const couldAddTextFile = useMemo(() => { + const relatedAssistantMessages = topicMessages.filter((m) => m.askId === message.id && m.role === 'assistant') + if (relatedAssistantMessages.length === 0) { + // 无关联消息时fallback到助手模型 + return isVisionModel(model) || (!isVisionModel(model) && !isGenerateImageModel(model)) + } + return relatedAssistantMessages.every((m) => { + if (m.model) { + return isVisionModel(m.model) || (!isVisionModel(m.model) && !isGenerateImageModel(m.model)) + } else { + // 若消息关联不存在的模型,视为其支持文本 + return true + } + }) + }, [message.id, model, topicMessages]) + + const extensions = useMemo(() => { + if (couldAddImageFile && couldAddTextFile) { + return [...imageExts, ...documentExts, ...textExts] + } else if (couldAddImageFile) { + return [...imageExts] + } else if (couldAddTextFile) { + return [...documentExts, ...textExts] + } else { + return [] + } + }, [couldAddImageFile, couldAddTextFile]) + const resizeTextArea = useCallback(() => { const textArea = textareaRef.current?.resizableTextArea?.textArea if (textArea) { @@ -70,9 +114,7 @@ const MessageBlockEditor: FC = ({ message, topicId, onSave, onResend, onC async (event: ClipboardEvent) => { return await PasteService.handlePaste( event, - isVisionModel(model), - isGenerateImageModel(model), - supportExts, + extensions, setFiles, undefined, // 不需要setText false, // 不需要 pasteLongTextAsFile @@ -82,7 +124,7 @@ const MessageBlockEditor: FC = ({ message, topicId, onSave, onResend, onC t ) }, - [model, pasteLongTextThreshold, resizeTextArea, supportExts, t] + [extensions, pasteLongTextThreshold, resizeTextArea, t] ) // 添加全局粘贴事件处理 @@ -125,7 +167,7 @@ const MessageBlockEditor: FC = ({ message, topicId, onSave, onResend, onC if (files) { let supportedFiles = 0 files.forEach((file) => { - if (supportExts.includes(getFileExtension(file.path))) { + if (extensions.includes(getFileExtension(file.path))) { setFiles((prevFiles) => [...prevFiles, file]) supportedFiles++ } @@ -209,52 +251,6 @@ const MessageBlockEditor: FC = ({ message, topicId, onSave, onResend, onC } } - const topicMessages = useAppSelector((state) => selectMessagesForTopic(state, topicId)) - - const couldAddImageFile = useMemo(() => { - const relatedAssistantMessages = topicMessages.filter((m) => m.askId === message.id && m.role === 'assistant') - if (relatedAssistantMessages.length === 0) { - // 无关联消息时fallback到助手模型 - return isVisionModel(model) - } - return relatedAssistantMessages.every((m) => { - if (m.model) { - return isVisionModel(m.model) - } else { - // 若消息关联不存在的模型,视为其支持视觉 - return true - } - }) - }, [message.id, model, topicMessages]) - - const couldAddTextFile = useMemo(() => { - const relatedAssistantMessages = topicMessages.filter((m) => m.askId === message.id && m.role === 'assistant') - if (relatedAssistantMessages.length === 0) { - // 无关联消息时fallback到助手模型 - return isVisionModel(model) || (!isVisionModel(model) && !isGenerateImageModel(model)) - } - return relatedAssistantMessages.every((m) => { - if (m.model) { - return isVisionModel(m.model) || (!isVisionModel(m.model) && !isGenerateImageModel(m.model)) - } else { - // 若消息关联不存在的模型,视为其支持文本 - return true - } - }) - }, [message.id, model, topicMessages]) - - const extensions = useMemo(() => { - if (couldAddImageFile && couldAddTextFile) { - return [...imageExts, ...documentExts, ...textExts] - } else if (couldAddImageFile) { - return [...imageExts] - } else if (couldAddTextFile) { - return [...documentExts, ...textExts] - } else { - return [] - } - }, [couldAddImageFile, couldAddTextFile]) - return ( <> e.preventDefault()} onDrop={handleDrop}> diff --git a/src/renderer/src/services/PasteService.ts b/src/renderer/src/services/PasteService.ts index 534a9ceaac..4cef946229 100644 --- a/src/renderer/src/services/PasteService.ts +++ b/src/renderer/src/services/PasteService.ts @@ -24,8 +24,6 @@ let isInitialized = false */ export const handlePaste = async ( event: ClipboardEvent, - isVisionModel: boolean, - isGenerateImageModel: boolean, supportExts: string[], setFiles: (updater: (prevFiles: FileMetadata[]) => FileMetadata[]) => void, setText?: (text: string) => void, @@ -57,7 +55,6 @@ export const handlePaste = async ( // 短文本走默认粘贴行为,直接返回 return false } - // 2. 文件/图片粘贴(仅在无文本时处理) if (event.clipboardData?.files && event.clipboardData.files.length > 0) { event.preventDefault() @@ -69,7 +66,7 @@ export const handlePaste = async ( // 如果没有路径,可能是剪贴板中的图像数据 if (!filePath) { // 图像生成也支持图像编辑 - if (file.type.startsWith('image/') && (isVisionModel || isGenerateImageModel)) { + if (file.type.startsWith('image/') && supportExts.includes(getFileExtension(file.name))) { const tempFilePath = await window.api.file.createTempFile(file.name) const arrayBuffer = await file.arrayBuffer() const uint8Array = new Uint8Array(arrayBuffer)