fix(uploader): accumulate file-input change events before resolving (#3571)

Some mobile pickers deliver a multi-file selection across several
'change' events; select() resolved its promise on the first one, so
every later file was silently dropped — matching the '3 selected, 1
uploaded' report. The handler now accumulates files and resolves once
the picker goes quiet for 400ms. Also binds only the input actually
being clicked instead of rebinding both on every select.
pull/3582/head
Tomas Dvorak 2 weeks ago
parent 6928fd571a
commit 1188662067

@ -169,11 +169,22 @@ export default class UploadManager {
throw new UploaderError(UploaderErrorName.NoPolicySelected, "No policy selected."); throw new UploaderError(UploaderErrorName.NoPolicySelected, "No policy selected.");
} }
this.fileInput.onchange = (ev: Event) => this.addFiles(ev, dst, resolve, reject); const input = type == SelectType.File ? this.fileInput : this.directoryInput;
this.directoryInput.onchange = (ev: Event) => this.addFiles(ev, dst, resolve, reject); // Some mobile pickers deliver multi-selections via several `change`
this.fileInput.value = ""; // events; the first resolve would swallow the rest. Accumulate and
this.directoryInput.value = ""; // resolve once the picker goes quiet (#3571).
type == SelectType.File ? this.fileInput.click() : this.directoryInput.click(); let files: File[] = [];
let timer: ReturnType<typeof setTimeout> | undefined;
input.onchange = (ev: Event) => {
const target = ev.target as HTMLInputElement;
if (target?.files?.length) {
files = files.concat(Array.from(target.files));
}
clearTimeout(timer);
timer = setTimeout(() => this.addFiles(files, dst, resolve, reject), 400);
};
input.value = "";
input.click();
}); });
}; };

Loading…
Cancel
Save