mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 03:31:24 +08:00
fix: Update file API usage for Electron 35.2.2 and add translations f… (#6087)
* Fix: Update file API usage for Electron 35.2.2 and add translations for file error messages * 修复Electron 35.2.2中的文件API问题
This commit is contained in:
parent
77f3770835
commit
a6aea0c8c9
@ -2,7 +2,7 @@ import type { ExtractChunkData } from '@cherrystudio/embedjs-interfaces'
|
||||
import { electronAPI } from '@electron-toolkit/preload'
|
||||
import { IpcChannel } from '@shared/IpcChannel'
|
||||
import { FileType, KnowledgeBaseParams, KnowledgeItem, MCPServer, Shortcut, WebDavConfig } from '@types'
|
||||
import { contextBridge, ipcRenderer, OpenDialogOptions, shell } from 'electron'
|
||||
import { contextBridge, ipcRenderer, OpenDialogOptions, shell, webUtils } from 'electron'
|
||||
import { CreateDirectoryOptions } from 'webdav'
|
||||
|
||||
// Custom APIs for renderer
|
||||
@ -73,7 +73,8 @@ const api = {
|
||||
download: (url: string) => ipcRenderer.invoke(IpcChannel.File_Download, url),
|
||||
copy: (fileId: string, destPath: string) => ipcRenderer.invoke(IpcChannel.File_Copy, fileId, destPath),
|
||||
binaryImage: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_BinaryImage, fileId),
|
||||
base64File: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_Base64File, fileId)
|
||||
base64File: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_Base64File, fileId),
|
||||
getPathForFile: (file: File) => webUtils.getPathForFile(file)
|
||||
},
|
||||
fs: {
|
||||
read: (path: string) => ipcRenderer.invoke(IpcChannel.Fs_Read, path)
|
||||
|
||||
@ -163,6 +163,7 @@
|
||||
"input.estimated_tokens.tip": "Estimated tokens",
|
||||
"input.expand": "Expand",
|
||||
"input.file_not_supported": "Model does not support this file type",
|
||||
"input.file_error": "Error processing file",
|
||||
"input.generate_image": "Generate image",
|
||||
"input.generate_image_not_supported": "The model does not support generating images.",
|
||||
"input.knowledge_base": "Knowledge Base",
|
||||
|
||||
@ -163,6 +163,7 @@
|
||||
"input.estimated_tokens.tip": "推定トークン数",
|
||||
"input.expand": "展開",
|
||||
"input.file_not_supported": "モデルはこのファイルタイプをサポートしません",
|
||||
"input.file_error": "ファイル処理エラー",
|
||||
"input.generate_image": "画像を生成する",
|
||||
"input.generate_image_not_supported": "モデルは画像の生成をサポートしていません。",
|
||||
"input.knowledge_base": "ナレッジベース",
|
||||
|
||||
@ -163,6 +163,7 @@
|
||||
"input.estimated_tokens.tip": "Затраты токенов",
|
||||
"input.expand": "Развернуть",
|
||||
"input.file_not_supported": "Модель не поддерживает этот тип файла",
|
||||
"input.file_error": "Ошибка обработки файла",
|
||||
"input.generate_image": "Сгенерировать изображение",
|
||||
"input.generate_image_not_supported": "Модель не поддерживает генерацию изображений.",
|
||||
"input.knowledge_base": "База знаний",
|
||||
|
||||
@ -163,6 +163,7 @@
|
||||
"input.estimated_tokens.tip": "预估 token 数",
|
||||
"input.expand": "展开",
|
||||
"input.file_not_supported": "模型不支持此文件类型",
|
||||
"input.file_error": "文件处理出错",
|
||||
"input.generate_image": "生成图片",
|
||||
"input.generate_image_not_supported": "模型不支持生成图片",
|
||||
"input.knowledge_base": "知识库",
|
||||
|
||||
@ -163,6 +163,7 @@
|
||||
"input.estimated_tokens.tip": "預估 Token 數",
|
||||
"input.expand": "展開",
|
||||
"input.file_not_supported": "模型不支援此檔案類型",
|
||||
"input.file_error": "檔案處理錯誤",
|
||||
"input.generate_image": "生成圖片",
|
||||
"input.generate_image_not_supported": "模型不支援生成圖片",
|
||||
"input.knowledge_base": "知識庫",
|
||||
|
||||
@ -584,27 +584,33 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
||||
if (event.clipboardData?.files && event.clipboardData.files.length > 0) {
|
||||
event.preventDefault()
|
||||
for (const file of event.clipboardData.files) {
|
||||
if (file.path === '') {
|
||||
// 图像生成也支持图像编辑
|
||||
if (file.type.startsWith('image/') && (isVisionModel(model) || isGenerateImageModel(model))) {
|
||||
const tempFilePath = await window.api.file.create(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)
|
||||
selectedFile && setFiles((prevFiles) => [...prevFiles, selectedFile])
|
||||
break
|
||||
} else {
|
||||
window.message.info({
|
||||
key: 'file_not_supported',
|
||||
content: t('chat.input.file_not_supported')
|
||||
})
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 使用新的API获取文件路径
|
||||
const filePath = window.api.file.getPathForFile(file)
|
||||
|
||||
if (file.path) {
|
||||
if (supportExts.includes(getFileExtension(file.path))) {
|
||||
const selectedFile = await window.api.file.get(file.path)
|
||||
// 如果没有路径,可能是剪贴板中的图像数据
|
||||
if (!filePath) {
|
||||
// 图像生成也支持图像编辑
|
||||
if (file.type.startsWith('image/') && (isVisionModel(model) || isGenerateImageModel(model))) {
|
||||
const tempFilePath = await window.api.file.create(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)
|
||||
selectedFile && setFiles((prevFiles) => [...prevFiles, selectedFile])
|
||||
break
|
||||
} else {
|
||||
window.message.info({
|
||||
key: 'file_not_supported',
|
||||
content: t('chat.input.file_not_supported')
|
||||
})
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 有路径的情况
|
||||
if (supportExts.includes(getFileExtension(filePath))) {
|
||||
const selectedFile = await window.api.file.get(filePath)
|
||||
selectedFile && setFiles((prevFiles) => [...prevFiles, selectedFile])
|
||||
} else {
|
||||
window.message.info({
|
||||
@ -612,6 +618,9 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
||||
content: t('chat.input.file_not_supported')
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
Logger.error('[src/renderer/src/pages/home/Inputbar/Inputbar.tsx] onPaste:', error)
|
||||
window.message.error(t('chat.input.file_error'))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@ -3,14 +3,27 @@ import { FileType } from '@renderer/types'
|
||||
|
||||
export const getFilesFromDropEvent = async (e: React.DragEvent<HTMLDivElement>): Promise<FileType[]> => {
|
||||
if (e.dataTransfer.files.length > 0) {
|
||||
const results = await Promise.allSettled([...e.dataTransfer.files].map((file) => window.api.file.get(file.path)))
|
||||
// 使用新的API获取文件路径
|
||||
const filePromises = [...e.dataTransfer.files].map(async (file) => {
|
||||
try {
|
||||
// 使用新的webUtils.getPathForFile API获取文件路径
|
||||
const filePath = window.api.file.getPathForFile(file)
|
||||
if (filePath) {
|
||||
return window.api.file.get(filePath)
|
||||
}
|
||||
return null
|
||||
} catch (error) {
|
||||
Logger.error('[src/renderer/src/utils/input.ts] getFilesFromDropEvent - getPathForFile error:', error)
|
||||
return null
|
||||
}
|
||||
})
|
||||
|
||||
const results = await Promise.allSettled(filePromises)
|
||||
const list: FileType[] = []
|
||||
for (const result of results) {
|
||||
if (result.status === 'fulfilled') {
|
||||
if (result.value !== null) {
|
||||
list.push(result.value)
|
||||
}
|
||||
} else {
|
||||
if (result.status === 'fulfilled' && result.value !== null) {
|
||||
list.push(result.value)
|
||||
} else if (result.status === 'rejected') {
|
||||
Logger.error('[src/renderer/src/utils/input.ts] getFilesFromDropEvent:', result.reason)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user