mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
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 <maryhipp@Marys-MacBook-Air.local> Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
This commit is contained in:
parent
1d9c115225
commit
bd1b84f7d0
@ -1,6 +1,6 @@
|
|||||||
import { Box, Flex, Image } from '@chakra-ui/react';
|
import { Box, Flex, Image } from '@chakra-ui/react';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
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 { useGetUrl } from 'common/util/getUrl';
|
||||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
@ -8,11 +8,13 @@ import { isEqual } from 'lodash-es';
|
|||||||
import { gallerySelector } from '../store/gallerySelectors';
|
import { gallerySelector } from '../store/gallerySelectors';
|
||||||
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
|
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
|
||||||
import NextPrevImageButtons from './NextPrevImageButtons';
|
import NextPrevImageButtons from './NextPrevImageButtons';
|
||||||
import CurrentImageHidden from './CurrentImageHidden';
|
|
||||||
import { DragEvent, memo, useCallback } from 'react';
|
import { DragEvent, memo, useCallback } from 'react';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import ImageFallbackSpinner from './ImageFallbackSpinner';
|
import ImageFallbackSpinner from './ImageFallbackSpinner';
|
||||||
import ImageMetadataOverlay from 'common/components/ImageMetadataOverlay';
|
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(
|
export const imagesSelector = createSelector(
|
||||||
[uiSelector, gallerySelector, systemSelector],
|
[uiSelector, gallerySelector, systemSelector],
|
||||||
@ -49,7 +51,10 @@ const CurrentImagePreview = () => {
|
|||||||
shouldShowProgressInViewer,
|
shouldShowProgressInViewer,
|
||||||
shouldAntialiasProgressImage,
|
shouldAntialiasProgressImage,
|
||||||
} = useAppSelector(imagesSelector);
|
} = useAppSelector(imagesSelector);
|
||||||
|
const { shouldFetchImages } = useAppSelector(configSelector);
|
||||||
const { getUrl } = useGetUrl();
|
const { getUrl } = useGetUrl();
|
||||||
|
const toaster = useAppToaster();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const handleDragStart = useCallback(
|
const handleDragStart = useCallback(
|
||||||
(e: DragEvent<HTMLDivElement>) => {
|
(e: DragEvent<HTMLDivElement>) => {
|
||||||
@ -63,6 +68,17 @@ const CurrentImagePreview = () => {
|
|||||||
[image]
|
[image]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleError = useCallback(() => {
|
||||||
|
dispatch(imageSelected());
|
||||||
|
if (shouldFetchImages) {
|
||||||
|
toaster({
|
||||||
|
title: 'Something went wrong, please refresh',
|
||||||
|
status: 'error',
|
||||||
|
isClosable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [dispatch, toaster, shouldFetchImages]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
@ -104,6 +120,7 @@ const CurrentImagePreview = () => {
|
|||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
borderRadius: 'base',
|
borderRadius: 'base',
|
||||||
}}
|
}}
|
||||||
|
onError={handleError}
|
||||||
/>
|
/>
|
||||||
<ImageMetadataOverlay image={image} />
|
<ImageMetadataOverlay image={image} />
|
||||||
</>
|
</>
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { Flex, Icon, Image } from '@chakra-ui/react';
|
import { Flex, Icon, Image } from '@chakra-ui/react';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import SelectImagePlaceholder from 'common/components/SelectImagePlaceholder';
|
|
||||||
import { useGetUrl } from 'common/util/getUrl';
|
import { useGetUrl } from 'common/util/getUrl';
|
||||||
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
|
||||||
import { DragEvent, useCallback } from 'react';
|
import { DragEvent, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ImageType } from 'services/api';
|
import { ImageType } from 'services/api';
|
||||||
@ -14,6 +12,8 @@ import { initialImageSelected } from 'features/parameters/store/actions';
|
|||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
import ImageFallbackSpinner from 'features/gallery/components/ImageFallbackSpinner';
|
import ImageFallbackSpinner from 'features/gallery/components/ImageFallbackSpinner';
|
||||||
import { FaImage } from 'react-icons/fa';
|
import { FaImage } from 'react-icons/fa';
|
||||||
|
import { configSelector } from '../../../../system/store/configSelectors';
|
||||||
|
import { useAppToaster } from 'app/components/Toaster';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[generationSelector],
|
[generationSelector],
|
||||||
@ -28,21 +28,29 @@ const selector = createSelector(
|
|||||||
|
|
||||||
const InitialImagePreview = () => {
|
const InitialImagePreview = () => {
|
||||||
const { initialImage } = useAppSelector(selector);
|
const { initialImage } = useAppSelector(selector);
|
||||||
|
const { shouldFetchImages } = useAppSelector(configSelector);
|
||||||
const { getUrl } = useGetUrl();
|
const { getUrl } = useGetUrl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const toaster = useAppToaster();
|
||||||
|
|
||||||
const onError = () => {
|
const handleError = useCallback(() => {
|
||||||
dispatch(
|
dispatch(clearInitialImage());
|
||||||
addToast({
|
if (shouldFetchImages) {
|
||||||
|
toaster({
|
||||||
|
title: 'Something went wrong, please refresh',
|
||||||
|
status: 'error',
|
||||||
|
isClosable: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
toaster({
|
||||||
title: t('toast.parametersFailed'),
|
title: t('toast.parametersFailed'),
|
||||||
description: t('toast.parametersFailedDesc'),
|
description: t('toast.parametersFailedDesc'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
})
|
});
|
||||||
);
|
}
|
||||||
dispatch(clearInitialImage());
|
}, [dispatch, t, toaster, shouldFetchImages]);
|
||||||
};
|
|
||||||
|
|
||||||
const handleDrop = useCallback(
|
const handleDrop = useCallback(
|
||||||
(e: DragEvent<HTMLDivElement>) => {
|
(e: DragEvent<HTMLDivElement>) => {
|
||||||
@ -71,7 +79,7 @@ const InitialImagePreview = () => {
|
|||||||
src={getUrl(initialImage?.url)}
|
src={getUrl(initialImage?.url)}
|
||||||
fallbackStrategy="beforeLoadOrError"
|
fallbackStrategy="beforeLoadOrError"
|
||||||
fallback={<ImageFallbackSpinner />}
|
fallback={<ImageFallbackSpinner />}
|
||||||
onError={onError}
|
onError={handleError}
|
||||||
sx={{
|
sx={{
|
||||||
objectFit: 'contain',
|
objectFit: 'contain',
|
||||||
maxWidth: '100%',
|
maxWidth: '100%',
|
||||||
|
Loading…
Reference in New Issue
Block a user