mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-31 16:49:07 +08:00
refactor(ocr): improve ocr provider handling and error states
- Add ListOcrProvidersQuery type for better type safety - Update useOcrProviders hook to accept query params and handle undefined data - Improve error handling and loading states in OcrImageSettings component - Memoize filtered image providers for better performance
This commit is contained in:
parent
389dfc08f6
commit
a2e628d7e9
@ -4,6 +4,7 @@ import type {
|
||||
CreateOcrProviderRequest,
|
||||
CreateOcrProviderResponse,
|
||||
GetOcrProviderResponse,
|
||||
ListOcrProvidersQuery,
|
||||
ListOcrProvidersResponse,
|
||||
OcrProviderId,
|
||||
PatchOcrProviderRequest,
|
||||
@ -360,7 +361,7 @@ export interface ApiSchemas {
|
||||
|
||||
'/ocr/providers': {
|
||||
GET: {
|
||||
query: { registered?: boolean }
|
||||
query: ListOcrProvidersQuery
|
||||
response: ListOcrProvidersResponse
|
||||
}
|
||||
POST: {
|
||||
|
||||
@ -7,10 +7,10 @@ import { useOcrProviders } from './useOcrProviders'
|
||||
|
||||
export const useOcrImageProvider = () => {
|
||||
const { providers, loading, error } = useOcrProviders()
|
||||
const imageProviders: ImageOcrProvider[] = providers.filter((p) => isImageOcrProvider(p))
|
||||
const imageProviders: ImageOcrProvider[] | undefined = providers?.filter((p) => isImageOcrProvider(p))
|
||||
const [imageProviderId, setImageProviderId] = usePreference('ocr.settings.image_provider_id')
|
||||
const imageProvider = useMemo(() => {
|
||||
return imageProviders.find((p) => p.id === imageProviderId)
|
||||
return imageProviders?.find((p) => p.id === imageProviderId)
|
||||
}, [imageProviderId, imageProviders])
|
||||
return { imageProvider, loading, error, setImageProviderId }
|
||||
return { imageProvider, loading, error, imageProviderId, setImageProviderId }
|
||||
}
|
||||
|
||||
@ -1,23 +1,17 @@
|
||||
import { useQuery } from '@data/hooks/useDataApi'
|
||||
import { getBuiltinOcrProviderLabel } from '@renderer/i18n/label'
|
||||
import type { OcrProvider } from '@renderer/types'
|
||||
import type { ListOcrProvidersQuery, OcrProvider } from '@renderer/types'
|
||||
import { isBuiltinOcrProvider } from '@renderer/types'
|
||||
import { BUILTIN_OCR_PROVIDERS } from '@shared/config/ocr'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
export const useOcrProviders = () => {
|
||||
const { data: validProviderIds, loading, error } = useQuery('/ocr/providers')
|
||||
const providers = useMemo(
|
||||
() => BUILTIN_OCR_PROVIDERS.filter((p) => validProviderIds?.includes(p.id)),
|
||||
[validProviderIds]
|
||||
)
|
||||
export const useOcrProviders = (query?: ListOcrProvidersQuery) => {
|
||||
const { data, loading, error } = useQuery('/ocr/providers', { query })
|
||||
|
||||
const getOcrProviderName = (p: OcrProvider) => {
|
||||
return isBuiltinOcrProvider(p) ? getBuiltinOcrProviderLabel(p.id) : p.name
|
||||
}
|
||||
|
||||
return {
|
||||
providers,
|
||||
providers: data?.data,
|
||||
loading,
|
||||
error,
|
||||
getOcrProviderName
|
||||
|
||||
@ -17,10 +17,10 @@ const logger = loggerService.withContext('OcrImageSettings')
|
||||
|
||||
const OcrImageSettings = () => {
|
||||
const { t } = useTranslation()
|
||||
const { providers, loading, error, getOcrProviderName } = useOcrProviders()
|
||||
const { imageProvider, setImageProviderId } = useOcrImageProvider()
|
||||
const { providers, loading, error, getOcrProviderName } = useOcrProviders({ registered: true })
|
||||
const { imageProvider, setImageProviderId, imageProviderId } = useOcrImageProvider()
|
||||
|
||||
const imageProviders = providers.filter((p) => isImageOcrProvider(p))
|
||||
const imageProviders = useMemo(() => providers?.filter((p) => isImageOcrProvider(p)) ?? [], [providers])
|
||||
|
||||
const setImageProvider = (id: string) => {
|
||||
const provider = imageProviders.find((p) => p.id === id)
|
||||
@ -43,29 +43,48 @@ const OcrImageSettings = () => {
|
||||
|
||||
const isSystem = imageProvider?.id === BuiltinOcrProviderIdMap.system
|
||||
|
||||
if (!imageProvider) {
|
||||
return <Alert color="danger" title={t('ocr.error.provider.not_found')} />
|
||||
}
|
||||
const content = useMemo(() => {
|
||||
if (loading) {
|
||||
return <Skeleton className="h-full w-50" />
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<Alert
|
||||
color="danger"
|
||||
title={t('ocr.provider.get.error.failed', { provider: imageProviderId })}
|
||||
description={getErrorMessage(error)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (!imageProvider) {
|
||||
return <Alert color="danger" title={t('ocr.error.provider.not_found')} />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{!platformSupport && isSystem && <ErrorTag message={t('settings.tool.ocr.error.not_system')} />}
|
||||
{!loading && !error && (
|
||||
<Select
|
||||
value={imageProvider.id}
|
||||
className="w-50"
|
||||
onChange={(id: string) => setImageProvider(id)}
|
||||
options={options}
|
||||
/>
|
||||
)}
|
||||
{!loading && error && (
|
||||
<Alert color="danger" title={t('ocr.error.provider.get_providers')} description={getErrorMessage(error)} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingRow>
|
||||
<SettingRowTitle>{t('settings.tool.ocr.image_provider')}</SettingRowTitle>
|
||||
<div className="flex items-center gap-2 self-stretch">
|
||||
{!platformSupport && isSystem && <ErrorTag message={t('settings.tool.ocr.error.not_system')} />}
|
||||
{loading && <Skeleton className="h-full w-50" />}
|
||||
{!loading && !error && (
|
||||
<Select
|
||||
value={imageProvider.id}
|
||||
className="w-50"
|
||||
onChange={(id: string) => setImageProvider(id)}
|
||||
options={options}
|
||||
/>
|
||||
)}
|
||||
{!loading && error && (
|
||||
<Alert color="danger" title={t('ocr.error.provider.get_providers')} description={getErrorMessage(error)} />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2 self-stretch">{content}</div>
|
||||
</SettingRow>
|
||||
</>
|
||||
)
|
||||
|
||||
@ -268,6 +268,8 @@ const TimestampExtendShape = {
|
||||
|
||||
const DbOcrProviderSchema = OcrProviderSchema.extend(TimestampExtendShape)
|
||||
|
||||
export type ListOcrProvidersQuery = { registered?: boolean }
|
||||
|
||||
export const ListOcrProvidersResponseSchema = z.object({
|
||||
data: z.array(DbOcrProviderSchema)
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user