From bd1b84f7d0004d02cb26fc19bdfadf6e3c28f7c0 Mon Sep 17 00:00:00 2001 From: Mary Hipp Rogers Date: Wed, 17 May 2023 11:52:37 -0400 Subject: [PATCH] tell user to refresh page on image load error (#3425) * refetch images list if error loading * tell user to refresh instead of refetching * unused import * feat(ui): use `useAppToaster` to make toast * fix(ui): clear selected/initial image on error --------- Co-authored-by: Mary Hipp Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com> --- .../components/CurrentImagePreview.tsx | 21 ++++++++++++-- .../ImageToImage/InitialImagePreview.tsx | 28 ++++++++++++------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx index b1dbed5a81..879123af2a 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx @@ -1,6 +1,6 @@ import { Box, Flex, Image } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; -import { useAppSelector } from 'app/store/storeHooks'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useGetUrl } from 'common/util/getUrl'; import { uiSelector } from 'features/ui/store/uiSelectors'; import { isEqual } from 'lodash-es'; @@ -8,11 +8,13 @@ import { isEqual } from 'lodash-es'; import { gallerySelector } from '../store/gallerySelectors'; import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer'; import NextPrevImageButtons from './NextPrevImageButtons'; -import CurrentImageHidden from './CurrentImageHidden'; import { DragEvent, memo, useCallback } from 'react'; import { systemSelector } from 'features/system/store/systemSelectors'; import ImageFallbackSpinner from './ImageFallbackSpinner'; import ImageMetadataOverlay from 'common/components/ImageMetadataOverlay'; +import { configSelector } from '../../system/store/configSelectors'; +import { useAppToaster } from 'app/components/Toaster'; +import { imageSelected } from '../store/gallerySlice'; export const imagesSelector = createSelector( [uiSelector, gallerySelector, systemSelector], @@ -49,7 +51,10 @@ const CurrentImagePreview = () => { shouldShowProgressInViewer, shouldAntialiasProgressImage, } = useAppSelector(imagesSelector); + const { shouldFetchImages } = useAppSelector(configSelector); const { getUrl } = useGetUrl(); + const toaster = useAppToaster(); + const dispatch = useAppDispatch(); const handleDragStart = useCallback( (e: DragEvent) => { @@ -63,6 +68,17 @@ const CurrentImagePreview = () => { [image] ); + const handleError = useCallback(() => { + dispatch(imageSelected()); + if (shouldFetchImages) { + toaster({ + title: 'Something went wrong, please refresh', + status: 'error', + isClosable: true, + }); + } + }, [dispatch, toaster, shouldFetchImages]); + return ( { position: 'absolute', borderRadius: 'base', }} + onError={handleError} /> diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImagePreview.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImagePreview.tsx index ca54d2fd67..9ae1ff55e2 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImagePreview.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImagePreview.tsx @@ -1,10 +1,8 @@ import { Flex, Icon, Image } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import SelectImagePlaceholder from 'common/components/SelectImagePlaceholder'; import { useGetUrl } from 'common/util/getUrl'; import { clearInitialImage } from 'features/parameters/store/generationSlice'; -import { addToast } from 'features/system/store/systemSlice'; import { DragEvent, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { ImageType } from 'services/api'; @@ -14,6 +12,8 @@ import { initialImageSelected } from 'features/parameters/store/actions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import ImageFallbackSpinner from 'features/gallery/components/ImageFallbackSpinner'; import { FaImage } from 'react-icons/fa'; +import { configSelector } from '../../../../system/store/configSelectors'; +import { useAppToaster } from 'app/components/Toaster'; const selector = createSelector( [generationSelector], @@ -28,21 +28,29 @@ const selector = createSelector( const InitialImagePreview = () => { const { initialImage } = useAppSelector(selector); + const { shouldFetchImages } = useAppSelector(configSelector); const { getUrl } = useGetUrl(); const dispatch = useAppDispatch(); const { t } = useTranslation(); + const toaster = useAppToaster(); - const onError = () => { - dispatch( - addToast({ + const handleError = useCallback(() => { + dispatch(clearInitialImage()); + if (shouldFetchImages) { + toaster({ + title: 'Something went wrong, please refresh', + status: 'error', + isClosable: true, + }); + } else { + toaster({ title: t('toast.parametersFailed'), description: t('toast.parametersFailedDesc'), status: 'error', isClosable: true, - }) - ); - dispatch(clearInitialImage()); - }; + }); + } + }, [dispatch, t, toaster, shouldFetchImages]); const handleDrop = useCallback( (e: DragEvent) => { @@ -71,7 +79,7 @@ const InitialImagePreview = () => { src={getUrl(initialImage?.url)} fallbackStrategy="beforeLoadOrError" fallback={} - onError={onError} + onError={handleError} sx={{ objectFit: 'contain', maxWidth: '100%',