import { Box, Flex, Grid, Portal } from '@chakra-ui/react'; import { useLogger } from 'app/logging/useLogger'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { PartialAppConfig } from 'app/types/invokeai'; import ImageUploader from 'common/components/ImageUploader'; import Loading from 'common/components/Loading/Loading'; import GalleryDrawer from 'features/gallery/components/GalleryPanel'; import Lightbox from 'features/lightbox/components/Lightbox'; import SiteHeader from 'features/system/components/SiteHeader'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { useIsApplicationReady } from 'features/system/hooks/useIsApplicationReady'; import { configChanged } from 'features/system/store/configSlice'; import { languageSelector } from 'features/system/store/systemSelectors'; import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton'; import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons'; import InvokeTabs from 'features/ui/components/InvokeTabs'; import ParametersDrawer from 'features/ui/components/ParametersDrawer'; import { AnimatePresence, motion } from 'framer-motion'; import i18n from 'i18n'; import { ReactNode, memo, useCallback, useEffect, useState } from 'react'; import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants'; import GlobalHotkeys from './GlobalHotkeys'; import Toaster from './Toaster'; const DEFAULT_CONFIG = {}; interface Props { config?: PartialAppConfig; headerComponent?: ReactNode; setIsReady?: (isReady: boolean) => void; } const App = ({ config = DEFAULT_CONFIG, headerComponent, setIsReady, }: Props) => { const language = useAppSelector(languageSelector); const log = useLogger(); const isLightboxEnabled = useFeatureStatus('lightbox').isFeatureEnabled; const isApplicationReady = useIsApplicationReady(); const [loadingOverridden, setLoadingOverridden] = useState(false); const dispatch = useAppDispatch(); useEffect(() => { i18n.changeLanguage(language); }, [language]); useEffect(() => { log.info({ namespace: 'App', data: config }, 'Received config'); dispatch(configChanged(config)); }, [dispatch, config, log]); const handleOverrideClicked = useCallback(() => { setLoadingOverridden(true); }, []); useEffect(() => { if (isApplicationReady && setIsReady) { setIsReady(true); } return () => { setIsReady && setIsReady(false); }; }, [isApplicationReady, setIsReady]); return ( <> {isLightboxEnabled && } {headerComponent || } {!isApplicationReady && !loadingOverridden && ( )} ); }; export default memo(App);