1+ import { logger } from 'app/logging/logger' ;
12import { useAppSelector } from 'app/store/storeHooks' ;
23import { selectAutoAddBoardId } from 'features/gallery/store/gallerySelectors' ;
34import { selectMaxImageUploadCount } from 'features/system/store/configSlice' ;
5+ import { toast } from 'features/toast/toast' ;
46import { useCallback } from 'react' ;
7+ import type { FileRejection } from 'react-dropzone' ;
58import { useDropzone } from 'react-dropzone' ;
9+ import { useTranslation } from 'react-i18next' ;
610import { useUploadImageMutation } from 'services/api/endpoints/images' ;
711import 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