feat(ui): fill up gallery on app start

taking the coward's way out on this and just fetching 100 images & 100 assets on app start...

- add `appStarted` action, dispatched once on mount in App.tsx. listener fetches 100 images & 100 assets
- fix bug with selectedBoardId & assets tab
This commit is contained in:
psychedelicious 2023-07-08 09:50:41 +10:00
parent cbecf3cb89
commit 18b6c1a24b
7 changed files with 112 additions and 82 deletions

View File

@ -1,5 +1,6 @@
import { Flex, Grid, Portal } from '@chakra-ui/react';
import { useLogger } from 'app/logging/useLogger';
import { appStarted } from 'app/store/middleware/listenerMiddleware/listeners/appStarted';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { PartialAppConfig } from 'app/types/invokeai';
import ImageUploader from 'common/components/ImageUploader';
@ -46,6 +47,10 @@ const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => {
dispatch(configChanged(config));
}, [dispatch, config, log]);
useEffect(() => {
dispatch(appStarted());
}, [dispatch]);
return (
<>
<Grid w="100vw" h="100vh" position="relative" overflow="hidden">

View File

@ -1,49 +1,68 @@
import type { TypedAddListener, TypedStartListening } from '@reduxjs/toolkit';
import {
createListenerMiddleware,
addListener,
ListenerEffect,
AnyAction,
ListenerEffect,
addListener,
createListenerMiddleware,
} from '@reduxjs/toolkit';
import type { TypedStartListening, TypedAddListener } from '@reduxjs/toolkit';
import type { RootState, AppDispatch } from '../../store';
import { addInitialImageSelectedListener } from './listeners/initialImageSelected';
import type { AppDispatch, RootState } from '../../store';
import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener';
import { addAppStartedListener } from './listeners/appStarted';
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
import { addRequestedBoardImageDeletionListener } from './listeners/boardImagesDeleted';
import { addCanvasCopiedToClipboardListener } from './listeners/canvasCopiedToClipboard';
import { addCanvasDownloadedAsImageListener } from './listeners/canvasDownloadedAsImage';
import { addCanvasMergedListener } from './listeners/canvasMerged';
import { addCanvasSavedToGalleryListener } from './listeners/canvasSavedToGallery';
import { addControlNetAutoProcessListener } from './listeners/controlNetAutoProcess';
import { addControlNetImageProcessedListener } from './listeners/controlNetImageProcessed';
import {
addImageUploadedFulfilledListener,
addImageUploadedRejectedListener,
} from './listeners/imageUploaded';
addImageAddedToBoardFulfilledListener,
addImageAddedToBoardRejectedListener,
} from './listeners/imageAddedToBoard';
import { addImageCategoriesChangedListener } from './listeners/imageCategoriesChanged';
import {
addImageDeletedFulfilledListener,
addImageDeletedPendingListener,
addImageDeletedRejectedListener,
addRequestedImageDeletionListener,
} from './listeners/imageDeleted';
import { addUserInvokedCanvasListener } from './listeners/userInvokedCanvas';
import { addUserInvokedNodesListener } from './listeners/userInvokedNodes';
import { addUserInvokedTextToImageListener } from './listeners/userInvokedTextToImage';
import { addUserInvokedImageToImageListener } from './listeners/userInvokedImageToImage';
import { addCanvasSavedToGalleryListener } from './listeners/canvasSavedToGallery';
import { addCanvasDownloadedAsImageListener } from './listeners/canvasDownloadedAsImage';
import { addCanvasCopiedToClipboardListener } from './listeners/canvasCopiedToClipboard';
import { addCanvasMergedListener } from './listeners/canvasMerged';
import { addGeneratorProgressEventListener as addGeneratorProgressListener } from './listeners/socketio/socketGeneratorProgress';
import { addGraphExecutionStateCompleteEventListener as addGraphExecutionStateCompleteListener } from './listeners/socketio/socketGraphExecutionStateComplete';
import { addInvocationCompleteEventListener as addInvocationCompleteListener } from './listeners/socketio/socketInvocationComplete';
import { addInvocationErrorEventListener as addInvocationErrorListener } from './listeners/socketio/socketInvocationError';
import { addInvocationStartedEventListener as addInvocationStartedListener } from './listeners/socketio/socketInvocationStarted';
import { addSocketConnectedEventListener as addSocketConnectedListener } from './listeners/socketio/socketConnected';
import { addSocketDisconnectedEventListener as addSocketDisconnectedListener } from './listeners/socketio/socketDisconnected';
import { addSocketSubscribedEventListener as addSocketSubscribedListener } from './listeners/socketio/socketSubscribed';
import { addSocketUnsubscribedEventListener as addSocketUnsubscribedListener } from './listeners/socketio/socketUnsubscribed';
import { addSessionReadyToInvokeListener } from './listeners/sessionReadyToInvoke';
import { addImageDroppedListener } from './listeners/imageDropped';
import {
addImageMetadataReceivedFulfilledListener,
addImageMetadataReceivedRejectedListener,
} from './listeners/imageMetadataReceived';
import {
addImageRemovedFromBoardFulfilledListener,
addImageRemovedFromBoardRejectedListener,
} from './listeners/imageRemovedFromBoard';
import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected';
import {
addImageUpdatedFulfilledListener,
addImageUpdatedRejectedListener,
} from './listeners/imageUpdated';
import {
addImageUploadedFulfilledListener,
addImageUploadedRejectedListener,
} from './listeners/imageUploaded';
import {
addImageUrlsReceivedFulfilledListener,
addImageUrlsReceivedRejectedListener,
} from './listeners/imageUrlsReceived';
import { addInitialImageSelectedListener } from './listeners/initialImageSelected';
import { addModelSelectedListener } from './listeners/modelSelected';
import { addReceivedOpenAPISchemaListener } from './listeners/receivedOpenAPISchema';
import {
addReceivedPageOfImagesFulfilledListener,
addReceivedPageOfImagesRejectedListener,
} from './listeners/receivedPageOfImages';
import { addSelectionAddedToBatchListener } from './listeners/selectionAddedToBatch';
import {
addSessionCanceledFulfilledListener,
addSessionCanceledPendingListener,
addSessionCanceledRejectedListener,
} from './listeners/sessionCanceled';
import {
addSessionCreatedFulfilledListener,
addSessionCreatedPendingListener,
@ -54,39 +73,21 @@ import {
addSessionInvokedPendingListener,
addSessionInvokedRejectedListener,
} from './listeners/sessionInvoked';
import {
addSessionCanceledFulfilledListener,
addSessionCanceledPendingListener,
addSessionCanceledRejectedListener,
} from './listeners/sessionCanceled';
import {
addImageUpdatedFulfilledListener,
addImageUpdatedRejectedListener,
} from './listeners/imageUpdated';
import {
addReceivedPageOfImagesFulfilledListener,
addReceivedPageOfImagesRejectedListener,
} from './listeners/receivedPageOfImages';
import { addSessionReadyToInvokeListener } from './listeners/sessionReadyToInvoke';
import { addSocketConnectedEventListener as addSocketConnectedListener } from './listeners/socketio/socketConnected';
import { addSocketDisconnectedEventListener as addSocketDisconnectedListener } from './listeners/socketio/socketDisconnected';
import { addGeneratorProgressEventListener as addGeneratorProgressListener } from './listeners/socketio/socketGeneratorProgress';
import { addGraphExecutionStateCompleteEventListener as addGraphExecutionStateCompleteListener } from './listeners/socketio/socketGraphExecutionStateComplete';
import { addInvocationCompleteEventListener as addInvocationCompleteListener } from './listeners/socketio/socketInvocationComplete';
import { addInvocationErrorEventListener as addInvocationErrorListener } from './listeners/socketio/socketInvocationError';
import { addInvocationStartedEventListener as addInvocationStartedListener } from './listeners/socketio/socketInvocationStarted';
import { addSocketSubscribedEventListener as addSocketSubscribedListener } from './listeners/socketio/socketSubscribed';
import { addSocketUnsubscribedEventListener as addSocketUnsubscribedListener } from './listeners/socketio/socketUnsubscribed';
import { addStagingAreaImageSavedListener } from './listeners/stagingAreaImageSaved';
import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener';
import { addImageCategoriesChangedListener } from './listeners/imageCategoriesChanged';
import { addControlNetImageProcessedListener } from './listeners/controlNetImageProcessed';
import { addControlNetAutoProcessListener } from './listeners/controlNetAutoProcess';
import {
addImageAddedToBoardFulfilledListener,
addImageAddedToBoardRejectedListener,
} from './listeners/imageAddedToBoard';
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
import {
addImageRemovedFromBoardFulfilledListener,
addImageRemovedFromBoardRejectedListener,
} from './listeners/imageRemovedFromBoard';
import { addReceivedOpenAPISchemaListener } from './listeners/receivedOpenAPISchema';
import { addRequestedBoardImageDeletionListener } from './listeners/boardImagesDeleted';
import { addSelectionAddedToBatchListener } from './listeners/selectionAddedToBatch';
import { addImageDroppedListener } from './listeners/imageDropped';
import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected';
import { addModelSelectedListener } from './listeners/modelSelected';
import { addUserInvokedCanvasListener } from './listeners/userInvokedCanvas';
import { addUserInvokedImageToImageListener } from './listeners/userInvokedImageToImage';
import { addUserInvokedNodesListener } from './listeners/userInvokedNodes';
import { addUserInvokedTextToImageListener } from './listeners/userInvokedTextToImage';
export const listenerMiddleware = createListenerMiddleware();
@ -224,3 +225,6 @@ addImageDroppedListener();
// Models
addModelSelectedListener();
// app startup
addAppStartedListener();

View File

@ -0,0 +1,30 @@
import { createAction } from '@reduxjs/toolkit';
import { receivedPageOfImages } from 'services/api/thunks/image';
import { startAppListening } from '..';
export const appStarted = createAction('app/appStarted');
export const addAppStartedListener = () => {
startAppListening({
actionCreator: appStarted,
effect: (action, { getState, dispatch }) => {
// fill up the gallery tab with images
dispatch(
receivedPageOfImages({
categories: ['general'],
is_intermediate: false,
limit: 100,
})
);
// fill up the assets tab with images
dispatch(
receivedPageOfImages({
categories: ['control', 'mask', 'user', 'other'],
is_intermediate: false,
limit: 100,
})
);
},
});
};

View File

@ -1,10 +1,10 @@
import { log } from 'app/logging/useLogger';
import { startAppListening } from '..';
import { receivedPageOfImages } from 'services/api/thunks/image';
import {
imageCategoriesChanged,
selectFilteredImages,
} from 'features/gallery/store/gallerySlice';
import { receivedPageOfImages } from 'services/api/thunks/image';
import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'gallery' });
@ -19,7 +19,7 @@ export const addImageCategoriesChangedListener = () => {
dispatch(
receivedPageOfImages({
categories: action.payload,
board_id: state.boards.selectedBoardId,
board_id: state.gallery.selectedBoardId,
is_intermediate: false,
})
);

View File

@ -14,9 +14,9 @@ import {
} from '@chakra-ui/react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
import IAIIconButton from 'common/components/IAIIconButton';
import IAIPopover from 'common/components/IAIPopover';
import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
import IAISlider from 'common/components/IAISlider';
import {
setGalleryImageMinimumWidth,
@ -40,25 +40,25 @@ import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs';
import { FaImage, FaServer, FaWrench } from 'react-icons/fa';
import GalleryImage from './GalleryImage';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
import { ChevronUpIcon } from '@chakra-ui/icons';
import { createSelector } from '@reduxjs/toolkit';
import { RootState, stateSelector } from 'app/store/store';
import { VirtuosoGrid } from 'react-virtuoso';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
import {
ASSETS_CATEGORIES,
IMAGE_CATEGORIES,
imageCategoriesChanged,
shouldAutoSwitchChanged,
selectFilteredImages,
shouldAutoSwitchChanged,
} from 'features/gallery/store/gallerySlice';
import { receivedPageOfImages } from 'services/api/thunks/image';
import BoardsList from './Boards/BoardsList';
import { ChevronUpIcon } from '@chakra-ui/icons';
import { VirtuosoGrid } from 'react-virtuoso';
import { useListAllBoardsQuery } from 'services/api/endpoints/boards';
import { mode } from 'theme/util/mode';
import { receivedPageOfImages } from 'services/api/thunks/image';
import { ImageDTO } from 'services/api/types';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import { mode } from 'theme/util/mode';
import BoardsList from './Boards/BoardsList';
const LOADING_IMAGE_ARRAY = Array(20).fill('loading');
@ -182,16 +182,6 @@ const ImageGalleryContent = () => {
return () => osInstance()?.destroy();
}, [scroller, initialize, osInstance]);
useEffect(() => {
dispatch(
receivedPageOfImages({
categories,
is_intermediate: false,
})
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const handleClickImagesCategory = useCallback(() => {
dispatch(imageCategoriesChanged(IMAGE_CATEGORIES));
dispatch(setGalleryView('images'));

View File

@ -11,5 +11,7 @@ export const galleryPersistDenylist: (keyof typeof initialGalleryState)[] = [
'limit',
'offset',
'selectedBoardId',
'categories',
'galleryView',
'total',
];

View File

@ -169,7 +169,6 @@ export const gallerySlice = createSlice({
}
state.offset = offset;
state.limit = limit;
state.total = total;
});
builder.addCase(imageUrlsReceived.fulfilled, (state, action) => {