From 442a6bffa493531cc0839586e3465f8dab8ce452 Mon Sep 17 00:00:00 2001 From: SammCheese Date: Sat, 15 Apr 2023 06:05:48 +0200 Subject: [PATCH] feat: add "Hide Preview" Button --- .../components/CurrentImageButtons.tsx | 26 +++++++++++++++++-- .../gallery/components/CurrentImageHidden.tsx | 21 +++++++++++++++ .../components/CurrentImagePreview.tsx | 16 +++++++++--- .../features/gallery/store/gallerySlice.ts | 6 +++++ .../tabs/ImageToImage/InitImagePreview.tsx | 10 ++++++- 5 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 invokeai/frontend/web/src/features/gallery/components/CurrentImageHidden.tsx diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx index 90e554f7f9..0d363a6238 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx @@ -8,7 +8,10 @@ import IAIButton from 'common/components/IAIButton'; import IAIIconButton from 'common/components/IAIIconButton'; import IAIPopover from 'common/components/IAIPopover'; import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice'; -import { GalleryState } from 'features/gallery/store/gallerySlice'; +import { + GalleryState, + setHiddenState, +} from 'features/gallery/store/gallerySlice'; import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors'; import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice'; import FaceRestoreSettings from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreSettings'; @@ -38,6 +41,8 @@ import { FaDownload, FaExpand, FaExpandArrowsAlt, + FaEye, + FaEyeSlash, FaGrinStars, FaQuoteRight, FaSeedling, @@ -77,7 +82,7 @@ const currentImageButtonsSelector = createSelector( const { shouldShowImageDetails } = ui; - const { intermediateImage, currentImage } = gallery; + const { intermediateImage, currentImage, hidden } = gallery; return { isProcessing, @@ -91,6 +96,7 @@ const currentImageButtonsSelector = createSelector( shouldShowImageDetails, activeTabName, isLightboxOpen, + hidden, }; }, { @@ -120,6 +126,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => { currentImage, isLightboxOpen, activeTabName, + hidden, } = useAppSelector(currentImageButtonsSelector); const toast = useToast(); @@ -188,6 +195,10 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => { [currentImage] ); + const handleHiddenChange = () => { + dispatch(setHiddenState(!hidden)); + }; + const handleClickUseAllParameters = () => { if (!currentImage) return; currentImage.metadata && dispatch(setAllParameters(currentImage.metadata)); @@ -455,6 +466,17 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => { + : } + tooltip={ + !hidden ? t('parameters.hidePreview') : t('parameters.showPreview') + } + aria-label={ + !hidden ? t('parameters.hidePreview') : t('parameters.showPreview') + } + isChecked={hidden} + onClick={handleHiddenChange} + /> } tooltip={ diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImageHidden.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImageHidden.tsx new file mode 100644 index 0000000000..2674f6a0ba --- /dev/null +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImageHidden.tsx @@ -0,0 +1,21 @@ +import { Flex } from '@chakra-ui/react'; +import { FaEyeSlash } from 'react-icons/fa'; + +const CurrentImageHidden = () => { + return ( + + + + ); +}; + +export default CurrentImageHidden; diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx index 76dc410b81..283e179ae5 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx @@ -10,17 +10,19 @@ import { gallerySelector } from '../store/gallerySelectors'; import CurrentImageFallback from './CurrentImageFallback'; import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer'; import NextPrevImageButtons from './NextPrevImageButtons'; +import CurrentImageHidden from './CurrentImageHidden'; export const imagesSelector = createSelector( [gallerySelector, uiSelector], (gallery: GalleryState, ui) => { - const { currentImage, intermediateImage } = gallery; + const { currentImage, intermediateImage, hidden } = gallery; const { shouldShowImageDetails } = ui; return { imageToDisplay: intermediateImage ? intermediateImage : currentImage, isIntermediate: Boolean(intermediateImage), shouldShowImageDetails, + hidden, }; }, { @@ -31,7 +33,7 @@ export const imagesSelector = createSelector( ); export default function CurrentImagePreview() { - const { shouldShowImageDetails, imageToDisplay, isIntermediate } = + const { shouldShowImageDetails, imageToDisplay, isIntermediate, hidden } = useAppSelector(imagesSelector); return ( @@ -46,10 +48,16 @@ export default function CurrentImagePreview() { > {imageToDisplay && ( : undefined} + fallback={ + hidden ? ( + + ) : !isIntermediate ? ( + + ) : undefined + } sx={{ objectFit: 'contain', maxWidth: '100%', diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts index dbb173c74a..a78ba4cef4 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts @@ -39,6 +39,7 @@ export interface GalleryState { currentCategory: GalleryCategory; galleryWidth: number; shouldUseSingleGalleryColumn: boolean; + hidden: boolean; } const initialState: GalleryState = { @@ -63,6 +64,7 @@ const initialState: GalleryState = { }, galleryWidth: 300, shouldUseSingleGalleryColumn: false, + hidden: false, }; export const gallerySlice = createSlice({ @@ -251,11 +253,15 @@ export const gallerySlice = createSlice({ ) => { state.shouldUseSingleGalleryColumn = action.payload; }, + setHiddenState: (state, action: PayloadAction) => { + state.hidden = action.payload; + }, }, }); export const { addImage, + setHiddenState, clearIntermediateImage, removeImage, setCurrentImage, diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/InitImagePreview.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/InitImagePreview.tsx index 9eb26129a7..69e1058a9e 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/InitImagePreview.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/InitImagePreview.tsx @@ -2,6 +2,7 @@ import { Flex, Image, Text, useToast } from '@chakra-ui/react'; import { RootState } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton'; +import CurrentImageHidden from 'features/gallery/components/CurrentImageHidden'; import { clearInitialImage } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; @@ -10,6 +11,8 @@ export default function InitImagePreview() { (state: RootState) => state.generation.initialImage ); + const { hidden } = useAppSelector((state: RootState) => state.gallery); + const { t } = useTranslation(); const dispatch = useAppDispatch(); @@ -66,8 +69,13 @@ export default function InitImagePreview() { position: 'absolute', }} src={ - typeof initialImage === 'string' ? initialImage : initialImage.url + hidden + ? undefined + : typeof initialImage === 'string' + ? initialImage + : initialImage.url } + fallback={} onError={alertMissingInitImage} />