diff --git a/src/renderer/src/hooks/ocr/useOcrProvider.tsx b/src/renderer/src/hooks/ocr/useOcrProvider.tsx
index c0a650f78e..bb6efb8bef 100644
--- a/src/renderer/src/hooks/ocr/useOcrProvider.tsx
+++ b/src/renderer/src/hooks/ocr/useOcrProvider.tsx
@@ -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
- case 'system':
- return
- case 'paddleocr':
- return
- case 'ovocr':
- return
- }
- }
- return
- }
-
- return {
- providers,
- imageProvider,
- addProvider,
- removeProvider,
- setImageProviderId,
- getOcrProviderName,
- OcrProviderLogo
- }
-}
-
export const useOcrProvider = (id: string) => {
const { t } = useTranslation()
const dispatch = useDispatch()
diff --git a/src/renderer/src/hooks/ocr/useOcrProviders.ts b/src/renderer/src/hooks/ocr/useOcrProviders.ts
new file mode 100644
index 0000000000..552e0208a9
--- /dev/null
+++ b/src/renderer/src/hooks/ocr/useOcrProviders.ts
@@ -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
+ }
+}
diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx
index 66db685f68..0e3a809ea0 100644
--- a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx
+++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx
@@ -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'
diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx
index b34f7fa185..43de14d9f1 100644
--- a/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx
+++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx
@@ -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
+ case 'system':
+ return
+ case 'paddleocr':
+ return
+ case 'ovocr':
+ return
+ }
+ }
+ return
+}
+
export default OcrProviderSettings
diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx
index 77316e37d5..e99c164439 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/useOcrProvider'
+import { useOcrProviders } from '@renderer/hooks/ocr/useOcrProviders'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'