From 07c7ecd0cfb586759ac4d7a09641b9bf3e8f88bb Mon Sep 17 00:00:00 2001 From: icarus Date: Sun, 24 Aug 2025 23:21:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor(PasteService):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=B2=98=E8=B4=B4=E6=9C=8D=E5=8A=A1=E9=80=BB=E8=BE=91=E5=B9=B6?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将`t`参数改为布尔类型的`showMessage`参数,简化消息显示逻辑 添加默认的粘贴文本长度阈值 使文件扩展名检查变为可选参数 更新相关调用处的参数传递 --- .../src/pages/home/Inputbar/Inputbar.tsx | 4 +- .../src/pages/home/Messages/MessageEditor.tsx | 4 +- src/renderer/src/services/PasteService.ts | 41 +++++++++++++------ 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx index e2de99df8c..acd7699e28 100644 --- a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx +++ b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx @@ -552,10 +552,10 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = pasteLongTextThreshold, text, resizeTextArea, - t + true ) }, - [pasteLongTextAsFile, pasteLongTextThreshold, resizeTextArea, supportedExts, t, text] + [pasteLongTextAsFile, pasteLongTextThreshold, resizeTextArea, supportedExts, 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 155312a368..f0b9c1efba 100644 --- a/src/renderer/src/pages/home/Messages/MessageEditor.tsx +++ b/src/renderer/src/pages/home/Messages/MessageEditor.tsx @@ -130,10 +130,10 @@ const MessageBlockEditor: FC = ({ message, topicId, onSave, onResend, onC pasteLongTextThreshold, undefined, // 不需要text undefined, // 不需要 resizeTextArea - t + true ) }, - [extensions, pasteLongTextThreshold, t] + [extensions, pasteLongTextThreshold] ) // 添加全局粘贴事件处理 diff --git a/src/renderer/src/services/PasteService.ts b/src/renderer/src/services/PasteService.ts index 277bc9ef66..83cbec2efb 100644 --- a/src/renderer/src/services/PasteService.ts +++ b/src/renderer/src/services/PasteService.ts @@ -1,6 +1,7 @@ import { loggerService } from '@logger' import { FileMetadata } from '@renderer/types' import { getFileExtension, isSupportedFile } from '@renderer/utils' +import { t } from 'i18next' const logger = loggerService.withContext('PasteService') @@ -23,19 +24,33 @@ let isInitialized = false /** * 处理粘贴事件的通用服务 * 处理各种粘贴场景,包括文本和文件 + * @param event - 粘贴事件对象 + * @param supportExts - 支持的文件扩展名数组,undefined表示支持所有类型 + * @param setFiles - 设置文件的回调函数,undefined表示不处理文件 + * @param setText - 设置文本的回调函数,undefined表示不设置文本 + * @param pasteLongTextAsFile - 是否将长文本作为文件粘贴,undefined表示不作为文件处理 + * @param pasteLongTextThreshold - 长文本阈值,超过此长度的文本将作为文件处理,undefined表示使用默认阈值 + * @param text - 当前输入框的文本内容,undefined表示无文本 + * @param resizeTextArea - 调整文本框大小的回调函数,undefined表示不调整大小 + * @param showMessage - 是否显示提示消息,undefined表示不显示 + * @returns 返回是否已处理粘贴事件 */ export const handlePaste = async ( event: ClipboardEvent, - supportExts: string[], - setFiles: (updater: (prevFiles: FileMetadata[]) => FileMetadata[]) => void, + supportExts?: string[], + setFiles?: (updater: (prevFiles: FileMetadata[]) => FileMetadata[]) => void, setText?: (text: string) => void, pasteLongTextAsFile?: boolean, pasteLongTextThreshold?: number, text?: string, resizeTextArea?: () => void, - t?: (key: string) => string + showMessage?: boolean ): Promise => { try { + if (!pasteLongTextThreshold) { + // default threshold + pasteLongTextThreshold = 2000 + } // 优先处理文本粘贴 const clipboardText = event.clipboardData?.getData('text') if (clipboardText) { @@ -48,7 +63,7 @@ export const handlePaste = async ( await window.api.file.write(tempFilePath, clipboardText) const selectedFile = await window.api.file.get(tempFilePath) if (selectedFile) { - setFiles((prevFiles) => [...prevFiles, selectedFile]) + setFiles?.((prevFiles) => [...prevFiles, selectedFile]) if (setText && text) setText(text) // 保持输入框内容不变 if (resizeTextArea) setTimeout(() => resizeTextArea(), 50) } @@ -60,7 +75,6 @@ export const handlePaste = async ( // 2. 文件/图片粘贴(仅在无文本时处理) if (event.clipboardData?.files && event.clipboardData.files.length > 0) { event.preventDefault() - const extensionSet = new Set(supportExts) try { for (const file of event.clipboardData.files) { // 使用新的API获取文件路径 @@ -69,18 +83,18 @@ export const handlePaste = async ( // 如果没有路径,可能是剪贴板中的图像数据 if (!filePath) { // 图像生成也支持图像编辑 - if (file.type.startsWith('image/') && supportExts.includes(getFileExtension(file.name))) { + if (file.type.startsWith('image/') && (supportExts?.includes(getFileExtension(file.name)) ?? true)) { const tempFilePath = await window.api.file.createTempFile(file.name) const arrayBuffer = await file.arrayBuffer() const uint8Array = new Uint8Array(arrayBuffer) await window.api.file.write(tempFilePath, uint8Array) const selectedFile = await window.api.file.get(tempFilePath) if (selectedFile) { - setFiles((prevFiles) => [...prevFiles, selectedFile]) + setFiles?.((prevFiles) => [...prevFiles, selectedFile]) break } } else { - if (t) { + if (showMessage) { window.message.info({ key: 'file_not_supported', content: t('chat.input.file_not_supported') @@ -91,23 +105,24 @@ export const handlePaste = async ( } // 有路径的情况 - if (await isSupportedFile(filePath, extensionSet)) { + const extensionSet = new Set(supportExts) + if (supportExts === undefined || (await isSupportedFile(filePath, extensionSet))) { const selectedFile = await window.api.file.get(filePath) if (selectedFile) { - setFiles((prevFiles) => [...prevFiles, selectedFile]) + setFiles?.((prevFiles) => [...prevFiles, selectedFile]) } } else { - if (t) { + if (showMessage) { window.message.info({ key: 'file_not_supported', - content: t('chat.input.file_not_supported') + content: t('common.file.not_supported', { type: getFileExtension(file.name) }) }) } } } } catch (error) { logger.error('onPaste:', error as Error) - if (t) { + if (showMessage) { window.message.error(t('chat.input.file_error')) } }