From 85a4d378837bad69632d24fe70dfa50cf5652dfb Mon Sep 17 00:00:00 2001 From: Mary Hipp <maryhipp@Marys-MacBook-Air.local> Date: Fri, 30 Jun 2023 13:26:46 -0400 Subject: [PATCH] remove long loading state, introduce loading to gallery and model list --- .../frontend/web/src/app/components/App.tsx | 56 +------------- .../components/ImageGalleryContent.tsx | 75 +++++++++++++------ .../src/features/gallery/store/imagesSlice.ts | 2 +- .../system/components/ModelSelect.tsx | 11 ++- 4 files changed, 63 insertions(+), 81 deletions(-) diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index 5b3cf5925f..67d2bb2a4b 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -1,9 +1,8 @@ -import { Box, Flex, Grid, Portal } from '@chakra-ui/react'; +import { 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'; @@ -15,10 +14,8 @@ 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'; import DeleteImageModal from 'features/gallery/components/DeleteImageModal'; @@ -59,9 +56,6 @@ const App = ({ const { data: embeddingModels } = useListModelsQuery({ model_type: 'embedding', }); - - const [loadingOverridden, setLoadingOverridden] = useState(false); - const dispatch = useAppDispatch(); useEffect(() => { @@ -73,27 +67,6 @@ const App = ({ dispatch(configChanged(config)); }, [dispatch, config, log]); - const handleOverrideClicked = useCallback(() => { - setLoadingOverridden(true); - }, []); - - useEffect(() => { - if (isApplicationReady && setIsReady) { - setIsReady(true); - } - - if (isApplicationReady) { - // TODO: This is a jank fix for canvas not filling the screen on first load - setTimeout(() => { - dispatch(requestCanvasRescale()); - }, 200); - } - - return () => { - setIsReady && setIsReady(false); - }; - }, [dispatch, isApplicationReady, setIsReady]); - return ( <> <Grid w="100vw" h="100vh" position="relative" overflow="hidden"> @@ -123,33 +96,6 @@ const App = ({ <GalleryDrawer /> <ParametersDrawer /> - - <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> diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx index a22eb6d20f..8cfce280b0 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx @@ -6,6 +6,7 @@ import { FlexProps, Grid, Icon, + Skeleton, Text, VStack, forwardRef, @@ -233,7 +234,7 @@ const ImageGalleryContent = () => { borderRadius: 'base', }} > - <Box sx={{ w: 'full' }}> + <Box sx={{ w: 'full', minWidth: '200px' }}> <Flex ref={resizeObserverRef} sx={{ @@ -355,7 +356,9 @@ const ImageGalleryContent = () => { </Box> </Box> <Flex direction="column" gap={2} h="full" w="full"> - {images.length || areMoreAvailable ? ( + {isLoading ? ( + <LoadingGallery /> + ) : images.length || areMoreAvailable ? ( <> <Box ref={rootRef} data-overlayscrollbars="" h="100%"> {shouldUseSingleGalleryColumn ? ( @@ -407,27 +410,7 @@ const ImageGalleryContent = () => { </IAIButton> </> ) : ( - <Flex - sx={{ - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - gap: 2, - padding: 8, - h: '100%', - w: '100%', - color: 'base.500', - }} - > - <Icon - as={MdPhotoLibrary} - sx={{ - w: 16, - h: 16, - }} - /> - <Text textAlign="center">{t('gallery.noImagesInGallery')}</Text> - </Flex> + <EmptyGallery /> )} </Flex> </VStack> @@ -462,4 +445,50 @@ const ListContainer = forwardRef((props: ListContainerProps, ref) => { ); }); +const LoadingGallery = () => { + return ( + <Box data-overlayscrollbars="" h="100%"> + <VirtuosoGrid + style={{ height: '100%' }} + data={new Array(20)} + components={{ + Item: ItemContainer, + List: ListContainer, + }} + itemContent={(index, item) => ( + <Flex sx={{ pb: 2 }}> + <Skeleton sx={{ width: 'full', paddingBottom: '100%' }} /> + </Flex> + )} + /> + </Box> + ); +}; +const EmptyGallery = () => { + const { t } = useTranslation(); + return ( + <Flex + sx={{ + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + gap: 2, + padding: 8, + h: '100%', + w: '100%', + color: 'base.500', + }} + > + <Icon + as={MdPhotoLibrary} + sx={{ + w: 16, + h: 16, + }} + /> + <Text textAlign="center">{t('gallery.noImagesInGallery')}</Text> + </Flex> + ); +}; + export default memo(ImageGalleryContent); diff --git a/invokeai/frontend/web/src/features/gallery/store/imagesSlice.ts b/invokeai/frontend/web/src/features/gallery/store/imagesSlice.ts index 8041ffd5c5..3c14d91994 100644 --- a/invokeai/frontend/web/src/features/gallery/store/imagesSlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/imagesSlice.ts @@ -41,7 +41,7 @@ export const initialImagesState = offset: 0, limit: 0, total: 0, - isLoading: false, + isLoading: true, categories: IMAGE_CATEGORIES, }); diff --git a/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx b/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx index f9eda624f2..2a14af32b2 100644 --- a/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx +++ b/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx @@ -23,7 +23,7 @@ const ModelSelect = () => { (state: RootState) => state.generation.model ); - const { data: pipelineModels } = useListModelsQuery({ + const { data: pipelineModels, isLoading } = useListModelsQuery({ model_type: 'main', }); @@ -78,7 +78,14 @@ const ModelSelect = () => { handleChangeModel(firstModel); }, [handleChangeModel, pipelineModels?.ids, selectedModelId]); - return ( + return isLoading ? ( + <IAIMantineSelect + label={t('modelManager.model')} + placeholder="Loading..." + disabled={true} + data={[]} + /> + ) : ( <IAIMantineSelect tooltip={selectedModel?.description} label={t('modelManager.model')}