diff --git a/src/AjaxUploader.tsx b/src/AjaxUploader.tsx index e88c291..c8d4b9a 100644 --- a/src/AjaxUploader.tsx +++ b/src/AjaxUploader.tsx @@ -66,7 +66,7 @@ class AjaxUploader extends Component { } }; - onFileDrop = (e: React.DragEvent) => { + onFileDrop = async (e: React.DragEvent) => { const { multiple } = this.props; e.preventDefault(); @@ -76,11 +76,11 @@ class AjaxUploader extends Component { } if (this.props.directory) { - traverseFileTree( + const files = await traverseFileTree( Array.prototype.slice.call(e.dataTransfer.items), - this.uploadFiles, (_file: RcFile) => attrAccept(_file, this.props.accept), ); + this.uploadFiles(files); } else { let files = [...e.dataTransfer.files].filter((file: RcFile) => attrAccept(file, this.props.accept), diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts index 7b74c0b..9e3007e 100644 --- a/src/traverseFileTree.ts +++ b/src/traverseFileTree.ts @@ -10,36 +10,34 @@ interface InternalDataTransferItem extends DataTransferItem { path: string; } -const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepted) => { +// https://github.com/ant-design/ant-design/issues/50080 +const traverseFileTree = async (files: InternalDataTransferItem[], isAccepted) => { const flattenFileList = []; const progressFileList = []; files.forEach(file => progressFileList.push(file.webkitGetAsEntry() as any)); - function loopFiles(item: InternalDataTransferItem) { - const dirReader = item.createReader(); - function sequence() { - dirReader.readEntries((entries: InternalDataTransferItem[]) => { - const entryList = Array.prototype.slice.apply(entries); + async function readDirectory(directory: InternalDataTransferItem) { + const dirReader = directory.createReader(); + const entries = []; - progressFileList.push(...entryList); - // Check if all the file has been viewed - const isFinished = !entryList.length; - if (!isFinished) { - sequence(); - } + while (true) { + const results = await new Promise((resolve, reject) => { + dirReader.readEntries(resolve, reject); }); - } - sequence(); - } - // eslint-disable-next-line @typescript-eslint/naming-convention - const _traverseFileTree = (item: InternalDataTransferItem, path?: string) => { - if (!item) { - return; + if (!results.length) { + break; + } + + for (const entry of results) { + entries.push(entry); + } } - // eslint-disable-next-line no-param-reassign - item.path = path || ''; - if (item.isFile) { + return entries; + } + + async function readFile(item: InternalDataTransferItem) { + return new Promise(reslove => { item.file(file => { if (isAccepted(file)) { // https://github.com/ant-design/ant-design/issues/16426 @@ -57,23 +55,39 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte }, }); } - flattenFileList.push(file); + reslove(file); + } else { + reslove(null); } }); + }); + } + + // eslint-disable-next-line @typescript-eslint/naming-convention + const _traverseFileTree = async (item: InternalDataTransferItem, path?: string) => { + if (!item) { + return; + } + // eslint-disable-next-line no-param-reassign + item.path = path || ''; + if (item.isFile) { + const file = await readFile(item); + if (file) { + flattenFileList.push(file); + } } else if (item.isDirectory) { - loopFiles(item); + const entries = await readDirectory(item); + progressFileList.push(...entries); } }; - function walkFiles() { - let wipIndex = 0; - while (wipIndex < progressFileList.length) { - _traverseFileTree(progressFileList[wipIndex]); - wipIndex++; - } - callback(flattenFileList); + let wipIndex = 0; + while (wipIndex < progressFileList.length) { + await _traverseFileTree(progressFileList[wipIndex]); + wipIndex++; } - walkFiles(); + + return flattenFileList; }; export default traverseFileTree;