mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
restore scroll bar, move all image queries over to main image list endpoint
This commit is contained in:
parent
e8d531b987
commit
29f7e4a5d1
@ -1,11 +1,5 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
import {
|
||||
ASSETS_CATEGORIES,
|
||||
IMAGE_CATEGORIES,
|
||||
INITIAL_IMAGE_LIMIT,
|
||||
isLoadingChanged,
|
||||
} from 'features/gallery/store/gallerySlice';
|
||||
import { receivedPageOfImages } from 'services/api/thunks/image';
|
||||
import { isLoadingChanged } from 'features/gallery/store/gallerySlice';
|
||||
import { startAppListening } from '..';
|
||||
|
||||
export const appStarted = createAction('app/appStarted');
|
||||
@ -19,25 +13,6 @@ export const addAppStartedListener = () => {
|
||||
) => {
|
||||
cancelActiveListeners();
|
||||
unsubscribe();
|
||||
// fill up the gallery tab with images
|
||||
await dispatch(
|
||||
receivedPageOfImages({
|
||||
categories: IMAGE_CATEGORIES,
|
||||
is_intermediate: false,
|
||||
offset: 0,
|
||||
limit: INITIAL_IMAGE_LIMIT,
|
||||
})
|
||||
);
|
||||
|
||||
// fill up the assets tab with images
|
||||
await dispatch(
|
||||
receivedPageOfImages({
|
||||
categories: ASSETS_CATEGORIES,
|
||||
is_intermediate: false,
|
||||
offset: 0,
|
||||
limit: INITIAL_IMAGE_LIMIT,
|
||||
})
|
||||
);
|
||||
|
||||
dispatch(isLoadingChanged(false));
|
||||
},
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
ASSETS_CATEGORIES,
|
||||
IMAGE_CATEGORIES,
|
||||
IMAGE_LIMIT,
|
||||
INITIAL_IMAGE_LIMIT,
|
||||
selectImagesAll,
|
||||
} from 'features/gallery//store/gallerySlice';
|
||||
import { selectFilteredImages } from 'features/gallery/store/gallerySelectors';
|
||||
@ -24,6 +25,7 @@ import { receivedPageOfImages } from 'services/api/thunks/image';
|
||||
import ImageGridItemContainer from './ImageGridItemContainer';
|
||||
import ImageGridListContainer from './ImageGridListContainer';
|
||||
import { useListBoardImagesQuery } from '../../../../services/api/endpoints/boardImages';
|
||||
import { useListImagesQuery } from '../../../../services/api/endpoints/images';
|
||||
|
||||
const selector = createSelector(
|
||||
[stateSelector, selectFilteredImages],
|
||||
@ -79,32 +81,34 @@ const GalleryImageGrid = () => {
|
||||
isLoading: isLoadingAll,
|
||||
} = useAppSelector(selector);
|
||||
|
||||
const { data: imagesForBoard, isLoading: isLoadingImagesForBoard } =
|
||||
useListBoardImagesQuery(
|
||||
{ board_id: selectedBoardId },
|
||||
{ skip: selectedBoardId === 'all' }
|
||||
);
|
||||
const { data: images, isLoading: isLoading } = useListImagesQuery({
|
||||
categories: galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES,
|
||||
is_intermediate: false,
|
||||
offset: 0,
|
||||
limit: INITIAL_IMAGE_LIMIT,
|
||||
...(selectedBoardId === 'all' ? {} : { board_id: selectedBoardId }),
|
||||
});
|
||||
|
||||
const imageNames = useMemo(() => {
|
||||
if (selectedBoardId === 'all') {
|
||||
return imageNamesAll; // already sorted by images/uploads in gallery selector
|
||||
} else {
|
||||
const categories =
|
||||
galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES;
|
||||
const imageList = (imagesForBoard?.items || []).filter((img) =>
|
||||
categories.includes(img.image_category)
|
||||
);
|
||||
return imageList.map((img) => img.image_name);
|
||||
}
|
||||
}, [selectedBoardId, galleryView, imagesForBoard, imageNamesAll]);
|
||||
// const imageNames = useMemo(() => {
|
||||
// if (selectedBoardId === 'all') {
|
||||
// return imageNamesAll; // already sorted by images/uploads in gallery selector
|
||||
// } else {
|
||||
// const categories =
|
||||
// galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES;
|
||||
// const imageList = (imagesForBoard?.items || []).filter((img) =>
|
||||
// categories.includes(img.image_category)
|
||||
// );
|
||||
// return imageList.map((img) => img.image_name);
|
||||
// }
|
||||
// }, [selectedBoardId, galleryView, imagesForBoard, imageNamesAll]);
|
||||
|
||||
const areMoreAvailable = useMemo(() => {
|
||||
return selectedBoardId === 'all' ? totalAll > imageNamesAll.length : false;
|
||||
}, [selectedBoardId, imageNamesAll.length, totalAll]);
|
||||
// const areMoreAvailable = useMemo(() => {
|
||||
// return selectedBoardId === 'all' ? totalAll > imageNamesAll.length : false;
|
||||
// }, [selectedBoardId, imageNamesAll.length, totalAll]);
|
||||
|
||||
const isLoading = useMemo(() => {
|
||||
return selectedBoardId === 'all' ? isLoadingAll : isLoadingImagesForBoard;
|
||||
}, [selectedBoardId, isLoadingAll, isLoadingImagesForBoard]);
|
||||
// const isLoading = useMemo(() => {
|
||||
// return selectedBoardId === 'all' ? isLoadingAll : isLoadingImagesForBoard;
|
||||
// }, [selectedBoardId, isLoadingAll, isLoadingImagesForBoard]);
|
||||
|
||||
const handleLoadMoreImages = useCallback(() => {
|
||||
dispatch(
|
||||
@ -112,51 +116,34 @@ const GalleryImageGrid = () => {
|
||||
categories:
|
||||
galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES,
|
||||
is_intermediate: false,
|
||||
offset: imageNames.length,
|
||||
offset: images?.items.length,
|
||||
limit: IMAGE_LIMIT,
|
||||
})
|
||||
);
|
||||
}, [dispatch, imageNames.length, galleryView]);
|
||||
}, [dispatch, images?.items.length, galleryView]);
|
||||
|
||||
const handleEndReached = useMemo(() => {
|
||||
if (areMoreAvailable) {
|
||||
return handleLoadMoreImages;
|
||||
}
|
||||
return undefined;
|
||||
}, [areMoreAvailable, handleLoadMoreImages]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!didInitialFetch) {
|
||||
// return;
|
||||
// const handleEndReached = useMemo(() => {
|
||||
// if (areMoreAvailable) {
|
||||
// return handleLoadMoreImages;
|
||||
// }
|
||||
// // rough, conservative calculation of how many images fit in the gallery
|
||||
// // TODO: this gets an incorrect value on first load...
|
||||
// const galleryHeight = rootRef.current?.clientHeight ?? 0;
|
||||
// const galleryWidth = rootRef.current?.clientHeight ?? 0;
|
||||
// return undefined;
|
||||
// }, [areMoreAvailable, handleLoadMoreImages]);
|
||||
|
||||
// const rows = galleryHeight / galleryImageMinimumWidth;
|
||||
// const columns = galleryWidth / galleryImageMinimumWidth;
|
||||
useEffect(() => {
|
||||
// Set up gallery scroler
|
||||
const { current: root } = rootRef;
|
||||
if (scroller && root) {
|
||||
initialize({
|
||||
target: root,
|
||||
elements: {
|
||||
viewport: scroller,
|
||||
},
|
||||
});
|
||||
}
|
||||
return () => osInstance()?.destroy();
|
||||
}, [scroller, initialize, osInstance]);
|
||||
|
||||
// const imagesToLoad = Math.ceil(rows * columns);
|
||||
|
||||
// setDidInitialFetch(true);
|
||||
|
||||
// // load up that many images
|
||||
// dispatch(
|
||||
// receivedPageOfImages({
|
||||
// offset: 0,
|
||||
// limit: 10,
|
||||
// })
|
||||
// );
|
||||
// }, [
|
||||
// didInitialFetch,
|
||||
// dispatch,
|
||||
// galleryImageMinimumWidth,
|
||||
// galleryView,
|
||||
// selectedBoardId,
|
||||
// ]);
|
||||
|
||||
if (!isLoading && imageNames.length === 0) {
|
||||
if (!isLoading && images?.items.length === 0) {
|
||||
return (
|
||||
<Box ref={emptyGalleryRef} sx={{ w: 'full', h: 'full' }}>
|
||||
<IAINoContentFallback
|
||||
@ -174,27 +161,30 @@ const GalleryImageGrid = () => {
|
||||
<Box ref={rootRef} data-overlayscrollbars="" h="100%">
|
||||
<VirtuosoGrid
|
||||
style={{ height: '100%' }}
|
||||
data={imageNames}
|
||||
data={images?.items || []}
|
||||
components={{
|
||||
Item: ImageGridItemContainer,
|
||||
List: ImageGridListContainer,
|
||||
}}
|
||||
scrollerRef={setScroller}
|
||||
itemContent={(index, imageName) => (
|
||||
<GalleryImage key={imageName} imageName={imageName} />
|
||||
itemContent={(index, image) => (
|
||||
<GalleryImage
|
||||
key={image.image_name}
|
||||
imageName={image.image_name}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Box>
|
||||
<IAIButton
|
||||
onClick={handleLoadMoreImages}
|
||||
isDisabled={!areMoreAvailable}
|
||||
// isDisabled={!areMoreAvailable}
|
||||
isLoading={status === 'pending'}
|
||||
loadingText="Loading"
|
||||
flexShrink={0}
|
||||
>
|
||||
{areMoreAvailable
|
||||
{/* {areMoreAvailable
|
||||
? t('gallery.loadMore')
|
||||
: t('gallery.allImagesLoaded')}
|
||||
: t('gallery.allImagesLoaded')} */}
|
||||
</IAIButton>
|
||||
</>
|
||||
);
|
||||
|
@ -1,11 +1,6 @@
|
||||
import { OffsetPaginatedResults_ImageDTO_ } from 'services/api/types';
|
||||
import { ApiFullTagDescription, LIST_TAG, api } from '..';
|
||||
import { api } from '..';
|
||||
import { paths } from '../schema';
|
||||
|
||||
type ListBoardImagesArg =
|
||||
paths['/api/v1/board_images/{board_id}']['get']['parameters']['path'] &
|
||||
paths['/api/v1/board_images/{board_id}']['get']['parameters']['query'];
|
||||
|
||||
type AddImageToBoardArg =
|
||||
paths['/api/v1/board_images/']['post']['requestBody']['content']['application/json'];
|
||||
|
||||
@ -14,37 +9,6 @@ type RemoveImageFromBoardArg =
|
||||
|
||||
export const boardImagesApi = api.injectEndpoints({
|
||||
endpoints: (build) => ({
|
||||
/**
|
||||
* Board Images Queries
|
||||
*/
|
||||
|
||||
listBoardImages: build.query<
|
||||
OffsetPaginatedResults_ImageDTO_,
|
||||
ListBoardImagesArg
|
||||
>({
|
||||
query: ({ board_id, offset, limit }) => ({
|
||||
url: `board_images/${board_id}`,
|
||||
method: 'GET',
|
||||
|
||||
}),
|
||||
providesTags: (result, error, arg) => {
|
||||
// any list of boardimages
|
||||
const tags: ApiFullTagDescription[] = [{ id: 'BoardImage', type: `${arg.board_id}_${LIST_TAG}` }];
|
||||
|
||||
if (result) {
|
||||
// and individual tags for each boardimage
|
||||
tags.push(
|
||||
...result.items.map(({ board_id, image_name }) => ({
|
||||
type: 'BoardImage' as const,
|
||||
id: `${board_id}_${image_name}`,
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
return tags;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Board Images Mutations
|
||||
*/
|
||||
@ -77,6 +41,5 @@ export const boardImagesApi = api.injectEndpoints({
|
||||
|
||||
export const {
|
||||
useAddImageToBoardMutation,
|
||||
useRemoveImageFromBoardMutation,
|
||||
useListBoardImagesQuery,
|
||||
useRemoveImageFromBoardMutation
|
||||
} = boardImagesApi;
|
||||
|
@ -1,6 +1,10 @@
|
||||
import { ApiFullTagDescription, api } from '..';
|
||||
import { components } from '../schema';
|
||||
import { ImageDTO } from '../types';
|
||||
import { ApiFullTagDescription, LIST_TAG, api } from '..';
|
||||
import { components, paths } from '../schema';
|
||||
import { ImageDTO, OffsetPaginatedResults_ImageDTO_ } from '../types';
|
||||
|
||||
type ListImagesArg = NonNullable<
|
||||
paths['/api/v1/images/']['get']['parameters']['query']
|
||||
>;
|
||||
|
||||
/**
|
||||
* This is an unsafe type; the object inside is not guaranteed to be valid.
|
||||
@ -15,6 +19,25 @@ export const imagesApi = api.injectEndpoints({
|
||||
/**
|
||||
* Image Queries
|
||||
*/
|
||||
listImages: build.query<OffsetPaginatedResults_ImageDTO_, ListImagesArg>({
|
||||
query: (arg) => ({ url: 'images/', params: arg }),
|
||||
providesTags: (result, error, arg) => {
|
||||
// any list of images
|
||||
const tags: ApiFullTagDescription[] = [{ id: 'Image', type: LIST_TAG }];
|
||||
|
||||
if (result) {
|
||||
// and individual tags for each image
|
||||
tags.push(
|
||||
...result.items.map(({ image_name }) => ({
|
||||
type: 'Image' as const,
|
||||
id: image_name,
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
return tags;
|
||||
},
|
||||
}),
|
||||
getImageDTO: build.query<ImageDTO, string>({
|
||||
query: (image_name) => ({ url: `images/${image_name}` }),
|
||||
providesTags: (result, error, arg) => {
|
||||
@ -39,4 +62,4 @@ export const imagesApi = api.injectEndpoints({
|
||||
}),
|
||||
});
|
||||
|
||||
export const { useGetImageDTOQuery, useGetImageMetadataQuery } = imagesApi;
|
||||
export const { useGetImageDTOQuery, useGetImageMetadataQuery, useListImagesQuery } = imagesApi;
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
createApi,
|
||||
fetchBaseQuery,
|
||||
} from '@reduxjs/toolkit/query/react';
|
||||
import queryString from 'query-string';
|
||||
import { $authToken, $baseUrl } from 'services/api/client';
|
||||
|
||||
export const tagTypes = ['Board', 'Image', 'ImageMetadata', 'Model'];
|
||||
@ -31,6 +32,9 @@ const dynamicBaseQuery: BaseQueryFn<
|
||||
|
||||
return headers;
|
||||
},
|
||||
paramsSerializer: (params: Record<string, any>) => {
|
||||
return queryString.stringify(params, { arrayFormat: 'none' })
|
||||
}
|
||||
});
|
||||
|
||||
return rawBaseQuery(args, api, extraOptions);
|
||||
|
Loading…
Reference in New Issue
Block a user