From 044bf3c2aa56174374c7fc1f871a4f0ec7710f5d Mon Sep 17 00:00:00 2001 From: James Brunton Date: Tue, 11 Nov 2025 11:54:43 +0000 Subject: [PATCH] Improve loading speed of desktop app (#4865) # Description of Changes Improve loading speed of desktop app by loading a default config until the backend has spawned. --- frontend/package.json | 1 + .../public/locales/en-GB/translation.json | 4 +- frontend/src/core/components/AppProviders.tsx | 13 +- .../tools/shared/OperationButton.tsx | 22 ++- .../src/core/contexts/AppConfigContext.tsx | 51 +++-- .../hooks/tools/shared/useToolOperation.ts | 7 + frontend/src/core/hooks/useBackendHealth.ts | 12 ++ .../core/services/backendReadinessGuard.ts | 7 + frontend/src/core/types/backendHealth.ts | 10 + .../src/desktop/components/AppProviders.tsx | 8 + .../desktop/components/DesktopConfigSync.tsx | 23 +++ .../src/desktop/config/defaultAppConfig.ts | 10 + .../src/desktop/constants/backendErrors.ts | 20 ++ .../src/desktop/hooks/useBackendHealth.ts | 91 ++------- .../src/desktop/hooks/useEndpointConfig.ts | 176 +++++++++++++++--- .../src/desktop/services/apiClientSetup.ts | 44 +++++ .../desktop/services/backendHealthMonitor.ts | 125 +++++++++++++ .../desktop/services/backendReadinessGuard.ts | 35 ++++ .../desktop/services/tauriBackendService.ts | 81 ++++++-- frontend/src/global.d.ts | 12 ++ .../proprietary/components/AppProviders.tsx | 7 +- 21 files changed, 622 insertions(+), 137 deletions(-) create mode 100644 frontend/src/core/hooks/useBackendHealth.ts create mode 100644 frontend/src/core/services/backendReadinessGuard.ts create mode 100644 frontend/src/core/types/backendHealth.ts create mode 100644 frontend/src/desktop/components/DesktopConfigSync.tsx create mode 100644 frontend/src/desktop/config/defaultAppConfig.ts create mode 100644 frontend/src/desktop/constants/backendErrors.ts create mode 100644 frontend/src/desktop/services/apiClientSetup.ts create mode 100644 frontend/src/desktop/services/backendHealthMonitor.ts create mode 100644 frontend/src/desktop/services/backendReadinessGuard.ts diff --git a/frontend/package.json b/frontend/package.json index 7b9480ece..b0989a0df 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -66,6 +66,7 @@ "preview": "vite preview", "tauri-dev": "tauri dev --no-watch", "tauri-build": "tauri build", + "tauri-clean": "cd src-tauri && cargo clean && cd .. && rm -rf dist build", "typecheck": "npm run typecheck:proprietary", "typecheck:core": "tsc --noEmit --project tsconfig.core.json", "typecheck:proprietary": "tsc --noEmit --project tsconfig.proprietary.json", diff --git a/frontend/public/locales/en-GB/translation.json b/frontend/public/locales/en-GB/translation.json index 626f16f44..81e2f0c64 100644 --- a/frontend/public/locales/en-GB/translation.json +++ b/frontend/public/locales/en-GB/translation.json @@ -5137,6 +5137,8 @@ "backendHealth": { "checking": "Checking backend status...", "online": "Backend Online", - "offline": "Backend Offline" + "offline": "Backend Offline", + "starting": "Backend starting up...", + "wait": "Please wait for the backend to finish launching and try again." } } diff --git a/frontend/src/core/components/AppProviders.tsx b/frontend/src/core/components/AppProviders.tsx index 2108b3550..3bf96f29f 100644 --- a/frontend/src/core/components/AppProviders.tsx +++ b/frontend/src/core/components/AppProviders.tsx @@ -8,7 +8,7 @@ import { ToolWorkflowProvider } from "@app/contexts/ToolWorkflowContext"; import { HotkeyProvider } from "@app/contexts/HotkeyContext"; import { SidebarProvider } from "@app/contexts/SidebarContext"; import { PreferencesProvider } from "@app/contexts/PreferencesContext"; -import { AppConfigProvider, AppConfigRetryOptions } from "@app/contexts/AppConfigContext"; +import { AppConfigProvider, AppConfigProviderProps, AppConfigRetryOptions } from "@app/contexts/AppConfigContext"; import { RightRailProvider } from "@app/contexts/RightRailContext"; import { ViewerProvider } from "@app/contexts/ViewerContext"; import { SignatureProvider } from "@app/contexts/SignatureContext"; @@ -31,22 +31,29 @@ function AppInitializer() { return null; } +// Avoid requirement to have props which are required in app providers anyway +type AppConfigProviderOverrides = Omit; + export interface AppProvidersProps { children: ReactNode; appConfigRetryOptions?: AppConfigRetryOptions; + appConfigProviderProps?: Partial; } /** * Core application providers * Contains all providers needed for the core */ -export function AppProviders({ children, appConfigRetryOptions }: AppProvidersProps) { +export function AppProviders({ children, appConfigRetryOptions, appConfigProviderProps }: AppProvidersProps) { return ( - + diff --git a/frontend/src/core/components/tools/shared/OperationButton.tsx b/frontend/src/core/components/tools/shared/OperationButton.tsx index 48e4d5a6a..656c4d195 100644 --- a/frontend/src/core/components/tools/shared/OperationButton.tsx +++ b/frontend/src/core/components/tools/shared/OperationButton.tsx @@ -1,5 +1,7 @@ import { Button } from '@mantine/core'; import { useTranslation } from 'react-i18next'; +import { Tooltip } from '@app/components/shared/Tooltip'; +import { useBackendHealth } from '@app/hooks/useBackendHealth'; export interface OperationButtonProps { onClick?: () => void; @@ -31,8 +33,14 @@ const OperationButton = ({ 'data-tour': dataTour }: OperationButtonProps) => { const { t } = useTranslation(); + const { isHealthy, message: backendMessage } = useBackendHealth(); + const blockedByBackend = !isHealthy; + const combinedDisabled = disabled || blockedByBackend; + const tooltipLabel = blockedByBackend + ? (backendMessage ?? t('backendHealth.checking', 'Checking backend status...')) + : null; - return ( + const button = (