From ed8501961af73508119b95108da8b492c4a274a7 Mon Sep 17 00:00:00 2001 From: icarus Date: Mon, 20 Oct 2025 02:26:55 +0800 Subject: [PATCH] refactor(ocr): extract image provider logic to separate hook Move image provider related state and logic from useOcrProviders to new useOcrImageProvider hook Update all components to use the new hook for better separation of concerns --- src/renderer/src/hooks/ocr/useOcr.ts | 4 ++-- .../src/hooks/ocr/useOcrImageProvider.ts | 16 ++++++++++++++ src/renderer/src/hooks/ocr/useOcrProviders.ts | 22 +++++++++---------- .../DocProcessSettings/OcrImageSettings.tsx | 4 +++- .../DocProcessSettings/OcrSettings.tsx | 4 ++-- 5 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 src/renderer/src/hooks/ocr/useOcrImageProvider.ts diff --git a/src/renderer/src/hooks/ocr/useOcr.ts b/src/renderer/src/hooks/ocr/useOcr.ts index e9ab72de8d..f67249ca3c 100644 --- a/src/renderer/src/hooks/ocr/useOcr.ts +++ b/src/renderer/src/hooks/ocr/useOcr.ts @@ -6,13 +6,13 @@ import { formatErrorMessage } from '@renderer/utils/error' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' -import { useOcrProviders } from './useOcrProviders' +import { useOcrImageProvider } from './useOcrImageProvider' const logger = loggerService.withContext('useOcr') export const useOcr = () => { const { t } = useTranslation() - const { imageProvider } = useOcrProviders() + const { imageProvider } = useOcrImageProvider() const isProviderAvailable = useCallback( (provider: ImageOcrProvider | undefined): provider is ImageOcrProvider => { diff --git a/src/renderer/src/hooks/ocr/useOcrImageProvider.ts b/src/renderer/src/hooks/ocr/useOcrImageProvider.ts new file mode 100644 index 0000000000..5f312b3666 --- /dev/null +++ b/src/renderer/src/hooks/ocr/useOcrImageProvider.ts @@ -0,0 +1,16 @@ +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' + +export const useOcrImageProvider = () => { + const { providers, loading, error } = useOcrProviders() + const imageProviders: ImageOcrProvider[] = 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, setImageProviderId } +} diff --git a/src/renderer/src/hooks/ocr/useOcrProviders.ts b/src/renderer/src/hooks/ocr/useOcrProviders.ts index 552e0208a9..3b17b9d702 100644 --- a/src/renderer/src/hooks/ocr/useOcrProviders.ts +++ b/src/renderer/src/hooks/ocr/useOcrProviders.ts @@ -1,10 +1,10 @@ -import { usePreference } from '@data/hooks/usePreference' +import { useQuery } from '@data/hooks/useDataApi' import { loggerService } from '@logger' import { getBuiltinOcrProviderLabel } from '@renderer/i18n/label' -import { useAppSelector } from '@renderer/store' import { addOcrProvider, removeOcrProvider } from '@renderer/store/ocr' import type { OcrProvider } from '@renderer/types' -import { isBuiltinOcrProvider, isBuiltinOcrProviderId, isImageOcrProvider } from '@renderer/types' +import { isBuiltinOcrProvider, isBuiltinOcrProviderId } from '@renderer/types' +import { BUILTIN_OCR_PROVIDERS } from '@shared/config/ocr' import { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { useDispatch } from 'react-redux' @@ -12,13 +12,11 @@ import { useDispatch } from 'react-redux' const logger = loggerService.withContext('useOcrProviders') export const useOcrProviders = () => { - // TODO: migrate to useQuery - const providers = useAppSelector((state) => state.ocr.providers) - const imageProviders = providers.filter(isImageOcrProvider) - const [imageProviderId, setImageProviderId] = usePreference('ocr.settings.image_provider_id') - const imageProvider = useMemo(() => { - return imageProviders.find((p) => p.id === imageProviderId) - }, [imageProviderId, imageProviders]) + const { data: validProviderIds, loading, error } = useQuery('/ocr/providers') + const providers = useMemo( + () => BUILTIN_OCR_PROVIDERS.filter((p) => validProviderIds?.includes(p.id)), + [validProviderIds] + ) const dispatch = useDispatch() const { t } = useTranslation() @@ -62,10 +60,10 @@ export const useOcrProviders = () => { return { providers, - imageProvider, + loading, + error, addProvider, removeProvider, - setImageProviderId, getOcrProviderName } } diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx index 0e3a809ea0..2d162c71ae 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx @@ -2,6 +2,7 @@ import { Alert, Skeleton } from '@heroui/react' import { loggerService } from '@logger' import { ErrorTag } from '@renderer/components/Tags/ErrorTag' import { isMac, isWin } from '@renderer/config/constant' +import { useOcrImageProvider } from '@renderer/hooks/ocr/useOcrImageProvider' import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProviders' import type { ImageOcrProvider } from '@renderer/types' import { BuiltinOcrProviderIds, isImageOcrProvider } from '@renderer/types' @@ -17,7 +18,8 @@ const logger = loggerService.withContext('OcrImageSettings') const OcrImageSettings = () => { const { t } = useTranslation() - const { providers, imageProvider, getOcrProviderName, setImageProviderId } = useOcrProviders() + const { providers, getOcrProviderName } = useOcrProviders() + const { imageProvider, setImageProviderId } = useOcrImageProvider() const fetcher = useCallback(() => { return window.api.ocr.listProviders() }, []) diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx index e99c164439..51f95b34cd 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx @@ -1,6 +1,6 @@ import { ErrorBoundary } from '@renderer/components/ErrorBoundary' import { useTheme } from '@renderer/context/ThemeProvider' -import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProviders' +import { useOcrImageProvider } from '@renderer/hooks/ocr/useOcrImageProvider' import type { FC } from 'react' import { useTranslation } from 'react-i18next' @@ -21,7 +21,7 @@ import OcrProviderSettings from './OcrProviderSettings' const OcrSettings: FC = () => { const { t } = useTranslation() const { theme: themeMode } = useTheme() - const { imageProvider: provider } = useOcrProviders() + const { imageProvider: provider } = useOcrImageProvider() // const [activeTab, setActiveTab] = useState('image') // const provider = useMemo(() => { // switch (activeTab) {