From dbfece3590a92e207e3a46a4f3813c44ab827152 Mon Sep 17 00:00:00 2001 From: icarus Date: Tue, 14 Oct 2025 22:03:21 +0800 Subject: [PATCH] refactor(translate): move auto detection method to preferences Move auto detection method configuration from local state to preference store Remove unused auto detection types from renderer types Add zod schema for auto detection method validation --- .../data/preference/preferenceSchemas.ts | 3 ++ .../shared/data/preference/preferenceTypes.ts | 8 +++++ .../src/pages/translate/TranslatePage.tsx | 31 +------------------ .../src/pages/translate/TranslateSettings.tsx | 9 ++---- src/renderer/src/types/index.ts | 12 ------- 5 files changed, 15 insertions(+), 48 deletions(-) diff --git a/packages/shared/data/preference/preferenceSchemas.ts b/packages/shared/data/preference/preferenceSchemas.ts index a9615a828d..90283f64f3 100644 --- a/packages/shared/data/preference/preferenceSchemas.ts +++ b/packages/shared/data/preference/preferenceSchemas.ts @@ -397,6 +397,8 @@ export interface PreferenceSchemas { 'topic.tab.show_time': boolean // redux/translate/settings 'translate.settings.auto_copy': boolean + // indexedDB/translate + 'translate.settings.auto_detection_method': PreferenceTypes.AutoDetectionMethod // redux/settings/customCss 'ui.custom_css': string // redux/settings/navbarPosition @@ -657,6 +659,7 @@ export const DefaultPreferences: PreferenceSchemas = { 'topic.tab.show': true, 'topic.tab.show_time': false, 'translate.settings.auto_copy': false, + 'translate.settings.auto_detection_method': 'franc', 'ui.custom_css': '', 'ui.navbar.position': 'top', 'ui.sidebar.icons.invisible': [], diff --git a/packages/shared/data/preference/preferenceTypes.ts b/packages/shared/data/preference/preferenceTypes.ts index a02e57cbcd..d0c990032f 100644 --- a/packages/shared/data/preference/preferenceTypes.ts +++ b/packages/shared/data/preference/preferenceTypes.ts @@ -1,3 +1,5 @@ +import * as z from 'zod' + import type { PreferenceSchemas } from './preferenceSchemas' export type PreferenceDefaultScopeType = PreferenceSchemas['default'] @@ -85,3 +87,9 @@ export type ChatMessageNavigationMode = 'none' | 'buttons' | 'anchor' export type MultiModelMessageStyle = 'horizontal' | 'vertical' | 'fold' | 'grid' export type MultiModelGridPopoverTrigger = 'hover' | 'click' + +const AutoDetectionMethodSchema = z.enum(['franc', 'llm', 'auto']) +export type AutoDetectionMethod = z.infer +export const isAutoDetectionMethod = (method: string): method is AutoDetectionMethod => { + return AutoDetectionMethodSchema.safeParse(method).success +} diff --git a/src/renderer/src/pages/translate/TranslatePage.tsx b/src/renderer/src/pages/translate/TranslatePage.tsx index 3174c47d7b..53f12ae9cc 100644 --- a/src/renderer/src/pages/translate/TranslatePage.tsx +++ b/src/renderer/src/pages/translate/TranslatePage.tsx @@ -22,13 +22,7 @@ import { estimateTextTokens } from '@renderer/services/TokenService' import { saveTranslateHistory, translateText } from '@renderer/services/TranslateService' // import { setTranslateAbortKey, setTranslating as setTranslatingAction } from '@renderer/store/runtime' import type { FileMetadata, SupportedOcrFile } from '@renderer/types' -import { - type AutoDetectionMethod, - isSupportedOcrFile, - type Model, - type TranslateHistory, - type TranslateLanguage -} from '@renderer/types' +import { isSupportedOcrFile, type Model, type TranslateHistory, type TranslateLanguage } from '@renderer/types' import { getFileExtension, isTextFile, runAsyncFunction } from '@renderer/utils' import { abortCompletion } from '@renderer/utils/abortController' import { isAbortError } from '@renderer/utils/error' @@ -91,7 +85,6 @@ const TranslatePage: FC = () => { const [detectedLanguage, setDetectedLanguage] = useState(null) const [sourceLanguage, setSourceLanguage] = useState(_sourceLanguage) const [targetLanguage, setTargetLanguage] = useState(_targetLanguage) - const [autoDetectionMethod, setAutoDetectionMethod] = useState('franc') const [isProcessing, setIsProcessing] = useState(false) // ref @@ -374,29 +367,9 @@ const TranslatePage: FC = () => { const markdownSetting = await db.settings.get({ id: 'translate:markdown:enabled' }) setEnableMarkdown(markdownSetting ? markdownSetting.value : false) - - const autoDetectionMethodSetting = await db.settings.get({ id: 'translate:detect:method' }) - - if (autoDetectionMethodSetting) { - setAutoDetectionMethod(autoDetectionMethodSetting.value) - } else { - setAutoDetectionMethod('franc') - db.settings.put({ id: 'translate:detect:method', value: 'franc' }) - } }) }, [getLanguageByLangcode]) - // 控制设置同步 - const updateAutoDetectionMethod = async (method: AutoDetectionMethod) => { - try { - await db.settings.put({ id: 'translate:detect:method', value: method }) - setAutoDetectionMethod(method) - } catch (e) { - logger.error('Failed to update auto detection method setting.', e as Error) - window.toast.error(t('translate.error.detect.update_setting') + formatErrorMessage(e)) - } - } - // 控制Enter触发翻译 const onKeyDown = (e: React.KeyboardEvent) => { const isEnterPressed = e.key === 'Enter' @@ -802,8 +775,6 @@ const TranslatePage: FC = () => { bidirectionalPair={bidirectionalPair} setBidirectionalPair={setBidirectionalPair} translateModel={translateModel} - autoDetectionMethod={autoDetectionMethod} - setAutoDetectionMethod={updateAutoDetectionMethod} /> ) diff --git a/src/renderer/src/pages/translate/TranslateSettings.tsx b/src/renderer/src/pages/translate/TranslateSettings.tsx index 8b1a29a9ef..912232c693 100644 --- a/src/renderer/src/pages/translate/TranslateSettings.tsx +++ b/src/renderer/src/pages/translate/TranslateSettings.tsx @@ -3,7 +3,7 @@ import { usePreference } from '@data/hooks/usePreference' import LanguageSelect from '@renderer/components/LanguageSelect' import db from '@renderer/databases' import useTranslate from '@renderer/hooks/useTranslate' -import type { AutoDetectionMethod, Model, TranslateLanguage } from '@renderer/types' +import type { Model, TranslateLanguage } from '@renderer/types' import { Modal, Radio, Space } from 'antd' import type { FC } from 'react' import { memo, useEffect, useState } from 'react' @@ -24,8 +24,6 @@ const TranslateSettings: FC<{ bidirectionalPair: [TranslateLanguage, TranslateLanguage] setBidirectionalPair: (value: [TranslateLanguage, TranslateLanguage]) => void translateModel: Model | undefined - autoDetectionMethod: AutoDetectionMethod - setAutoDetectionMethod: (method: AutoDetectionMethod) => void }> = ({ visible, onClose, @@ -36,14 +34,13 @@ const TranslateSettings: FC<{ enableMarkdown, setEnableMarkdown, bidirectionalPair, - setBidirectionalPair, - autoDetectionMethod, - setAutoDetectionMethod + setBidirectionalPair }) => { const { t } = useTranslation() const [localPair, setLocalPair] = useState<[TranslateLanguage, TranslateLanguage]>(bidirectionalPair) const { getLanguageByLangcode } = useTranslate() const [autoCopy, setAutoCopy] = usePreference('translate.settings.auto_copy') + const [autoDetectionMethod, setAutoDetectionMethod] = usePreference('translate.settings.auto_detection_method') useEffect(() => { setLocalPair(bidirectionalPair) diff --git a/src/renderer/src/types/index.ts b/src/renderer/src/types/index.ts index d0540a69b2..caacb44ebb 100644 --- a/src/renderer/src/types/index.ts +++ b/src/renderer/src/types/index.ts @@ -507,18 +507,6 @@ export type CustomTranslateLanguage = { emoji: string } -export const AutoDetectionMethods = { - franc: 'franc', - llm: 'llm', - auto: 'auto' -} as const - -export type AutoDetectionMethod = keyof typeof AutoDetectionMethods - -export const isAutoDetectionMethod = (method: string): method is AutoDetectionMethod => { - return Object.hasOwn(AutoDetectionMethods, method) -} - // by fullex @ data refactor // export type SidebarIcon = // | 'assistants'