@@ -71,8 +71,59 @@ function FileDropZone(props: PropsType) {
71
71
lg : < FullDropZone /> ,
72
72
} ) ;
73
73
74
+ const MAX_VIDEO_SIZE = 50 * 1024 * 1024 ; // 50MB
75
+ const MAX_IMAGE_SIZE = 3 * 1024 * 1024 ; // 3MB
76
+
77
+ async function resizeImage ( file : File ) : Promise < File > {
78
+ return new Promise ( ( resolve , reject ) => {
79
+ const reader = new FileReader ( ) ;
80
+ reader . readAsDataURL ( file ) ;
81
+ reader . onload = ( ) => {
82
+ const img = new Image ( ) ;
83
+ img . src = reader . result as string ;
84
+ img . onload = ( ) => {
85
+ const canvas = document . createElement ( "canvas" ) ;
86
+ const ctx = canvas . getContext ( "2d" ) ;
87
+ if ( ! ctx ) return reject ( new Error ( "Canvas context not available" ) ) ;
88
+
89
+ const MAX_WIDTH = 4096 ;
90
+ const MAX_HEIGHT = 4096 ;
91
+ let width = img . width ;
92
+ let height = img . height ;
93
+
94
+ if ( width > MAX_WIDTH || height > MAX_HEIGHT ) {
95
+ if ( width > height ) {
96
+ height = ( height * MAX_WIDTH ) / width ;
97
+ width = MAX_WIDTH ;
98
+ } else {
99
+ width = ( width * MAX_HEIGHT ) / height ;
100
+ height = MAX_HEIGHT ;
101
+ }
102
+ }
103
+
104
+ canvas . width = width ;
105
+ canvas . height = height ;
106
+ ctx . drawImage ( img , 0 , 0 , width , height ) ;
107
+
108
+ canvas . toBlob (
109
+ ( blob ) => {
110
+ if ( blob ) {
111
+ resolve ( new File ( [ blob ] , file . name , { type : "image/jpeg" } ) ) ;
112
+ } else {
113
+ reject ( new Error ( "Failed to resize image" ) ) ;
114
+ }
115
+ } ,
116
+ "image/jpeg" ,
117
+ 0.8
118
+ ) ;
119
+ } ;
120
+ } ;
121
+ reader . onerror = ( error ) => reject ( error ) ;
122
+ } ) ;
123
+ }
124
+
74
125
const onDrop = useCallback (
75
- ( acceptedFiles : File [ ] , fileRejections : FileRejection [ ] ) => {
126
+ async ( acceptedFiles : File [ ] , fileRejections : FileRejection [ ] ) => {
76
127
if ( fileRejections . length > 0 ) {
77
128
toast ( {
78
129
status : "error" ,
@@ -104,7 +155,49 @@ function FileDropZone(props: PropsType) {
104
155
return ;
105
156
}
106
157
107
- setFileArr ( [ ...fileArr , ...acceptedFiles ] ) ;
158
+ let newFiles : File [ ] = [ ] ;
159
+
160
+ const processedFiles = await Promise . all (
161
+ acceptedFiles . map ( async ( file ) => {
162
+ console . log ( file . size ) ;
163
+ if ( file . type . startsWith ( "video/" ) ) {
164
+ if ( file . size > MAX_VIDEO_SIZE ) {
165
+ toast ( {
166
+ status : "error" ,
167
+ position : "top" ,
168
+ title : "Error" ,
169
+ description : `The video ${ file . name } exceeds the 50MB limit.` ,
170
+ duration : 4000 ,
171
+ isClosable : true ,
172
+ } ) ;
173
+ return null ;
174
+ }
175
+ return file ;
176
+ } else if ( file . type . startsWith ( "image/" ) ) {
177
+ if ( file . size > MAX_IMAGE_SIZE ) {
178
+ try {
179
+ return await resizeImage ( file ) ;
180
+ } catch ( error ) {
181
+ console . error ( `Failed to resize image ${ file . name } ` , error ) ;
182
+ toast ( {
183
+ status : "error" ,
184
+ position : "top" ,
185
+ title : "Error" ,
186
+ description : `Failed to resize image ${ file . name } .` ,
187
+ duration : 4000 ,
188
+ isClosable : true ,
189
+ } ) ;
190
+ return null ;
191
+ }
192
+ }
193
+ return file ;
194
+ }
195
+ return null ;
196
+ } )
197
+ ) ;
198
+
199
+ newFiles = processedFiles . filter ( ( file ) : file is File => file !== null ) ;
200
+ setFileArr ( [ ...fileArr , ...newFiles ] ) ;
108
201
} ,
109
202
[ fileArr , setFileArr ]
110
203
) ;
0 commit comments