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
This commit is contained in:
icarus 2025-10-20 02:26:55 +08:00
parent 78000816e5
commit ed8501961a
5 changed files with 33 additions and 17 deletions

View File

@ -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 => {

View File

@ -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 }
}

View File

@ -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
}
}

View File

@ -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()
}, [])

View File

@ -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<Tab>('image')
// const provider = useMemo(() => {
// switch (activeTab) {