Revert "style(PasteService): 统一文件换行符为LF格式"

This reverts commit 37a1443b73.
This commit is contained in:
icarus 2025-07-04 15:32:14 +08:00
parent 37a1443b73
commit 16fbd685c7

View File

@ -1,216 +1,216 @@
import Logger from '@renderer/config/logger' import Logger from '@renderer/config/logger'
import { FileMetadata } from '@renderer/types' import { FileMetadata } from '@renderer/types'
import { getFileExtension } from '@renderer/utils' import { getFileExtension } from '@renderer/utils'
// Track last focused component // Track last focused component
type ComponentType = 'inputbar' | 'messageEditor' | null type ComponentType = 'inputbar' | 'messageEditor' | null
let lastFocusedComponent: ComponentType = 'inputbar' // Default to inputbar let lastFocusedComponent: ComponentType = 'inputbar' // Default to inputbar
// 处理函数类型 // 处理函数类型
type PasteHandler = (event: ClipboardEvent) => Promise<boolean> type PasteHandler = (event: ClipboardEvent) => Promise<boolean>
// 处理函数存储 // 处理函数存储
const handlers: { const handlers: {
inputbar?: PasteHandler inputbar?: PasteHandler
messageEditor?: PasteHandler messageEditor?: PasteHandler
} = {} } = {}
// 初始化标志 // 初始化标志
let isInitialized = false let isInitialized = false
/** /**
* *
* *
*/ */
export const handlePaste = async ( export const handlePaste = async (
event: ClipboardEvent, event: ClipboardEvent,
isVisionModel: boolean, isVisionModel: boolean,
isGenerateImageModel: boolean, isGenerateImageModel: boolean,
supportExts: string[], supportExts: string[],
setFiles: (updater: (prevFiles: FileMetadata[]) => FileMetadata[]) => void, setFiles: (updater: (prevFiles: FileMetadata[]) => FileMetadata[]) => void,
setText?: (text: string) => void, setText?: (text: string) => void,
pasteLongTextAsFile?: boolean, pasteLongTextAsFile?: boolean,
pasteLongTextThreshold?: number, pasteLongTextThreshold?: number,
text?: string, text?: string,
resizeTextArea?: () => void, resizeTextArea?: () => void,
t?: (key: string) => string t?: (key: string) => string
): Promise<boolean> => { ): Promise<boolean> => {
try { try {
// 优先处理文本粘贴 // 优先处理文本粘贴
const clipboardText = event.clipboardData?.getData('text') const clipboardText = event.clipboardData?.getData('text')
if (clipboardText) { if (clipboardText) {
// 1. 文本粘贴 // 1. 文本粘贴
if (pasteLongTextAsFile && pasteLongTextThreshold && clipboardText.length > pasteLongTextThreshold) { if (pasteLongTextAsFile && pasteLongTextThreshold && clipboardText.length > pasteLongTextThreshold) {
// 长文本直接转文件,阻止默认粘贴 // 长文本直接转文件,阻止默认粘贴
event.preventDefault() event.preventDefault()
const tempFilePath = await window.api.file.createTempFile('pasted_text.txt') const tempFilePath = await window.api.file.createTempFile('pasted_text.txt')
await window.api.file.write(tempFilePath, clipboardText) await window.api.file.write(tempFilePath, clipboardText)
const selectedFile = await window.api.file.get(tempFilePath) const selectedFile = await window.api.file.get(tempFilePath)
if (selectedFile) { if (selectedFile) {
setFiles((prevFiles) => [...prevFiles, selectedFile]) setFiles((prevFiles) => [...prevFiles, selectedFile])
if (setText && text) setText(text) // 保持输入框内容不变 if (setText && text) setText(text) // 保持输入框内容不变
if (resizeTextArea) setTimeout(() => resizeTextArea(), 50) if (resizeTextArea) setTimeout(() => resizeTextArea(), 50)
} }
return true return true
} }
// 短文本走默认粘贴行为,直接返回 // 短文本走默认粘贴行为,直接返回
return false return false
} }
// 2. 文件/图片粘贴(仅在无文本时处理) // 2. 文件/图片粘贴(仅在无文本时处理)
if (event.clipboardData?.files && event.clipboardData.files.length > 0) { if (event.clipboardData?.files && event.clipboardData.files.length > 0) {
event.preventDefault() event.preventDefault()
try { try {
for (const file of event.clipboardData.files) { for (const file of event.clipboardData.files) {
// 使用新的API获取文件路径 // 使用新的API获取文件路径
const filePath = window.api.file.getPathForFile(file) const filePath = window.api.file.getPathForFile(file)
// 如果没有路径,可能是剪贴板中的图像数据 // 如果没有路径,可能是剪贴板中的图像数据
if (!filePath) { if (!filePath) {
// 图像生成也支持图像编辑 // 图像生成也支持图像编辑
if (file.type.startsWith('image/') && (isVisionModel || isGenerateImageModel)) { if (file.type.startsWith('image/') && (isVisionModel || isGenerateImageModel)) {
const tempFilePath = await window.api.file.createTempFile(file.name) const tempFilePath = await window.api.file.createTempFile(file.name)
const arrayBuffer = await file.arrayBuffer() const arrayBuffer = await file.arrayBuffer()
const uint8Array = new Uint8Array(arrayBuffer) const uint8Array = new Uint8Array(arrayBuffer)
await window.api.file.write(tempFilePath, uint8Array) await window.api.file.write(tempFilePath, uint8Array)
const selectedFile = await window.api.file.get(tempFilePath) const selectedFile = await window.api.file.get(tempFilePath)
if (selectedFile) { if (selectedFile) {
setFiles((prevFiles) => [...prevFiles, selectedFile]) setFiles((prevFiles) => [...prevFiles, selectedFile])
break break
} }
} else { } else {
if (t) { if (t) {
window.message.info({ window.message.info({
key: 'file_not_supported', key: 'file_not_supported',
content: t('chat.input.file_not_supported') content: t('chat.input.file_not_supported')
}) })
} }
} }
continue continue
} }
// 有路径的情况 // 有路径的情况
if (supportExts.includes(getFileExtension(filePath))) { if (supportExts.includes(getFileExtension(filePath))) {
const selectedFile = await window.api.file.get(filePath) const selectedFile = await window.api.file.get(filePath)
if (selectedFile) { if (selectedFile) {
setFiles((prevFiles) => [...prevFiles, selectedFile]) setFiles((prevFiles) => [...prevFiles, selectedFile])
} }
} else { } else {
if (t) { if (t) {
window.message.info({ window.message.info({
key: 'file_not_supported', key: 'file_not_supported',
content: t('chat.input.file_not_supported') content: t('chat.input.file_not_supported')
}) })
} }
} }
} }
} catch (error) { } catch (error) {
Logger.error('[PasteService] onPaste:', error) Logger.error('[PasteService] onPaste:', error)
if (t) { if (t) {
window.message.error(t('chat.input.file_error')) window.message.error(t('chat.input.file_error'))
} }
} }
return true return true
} }
// 其他情况默认粘贴 // 其他情况默认粘贴
return false return false
} catch (error) { } catch (error) {
Logger.error('[PasteService] handlePaste error:', error) Logger.error('[PasteService] handlePaste error:', error)
return false return false
} }
} }
/** /**
* *
*/ */
export const setLastFocusedComponent = (component: ComponentType) => { export const setLastFocusedComponent = (component: ComponentType) => {
lastFocusedComponent = component lastFocusedComponent = component
} }
/** /**
* *
*/ */
export const getLastFocusedComponent = (): ComponentType => { export const getLastFocusedComponent = (): ComponentType => {
return lastFocusedComponent return lastFocusedComponent
} }
/** /**
* *
* *
*/ */
export const init = () => { export const init = () => {
if (isInitialized) return if (isInitialized) return
// 添加全局粘贴事件监听 // 添加全局粘贴事件监听
document.addEventListener('paste', async (event) => { document.addEventListener('paste', async (event) => {
await handleGlobalPaste(event) await handleGlobalPaste(event)
}) })
isInitialized = true isInitialized = true
Logger.info('[PasteService] Global paste handler initialized') Logger.info('[PasteService] Global paste handler initialized')
} }
/** /**
* *
*/ */
export const registerHandler = (component: ComponentType, handler: PasteHandler) => { export const registerHandler = (component: ComponentType, handler: PasteHandler) => {
if (!component) return if (!component) return
// Only log and update if the handler actually changes // Only log and update if the handler actually changes
if (!handlers[component] || handlers[component] !== handler) { if (!handlers[component] || handlers[component] !== handler) {
handlers[component] = handler handlers[component] = handler
} }
} }
/** /**
* *
*/ */
export const unregisterHandler = (component: ComponentType) => { export const unregisterHandler = (component: ComponentType) => {
if (!component || !handlers[component]) return if (!component || !handlers[component]) return
delete handlers[component] delete handlers[component]
} }
/** /**
* *
*/ */
const handleGlobalPaste = async (event: ClipboardEvent): Promise<boolean> => { const handleGlobalPaste = async (event: ClipboardEvent): Promise<boolean> => {
// 如果当前有活动元素且是输入区域,不执行全局处理 // 如果当前有活动元素且是输入区域,不执行全局处理
const activeElement = document.activeElement const activeElement = document.activeElement
if ( if (
activeElement && activeElement &&
(activeElement.tagName === 'INPUT' || (activeElement.tagName === 'INPUT' ||
activeElement.tagName === 'TEXTAREA' || activeElement.tagName === 'TEXTAREA' ||
activeElement.getAttribute('contenteditable') === 'true') activeElement.getAttribute('contenteditable') === 'true')
) { ) {
return false return false
} }
// 根据最后聚焦的组件调用相应处理程序 // 根据最后聚焦的组件调用相应处理程序
if (lastFocusedComponent && handlers[lastFocusedComponent]) { if (lastFocusedComponent && handlers[lastFocusedComponent]) {
const handler = handlers[lastFocusedComponent] const handler = handlers[lastFocusedComponent]
if (handler) { if (handler) {
return await handler(event) return await handler(event)
} }
} }
// 如果没有匹配的处理程序默认使用inputbar处理 // 如果没有匹配的处理程序默认使用inputbar处理
if (handlers.inputbar) { if (handlers.inputbar) {
const handler = handlers.inputbar const handler = handlers.inputbar
if (handler) { if (handler) {
return await handler(event) return await handler(event)
} }
} }
return false return false
} }
export default { export default {
handlePaste, handlePaste,
setLastFocusedComponent, setLastFocusedComponent,
getLastFocusedComponent, getLastFocusedComponent,
init, init,
registerHandler, registerHandler,
unregisterHandler unregisterHandler
} }