NEWONE1 / invokeai /frontend /web /src /features /deleteImageModal /components /DeleteImageModal.tsx
| import { ConfirmationAlertDialog, Divider, Flex, FormControl, FormLabel, Switch, Text } from '@invoke-ai/ui-library'; | |
| import { createSelector } from '@reduxjs/toolkit'; | |
| import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; | |
| import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; | |
| import { useAssertSingleton } from 'common/hooks/useAssertSingleton'; | |
| import { selectCanvasSlice } from 'features/controlLayers/store/selectors'; | |
| import { imageDeletionConfirmed } from 'features/deleteImageModal/store/actions'; | |
| import { getImageUsage, selectImageUsage } from 'features/deleteImageModal/store/selectors'; | |
| import { | |
| imageDeletionCanceled, | |
| isModalOpenChanged, | |
| selectDeleteImageModalSlice, | |
| } from 'features/deleteImageModal/store/slice'; | |
| import type { ImageUsage } from 'features/deleteImageModal/store/types'; | |
| import { selectNodesSlice } from 'features/nodes/store/selectors'; | |
| import { selectUpscaleSlice } from 'features/parameters/store/upscaleSlice'; | |
| import { selectSystemSlice, setShouldConfirmOnDelete } from 'features/system/store/systemSlice'; | |
| import { some } from 'lodash-es'; | |
| import type { ChangeEvent } from 'react'; | |
| import { memo, useCallback } from 'react'; | |
| import { useTranslation } from 'react-i18next'; | |
| import ImageUsageMessage from './ImageUsageMessage'; | |
| const selectImageUsages = createMemoizedSelector( | |
| [selectDeleteImageModalSlice, selectNodesSlice, selectCanvasSlice, selectImageUsage, selectUpscaleSlice], | |
| (deleteImageModal, nodes, canvas, imagesUsage, upscale) => { | |
| const { imagesToDelete } = deleteImageModal; | |
| const allImageUsage = (imagesToDelete ?? []).map(({ image_name }) => | |
| getImageUsage(nodes, canvas, upscale, image_name) | |
| ); | |
| const imageUsageSummary: ImageUsage = { | |
| isUpscaleImage: some(allImageUsage, (i) => i.isUpscaleImage), | |
| isRasterLayerImage: some(allImageUsage, (i) => i.isRasterLayerImage), | |
| isInpaintMaskImage: some(allImageUsage, (i) => i.isInpaintMaskImage), | |
| isRegionalGuidanceImage: some(allImageUsage, (i) => i.isRegionalGuidanceImage), | |
| isNodesImage: some(allImageUsage, (i) => i.isNodesImage), | |
| isControlLayerImage: some(allImageUsage, (i) => i.isControlLayerImage), | |
| isReferenceImage: some(allImageUsage, (i) => i.isReferenceImage), | |
| }; | |
| return { | |
| imagesToDelete, | |
| imagesUsage, | |
| imageUsageSummary, | |
| }; | |
| } | |
| ); | |
| const selectShouldConfirmOnDelete = createSelector(selectSystemSlice, (system) => system.shouldConfirmOnDelete); | |
| const selectIsModalOpen = createSelector( | |
| selectDeleteImageModalSlice, | |
| (deleteImageModal) => deleteImageModal.isModalOpen | |
| ); | |
| const DeleteImageModal = () => { | |
| useAssertSingleton('DeleteImageModal'); | |
| const dispatch = useAppDispatch(); | |
| const { t } = useTranslation(); | |
| const shouldConfirmOnDelete = useAppSelector(selectShouldConfirmOnDelete); | |
| const isModalOpen = useAppSelector(selectIsModalOpen); | |
| const { imagesToDelete, imagesUsage, imageUsageSummary } = useAppSelector(selectImageUsages); | |
| const handleChangeShouldConfirmOnDelete = useCallback( | |
| (e: ChangeEvent<HTMLInputElement>) => dispatch(setShouldConfirmOnDelete(!e.target.checked)), | |
| [dispatch] | |
| ); | |
| const handleClose = useCallback(() => { | |
| dispatch(imageDeletionCanceled()); | |
| dispatch(isModalOpenChanged(false)); | |
| }, [dispatch]); | |
| const handleDelete = useCallback(() => { | |
| if (!imagesToDelete.length || !imagesUsage.length) { | |
| return; | |
| } | |
| dispatch(imageDeletionCanceled()); | |
| dispatch(imageDeletionConfirmed({ imageDTOs: imagesToDelete, imagesUsage })); | |
| }, [dispatch, imagesToDelete, imagesUsage]); | |
| return ( | |
| <ConfirmationAlertDialog | |
| title={t('gallery.deleteImage', { count: imagesToDelete.length })} | |
| isOpen={isModalOpen} | |
| onClose={handleClose} | |
| cancelButtonText={t('common.cancel')} | |
| acceptButtonText={t('common.delete')} | |
| acceptCallback={handleDelete} | |
| useInert={false} | |
| > | |
| <Flex direction="column" gap={3}> | |
| <ImageUsageMessage imageUsage={imageUsageSummary} /> | |
| <Divider /> | |
| <Text>{t('gallery.deleteImagePermanent')}</Text> | |
| <Text>{t('common.areYouSure')}</Text> | |
| <FormControl> | |
| <FormLabel>{t('common.dontAskMeAgain')}</FormLabel> | |
| <Switch isChecked={!shouldConfirmOnDelete} onChange={handleChangeShouldConfirmOnDelete} /> | |
| </FormControl> | |
| </Flex> | |
| </ConfirmationAlertDialog> | |
| ); | |
| }; | |
| export default memo(DeleteImageModal); | |