From a2e628d7e96d7e4923c2933fa9584ad1d6b4d5d6 Mon Sep 17 00:00:00 2001 From: icarus Date: Mon, 20 Oct 2025 08:07:32 +0800 Subject: [PATCH] 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 --- packages/shared/data/api/apiSchemas.ts | 3 +- .../src/hooks/ocr/useOcrImageProvider.ts | 6 +- src/renderer/src/hooks/ocr/useOcrProviders.ts | 14 ++--- .../DocProcessSettings/OcrImageSettings.tsx | 61 ++++++++++++------- src/renderer/src/types/ocr.ts | 2 + 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/packages/shared/data/api/apiSchemas.ts b/packages/shared/data/api/apiSchemas.ts index 6089c24b96..7fdb417e22 100644 --- a/packages/shared/data/api/apiSchemas.ts +++ b/packages/shared/data/api/apiSchemas.ts @@ -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: { diff --git a/src/renderer/src/hooks/ocr/useOcrImageProvider.ts b/src/renderer/src/hooks/ocr/useOcrImageProvider.ts index 5f312b3666..002c0a711f 100644 --- a/src/renderer/src/hooks/ocr/useOcrImageProvider.ts +++ b/src/renderer/src/hooks/ocr/useOcrImageProvider.ts @@ -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 } } diff --git a/src/renderer/src/hooks/ocr/useOcrProviders.ts b/src/renderer/src/hooks/ocr/useOcrProviders.ts index 717c1ea565..7b5abe052b 100644 --- a/src/renderer/src/hooks/ocr/useOcrProviders.ts +++ b/src/renderer/src/hooks/ocr/useOcrProviders.ts @@ -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 diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx index 831496ad45..2a2852d786 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx @@ -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 - } + const content = useMemo(() => { + if (loading) { + return + } + + if (error) { + return ( + + ) + } + + if (!imageProvider) { + return + } + + return ( + <> + {!platformSupport && isSystem && } + {!loading && !error && ( + setImageProvider(id)} - options={options} - /> - )} - {!loading && error && ( - - )} - +
{content}
) diff --git a/src/renderer/src/types/ocr.ts b/src/renderer/src/types/ocr.ts index 0f6e9d1a86..e8108d7135 100644 --- a/src/renderer/src/types/ocr.ts +++ b/src/renderer/src/types/ocr.ts @@ -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) })