mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
remove long loading state, introduce loading to gallery and model list
This commit is contained in:
parent
96212bb35f
commit
85a4d37883
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -41,7 +41,7 @@ export const initialImagesState =
|
||||
offset: 0,
|
||||
limit: 0,
|
||||
total: 0,
|
||||
isLoading: false,
|
||||
isLoading: true,
|
||||
categories: IMAGE_CATEGORIES,
|
||||
});
|
||||
|
||||
|
@ -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')}
|
||||
|
Loading…
Reference in New Issue
Block a user