diff --git a/invokeai/frontend/web/src/app/components/ImageDnd/typesafeDnd.tsx b/invokeai/frontend/web/src/app/components/ImageDnd/typesafeDnd.tsx index af4b5bbe3b..1b2b10c897 100644 --- a/invokeai/frontend/web/src/app/components/ImageDnd/typesafeDnd.tsx +++ b/invokeai/frontend/web/src/app/components/ImageDnd/typesafeDnd.tsx @@ -175,9 +175,7 @@ export const isValidDrop = ( const destinationBoard = overData.context.boardId; const isSameBoard = currentBoard === destinationBoard; - const isDestinationValid = !currentBoard - ? destinationBoard !== 'no_board' - : true; + const isDestinationValid = !currentBoard ? destinationBoard : true; return !isSameBoard && isDestinationValid; } diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx index 787a08a136..07fde01f9f 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx @@ -19,12 +19,12 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import IAIDroppable from 'common/components/IAIDroppable'; import { boardIdSelected } from 'features/gallery/store/gallerySlice'; import { memo, useCallback, useMemo, useState } from 'react'; -import { FaFolder } from 'react-icons/fa'; +import { FaUser } from 'react-icons/fa'; import { useUpdateBoardMutation } from 'services/api/endpoints/boards'; import { useGetImageDTOQuery } from 'services/api/endpoints/images'; +import { useBoardTotal } from 'services/api/hooks/useBoardTotal'; import { BoardDTO } from 'services/api/types'; import BoardContextMenu from '../BoardContextMenu'; -import { useBoardTotal } from 'services/api/hooks/useBoardTotal'; const AUTO_ADD_BADGE_STYLES: ChakraProps['sx'] = { bg: 'accent.200', @@ -176,7 +176,7 @@ const GalleryBoard = memo( > { justifyContent: 'center', alignItems: 'center', px: 2, + bg: 'base.100', + _dark: { bg: 'base.800' }, _hover: { - bg: 'base.100', - _dark: { bg: 'base.800' }, + bg: 'base.200', + _dark: { bg: 'base.700' }, }, }} > diff --git a/invokeai/frontend/web/src/services/api/endpoints/boardImages.ts b/invokeai/frontend/web/src/services/api/endpoints/boardImages.ts index 368303c7c5..2dc292321e 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/boardImages.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/boardImages.ts @@ -1,52 +1,36 @@ -import { ImageDTO, OffsetPaginatedResults_ImageDTO_ } from 'services/api/types'; -import { ApiFullTagDescription, LIST_TAG, api } from '..'; -import { paths } from '../schema'; -import { BoardId } from 'features/gallery/store/gallerySlice'; - -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']; - -type RemoveImageFromBoardArg = - paths['/api/v1/board_images/']['delete']['requestBody']['content']['application/json']; +import { api } from '..'; 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[] = [ - { type: 'BoardImage', id: `${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; - }, - }), + // 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[] = [ + // { type: 'BoardImage', id: `${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; + // }, + // }), }), }); -export const { useListBoardImagesQuery } = boardImagesApi; +// export const { useListBoardImagesQuery } = boardImagesApi; diff --git a/invokeai/frontend/web/src/services/api/endpoints/boards.ts b/invokeai/frontend/web/src/services/api/endpoints/boards.ts index b019652ce5..098455789b 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/boards.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/boards.ts @@ -109,10 +109,25 @@ export const boardsApi = api.injectEndpoints({ deleteBoard: build.mutation({ query: (board_id) => ({ url: `boards/${board_id}`, method: 'DELETE' }), - invalidatesTags: (result, error, arg) => [ - { type: 'Board', id: arg }, + invalidatesTags: (result, error, board_id) => [ + { type: 'Board', id: LIST_TAG }, // invalidate the 'No Board' cache - { type: 'ImageList', id: getListImagesUrl({ board_id: 'none' }) }, + { + type: 'ImageList', + id: getListImagesUrl({ + board_id: 'none', + categories: IMAGE_CATEGORIES, + }), + }, + { + type: 'ImageList', + id: getListImagesUrl({ + board_id: 'none', + categories: ASSETS_CATEGORIES, + }), + }, + { type: 'BoardImagesTotal', id: 'none' }, + { type: 'BoardAssetsTotal', id: 'none' }, ], async onQueryStarted(board_id, { dispatch, queryFulfilled, getState }) { /** @@ -167,17 +182,10 @@ export const boardsApi = api.injectEndpoints({ 'listImages', queryArgs, (draft) => { - const oldCount = imagesAdapter - .getSelectors() - .selectTotal(draft); + const oldTotal = draft.total; const newState = imagesAdapter.updateMany(draft, updates); - const newCount = imagesAdapter - .getSelectors() - .selectTotal(newState); - draft.total = Math.max( - draft.total - (oldCount - newCount), - 0 - ); + const delta = newState.total - oldTotal; + draft.total = draft.total + delta; } ) ); @@ -197,9 +205,24 @@ export const boardsApi = api.injectEndpoints({ method: 'DELETE', params: { include_images: true }, }), - invalidatesTags: (result, error, arg) => [ - { type: 'Board', id: arg }, - { type: 'ImageList', id: getListImagesUrl({ board_id: 'none' }) }, + invalidatesTags: (result, error, board_id) => [ + { type: 'Board', id: LIST_TAG }, + { + type: 'ImageList', + id: getListImagesUrl({ + board_id: 'none', + categories: IMAGE_CATEGORIES, + }), + }, + { + type: 'ImageList', + id: getListImagesUrl({ + board_id: 'none', + categories: ASSETS_CATEGORIES, + }), + }, + { type: 'BoardImagesTotal', id: 'none' }, + { type: 'BoardAssetsTotal', id: 'none' }, ], async onQueryStarted(board_id, { dispatch, queryFulfilled, getState }) { /** @@ -231,20 +254,13 @@ export const boardsApi = api.injectEndpoints({ 'listImages', queryArgs, (draft) => { - const oldCount = imagesAdapter - .getSelectors() - .selectTotal(draft); + const oldTotal = draft.total; const newState = imagesAdapter.removeMany( draft, deleted_images ); - const newCount = imagesAdapter - .getSelectors() - .selectTotal(newState); - draft.total = Math.max( - draft.total - (oldCount - newCount), - 0 - ); + const delta = newState.total - oldTotal; + draft.total = draft.total + delta; } ) ); diff --git a/invokeai/frontend/web/src/services/api/endpoints/images.ts b/invokeai/frontend/web/src/services/api/endpoints/images.ts index e0cfbd13ea..4b9443c00f 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/images.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/images.ts @@ -6,6 +6,7 @@ import { BoardId, IMAGE_CATEGORIES, } from 'features/gallery/store/gallerySlice'; +import { getCategories } from 'features/gallery/store/util'; import queryString from 'query-string'; import { ApiFullTagDescription, api } from '..'; import { components, paths } from '../schema'; @@ -15,8 +16,7 @@ import { OffsetPaginatedResults_ImageDTO_, PostUploadAction, } from '../types'; -import { getCacheAction, getIsImageInDateRange } from './util'; -import { getCategories } from 'features/gallery/store/util'; +import { getIsImageInDateRange } from './util'; export type ListImagesArgs = NonNullable< paths['/api/v1/images/']['get']['parameters']['query'] @@ -502,7 +502,6 @@ export const imagesApi = api.injectEndpoints({ }; }, invalidatesTags: (result, error, { board_id, imageDTO }) => [ - { type: 'BoardImage' }, { type: 'Board', id: board_id }, { type: 'BoardImagesTotal', id: board_id }, { type: 'BoardImagesTotal', id: imageDTO.board_id ?? 'none' }, @@ -636,7 +635,6 @@ export const imagesApi = api.injectEndpoints({ }; }, invalidatesTags: (result, error, { imageDTO }) => [ - { type: 'BoardImage' }, { type: 'Board', id: imageDTO.board_id }, { type: 'BoardImagesTotal', id: imageDTO.board_id }, { type: 'BoardImagesTotal', id: 'none' }, diff --git a/invokeai/frontend/web/src/services/api/endpoints/util.ts b/invokeai/frontend/web/src/services/api/endpoints/util.ts index d613711dc2..0172c1af44 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/util.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/util.ts @@ -25,27 +25,27 @@ export const getIsImageInDateRange = ( return false; }; -/** - * Determines the action we should take when an image may need to be added or updated in a cache. - */ -export const getCacheAction = ( - data: ImageCache | undefined, - imageDTO: ImageDTO -): 'add' | 'update' | 'none' => { - const isInDateRange = getIsImageInDateRange(data, imageDTO); - const isCacheFullyPopulated = data && data.total === data.ids.length; - const shouldUpdateCache = - Boolean(isInDateRange) || Boolean(isCacheFullyPopulated); +// /** +// * Determines the action we should take when an image may need to be added or updated in a cache. +// */ +// export const getCacheAction = ( +// data: ImageCache | undefined, +// imageDTO: ImageDTO +// ): 'add' | 'update' | 'none' => { +// const isInDateRange = getIsImageInDateRange(data, imageDTO); +// const isCacheFullyPopulated = data && data.total === data.ids.length; +// const shouldUpdateCache = +// Boolean(isInDateRange) || Boolean(isCacheFullyPopulated); - const isImageInCache = data && data.ids.includes(imageDTO.image_name); +// const isImageInCache = data && data.ids.includes(imageDTO.image_name); - if (shouldUpdateCache && isImageInCache) { - return 'update'; - } +// if (shouldUpdateCache && isImageInCache) { +// return 'update'; +// } - if (shouldUpdateCache && !isImageInCache) { - return 'add'; - } +// if (shouldUpdateCache && !isImageInCache) { +// return 'add'; +// } - return 'none'; -}; +// return 'none'; +// };