feat(ui): rename main app components

This commit is contained in:
psychedelicious 2023-04-28 14:27:17 +10:00
parent de574eb4d9
commit d582949488
3 changed files with 168 additions and 168 deletions

View File

@ -1,70 +1,126 @@
import React, { lazy, memo, PropsWithChildren, useEffect } from 'react'; import ImageUploader from 'common/components/ImageUploader';
import { Provider } from 'react-redux'; import Console from 'features/system/components/Console';
import { PersistGate } from 'redux-persist/integration/react'; import ProgressBar from 'features/system/components/ProgressBar';
import { buildMiddleware, store } from 'app/store/store'; import SiteHeader from 'features/system/components/SiteHeader';
import { persistor } from '../store/persistor'; import InvokeTabs from 'features/ui/components/InvokeTabs';
import { OpenAPI } from 'services/api';
import '@fontsource/inter/100.css';
import '@fontsource/inter/200.css';
import '@fontsource/inter/300.css';
import '@fontsource/inter/400.css';
import '@fontsource/inter/500.css';
import '@fontsource/inter/600.css';
import '@fontsource/inter/700.css';
import '@fontsource/inter/800.css';
import '@fontsource/inter/900.css';
import Loading from '../../common/components/Loading/Loading'; import useToastWatcher from 'features/system/hooks/useToastWatcher';
import { addMiddleware, resetMiddlewares } from 'redux-dynamic-middlewares';
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
import { Box, Flex, Grid, Portal, useColorMode } from '@chakra-ui/react';
import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel';
import Lightbox from 'features/lightbox/components/Lightbox';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import {
memo,
PropsWithChildren,
useCallback,
useEffect,
useState,
} from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import Loading from 'common/components/Loading/Loading';
import { useIsApplicationReady } from 'features/system/hooks/useIsApplicationReady';
import { PartialAppConfig } from 'app/types/invokeai'; import { PartialAppConfig } from 'app/types/invokeai';
import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys';
import '../../i18n'; import { configChanged } from 'features/system/store/configSlice';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
const InvokeAIUI = lazy(() => import('./InvokeAIUI'));
const ThemeLocaleProvider = lazy(() => import('./ThemeLocaleProvider'));
interface Props extends PropsWithChildren { interface Props extends PropsWithChildren {
apiUrl?: string;
token?: string;
config?: PartialAppConfig; config?: PartialAppConfig;
} }
const App = ({ apiUrl, token, config, children }: Props) => { const App = ({ config = {}, children }: Props) => {
useToastWatcher();
useGlobalHotkeys();
const currentTheme = useAppSelector((state) => state.ui.currentTheme);
const isLightboxEnabled = useFeatureStatus('lightbox').isFeatureEnabled;
const isApplicationReady = useIsApplicationReady();
const [loadingOverridden, setLoadingOverridden] = useState(false);
const { setColorMode } = useColorMode();
const dispatch = useAppDispatch();
useEffect(() => { useEffect(() => {
// configure API client token console.log('Received config: ', config);
if (token) { dispatch(configChanged(config));
OpenAPI.TOKEN = token; }, [dispatch, config]);
}
// configure API client base url useEffect(() => {
if (apiUrl) { setColorMode(['light'].includes(currentTheme) ? 'light' : 'dark');
OpenAPI.BASE = apiUrl; }, [setColorMode, currentTheme]);
}
// reset dynamically added middlewares const handleOverrideClicked = useCallback(() => {
resetMiddlewares(); setLoadingOverridden(true);
}, []);
// TODO: at this point, after resetting the middleware, we really ought to clean up the socket
// stuff by calling `dispatch(socketReset())`. but we cannot dispatch from here as we are
// outside the provider. it's not needed until there is the possibility that we will change
// the `apiUrl`/`token` dynamically.
// rebuild socket middleware with token and apiUrl
addMiddleware(buildMiddleware());
}, [apiUrl, token]);
return ( return (
<React.StrictMode> <Grid w="100vw" h="100vh" position="relative">
<Provider store={store}> {isLightboxEnabled && <Lightbox />}
<PersistGate loading={<Loading />} persistor={persistor}> <ImageUploader>
<React.Suspense fallback={<Loading />}> <ProgressBar />
<ThemeLocaleProvider> <Grid
<InvokeAIUI config={config}>{children}</InvokeAIUI> gap={4}
</ThemeLocaleProvider> p={4}
</React.Suspense> gridAutoRows="min-content auto"
</PersistGate> w={APP_WIDTH}
</Provider> h={APP_HEIGHT}
</React.StrictMode> >
{children || <SiteHeader />}
<Flex
gap={4}
w={{ base: '100vw', xl: 'full' }}
h="full"
flexDir={{ base: 'column', xl: 'row' }}
>
<InvokeTabs />
<ImageGalleryPanel />
</Flex>
</Grid>
</ImageUploader>
<AnimatePresence>
{!isApplicationReady && !loadingOverridden && (
<motion.div
key="loading"
initial={{ opacity: 1 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
style={{ zIndex: 3 }}
>
<Box position="absolute" top={0} left={0} w="100vw" h="100vh">
<Loading />
</Box>
<Box
onClick={handleOverrideClicked}
position="absolute"
top={0}
right={0}
cursor="pointer"
w="2rem"
h="2rem"
/>
</motion.div>
)}
</AnimatePresence>
<Portal>
<FloatingParametersPanelButtons />
</Portal>
<Portal>
<FloatingGalleryButton />
</Portal>
<Portal>
<Console />
</Portal>
</Grid>
); );
}; };

View File

@ -1,126 +1,70 @@
import ImageUploader from 'common/components/ImageUploader'; import React, { lazy, memo, PropsWithChildren, useEffect } from 'react';
import Console from 'features/system/components/Console'; import { Provider } from 'react-redux';
import ProgressBar from 'features/system/components/ProgressBar'; import { PersistGate } from 'redux-persist/integration/react';
import SiteHeader from 'features/system/components/SiteHeader'; import { buildMiddleware, store } from 'app/store/store';
import InvokeTabs from 'features/ui/components/InvokeTabs'; import { persistor } from '../store/persistor';
import { OpenAPI } from 'services/api';
import '@fontsource/inter/100.css';
import '@fontsource/inter/200.css';
import '@fontsource/inter/300.css';
import '@fontsource/inter/400.css';
import '@fontsource/inter/500.css';
import '@fontsource/inter/600.css';
import '@fontsource/inter/700.css';
import '@fontsource/inter/800.css';
import '@fontsource/inter/900.css';
import useToastWatcher from 'features/system/hooks/useToastWatcher'; import Loading from '../../common/components/Loading/Loading';
import { addMiddleware, resetMiddlewares } from 'redux-dynamic-middlewares';
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
import { Box, Flex, Grid, Portal, useColorMode } from '@chakra-ui/react';
import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel';
import Lightbox from 'features/lightbox/components/Lightbox';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import {
memo,
PropsWithChildren,
useCallback,
useEffect,
useState,
} from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import Loading from 'common/components/Loading/Loading';
import { useIsApplicationReady } from 'features/system/hooks/useIsApplicationReady';
import { PartialAppConfig } from 'app/types/invokeai'; import { PartialAppConfig } from 'app/types/invokeai';
import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys';
import { configChanged } from 'features/system/store/configSlice'; import '../../i18n';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
const App = lazy(() => import('./App'));
const ThemeLocaleProvider = lazy(() => import('./ThemeLocaleProvider'));
interface Props extends PropsWithChildren { interface Props extends PropsWithChildren {
apiUrl?: string;
token?: string;
config?: PartialAppConfig; config?: PartialAppConfig;
} }
const InvokeAIUI = ({ config = {}, children }: Props) => { const InvokeAIUI = ({ apiUrl, token, config, children }: Props) => {
useToastWatcher();
useGlobalHotkeys();
const currentTheme = useAppSelector((state) => state.ui.currentTheme);
const isLightboxEnabled = useFeatureStatus('lightbox').isFeatureEnabled;
const isApplicationReady = useIsApplicationReady();
const [loadingOverridden, setLoadingOverridden] = useState(false);
const { setColorMode } = useColorMode();
const dispatch = useAppDispatch();
useEffect(() => { useEffect(() => {
console.log('Received config: ', config); // configure API client token
dispatch(configChanged(config)); if (token) {
}, [dispatch, config]); OpenAPI.TOKEN = token;
}
useEffect(() => { // configure API client base url
setColorMode(['light'].includes(currentTheme) ? 'light' : 'dark'); if (apiUrl) {
}, [setColorMode, currentTheme]); OpenAPI.BASE = apiUrl;
}
const handleOverrideClicked = useCallback(() => { // reset dynamically added middlewares
setLoadingOverridden(true); resetMiddlewares();
}, []);
// TODO: at this point, after resetting the middleware, we really ought to clean up the socket
// stuff by calling `dispatch(socketReset())`. but we cannot dispatch from here as we are
// outside the provider. it's not needed until there is the possibility that we will change
// the `apiUrl`/`token` dynamically.
// rebuild socket middleware with token and apiUrl
addMiddleware(buildMiddleware());
}, [apiUrl, token]);
return ( return (
<Grid w="100vw" h="100vh" position="relative"> <React.StrictMode>
{isLightboxEnabled && <Lightbox />} <Provider store={store}>
<ImageUploader> <PersistGate loading={<Loading />} persistor={persistor}>
<ProgressBar /> <React.Suspense fallback={<Loading />}>
<Grid <ThemeLocaleProvider>
gap={4} <App config={config}>{children}</App>
p={4} </ThemeLocaleProvider>
gridAutoRows="min-content auto" </React.Suspense>
w={APP_WIDTH} </PersistGate>
h={APP_HEIGHT} </Provider>
> </React.StrictMode>
{children || <SiteHeader />}
<Flex
gap={4}
w={{ base: '100vw', xl: 'full' }}
h="full"
flexDir={{ base: 'column', xl: 'row' }}
>
<InvokeTabs />
<ImageGalleryPanel />
</Flex>
</Grid>
</ImageUploader>
<AnimatePresence>
{!isApplicationReady && !loadingOverridden && (
<motion.div
key="loading"
initial={{ opacity: 1 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
style={{ zIndex: 3 }}
>
<Box position="absolute" top={0} left={0} w="100vw" h="100vh">
<Loading />
</Box>
<Box
onClick={handleOverrideClicked}
position="absolute"
top={0}
right={0}
cursor="pointer"
w="2rem"
h="2rem"
/>
</motion.div>
)}
</AnimatePresence>
<Portal>
<FloatingParametersPanelButtons />
</Portal>
<Portal>
<FloatingGalleryButton />
</Portal>
<Portal>
<Console />
</Portal>
</Grid>
); );
}; };

View File

@ -1,7 +1,7 @@
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import App from './app/components/App'; import InvokeAIUI from './app/components/InvokeAIUI';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<App /> <InvokeAIUI />
); );