From 1c337c689867829447f3952813b03cc07cf1c9b9 Mon Sep 17 00:00:00 2001 From: Pleasurecruise <3196812536@qq.com> Date: Mon, 26 May 2025 16:26:20 +0800 Subject: [PATCH] feat: add auto-detect language option and improve translation logic --- src/preload/index.ts | 3 +- src/renderer/src/config/translate.ts | 23 +++++++++++-- src/renderer/src/i18n/locales/en-us.json | 1 + src/renderer/src/i18n/locales/ja-jp.json | 1 + src/renderer/src/i18n/locales/ru-ru.json | 1 + src/renderer/src/i18n/locales/zh-cn.json | 1 + src/renderer/src/i18n/locales/zh-tw.json | 1 + .../src/pages/translate/TranslatePage.tsx | 32 +++++++++++++++++-- 8 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/preload/index.ts b/src/preload/index.ts index 70aae1b18e..e31efbcb2c 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -74,7 +74,8 @@ const api = { selectFolder: () => ipcRenderer.invoke(IpcChannel.File_SelectFolder), saveImage: (name: string, data: string) => ipcRenderer.invoke(IpcChannel.File_SaveImage, name, data), base64Image: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_Base64Image, fileId), - download: (url: string, isUseContentType?: boolean) => ipcRenderer.invoke(IpcChannel.File_Download, url, isUseContentType), + download: (url: string, isUseContentType?: boolean) => + ipcRenderer.invoke(IpcChannel.File_Download, url, isUseContentType), 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), diff --git a/src/renderer/src/config/translate.ts b/src/renderer/src/config/translate.ts index fa35acea1a..3aebd51b60 100644 --- a/src/renderer/src/config/translate.ts +++ b/src/renderer/src/config/translate.ts @@ -1,6 +1,18 @@ import i18n from '@renderer/i18n' -export const TranslateLanguageOptions = [ +type LanguageOption = { + value: string + label: string + emoji: string + style?: React.CSSProperties +} + +export const TranslateLanguageOptions: LanguageOption[] = [ + { + value: 'auto-detect', + label: i18n.t('languages.auto-detect'), + emoji: '🌐' + }, { value: 'english', label: i18n.t('languages.english'), @@ -63,12 +75,17 @@ export const TranslateLanguageOptions = [ } ] -export const translateLanguageOptions = (): typeof TranslateLanguageOptions => { +export const translateLanguageOptions = (): LanguageOption[] => { return TranslateLanguageOptions.map((option) => { return { value: option.value, label: i18n.t(`languages.${option.value}`), - emoji: option.emoji + emoji: option.emoji, + style: { + display: 'flex', + alignItems: 'center', + gap: '8px' + } } }) } diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index cf3efe3dca..2f5361c29b 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -558,6 +558,7 @@ "dimensions_size_too_large": "The embedding dimension cannot exceed the model's context limit ({{max_context}})." }, "languages": { + "auto-detect": "Auto Detect", "arabic": "Arabic", "chinese": "Chinese", "chinese-traditional": "Traditional Chinese", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index d2a7c50ca9..0362fe44ae 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -558,6 +558,7 @@ "dimensions_size_too_large": "埋め込み次元はモデルのコンテキスト制限({{max_context}})を超えてはなりません。" }, "languages": { + "auto-detect": "自動検出", "arabic": "アラビア語", "chinese": "中国語", "chinese-traditional": "繁体字中国語", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 3d7d925dce..3aac474179 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -558,6 +558,7 @@ "dimensions_size_too_large": "Размерность вложения не может превышать ограничение контекста модели ({{max_context}})" }, "languages": { + "auto-detect": "Автоопределение", "arabic": "Арабский", "chinese": "Китайский", "chinese-traditional": "Китайский традиционный", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index bd842b58c4..88f1c53b46 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -558,6 +558,7 @@ "urls": "网址" }, "languages": { + "auto-detect": "自动检测", "arabic": "阿拉伯文", "chinese": "简体中文", "chinese-traditional": "繁体中文", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 9003d65fb0..05f599317d 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -558,6 +558,7 @@ "dimensions_size_too_large": "嵌入維度不能超過模型上下文限制({{max_context}})" }, "languages": { + "auto-detect": "自動偵測", "arabic": "阿拉伯文", "chinese": "簡體中文", "chinese-traditional": "繁體中文", diff --git a/src/renderer/src/pages/translate/TranslatePage.tsx b/src/renderer/src/pages/translate/TranslatePage.tsx index 0a29238eb7..698734a76b 100644 --- a/src/renderer/src/pages/translate/TranslatePage.tsx +++ b/src/renderer/src/pages/translate/TranslatePage.tsx @@ -5,6 +5,7 @@ import { isLocalAi } from '@renderer/config/env' import { translateLanguageOptions } from '@renderer/config/translate' import db from '@renderer/databases' import { useDefaultModel } from '@renderer/hooks/useAssistant' +import i18n from '@renderer/i18n' import { fetchTranslate } from '@renderer/services/ApiService' import { getDefaultTranslateAssistant } from '@renderer/services/AssistantService' import type { Assistant, TranslateHistory } from '@renderer/types' @@ -83,7 +84,20 @@ const TranslatePage: FC = () => { return } - const assistant: Assistant = getDefaultTranslateAssistant(targetLanguage, text) + let assistant: Assistant + + if (targetLanguage === 'auto-detect') { + const currentLanguage = i18n.language + const targetLang = currentLanguage === 'en' ? 'Chinese' : 'English' + + assistant = { + ...getDefaultTranslateAssistant(currentLanguage === 'en' ? 'chinese' : 'english', text), + name: 'Auto Translator', + prompt: `You are a translator. If input is in ${targetLang}, translate to ${currentLanguage === 'en' ? 'English' : 'Chinese'}. Otherwise translate to ${targetLang}. Output translation only. Text: ${text}` + } + } else { + assistant = getDefaultTranslateAssistant(targetLanguage, text) + } setLoading(true) let translatedText = '' @@ -342,8 +356,20 @@ const TranslatePage: FC = () => { db.settings.put({ id: 'translate:target:language', value }) }} optionRender={(option) => ( - - + + {option.data.emoji} {option.label}