DEV: Send multiple files in batches to composer upload handlers when using uppy (#15124)

In jQuery file upload land, we were sending a single file through
at a time to matching upload handlers. This in turn required plugin
authors to marshal the files as they came through one by one if they
wanted to group them together to do something with them. Now that
we are using uppy, files come through in the groups they are added
in (for example dropping multiple, selecting multiple from the system
file dialogue).

This commit changes the matching upload handlers to send through
all matching files at once instead of piecemeal.
This commit is contained in:
Martin Brennan 2021-11-29 11:19:02 +10:00 committed by GitHub
parent 13aed6fe3b
commit 20b2a42f49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 10 deletions

View File

@ -146,26 +146,35 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, {
// In future we may want to devise a nicer way of doing this. // In future we may want to devise a nicer way of doing this.
// Uppy plugins are out of the question because there is no way to // Uppy plugins are out of the question because there is no way to
// define which uploader plugin handles which file extensions at this time. // define which uploader plugin handles which file extensions at this time.
const uploadHandlerFiles = [];
const unhandledFiles = {}; const unhandledFiles = {};
const handlerBuckets = {};
for (const [fileId, file] of Object.entries(files)) { for (const [fileId, file] of Object.entries(files)) {
const matchingHandler = this._findMatchingUploadHandler(file.name); const matchingHandler = this._findMatchingUploadHandler(file.name);
if (matchingHandler) { if (matchingHandler) {
uploadHandlerFiles.push([file, matchingHandler]); // the function signature will be converted to a string for the
// object key, so we can send multiple files at once to each handler
if (handlerBuckets[matchingHandler.method]) {
handlerBuckets[matchingHandler.method].files.push(file);
} else {
handlerBuckets[matchingHandler.method] = {
fn: matchingHandler.method,
files: [file],
};
}
} else { } else {
unhandledFiles[fileId] = { ...files[fileId] }; unhandledFiles[fileId] = { ...files[fileId] };
} }
} }
// This replicates what the old composer upload handler did; because // Send the collected array of files to each matching handler,
// jQuery file uploader passed through a single file at a time to // rather than the old jQuery file uploader method of sending
// the upload handlers. // a single file at a time through to the handler.
uploadHandlerFiles.forEach((fileWithHandler) => { for (const bucket of Object.values(handlerBuckets)) {
const [file, matchingHandler] = fileWithHandler; if (!bucket.fn(bucket.files, this)) {
if (matchingHandler && !matchingHandler.method(file.data, this)) {
return this._abortAndReset(); return this._abortAndReset();
} }
}); }
// Limit the number of simultaneous uploads, for files which have // Limit the number of simultaneous uploads, for files which have
// _not_ been handled by an upload handler. // _not_ been handled by an upload handler.

View File

@ -234,7 +234,8 @@ acceptance("Uppy Composer Attachment - Upload Handler", function (needs) {
}); });
needs.hooks.beforeEach(() => { needs.hooks.beforeEach(() => {
withPluginApi("0.8.14", (api) => { withPluginApi("0.8.14", (api) => {
api.addComposerUploadHandler(["png"], (file) => { api.addComposerUploadHandler(["png"], (files) => {
const file = files[0];
bootbox.alert(`This is an upload handler test for ${file.name}`); bootbox.alert(`This is an upload handler test for ${file.name}`);
}); });
}); });