mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): rudimentary categorized gallery image fetching
This commit is contained in:
parent
d501986610
commit
f560a462a0
@ -56,36 +56,39 @@ import {
|
||||
imageCategoriesChanged,
|
||||
selectImagesAll,
|
||||
} from '../store/imagesSlice';
|
||||
import { receivedPageOfImages } from 'services/thunks/image';
|
||||
import {
|
||||
IMAGES_PER_PAGE,
|
||||
receivedImages,
|
||||
receivedPageOfImages,
|
||||
} from 'services/thunks/image';
|
||||
import BoardsList from './Boards/BoardsList';
|
||||
import { boardsSelector, selectBoardsById } from '../store/boardSlice';
|
||||
import { boardsSelector } from '../store/boardSlice';
|
||||
import { ChevronUpIcon } from '@chakra-ui/icons';
|
||||
import { useListAllBoardsQuery } from 'services/apiSlice';
|
||||
|
||||
const itemSelector = createSelector(
|
||||
[(state: RootState) => state],
|
||||
(state) => {
|
||||
const { images, boards } = state;
|
||||
|
||||
const { categories } = images;
|
||||
const { categories, total, isLoading } = state.images;
|
||||
const { selectedBoardId } = state.boards;
|
||||
|
||||
const allImages = selectImagesAll(state);
|
||||
const items = allImages.filter((i) =>
|
||||
categories.includes(i.image_category)
|
||||
);
|
||||
const areMoreAvailable = items.length < images.total;
|
||||
const isLoading = images.isLoading;
|
||||
|
||||
const selectedBoard = boards.selectedBoardId
|
||||
? selectBoardsById(state, boards.selectedBoardId)
|
||||
: undefined;
|
||||
const images = allImages.filter((i) => {
|
||||
const isInCategory = categories.includes(i.image_category);
|
||||
const isInSelectedBoard = selectedBoardId
|
||||
? i.board_id === selectedBoardId
|
||||
: true;
|
||||
return isInCategory && isInSelectedBoard;
|
||||
});
|
||||
|
||||
const areMoreAvailable = images.length < total;
|
||||
|
||||
return {
|
||||
items,
|
||||
images,
|
||||
isLoading,
|
||||
areMoreAvailable,
|
||||
categories: images.categories,
|
||||
selectedBoard,
|
||||
categories,
|
||||
};
|
||||
},
|
||||
defaultSelectorOptions
|
||||
@ -148,7 +151,7 @@ const ImageGalleryContent = () => {
|
||||
selectedBoardId,
|
||||
} = useAppSelector(mainSelector);
|
||||
|
||||
const { items, areMoreAvailable, isLoading, categories } =
|
||||
const { images, areMoreAvailable, isLoading, categories } =
|
||||
useAppSelector(itemSelector);
|
||||
|
||||
const { selectedBoard } = useListAllBoardsQuery(undefined, {
|
||||
@ -158,7 +161,7 @@ const ImageGalleryContent = () => {
|
||||
});
|
||||
|
||||
const handleLoadMoreImages = useCallback(() => {
|
||||
dispatch(receivedPageOfImages());
|
||||
dispatch(receivedPageOfImages({}));
|
||||
}, [dispatch]);
|
||||
|
||||
const handleEndReached = useMemo(() => {
|
||||
@ -208,6 +211,17 @@ const ImageGalleryContent = () => {
|
||||
dispatch(setGalleryView('assets'));
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (images.length < 20) {
|
||||
dispatch(
|
||||
receivedPageOfImages({
|
||||
categories,
|
||||
boardId: selectedBoardId,
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [categories, dispatch, images.length, selectedBoardId]);
|
||||
|
||||
return (
|
||||
<VStack
|
||||
sx={{
|
||||
@ -335,13 +349,13 @@ const ImageGalleryContent = () => {
|
||||
</Box>
|
||||
</Box>
|
||||
<Flex direction="column" gap={2} h="full" w="full">
|
||||
{items.length || areMoreAvailable ? (
|
||||
{images.length || areMoreAvailable ? (
|
||||
<>
|
||||
<Box ref={rootRef} data-overlayscrollbars="" h="100%">
|
||||
{shouldUseSingleGalleryColumn ? (
|
||||
<Virtuoso
|
||||
style={{ height: '100%' }}
|
||||
data={items}
|
||||
data={images}
|
||||
endReached={handleEndReached}
|
||||
scrollerRef={(ref) => setScrollerRef(ref)}
|
||||
itemContent={(index, item) => (
|
||||
@ -357,7 +371,7 @@ const ImageGalleryContent = () => {
|
||||
) : (
|
||||
<VirtuosoGrid
|
||||
style={{ height: '100%' }}
|
||||
data={items}
|
||||
data={images}
|
||||
endReached={handleEndReached}
|
||||
components={{
|
||||
Item: ItemContainer,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { createAppAsyncThunk } from 'app/store/storeUtils';
|
||||
import { selectImagesAll } from 'features/gallery/store/imagesSlice';
|
||||
import { size } from 'lodash-es';
|
||||
import { ImagesService } from 'services/api';
|
||||
|
||||
type imageUrlsReceivedArg = Parameters<
|
||||
@ -121,25 +122,57 @@ type ImagesListedArg = Parameters<
|
||||
|
||||
export const IMAGES_PER_PAGE = 20;
|
||||
|
||||
const DEFAULT_IMAGES_LISTED_ARG = {
|
||||
isIntermediate: false,
|
||||
limit: IMAGES_PER_PAGE,
|
||||
};
|
||||
|
||||
/**
|
||||
* `ImagesService.listImagesWithMetadata()` thunk
|
||||
*/
|
||||
export const receivedPageOfImages = createAppAsyncThunk(
|
||||
'api/receivedPageOfImages',
|
||||
async (_, { getState }) => {
|
||||
async (arg: ImagesListedArg, { getState }) => {
|
||||
const state = getState();
|
||||
const { categories } = state.images;
|
||||
const { selectedBoardId } = state.boards;
|
||||
|
||||
const totalImagesInFilter = selectImagesAll(state).filter((i) =>
|
||||
categories.includes(i.image_category)
|
||||
).length;
|
||||
|
||||
const response = await ImagesService.listImagesWithMetadata({
|
||||
categories,
|
||||
isIntermediate: false,
|
||||
offset: totalImagesInFilter,
|
||||
limit: IMAGES_PER_PAGE,
|
||||
const images = selectImagesAll(state).filter((i) => {
|
||||
const isInCategory = categories.includes(i.image_category);
|
||||
const isInSelectedBoard = selectedBoardId
|
||||
? i.board_id === selectedBoardId
|
||||
: true;
|
||||
return isInCategory && isInSelectedBoard;
|
||||
});
|
||||
|
||||
let queryArg: ReceivedImagesArg = {};
|
||||
|
||||
if (size(arg)) {
|
||||
queryArg = { ...DEFAULT_IMAGES_LISTED_ARG, ...arg };
|
||||
} else {
|
||||
queryArg = {
|
||||
...DEFAULT_IMAGES_LISTED_ARG,
|
||||
categories,
|
||||
offset: images.length,
|
||||
};
|
||||
}
|
||||
|
||||
const response = await ImagesService.listImagesWithMetadata(queryArg);
|
||||
return response;
|
||||
}
|
||||
);
|
||||
|
||||
type ReceivedImagesArg = Parameters<
|
||||
(typeof ImagesService)['listImagesWithMetadata']
|
||||
>[0];
|
||||
|
||||
/**
|
||||
* `ImagesService.listImagesWithMetadata()` thunk
|
||||
*/
|
||||
export const receivedImages = createAppAsyncThunk(
|
||||
'api/receivedImages',
|
||||
async (arg: ReceivedImagesArg, { getState }) => {
|
||||
const response = await ImagesService.listImagesWithMetadata(arg);
|
||||
return response;
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user