import { useState, useCallback, useEffect, useRef } from 'react' import ThemeProvider from '@/components/ThemeProvider' import TabVisibilityProvider from '@/contexts/TabVisibilityProvider' import ApiKeyAlert from '@/components/ApiKeyAlert' import StatusIndicator from '@/components/status/StatusIndicator' import { healthCheckInterval } from '@/lib/constants' import { useBackendState, useAuthStore } from '@/stores/state' import { useSettingsStore } from '@/stores/settings' import { getAuthStatus } from '@/api/lightrag' import SiteHeader from '@/features/SiteHeader' import { InvalidApiKeyError, RequireApiKeError } from '@/api/lightrag' import GraphViewer from '@/features/GraphViewer' import DocumentManager from '@/features/DocumentManager' import RetrievalTesting from '@/features/RetrievalTesting' import ApiSite from '@/features/ApiSite' import { Tabs, TabsContent } from '@/components/ui/Tabs' function App() { const message = useBackendState.use.message() const enableHealthCheck = useSettingsStore.use.enableHealthCheck() const currentTab = useSettingsStore.use.currentTab() const [apiKeyAlertOpen, setApiKeyAlertOpen] = useState(false) const versionCheckRef = useRef(false); // Prevent duplicate calls in Vite dev mode const handleApiKeyAlertOpenChange = useCallback((open: boolean) => { setApiKeyAlertOpen(open) if (!open) { useBackendState.getState().clear() } }, []) // Health check - can be disabled useEffect(() => { // Only execute if health check is enabled and ApiKeyAlert is closed if (!enableHealthCheck || apiKeyAlertOpen) return; // Health check function const performHealthCheck = async () => { await useBackendState.getState().check(); }; // Set interval for periodic execution const interval = setInterval(performHealthCheck, healthCheckInterval * 1000); return () => clearInterval(interval); }, [enableHealthCheck, apiKeyAlertOpen]); // Version check - independent and executed only once useEffect(() => { const checkVersion = async () => { // Prevent duplicate calls in Vite dev mode if (versionCheckRef.current) return; versionCheckRef.current = true; // Check if version info was already obtained in login page const versionCheckedFromLogin = sessionStorage.getItem('VERSION_CHECKED_FROM_LOGIN') === 'true'; if (versionCheckedFromLogin) return; // Get version info const token = localStorage.getItem('LIGHTRAG-API-TOKEN'); if (!token) return; try { const status = await getAuthStatus(); if (status.core_version || status.api_version) { const isGuestMode = status.auth_mode === 'disabled' || useAuthStore.getState().isGuestMode; // Update version info while maintaining login state useAuthStore.getState().login( token, isGuestMode, status.core_version, status.api_version ); // Set flag to indicate version info has been checked sessionStorage.setItem('VERSION_CHECKED_FROM_LOGIN', 'true'); } } catch (error) { console.error('Failed to get version info:', error); } }; // Execute version check checkVersion(); }, []); // Empty dependency array ensures it only runs once on mount const handleTabChange = useCallback( (tab: string) => useSettingsStore.getState().setCurrentTab(tab as any), [] ) useEffect(() => { if (message) { if (message.includes(InvalidApiKeyError) || message.includes(RequireApiKeError)) { setApiKeyAlertOpen(true) } } }, [message]) return (
{enableHealthCheck && }
) } export default App