mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-29 23:12:38 +08:00
feat(翻译): 添加文件读取功能并改进错误处理
添加对文本文件的支持并优化文件处理流程 改进错误提示信息,包括文件过大和读取失败的场景
This commit is contained in:
parent
c04cd3b71e
commit
9d31ccb5ea
@ -3737,6 +3737,13 @@
|
||||
"exchange": {
|
||||
"label": "交换源语言与目标语言"
|
||||
},
|
||||
"files": {
|
||||
"error": {
|
||||
"too_large": "文件过大 (0 ~ 5MB)",
|
||||
"unknown": "读取文件内容失败"
|
||||
},
|
||||
"reading": "读取文件内容中..."
|
||||
},
|
||||
"history": {
|
||||
"clear": "清空历史",
|
||||
"clear_description": "清空历史将删除所有翻译历史记录,是否继续?",
|
||||
|
||||
@ -20,6 +20,7 @@ import { setTranslating as setTranslatingAction } from '@renderer/store/runtime'
|
||||
import { setTranslatedContent as setTranslatedContentAction } from '@renderer/store/translate'
|
||||
import {
|
||||
type AutoDetectionMethod,
|
||||
isImageFile,
|
||||
isSupportedOcrFile,
|
||||
type Model,
|
||||
type TranslateHistory,
|
||||
@ -33,6 +34,7 @@ import {
|
||||
detectLanguage,
|
||||
determineTargetLanguage
|
||||
} from '@renderer/utils/translate'
|
||||
import { imageExts, MB, textExts } from '@shared/config/constant'
|
||||
import { Button, Flex, FloatButton, Popover, Tooltip, Typography } from 'antd'
|
||||
import TextArea, { TextAreaRef } from 'antd/es/input/TextArea'
|
||||
import { isEmpty, throttle } from 'lodash'
|
||||
@ -57,7 +59,7 @@ const TranslatePage: FC = () => {
|
||||
const { translateModel, setTranslateModel } = useDefaultModel()
|
||||
const { prompt, getLanguageByLangcode } = useTranslate()
|
||||
const { shikiMarkdownIt } = useCodeStyle()
|
||||
const { onSelectFile, selecting } = useFiles()
|
||||
const { onSelectFile, selecting } = useFiles({ extensions: [...imageExts, ...textExts] })
|
||||
const { ocr } = useOcr()
|
||||
|
||||
// states
|
||||
@ -442,19 +444,46 @@ const TranslatePage: FC = () => {
|
||||
if (!file) {
|
||||
return
|
||||
}
|
||||
if (isSupportedOcrFile(file)) {
|
||||
window.message.loading({ content: t('ocr.processing'), key: 'translate_ocr_processing', duration: 0 })
|
||||
const ocrResult = await ocr(file)
|
||||
setText(ocrResult.text)
|
||||
|
||||
// extensible
|
||||
const shouldOCR = isImageFile(file)
|
||||
|
||||
if (shouldOCR) {
|
||||
if (isSupportedOcrFile(file)) {
|
||||
window.message.loading({ content: t('ocr.processing'), key: 'translate_ocr_processing', duration: 0 })
|
||||
try {
|
||||
const ocrResult = await ocr(file)
|
||||
setText(ocrResult.text)
|
||||
} catch (e) {
|
||||
logger.error('Failed to ocr.', e as Error)
|
||||
window.message.error(t('ocr.error.unknown') + ': ' + formatErrorMessage(e))
|
||||
}
|
||||
} else {
|
||||
// @ts-expect-error all situations covered. just for robustness
|
||||
window.message.error(t('ocr.file.not_supported', { type: file.type }))
|
||||
}
|
||||
} else {
|
||||
window.message.error(t('ocr.file.not_supported', { type: file.type }))
|
||||
// the threshold may be too large
|
||||
if (file.size > 5 * MB) {
|
||||
window.message.error(t('translate.files.error.too_large'))
|
||||
} else {
|
||||
window.message.loading({ content: t('translate.files.reading'), key: 'translate_files_reading', duration: 0 })
|
||||
try {
|
||||
const result = await window.api.fs.readText(file.path)
|
||||
setText(result)
|
||||
} catch (e) {
|
||||
logger.error('Failed to read text file.', e as Error)
|
||||
window.message.error(t('translate.files.error.unknown') + ': ' + formatErrorMessage(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('Failed to select file and ocr.', e as Error)
|
||||
window.message.error(t('ocr.error.unknown') + ' ' + formatErrorMessage(e))
|
||||
logger.error('Unknown error when selecting file.', e as Error)
|
||||
window.message.error(t('translate.files.error.unknown') + ': ' + formatErrorMessage(e))
|
||||
} finally {
|
||||
setIsProcessing(false)
|
||||
window.message.destroy('translate_ocr_processing')
|
||||
window.message.destroy('translate_files_reading')
|
||||
}
|
||||
}, [ocr, onSelectFile, selecting, t])
|
||||
|
||||
|
||||
@ -57,6 +57,15 @@ export function removeSpecialCharactersForFileName(str: string): string {
|
||||
.trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件是否为支持的类型。
|
||||
* 支持的文件类型包括:
|
||||
* 1. 文件扩展名在supportExts集合中的文件
|
||||
* 2. 文本文件
|
||||
* @param {string} filePath 文件路径
|
||||
* @param {Set<string>} supportExts 支持的文件扩展名集合
|
||||
* @returns {Promise<boolean>} 如果文件类型受支持返回true,否则返回false
|
||||
*/
|
||||
export async function isSupportedFile(filePath: string, supportExts: Set<string>): Promise<boolean> {
|
||||
try {
|
||||
if (supportExts.has(getFileExtension(filePath))) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user