mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-08 22:39:36 +08:00
refactor(ocr): improve type safety and config handling in useOcrProvider
- Replace dynamic provider lookup with type-safe registry pattern - Add separate config management for each provider type - Remove unused imports and simplify provider fallback logic
This commit is contained in:
parent
94ed39ab27
commit
a34426d431
@ -1,35 +1,106 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { updateOcrProviderConfig } from '@renderer/store/ocr'
|
import type {
|
||||||
import type { OcrProviderConfig } from '@renderer/types'
|
BuiltinOcrProviderId,
|
||||||
|
OcrOvConfig,
|
||||||
|
OcrOvProvider,
|
||||||
|
OcrPpocrConfig,
|
||||||
|
OcrPpocrProvider,
|
||||||
|
OcrSystemConfig,
|
||||||
|
OcrSystemProvider,
|
||||||
|
OcrTesseractConfig,
|
||||||
|
OcrTesseractProvider
|
||||||
|
} from '@renderer/types'
|
||||||
import { BUILTIN_OCR_PROVIDERS_MAP } from '@shared/config/ocr'
|
import { BUILTIN_OCR_PROVIDERS_MAP } from '@shared/config/ocr'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { merge } from 'lodash'
|
||||||
import { useDispatch } from 'react-redux'
|
import { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import { useOcrProviders } from './useOcrProviders'
|
|
||||||
|
|
||||||
const logger = loggerService.withContext('useOcrProvider')
|
const logger = loggerService.withContext('useOcrProvider')
|
||||||
|
|
||||||
export const useOcrProvider = (id: string) => {
|
const PROVIDER_REGISTRY = {
|
||||||
const { t } = useTranslation()
|
ovocr: null as unknown as OcrOvProvider,
|
||||||
const dispatch = useDispatch()
|
paddleocr: null as unknown as OcrPpocrProvider,
|
||||||
const { providers } = useOcrProviders()
|
system: null as unknown as OcrSystemProvider,
|
||||||
let provider = providers.find((p) => p.id === id)
|
tesseract: null as unknown as OcrTesseractProvider
|
||||||
|
}
|
||||||
|
|
||||||
// safely fallback
|
const CONFIG_REGISTRY = {
|
||||||
if (!provider) {
|
ovocr: null as unknown as OcrOvConfig,
|
||||||
logger.error(`Ocr Provider ${id} not found`)
|
paddleocr: null as unknown as OcrPpocrConfig,
|
||||||
logger.warn(`Fallback to tesseract`)
|
system: null as unknown as OcrSystemConfig,
|
||||||
window.toast.error(t('ocr.error.provider.not_found'))
|
tesseract: null as unknown as OcrTesseractConfig
|
||||||
window.toast.warning(t('ocr.warning.provider.fallback', { name: 'Tesseract' }))
|
} as const
|
||||||
provider = BUILTIN_OCR_PROVIDERS_MAP.tesseract
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateConfig = (update: Partial<OcrProviderConfig>) => {
|
type ProviderMap = typeof PROVIDER_REGISTRY
|
||||||
dispatch(updateOcrProviderConfig({ id: provider.id, update }))
|
|
||||||
}
|
type ConfigMap = typeof CONFIG_REGISTRY
|
||||||
|
|
||||||
|
type TProvider<T extends BuiltinOcrProviderId> = ProviderMap[T]
|
||||||
|
|
||||||
|
type TConfig<T extends BuiltinOcrProviderId> = ConfigMap[T]
|
||||||
|
|
||||||
|
type UseOcrProviderReturn<T extends BuiltinOcrProviderId> = {
|
||||||
|
provider: TProvider<T>
|
||||||
|
config: TConfig<T>
|
||||||
|
updateConfig: (update: Partial<TConfig<T>>) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useOcrProvider = <T extends BuiltinOcrProviderId>(id: T): UseOcrProviderReturn<T> => {
|
||||||
|
const provider = useMemo(() => {
|
||||||
|
switch (id) {
|
||||||
|
case 'ovocr':
|
||||||
|
return BUILTIN_OCR_PROVIDERS_MAP.ovocr
|
||||||
|
case 'paddleocr':
|
||||||
|
return BUILTIN_OCR_PROVIDERS_MAP.paddleocr
|
||||||
|
case 'system':
|
||||||
|
return BUILTIN_OCR_PROVIDERS_MAP.system
|
||||||
|
case 'tesseract':
|
||||||
|
return BUILTIN_OCR_PROVIDERS_MAP.tesseract
|
||||||
|
}
|
||||||
|
}, [id])
|
||||||
|
const [ovConfig, setOvConfig] = usePreference('ocr.provider.config.ovocr')
|
||||||
|
const [ppConfig, setPpConfig] = usePreference('ocr.provider.config.paddleocr')
|
||||||
|
const [sysConfig, setSysConfig] = usePreference('ocr.provider.config.system')
|
||||||
|
const [tesConfig, setTesConfig] = usePreference('ocr.provider.config.tesseract')
|
||||||
|
|
||||||
|
const config = useMemo(() => {
|
||||||
|
switch (id) {
|
||||||
|
case 'ovocr':
|
||||||
|
return ovConfig
|
||||||
|
case 'paddleocr':
|
||||||
|
return ppConfig
|
||||||
|
case 'system':
|
||||||
|
return sysConfig
|
||||||
|
case 'tesseract':
|
||||||
|
return tesConfig
|
||||||
|
}
|
||||||
|
}, [id, ovConfig, ppConfig, sysConfig, tesConfig])
|
||||||
|
|
||||||
|
const updateConfig = useCallback(
|
||||||
|
(update: Partial<TConfig<T>>) => {
|
||||||
|
switch (id) {
|
||||||
|
case 'ovocr':
|
||||||
|
setOvConfig(merge({}, ovConfig, update))
|
||||||
|
break
|
||||||
|
case 'paddleocr':
|
||||||
|
setPpConfig(merge({}, ppConfig, update))
|
||||||
|
break
|
||||||
|
case 'system':
|
||||||
|
setSysConfig(merge({}, sysConfig, update))
|
||||||
|
break
|
||||||
|
case 'tesseract':
|
||||||
|
setTesConfig(merge({}, tesConfig, update))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
logger.warn(`Unsupported OCR provider id: ${id}`)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[id, ovConfig, ppConfig, setOvConfig, setPpConfig, setSysConfig, setTesConfig, sysConfig, tesConfig]
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
provider,
|
provider,
|
||||||
|
config,
|
||||||
updateConfig
|
updateConfig
|
||||||
}
|
} as UseOcrProviderReturn<T>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
import { useQuery } from '@data/hooks/useDataApi'
|
import { useQuery } from '@data/hooks/useDataApi'
|
||||||
import { loggerService } from '@logger'
|
|
||||||
import { getBuiltinOcrProviderLabel } from '@renderer/i18n/label'
|
import { getBuiltinOcrProviderLabel } from '@renderer/i18n/label'
|
||||||
import type { OcrProvider } from '@renderer/types'
|
import type { OcrProvider } from '@renderer/types'
|
||||||
import { isBuiltinOcrProvider } from '@renderer/types'
|
import { isBuiltinOcrProvider } from '@renderer/types'
|
||||||
import { BUILTIN_OCR_PROVIDERS } from '@shared/config/ocr'
|
import { BUILTIN_OCR_PROVIDERS } from '@shared/config/ocr'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
const logger = loggerService.withContext('useOcrProviders')
|
|
||||||
|
|
||||||
export const useOcrProviders = () => {
|
export const useOcrProviders = () => {
|
||||||
const { data: validProviderIds, loading, error } = useQuery('/ocr/providers')
|
const { data: validProviderIds, loading, error } = useQuery('/ocr/providers')
|
||||||
const providers = useMemo(
|
const providers = useMemo(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user