mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 18:50:56 +08:00
refactor(ocr): move provider logo logic to component and consolidate hooks
Move OcrProviderLogo implementation from useOcrProviders hook to the component file Extract common OCR provider logic into a separate useOcrProviders hook Clean up and reorganize related imports and exports
This commit is contained in:
parent
7658b1e79f
commit
beb44eea61
@ -1,98 +1,15 @@
|
||||
import { Avatar } from '@cherrystudio/ui'
|
||||
import { usePreference } from '@data/hooks/usePreference'
|
||||
import { loggerService } from '@logger'
|
||||
import IntelLogo from '@renderer/assets/images/providers/intel.png'
|
||||
import PaddleocrLogo from '@renderer/assets/images/providers/paddleocr.png'
|
||||
import TesseractLogo from '@renderer/assets/images/providers/Tesseract.js.png'
|
||||
import { getBuiltinOcrProviderLabel } from '@renderer/i18n/label'
|
||||
import { useAppSelector } from '@renderer/store'
|
||||
import { addOcrProvider, removeOcrProvider, updateOcrProviderConfig } from '@renderer/store/ocr'
|
||||
import type { OcrProvider, OcrProviderConfig } from '@renderer/types'
|
||||
import { isBuiltinOcrProvider, isBuiltinOcrProviderId, isImageOcrProvider } from '@renderer/types'
|
||||
import { updateOcrProviderConfig } from '@renderer/store/ocr'
|
||||
import type { OcrProviderConfig } from '@renderer/types'
|
||||
import { isBuiltinOcrProviderId } from '@renderer/types'
|
||||
import { BUILTIN_OCR_PROVIDERS_MAP } from '@shared/config/ocr'
|
||||
import { FileQuestionMarkIcon, MonitorIcon } from 'lucide-react'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useDispatch } from 'react-redux'
|
||||
|
||||
import { useOcrProviders } from './useOcrProviders'
|
||||
|
||||
const logger = loggerService.withContext('useOcrProvider')
|
||||
|
||||
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 dispatch = useDispatch()
|
||||
const { t } = useTranslation()
|
||||
|
||||
/**
|
||||
* 添加一个新的OCR服务提供者
|
||||
* @param provider - OCR提供者对象,包含id和其他配置信息
|
||||
* @throws {Error} 当尝试添加一个已存在ID的提供者时抛出错误
|
||||
*/
|
||||
const addProvider = useCallback(
|
||||
(provider: OcrProvider) => {
|
||||
if (providers.some((p) => p.id === provider.id)) {
|
||||
const msg = `Provider with id ${provider.id} already exists`
|
||||
logger.error(msg)
|
||||
window.toast.error(t('ocr.error.provider.existing'))
|
||||
throw new Error(msg)
|
||||
}
|
||||
dispatch(addOcrProvider(provider))
|
||||
},
|
||||
[dispatch, providers, t]
|
||||
)
|
||||
|
||||
/**
|
||||
* 移除一个OCR服务提供者
|
||||
* @param id - 要移除的OCR提供者ID
|
||||
* @throws {Error} 当尝试移除一个内置提供商时抛出错误
|
||||
*/
|
||||
const removeProvider = (id: string) => {
|
||||
if (isBuiltinOcrProviderId(id)) {
|
||||
const msg = `Cannot remove builtin provider ${id}`
|
||||
logger.error(msg)
|
||||
window.toast.error(t('ocr.error.provider.cannot_remove_builtin'))
|
||||
throw new Error(msg)
|
||||
}
|
||||
|
||||
dispatch(removeOcrProvider(id))
|
||||
}
|
||||
|
||||
const getOcrProviderName = (p: OcrProvider) => {
|
||||
return isBuiltinOcrProvider(p) ? getBuiltinOcrProviderLabel(p.id) : p.name
|
||||
}
|
||||
|
||||
const OcrProviderLogo = ({ provider: p, size = 14 }: { provider: OcrProvider; size?: number }) => {
|
||||
if (isBuiltinOcrProvider(p)) {
|
||||
switch (p.id) {
|
||||
case 'tesseract':
|
||||
return <Avatar src={TesseractLogo} style={{ width: size, height: size }} />
|
||||
case 'system':
|
||||
return <MonitorIcon size={size} />
|
||||
case 'paddleocr':
|
||||
return <Avatar src={PaddleocrLogo} style={{ width: size, height: size }} />
|
||||
case 'ovocr':
|
||||
return <Avatar src={IntelLogo} style={{ width: size, height: size }} />
|
||||
}
|
||||
}
|
||||
return <FileQuestionMarkIcon size={size} />
|
||||
}
|
||||
|
||||
return {
|
||||
providers,
|
||||
imageProvider,
|
||||
addProvider,
|
||||
removeProvider,
|
||||
setImageProviderId,
|
||||
getOcrProviderName,
|
||||
OcrProviderLogo
|
||||
}
|
||||
}
|
||||
|
||||
export const useOcrProvider = (id: string) => {
|
||||
const { t } = useTranslation()
|
||||
const dispatch = useDispatch()
|
||||
|
||||
71
src/renderer/src/hooks/ocr/useOcrProviders.ts
Normal file
71
src/renderer/src/hooks/ocr/useOcrProviders.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import { usePreference } from '@data/hooks/usePreference'
|
||||
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 { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
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 dispatch = useDispatch()
|
||||
const { t } = useTranslation()
|
||||
|
||||
/**
|
||||
* 添加一个新的OCR服务提供者
|
||||
* @param provider - OCR提供者对象,包含id和其他配置信息
|
||||
* @throws {Error} 当尝试添加一个已存在ID的提供者时抛出错误
|
||||
*/
|
||||
const addProvider = useCallback(
|
||||
(provider: OcrProvider) => {
|
||||
if (providers.some((p) => p.id === provider.id)) {
|
||||
const msg = `Provider with id ${provider.id} already exists`
|
||||
logger.error(msg)
|
||||
window.toast.error(t('ocr.error.provider.existing'))
|
||||
throw new Error(msg)
|
||||
}
|
||||
dispatch(addOcrProvider(provider))
|
||||
},
|
||||
[dispatch, providers, t]
|
||||
)
|
||||
|
||||
/**
|
||||
* 移除一个OCR服务提供者
|
||||
* @param id - 要移除的OCR提供者ID
|
||||
* @throws {Error} 当尝试移除一个内置提供商时抛出错误
|
||||
*/
|
||||
const removeProvider = (id: string) => {
|
||||
if (isBuiltinOcrProviderId(id)) {
|
||||
const msg = `Cannot remove builtin provider ${id}`
|
||||
logger.error(msg)
|
||||
window.toast.error(t('ocr.error.provider.cannot_remove_builtin'))
|
||||
throw new Error(msg)
|
||||
}
|
||||
|
||||
dispatch(removeOcrProvider(id))
|
||||
}
|
||||
|
||||
const getOcrProviderName = (p: OcrProvider) => {
|
||||
return isBuiltinOcrProvider(p) ? getBuiltinOcrProviderLabel(p.id) : p.name
|
||||
}
|
||||
|
||||
return {
|
||||
providers,
|
||||
imageProvider,
|
||||
addProvider,
|
||||
removeProvider,
|
||||
setImageProviderId,
|
||||
getOcrProviderName
|
||||
}
|
||||
}
|
||||
@ -2,7 +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 { useOcrProviders } from '@renderer/hooks/ocr/useOcrProvider'
|
||||
import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProviders'
|
||||
import type { ImageOcrProvider } from '@renderer/types'
|
||||
import { BuiltinOcrProviderIds, isImageOcrProvider } from '@renderer/types'
|
||||
import { getErrorMessage } from '@renderer/utils'
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
// import { loggerService } from '@logger'
|
||||
import { Flex } from '@cherrystudio/ui'
|
||||
import { Avatar, Flex } from '@cherrystudio/ui'
|
||||
import IntelLogo from '@renderer/assets/images/providers/intel.png'
|
||||
import PaddleocrLogo from '@renderer/assets/images/providers/paddleocr.png'
|
||||
import TesseractLogo from '@renderer/assets/images/providers/Tesseract.js.png'
|
||||
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/useOcrProvider'
|
||||
import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProviders'
|
||||
import type { OcrProvider } from '@renderer/types'
|
||||
import { isBuiltinOcrProvider, isOcrSystemProvider } from '@renderer/types'
|
||||
import { Divider } from 'antd'
|
||||
import { FileQuestionMarkIcon, MonitorIcon } from 'lucide-react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { SettingGroup, SettingTitle } from '..'
|
||||
@ -23,7 +27,7 @@ type Props = {
|
||||
|
||||
const OcrProviderSettings = ({ provider }: Props) => {
|
||||
const { theme: themeMode } = useTheme()
|
||||
const { OcrProviderLogo, getOcrProviderName } = useOcrProviders()
|
||||
const { getOcrProviderName } = useOcrProviders()
|
||||
|
||||
if (!provider || (!isWin && !isMac && isOcrSystemProvider(provider))) {
|
||||
return null
|
||||
@ -69,4 +73,20 @@ const ProviderName = styled.span`
|
||||
font-weight: 500;
|
||||
`
|
||||
|
||||
const OcrProviderLogo = ({ provider: p, size = 14 }: { provider: OcrProvider; size?: number }) => {
|
||||
if (isBuiltinOcrProvider(p)) {
|
||||
switch (p.id) {
|
||||
case 'tesseract':
|
||||
return <Avatar src={TesseractLogo} style={{ width: size, height: size }} />
|
||||
case 'system':
|
||||
return <MonitorIcon size={size} />
|
||||
case 'paddleocr':
|
||||
return <Avatar src={PaddleocrLogo} style={{ width: size, height: size }} />
|
||||
case 'ovocr':
|
||||
return <Avatar src={IntelLogo} style={{ width: size, height: size }} />
|
||||
}
|
||||
}
|
||||
return <FileQuestionMarkIcon size={size} />
|
||||
}
|
||||
|
||||
export default OcrProviderSettings
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ErrorBoundary } from '@renderer/components/ErrorBoundary'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProvider'
|
||||
import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProviders'
|
||||
import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user