Skip to content

Commit d9a257e

Browse files
Mary Hippmaryhipp
authored andcommitted
fix(ui): add error handling to upload button
1 parent 23fada3 commit d9a257e

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

invokeai/frontend/web/src/common/hooks/useImageUploadButton.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import { logger } from 'app/logging/logger';
12
import { useAppSelector } from 'app/store/storeHooks';
23
import { selectAutoAddBoardId } from 'features/gallery/store/gallerySelectors';
34
import { selectMaxImageUploadCount } from 'features/system/store/configSlice';
5+
import { toast } from 'features/toast/toast';
46
import { useCallback } from 'react';
7+
import type { FileRejection } from 'react-dropzone';
58
import { useDropzone } from 'react-dropzone';
9+
import { useTranslation } from 'react-i18next';
610
import { useUploadImageMutation } from 'services/api/endpoints/images';
711
import type { PostUploadAction } from 'services/api/types';
812

@@ -12,6 +16,8 @@ type UseImageUploadButtonArgs = {
1216
allowMultiple?: boolean;
1317
};
1418

19+
const log = logger('gallery');
20+
1521
/**
1622
* Provides image uploader functionality to any component.
1723
*
@@ -39,29 +45,58 @@ export const useImageUploadButton = ({
3945
const autoAddBoardId = useAppSelector(selectAutoAddBoardId);
4046
const [uploadImage] = useUploadImageMutation();
4147
const maxImageUploadCount = useAppSelector(selectMaxImageUploadCount);
48+
const { t } = useTranslation();
4249

4350
const onDropAccepted = useCallback(
4451
(files: File[]) => {
45-
for (const file of files) {
52+
for (const [i, file] of files.entries()) {
4653
uploadImage({
4754
file,
4855
image_category: 'user',
4956
is_intermediate: false,
5057
postUploadAction: postUploadAction ?? { type: 'TOAST' },
5158
board_id: autoAddBoardId === 'none' ? undefined : autoAddBoardId,
59+
isFirstUploadOfBatch: i === 0,
5260
});
5361
}
5462
},
5563
[autoAddBoardId, postUploadAction, uploadImage]
5664
);
5765

66+
const onDropRejected = useCallback(
67+
(fileRejections: FileRejection[]) => {
68+
if (fileRejections.length > 0) {
69+
const errors = fileRejections.map((rejection) => ({
70+
errors: rejection.errors.map(({ message }) => message),
71+
file: rejection.file.path,
72+
}));
73+
log.error({ errors }, 'Invalid upload');
74+
const description =
75+
maxImageUploadCount === undefined
76+
? t('toast.uploadFailedInvalidUploadDesc')
77+
: t('toast.uploadFailedInvalidUploadDesc_withCount', { count: maxImageUploadCount });
78+
79+
toast({
80+
id: 'UPLOAD_FAILED',
81+
title: t('toast.uploadFailed'),
82+
description,
83+
status: 'error',
84+
});
85+
86+
return;
87+
}
88+
},
89+
[maxImageUploadCount, t]
90+
);
91+
5892
const {
5993
getRootProps: getUploadButtonProps,
6094
getInputProps: getUploadInputProps,
6195
open: openUploader,
6296
} = useDropzone({
6397
accept: { 'image/png': ['.png'], 'image/jpeg': ['.jpg', '.jpeg', '.png'] },
6498
onDropAccepted,
99+
onDropRejected,
65100
disabled: isDisabled,
66101
noDrag: true,
67102
multiple: allowMultiple && (maxImageUploadCount === undefined || maxImageUploadCount > 1),

0 commit comments

Comments
 (0)