diff --git a/src/renderer/src/hooks/ocr/useOcrImageProvider.ts b/src/renderer/src/hooks/ocr/useOcrImageProvider.ts index 002c0a711f..97709d56d6 100644 --- a/src/renderer/src/hooks/ocr/useOcrImageProvider.ts +++ b/src/renderer/src/hooks/ocr/useOcrImageProvider.ts @@ -1,16 +1,9 @@ import { usePreference } from '@data/hooks/usePreference' -import type { ImageOcrProvider } from '@renderer/types' -import { isImageOcrProvider } from '@renderer/types' -import { useMemo } from 'react' -import { useOcrProviders } from './useOcrProviders' +import { useOcrProvider } from './useOcrProvider' export const useOcrImageProvider = () => { - const { providers, loading, error } = useOcrProviders() - const imageProviders: ImageOcrProvider[] | undefined = providers?.filter((p) => isImageOcrProvider(p)) const [imageProviderId, setImageProviderId] = usePreference('ocr.settings.image_provider_id') - const imageProvider = useMemo(() => { - return imageProviders?.find((p) => p.id === imageProviderId) - }, [imageProviderId, imageProviders]) - return { imageProvider, loading, error, imageProviderId, setImageProviderId } + const { provider: imageProvider, mutating, loading, error, updateConfig } = useOcrProvider(imageProviderId) + return { imageProvider, loading, mutating, error, updateConfig, imageProviderId, setImageProviderId } } diff --git a/src/renderer/src/hooks/ocr/useOcrProvider.ts b/src/renderer/src/hooks/ocr/useOcrProvider.ts index 100ad7808e..d101dba61e 100644 --- a/src/renderer/src/hooks/ocr/useOcrProvider.ts +++ b/src/renderer/src/hooks/ocr/useOcrProvider.ts @@ -7,15 +7,16 @@ import { useTranslation } from 'react-i18next' // const logger = loggerService.withContext('useOcrProvider') -export const useOcrProvider = (id: string) => { +export const useOcrProvider = (id: string | null) => { const { t } = useTranslation() const path: ConcreteApiPaths = `/ocr/providers/${id}` - const { data, loading, error } = useQuery(path, undefined) + const { data, loading, error } = useQuery(path) const { mutate, loading: mutating } = useMutation('PATCH', path) const updateConfig = useCallback( async (update: Partial) => { + if (!id) return try { await mutate({ body: { id, config: update } }) } catch (e) { @@ -26,7 +27,8 @@ export const useOcrProvider = (id: string) => { ) return { - provider: data?.data, + /** undefined: loading; null: invalid, id is null */ + provider: id ? data?.data : null, loading, mutating, error, diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx index 43de14d9f1..2eab5f1203 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx @@ -7,11 +7,17 @@ import { ErrorBoundary } from '@renderer/components/ErrorBoundary' import { isMac, isWin } from '@renderer/config/constant' import { useTheme } from '@renderer/context/ThemeProvider' import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProviders' -import type { OcrProvider } from '@renderer/types' -import { isBuiltinOcrProvider, isOcrSystemProvider } from '@renderer/types' +import type { OcrProvider, OcrProviderConfig } from '@renderer/types' +import { + isBuiltinOcrProvider, + isOcrOVProvider, + isOcrPpocrProvider, + isOcrSystemProvider, + isOcrTesseractProvider +} from '@renderer/types' import { Divider } from 'antd' import { FileQuestionMarkIcon, MonitorIcon } from 'lucide-react' -import styled from 'styled-components' +import { useMemo } from 'react' import { SettingGroup, SettingTitle } from '..' import { OcrOVSettings } from './OcrOVSettings' @@ -22,34 +28,37 @@ import { OcrTesseractSettings } from './OcrTesseractSettings' // const logger = loggerService.withContext('OcrTesseractSettings') type Props = { - provider: OcrProvider | undefined + provider: OcrProvider | undefined | null + updateConfig: (config: Partial) => Promise } -const OcrProviderSettings = ({ provider }: Props) => { +const OcrProviderSettings = ({ provider, updateConfig }: Props) => { const { theme: themeMode } = useTheme() const { getOcrProviderName } = useOcrProviders() - if (!provider || (!isWin && !isMac && isOcrSystemProvider(provider))) { - return null - } - - const ProviderSettings = () => { + const settings = useMemo(() => { + if (!provider) return null if (isBuiltinOcrProvider(provider)) { - switch (provider.id) { - case 'tesseract': - return - case 'system': - return - case 'paddleocr': - return - case 'ovocr': - return - default: - return null + if (isOcrTesseractProvider(provider)) { + return } + if (isOcrSystemProvider(provider)) { + return + } + if (isOcrPpocrProvider(provider)) { + return + } + if (isOcrOVProvider(provider)) { + return + } + return null } else { throw new Error('Not supported OCR provider') } + }, [provider, updateConfig]) + + if (!provider || (!isWin && !isMac && isOcrSystemProvider(provider))) { + return null } return ( @@ -57,22 +66,15 @@ const OcrProviderSettings = ({ provider }: Props) => { - {getOcrProviderName(provider)} + {getOcrProviderName(provider)} - - - + {settings} ) } -const ProviderName = styled.span` - font-size: 14px; - font-weight: 500; -` - const OcrProviderLogo = ({ provider: p, size = 14 }: { provider: OcrProvider; size?: number }) => { if (isBuiltinOcrProvider(p)) { switch (p.id) { diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx index 51f95b34cd..69ada58565 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx @@ -21,7 +21,7 @@ import OcrProviderSettings from './OcrProviderSettings' const OcrSettings: FC = () => { const { t } = useTranslation() const { theme: themeMode } = useTheme() - const { imageProvider: provider } = useOcrImageProvider() + const { imageProvider: provider, updateConfig } = useOcrImageProvider() // const [activeTab, setActiveTab] = useState('image') // const provider = useMemo(() => { // switch (activeTab) { @@ -82,7 +82,7 @@ const OcrSettings: FC = () => { - + ) diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx index a152d24862..aee46ff1de 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx @@ -2,10 +2,9 @@ import { Flex } from '@cherrystudio/ui' import { InfoTooltip } from '@cherrystudio/ui' import CustomTag from '@renderer/components/Tags/CustomTag' -import { useOcrProvider } from '@renderer/hooks/ocr/useOcrProvider' import useTranslate from '@renderer/hooks/useTranslate' -import type { TesseractLangCode } from '@renderer/types' -import { BuiltinOcrProviderIdMap, isOcrTesseractProvider } from '@renderer/types' +import type { OcrProviderConfig, OcrTesseractConfig, OcrTesseractProvider, TesseractLangCode } from '@renderer/types' +import { objectEntries } from '@renderer/types' import { TESSERACT_LANG_MAP } from '@shared/config/ocr' import { Select } from 'antd' import { useCallback, useMemo, useState } from 'react' @@ -15,15 +14,16 @@ import { SettingRow, SettingRowTitle } from '..' // const logger = loggerService.withContext('OcrTesseractSettings') -export const OcrTesseractSettings = () => { +export const OcrTesseractSettings = ({ + provider, + updateConfig +}: { + provider: OcrTesseractProvider + updateConfig: (config: Partial) => Promise +}) => { const { t } = useTranslation() - const { provider, config, updateConfig } = useOcrProvider(BuiltinOcrProviderIdMap.tesseract) - if (!isOcrTesseractProvider(provider)) { - throw new Error('Not tesseract provider.') - } - - const [langs, setLangs] = useState>>(config?.langs ?? {}) + const [langs, setLangs] = useState(provider?.config.langs) const { translateLanguages } = useTranslate() const options = useMemo( @@ -37,14 +37,12 @@ export const OcrTesseractSettings = () => { [translateLanguages] ) - // TODO: type safe objectKeys - const value = useMemo( - () => - Object.entries(langs) - .filter(([, enabled]) => enabled) - .map(([lang]) => lang) as TesseractLangCode[], - [langs] - ) + const selectedLangs = useMemo(() => { + if (!langs) return + return objectEntries(langs) + .filter(([, enabled]) => enabled) + .map(([lang]) => lang) as TesseractLangCode[] + }, [langs]) const onChange = useCallback((values: TesseractLangCode[]) => { setLangs(() => { @@ -69,11 +67,11 @@ export const OcrTesseractSettings = () => { -
+