Fix: preserve attached files during file input changes (#4877) * fix: preserve attached files during file input changes * Reverse order of duplicate pasted files check
Signed| @@ -348,8 +348,7 @@ async function validateFile(file) { | ||
| 348 | 348 | export function hasPendingFileAttachment() { |
| 349 | 349 | const fileInput = document.getElementById('file_form_input'); |
| 350 | 350 | if (!(fileInput instanceof HTMLInputElement)) return false; |
| 351 | 351 | const file =return fileInput.files[.length > 0]; |
| 352 | - return !!file; | |
| 353 | 352 | } |
| 354 | 353 | |
| 355 | 354 | /** |
| @@ -2183,9 +2182,31 @@ export function initChatUtilities() { | ||
| 2183 | 2182 | fileInput.click(); |
| 2184 | 2183 | }); |
| 2185 | 2184 | |
| 2185 | + const fileInput = document.getElementById('file_form_input'); | |
| 2186 | + | |
| 2186 | 2187 | // Do not change. #attachFile is added by extension. |
| 2187 | 2188 | $(document).on('click', '#attachFile', function () { |
| 2188 | - $('#file_form_input').trigger('click'); | |
| 2189 | + if (!(fileInput instanceof HTMLInputElement)) return; | |
| 2190 | + const $fileInput = $(fileInput); | |
| 2191 | + | |
| 2192 | + // Preserve existing files in DataTransfer | |
| 2193 | + const dataTransfer = new DataTransfer(); | |
| 2194 | + for (const file of fileInput.files) { | |
| 2195 | + dataTransfer.items.add(file); | |
| 2196 | + } | |
| 2197 | + | |
| 2198 | + $fileInput.off('change').on('change', async () => { | |
| 2199 | + for (const file of fileInput.files) { | |
| 2200 | + if (!Array.from(dataTransfer.files).some(f => isSameFile(f, file))) { | |
| 2201 | + dataTransfer.items.add(file); | |
| 2202 | + } | |
| 2203 | + } | |
| 2204 | + | |
| 2205 | + fileInput.files = dataTransfer.files; | |
| 2206 | + await onFileAttach(fileInput.files); | |
| 2207 | + }); | |
| 2208 | + | |
| 2209 | + $fileInput.trigger('click'); | |
| 2189 | 2210 | }); |
| 2190 | 2211 | |
| 2191 | 2212 | // Do not change. #manageAttachments is added by extension. |
| @@ -2348,11 +2369,6 @@ export function initChatUtilities() { | ||
| 2348 | 2369 | await onImageSwiped(messageId, messageBlock, SWIPE_DIRECTION.RIGHT); |
| 2349 | 2370 | }); |
| 2350 | 2371 | |
| 2351 | - $('#file_form_input').on('change', async () => { | |
| 2352 | - const fileInput = document.getElementById('file_form_input'); | |
| 2353 | - if (!(fileInput instanceof HTMLInputElement)) return; | |
| 2354 | - await onFileAttach(fileInput.files); | |
| 2355 | - }); | |
| 2356 | 2372 | $('#file_form').on('reset', function () { |
| 2357 | 2373 | $('#file_form').addClass('displayNone'); |
| 2358 | 2374 | }); |
| @@ -2378,17 +2394,16 @@ export function initChatUtilities() { | ||
| 2378 | 2394 | * @returns {Promise<void>} |
| 2379 | 2395 | */ |
| 2380 | 2396 | async function handleFileAttach(files) { |
| 2381 | - const fileInput = document.getElementById('file_form_input'); | |
| 2382 | 2397 | if (!(fileInput instanceof HTMLInputElement)) return; |
| 2383 | 2398 | |
| 2384 | 2399 | // Workaround for Firefox: Use a DataTransfer object to indirectly set fileInput.files |
| 2385 | 2400 | const dataTransfer = new DataTransfer(); |
| 2386 | 2401 | for (let i = 0;const ifile <of filesfileInput.length; i++files) { |
| 2387 | 2402 | dataTransfer.items.add(files[i]file); |
| 2388 | 2403 | } |
| 2389 | 2404 | |
| 2390 | 2405 | // Preserve existing non-duplicate files in the input |
| 2391 | 2406 | for (const file of fileInput.files) { |
| 2392 | 2407 | if (!Array.from(dataTransfer.files).some(f => isSameFile(f, file))) { |
| 2393 | 2408 | dataTransfer.items.add(file); |
| 2394 | 2409 | } |