mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Fixes #1295
This commit is contained in:
parent
050d72478e
commit
1e7a5fda24
@ -8,6 +8,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
GalleryCategory,
|
GalleryCategory,
|
||||||
GalleryState,
|
GalleryState,
|
||||||
|
removeImage,
|
||||||
} from '../../features/gallery/gallerySlice';
|
} from '../../features/gallery/gallerySlice';
|
||||||
import { OptionsState } from '../../features/options/optionsSlice';
|
import { OptionsState } from '../../features/options/optionsSlice';
|
||||||
import {
|
import {
|
||||||
@ -163,6 +164,7 @@ const makeSocketIOEmitters = (
|
|||||||
},
|
},
|
||||||
emitDeleteImage: (imageToDelete: InvokeAI.Image) => {
|
emitDeleteImage: (imageToDelete: InvokeAI.Image) => {
|
||||||
const { url, uuid, category } = imageToDelete;
|
const { url, uuid, category } = imageToDelete;
|
||||||
|
dispatch(removeImage(imageToDelete));
|
||||||
socketio.emit('deleteImage', url, uuid, category);
|
socketio.emit('deleteImage', url, uuid, category);
|
||||||
},
|
},
|
||||||
emitRequestImages: (category: GalleryCategory) => {
|
emitRequestImages: (category: GalleryCategory) => {
|
||||||
|
@ -17,13 +17,7 @@ import { SystemState } from '../system/systemSlice';
|
|||||||
import IAIButton from '../../common/components/IAIButton';
|
import IAIButton from '../../common/components/IAIButton';
|
||||||
import { runESRGAN, runFacetool } from '../../app/socketio/actions';
|
import { runESRGAN, runFacetool } from '../../app/socketio/actions';
|
||||||
import IAIIconButton from '../../common/components/IAIIconButton';
|
import IAIIconButton from '../../common/components/IAIIconButton';
|
||||||
import {
|
import { MdDelete, MdFace, MdHd, MdImage, MdInfo } from 'react-icons/md';
|
||||||
MdDelete,
|
|
||||||
MdFace,
|
|
||||||
MdHd,
|
|
||||||
MdImage,
|
|
||||||
MdInfo,
|
|
||||||
} from 'react-icons/md';
|
|
||||||
import InvokePopover from './InvokePopover';
|
import InvokePopover from './InvokePopover';
|
||||||
import UpscaleOptions from '../options/AdvancedOptions/Upscale/UpscaleOptions';
|
import UpscaleOptions from '../options/AdvancedOptions/Upscale/UpscaleOptions';
|
||||||
import FaceRestoreOptions from '../options/AdvancedOptions/FaceRestore/FaceRestoreOptions';
|
import FaceRestoreOptions from '../options/AdvancedOptions/FaceRestore/FaceRestoreOptions';
|
||||||
@ -360,7 +354,9 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
|||||||
icon={<MdDelete />}
|
icon={<MdDelete />}
|
||||||
tooltip="Delete Image"
|
tooltip="Delete Image"
|
||||||
aria-label="Delete Image"
|
aria-label="Delete Image"
|
||||||
isDisabled={Boolean(intermediateImage)}
|
isDisabled={
|
||||||
|
Boolean(intermediateImage) || !isConnected || isProcessing
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</DeleteImageModal>
|
</DeleteImageModal>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,6 +30,13 @@ import { setShouldConfirmOnDelete, SystemState } from '../system/systemSlice';
|
|||||||
import * as InvokeAI from '../../app/invokeai';
|
import * as InvokeAI from '../../app/invokeai';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
|
const systemSelector = createSelector(
|
||||||
|
(state: RootState) => state.system,
|
||||||
|
(system: SystemState) => {
|
||||||
|
const { shouldConfirmOnDelete, isConnected, isProcessing } = system;
|
||||||
|
return { shouldConfirmOnDelete, isConnected, isProcessing };
|
||||||
|
}
|
||||||
|
);
|
||||||
interface DeleteImageModalProps {
|
interface DeleteImageModalProps {
|
||||||
/**
|
/**
|
||||||
* Component which, on click, should delete the image/open the modal.
|
* Component which, on click, should delete the image/open the modal.
|
||||||
@ -41,11 +48,6 @@ interface DeleteImageModalProps {
|
|||||||
image: InvokeAI.Image;
|
image: InvokeAI.Image;
|
||||||
}
|
}
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
|
||||||
(state: RootState) => state.system,
|
|
||||||
(system: SystemState) => system.shouldConfirmOnDelete
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Needs a child, which will act as the button to delete an image.
|
* Needs a child, which will act as the button to delete an image.
|
||||||
* If system.shouldConfirmOnDelete is true, a confirmation modal is displayed.
|
* If system.shouldConfirmOnDelete is true, a confirmation modal is displayed.
|
||||||
@ -56,9 +58,9 @@ const DeleteImageModal = forwardRef(
|
|||||||
({ image, children }: DeleteImageModalProps, ref) => {
|
({ image, children }: DeleteImageModalProps, ref) => {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const shouldConfirmOnDelete = useAppSelector(systemSelector);
|
const { shouldConfirmOnDelete, isConnected, isProcessing } =
|
||||||
|
useAppSelector(systemSelector);
|
||||||
const cancelRef = useRef<HTMLButtonElement>(null);
|
const cancelRef = useRef<HTMLButtonElement>(null);
|
||||||
const toast = useToast();
|
|
||||||
|
|
||||||
const handleClickDelete = (e: SyntheticEvent) => {
|
const handleClickDelete = (e: SyntheticEvent) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -66,13 +68,9 @@ const DeleteImageModal = forwardRef(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
dispatch(deleteImage(image));
|
if (isConnected && !isProcessing) {
|
||||||
toast({
|
dispatch(deleteImage(image));
|
||||||
title: 'Image Deleted',
|
}
|
||||||
status: 'success',
|
|
||||||
duration: 2500,
|
|
||||||
isClosable: true,
|
|
||||||
});
|
|
||||||
onClose();
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,8 +39,12 @@ const memoEqualityCheck = (
|
|||||||
*/
|
*/
|
||||||
const HoverableImage = memo((props: HoverableImageProps) => {
|
const HoverableImage = memo((props: HoverableImageProps) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { activeTabName, galleryImageObjectFit, galleryImageMinimumWidth } =
|
const {
|
||||||
useAppSelector(hoverableImageSelector);
|
activeTabName,
|
||||||
|
galleryImageObjectFit,
|
||||||
|
galleryImageMinimumWidth,
|
||||||
|
mayDeleteImage,
|
||||||
|
} = useAppSelector(hoverableImageSelector);
|
||||||
const { image, isSelected } = props;
|
const { image, isSelected } = props;
|
||||||
const { url, uuid, metadata } = image;
|
const { url, uuid, metadata } = image;
|
||||||
|
|
||||||
@ -177,6 +181,7 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
size="xs"
|
size="xs"
|
||||||
variant={'imageHoverIconButton'}
|
variant={'imageHoverIconButton'}
|
||||||
fontSize={14}
|
fontSize={14}
|
||||||
|
isDisabled={!mayDeleteImage}
|
||||||
/>
|
/>
|
||||||
</DeleteImageModal>
|
</DeleteImageModal>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { RootState } from '../../app/store';
|
import { RootState } from '../../app/store';
|
||||||
import { activeTabNameSelector } from '../options/optionsSelectors';
|
import { activeTabNameSelector } from '../options/optionsSelectors';
|
||||||
import { OptionsState } from '../options/optionsSlice';
|
import { OptionsState } from '../options/optionsSlice';
|
||||||
|
import { SystemState } from '../system/systemSlice';
|
||||||
import { GalleryState } from './gallerySlice';
|
import { GalleryState } from './gallerySlice';
|
||||||
|
|
||||||
export const imageGallerySelector = createSelector(
|
export const imageGallerySelector = createSelector(
|
||||||
@ -46,9 +47,20 @@ export const imageGallerySelector = createSelector(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const hoverableImageSelector = createSelector(
|
export const hoverableImageSelector = createSelector(
|
||||||
[(state: RootState) => state.options, (state: RootState) => state.gallery, activeTabNameSelector],
|
[
|
||||||
(options: OptionsState, gallery: GalleryState, activeTabName) => {
|
(state: RootState) => state.options,
|
||||||
|
(state: RootState) => state.gallery,
|
||||||
|
(state: RootState) => state.system,
|
||||||
|
activeTabNameSelector,
|
||||||
|
],
|
||||||
|
(
|
||||||
|
options: OptionsState,
|
||||||
|
gallery: GalleryState,
|
||||||
|
system: SystemState,
|
||||||
|
activeTabName
|
||||||
|
) => {
|
||||||
return {
|
return {
|
||||||
|
mayDeleteImage: system.isConnected && !system.isProcessing,
|
||||||
galleryImageObjectFit: gallery.galleryImageObjectFit,
|
galleryImageObjectFit: gallery.galleryImageObjectFit,
|
||||||
galleryImageMinimumWidth: gallery.galleryImageMinimumWidth,
|
galleryImageMinimumWidth: gallery.galleryImageMinimumWidth,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user