@@ -128,14 +128,21 @@ document.addEventListener("drop", async e => {
128128 "ogg" ,
129129 ] ) ;
130130
131+ const MAX_FILES = 100 ;
131132 const toHighlight : string [ ] = [ ] ;
132133 const uploadTasks : Promise < void > [ ] = [ ] ;
134+ let fileCount = 0 ;
133135
134136 async function traverseEntry ( entry : FileSystemEntry ) : Promise < void > {
135137 if ( entry . isFile ) {
136138 const fileEntry = entry as FileSystemFileEntry ;
137139 const file : File = await new Promise ( ( res , rej ) => fileEntry . file ( res , rej ) ) ;
138140
141+ fileCount ++ ;
142+ if ( fileCount > MAX_FILES ) {
143+ throw new Error ( `Too many files. Maximum ${ MAX_FILES } files allowed.` ) ;
144+ }
145+
139146 const ext = file . name . split ( "." ) . pop ( ) ?. toLowerCase ( ) || "" ;
140147 const topFolder = mediaExts . has ( ext ) ? "assets" : "src" ;
141148
@@ -164,18 +171,26 @@ document.addEventListener("drop", async e => {
164171 }
165172 }
166173
174+ const traversalPromises : Promise < void > [ ] = [ ] ;
167175 for ( let i = 0 ; i < items . length ; i ++ ) {
168176 const item = items [ i ] ;
169177 const entry = item . webkitGetAsEntry ?.( ) ;
170178 if ( entry ) {
171- await traverseEntry ( entry ) ;
179+ traversalPromises . push ( traverseEntry ( entry ) ) ;
172180 }
173181 }
174182
175183 try {
184+ await Promise . all ( traversalPromises ) ;
176185 await Promise . all ( uploadTasks ) ;
177186 } catch ( err ) {
178187 console . error ( "upload error" , err ) ;
188+ if ( err instanceof Error ) {
189+ alert ( `Upload failed: ${ err . message } ` ) ;
190+ } else {
191+ alert ( "Upload failed. Check console for details." ) ;
192+ }
193+ return ;
179194 }
180195
181196 setTimeout ( ( ) => {
0 commit comments