From 3a610e1a65ace9aef57285e4487f56cfab7e1f0f Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Fri, 21 Jul 2023 15:00:07 +1000 Subject: [PATCH] fix(ui): more fixing of auto-add --- .../socketio/socketInvocationComplete.ts | 7 + .../gallery/components/Boards/AutoAddIcon.tsx | 19 +++ .../components/Boards/BoardAutoAddSelect.tsx | 2 +- .../components/Boards/BoardContextMenu.tsx | 47 +++++- .../Boards/BoardsList/GalleryBoard.tsx | 7 +- .../Boards/BoardsList/NoBoardBoard.tsx | 156 ++++++++++-------- .../Boards/GalleryBoardContextMenuItems.tsx | 51 +----- .../gallery/components/GalleryBoardName.tsx | 14 +- .../components/ImageGalleryContent.tsx | 43 +++-- .../features/gallery/store/gallerySlice.ts | 16 +- .../web/src/services/api/endpoints/boards.ts | 6 - 11 files changed, 197 insertions(+), 171 deletions(-) create mode 100644 invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts index 24cec186be..df67f286d6 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts @@ -84,6 +84,13 @@ export const addInvocationCompleteEventListener = () => { ); } + dispatch( + imagesApi.util.invalidateTags([ + { type: 'BoardImagesTotal', id: autoAddBoardId ?? 'none' }, + { type: 'BoardAssetsTotal', id: autoAddBoardId ?? 'none' }, + ]) + ); + const { selectedBoardId, shouldAutoSwitch } = gallery; // If auto-switch is enabled, select the new image diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx new file mode 100644 index 0000000000..39b0a6f53f --- /dev/null +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx @@ -0,0 +1,19 @@ +import { Flex, Icon } from '@chakra-ui/react'; +import { FaPlus } from 'react-icons/fa'; + +const AutoAddIcon = () => { + return ( + + + + ); +}; + +export default AutoAddIcon; diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx index 827d49c88e..ad0e5ab80d 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx @@ -52,7 +52,7 @@ const BoardAutoAddSelect = () => { return; } - dispatch(autoAddBoardIdChanged(v === 'none' ? null : v)); + dispatch(autoAddBoardIdChanged(v === 'none' ? undefined : v)); }, [dispatch] ); diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx index 3b3303f0c8..3f4219bee1 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx @@ -1,9 +1,15 @@ -import { Box, MenuItem, MenuList } from '@chakra-ui/react'; -import { useAppDispatch } from 'app/store/storeHooks'; +import { MenuItem, MenuList } from '@chakra-ui/react'; +import { createSelector } from '@reduxjs/toolkit'; +import { stateSelector } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { ContextMenu, ContextMenuProps } from 'chakra-ui-contextmenu'; -import { boardIdSelected } from 'features/gallery/store/gallerySlice'; -import { memo, useCallback } from 'react'; -import { FaFolder } from 'react-icons/fa'; +import { + autoAddBoardIdChanged, + boardIdSelected, +} from 'features/gallery/store/gallerySlice'; +import { memo, useCallback, useMemo } from 'react'; +import { FaFolder, FaMinus, FaPlus } from 'react-icons/fa'; import { BoardDTO } from 'services/api/types'; import { menuListMotionProps } from 'theme/components/menu'; import GalleryBoardContextMenuItems from './GalleryBoardContextMenuItems'; @@ -11,7 +17,7 @@ import SystemBoardContextMenuItems from './SystemBoardContextMenuItems'; type Props = { board?: BoardDTO; - board_id: string; + board_id?: string; children: ContextMenuProps['children']; setBoardToDelete?: (board?: BoardDTO) => void; }; @@ -19,9 +25,30 @@ type Props = { const BoardContextMenu = memo( ({ board, board_id, setBoardToDelete, children }: Props) => { const dispatch = useAppDispatch(); + const selector = useMemo( + () => + createSelector( + stateSelector, + ({ gallery }) => { + const isSelectedForAutoAdd = board_id === gallery.autoAddBoardId; + + return { isSelectedForAutoAdd }; + }, + defaultSelectorOptions + ), + [board_id] + ); + + const { isSelectedForAutoAdd } = useAppSelector(selector); + const handleSelectBoard = useCallback(() => { dispatch(boardIdSelected(board?.board_id ?? board_id)); }, [board?.board_id, board_id, dispatch]); + + const handleAutoAdd = useCallback(() => { + dispatch(autoAddBoardIdChanged(board_id)); + }, [board_id, dispatch]); + return ( menuProps={{ size: 'sm', isLazy: true }} @@ -37,6 +64,14 @@ const BoardContextMenu = memo( } onClickCapture={handleSelectBoard}> Select Board + : } + onClickCapture={handleAutoAdd} + > + {isSelectedForAutoAdd + ? 'Disable Auto-Add' + : 'Auto-Add to this Board'} + {!board && } {board && ( + {isSelectedForAutoAdd && } { + const { autoAddBoardId } = gallery; + return { autoAddBoardId }; + }, + defaultSelectorOptions +); + const NoBoardBoard = memo(({ isSelected }: Props) => { const dispatch = useAppDispatch(); const { totalImages, totalAssets } = useBoardTotal(undefined); + const { autoAddBoardId } = useAppSelector(selector); const handleSelectBoard = useCallback(() => { dispatch(boardIdSelected(undefined)); }, [dispatch]); @@ -34,85 +49,92 @@ const NoBoardBoard = memo(({ isSelected }: Props) => { return ( - - - + {(ref) => ( + - - - - - {totalImages}/{totalAssets} - - - - Move} - /> + > + + + + + + {totalImages}/{totalAssets} + + + {!autoAddBoardId && } + + Move} + /> + + )} + ); diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx index 5d39eaaf28..14b954ed59 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx @@ -1,11 +1,6 @@ import { MenuItem } from '@chakra-ui/react'; -import { createSelector } from '@reduxjs/toolkit'; -import { stateSelector } from 'app/store/store'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; -import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice'; -import { memo, useCallback, useMemo } from 'react'; -import { FaMinus, FaPlus, FaTrash } from 'react-icons/fa'; +import { memo, useCallback } from 'react'; +import { FaTrash } from 'react-icons/fa'; import { BoardDTO } from 'services/api/types'; type Props = { @@ -14,25 +9,6 @@ type Props = { }; const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => { - const dispatch = useAppDispatch(); - - const selector = useMemo( - () => - createSelector( - stateSelector, - ({ gallery }) => { - const isSelectedForAutoAdd = - board.board_id === gallery.autoAddBoardId; - - return { isSelectedForAutoAdd }; - }, - defaultSelectorOptions - ), - [board.board_id] - ); - - const { isSelectedForAutoAdd } = useAppSelector(selector); - const handleDelete = useCallback(() => { if (!setBoardToDelete) { return; @@ -40,31 +16,8 @@ const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => { setBoardToDelete(board); }, [board, setBoardToDelete]); - const handleToggleAutoAdd = useCallback(() => { - dispatch( - autoAddBoardIdChanged(isSelectedForAutoAdd ? null : board.board_id) - ); - }, [board.board_id, dispatch, isSelectedForAutoAdd]); - return ( <> - {board.image_count > 0 && ( - <> - {/* } - onClickCapture={handleAddBoardToBatch} - > - Add Board to Batch - */} - - )} - : } - onClickCapture={handleToggleAutoAdd} - > - {isSelectedForAutoAdd ? 'Disable Auto-Add' : 'Auto-Add to this Board'} - } diff --git a/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx b/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx index 759d731e7e..6600a2b278 100644 --- a/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx @@ -51,7 +51,7 @@ const GalleryBoardName = (props: Props) => { as={Button} onClick={onToggle} size="sm" - variant="ghost" + // variant="ghost" sx={{ position: 'relative', gap: 2, @@ -59,12 +59,12 @@ const GalleryBoardName = (props: Props) => { justifyContent: 'center', alignItems: 'center', px: 2, - bg: 'base.100', - _dark: { bg: 'base.800' }, - _hover: { - bg: 'base.200', - _dark: { bg: 'base.700' }, - }, + // bg: 'base.100', + // _dark: { bg: 'base.800' }, + // _hover: { + // bg: 'base.200', + // _dark: { bg: 'base.700' }, + // }, }} > diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx index 7d85caee5e..8af04ff58a 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx @@ -3,6 +3,9 @@ import { ButtonGroup, Flex, Spacer, + Tab, + TabList, + Tabs, VStack, useDisclosure, } from '@chakra-ui/react'; @@ -87,30 +90,22 @@ const ImageGalleryContent = () => { gap: 2, }} > - - } - size="sm" - isChecked={galleryView === 'images'} - onClick={handleClickImages} - sx={{ - w: 'full', - }} - > - Images - - } - size="sm" - isChecked={galleryView === 'assets'} - onClick={handleClickAssets} - sx={{ - w: 'full', - }} - > - Assets - - + + + + Images + + + Assets + + + {selectedBoardId === 'batch' ? ( diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts index 642a75330b..ab4942d927 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts @@ -21,7 +21,7 @@ export type BoardId = string | undefined; type GalleryState = { selection: string[]; shouldAutoSwitch: boolean; - autoAddBoardId: string | null; + autoAddBoardId: string | undefined; galleryImageMinimumWidth: number; selectedBoardId: BoardId; galleryView: GalleryView; @@ -32,7 +32,7 @@ type GalleryState = { export const initialGalleryState: GalleryState = { selection: [], shouldAutoSwitch: true, - autoAddBoardId: null, + autoAddBoardId: undefined, galleryImageMinimumWidth: 96, selectedBoardId: undefined, galleryView: 'images', @@ -124,7 +124,10 @@ export const gallerySlice = createSlice({ state.batchImageNames = []; state.selection = []; }, - autoAddBoardIdChanged: (state, action: PayloadAction) => { + autoAddBoardIdChanged: ( + state, + action: PayloadAction + ) => { state.autoAddBoardId = action.payload; }, galleryViewChanged: (state, action: PayloadAction) => { @@ -137,10 +140,11 @@ export const gallerySlice = createSlice({ (state, action) => { const deletedBoardId = action.meta.arg.originalArgs; if (deletedBoardId === state.selectedBoardId) { - state.selectedBoardId = 'images'; + state.selectedBoardId = undefined; + state.galleryView = 'images'; } if (deletedBoardId === state.autoAddBoardId) { - state.autoAddBoardId = null; + state.autoAddBoardId = undefined; } } ); @@ -153,7 +157,7 @@ export const gallerySlice = createSlice({ } if (!boards.map((b) => b.board_id).includes(state.autoAddBoardId)) { - state.autoAddBoardId = null; + state.autoAddBoardId = undefined; } } ); diff --git a/invokeai/frontend/web/src/services/api/endpoints/boards.ts b/invokeai/frontend/web/src/services/api/endpoints/boards.ts index 098455789b..779e5708fe 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/boards.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/boards.ts @@ -190,9 +190,6 @@ export const boardsApi = api.injectEndpoints({ ) ); }); - - // after deleting a board, select the 'All Images' board - dispatch(boardIdSelected('images')); } catch { //no-op } @@ -265,9 +262,6 @@ export const boardsApi = api.injectEndpoints({ ) ); }); - - // after deleting a board, select the 'All Images' board - dispatch(boardIdSelected('images')); } catch { //no-op }