From f1a30e821db16bf702a6f3d4a518f589968b8dd5 Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Fri, 5 Jul 2024 21:17:17 +0800
Subject: [PATCH 1/8] fix:delay folder upload until all children files are
parsed when drag
---
src/traverseFileTree.ts | 49 ++++++++++++++++++++++-----------------
tests/uploader.spec.tsx | 51 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 78 insertions(+), 22 deletions(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index 06665d3c..4c1f644f 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -10,33 +10,36 @@ interface InternalDataTransferItem extends DataTransferItem {
path: string;
}
-function loopFiles(item: InternalDataTransferItem, callback) {
- const dirReader = item.createReader();
- let fileList = [];
-
- function sequence() {
- dirReader.readEntries((entries: InternalDataTransferItem[]) => {
- const entryList = Array.prototype.slice.apply(entries);
- fileList = fileList.concat(entryList);
+const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepted) => {
+ let restFile = files.length;
+ const flattenFileList = [];
+ function loopFiles(item: InternalDataTransferItem, InnerCallback) {
+ const dirReader = item.createReader();
+ let fileList = [];
- // Check if all the file has been viewed
- const isFinished = !entryList.length;
+ function sequence() {
+ dirReader.readEntries((entries: InternalDataTransferItem[]) => {
+ const entryList = Array.prototype.slice.apply(entries);
+ fileList = fileList.concat(entryList);
- if (isFinished) {
- callback(fileList);
- } else {
- sequence();
- }
- });
- }
+ // Check if all the file has been viewed
+ const isFinished = !entryList.length;
- sequence();
-}
+ if (isFinished) {
+ restFile = restFile - 1 + fileList.length;
+ InnerCallback(fileList);
+ } else {
+ sequence();
+ }
+ });
+ }
-const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepted) => {
+ sequence();
+ }
// eslint-disable-next-line @typescript-eslint/naming-convention
const _traverseFileTree = (item: InternalDataTransferItem, path?: string) => {
if (!item) {
+ restFile = restFile - 1;
return;
}
// eslint-disable-next-line no-param-reassign
@@ -59,7 +62,11 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
},
});
}
- callback([file]);
+ flattenFileList.push(file);
+ restFile = restFile - 1;
+ if (restFile === 0) {
+ callback(flattenFileList);
+ }
}
});
} else if (item.isDirectory) {
diff --git a/tests/uploader.spec.tsx b/tests/uploader.spec.tsx
index b7e060cd..77b90cc8 100644
--- a/tests/uploader.spec.tsx
+++ b/tests/uploader.spec.tsx
@@ -25,7 +25,7 @@ const makeFileSystemEntry = item => {
return {
readEntries(handle) {
if (!first) {
- return [];
+ return handle([]);
}
first = false;
@@ -373,7 +373,56 @@ describe('uploader', () => {
beforeEach(() => {
uploader = render();
});
+ it('beforeUpload should run after all children files are parsed', done => {
+ const props = { action: '/test', directory: true, accept: '.png' };
+ const mockBeforeUpload = jest.fn();
+ const beforeUpload = (file, fileList) => {
+ console.log('beforeUpload', file, fileList);
+ mockBeforeUpload(file, fileList);
+ };
+ const Test = () => {
+ return ;
+ };
+ const { container } = render();
+ const files = {
+ name: 'foo',
+ children: [
+ {
+ name: 'bar',
+ children: [
+ {
+ name: '1.png',
+ },
+ {
+ name: '2.png',
+ },
+ {
+ name: 'rc',
+ children: [
+ {
+ name: '3.png',
+ },
+ {
+ name: '4.png',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ };
+ const input = container.querySelector('input')!;
+ fireEvent.drop(input, { dataTransfer: { items: [makeDataTransferItem(files)] } });
+ setTimeout(() => {
+ expect(mockBeforeUpload.mock.calls.length).toBe(4);
+ expect(mockBeforeUpload.mock.calls[0][1].length).toBe(4);
+ expect(mockBeforeUpload.mock.calls[1][1].length).toBe(4);
+ expect(mockBeforeUpload.mock.calls[2][1].length).toBe(4);
+ expect(mockBeforeUpload.mock.calls[3][1].length).toBe(4);
+ done();
+ }, 100);
+ });
it('unaccepted type files to upload will not trigger onStart', done => {
const input = uploader.container.querySelector('input')!;
const files = {
From bf48f50db1ae3cd633d542df56610cc147428af6 Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Tue, 9 Jul 2024 21:15:40 +0800
Subject: [PATCH 2/8] fix: isAcceptable case
---
src/traverseFileTree.ts | 5 +++++
tests/uploader.spec.tsx | 12 +++++-------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index 4c1f644f..57420d4e 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -67,6 +67,11 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
if (restFile === 0) {
callback(flattenFileList);
}
+ } else {
+ restFile = restFile - 1;
+ if (restFile === 0) {
+ callback(flattenFileList);
+ }
}
});
} else if (item.isDirectory) {
diff --git a/tests/uploader.spec.tsx b/tests/uploader.spec.tsx
index 77b90cc8..ba3e47d0 100644
--- a/tests/uploader.spec.tsx
+++ b/tests/uploader.spec.tsx
@@ -401,10 +401,10 @@ describe('uploader', () => {
name: 'rc',
children: [
{
- name: '3.png',
+ name: '5.webp',
},
{
- name: '4.png',
+ name: '4.webp',
},
],
},
@@ -415,11 +415,9 @@ describe('uploader', () => {
const input = container.querySelector('input')!;
fireEvent.drop(input, { dataTransfer: { items: [makeDataTransferItem(files)] } });
setTimeout(() => {
- expect(mockBeforeUpload.mock.calls.length).toBe(4);
- expect(mockBeforeUpload.mock.calls[0][1].length).toBe(4);
- expect(mockBeforeUpload.mock.calls[1][1].length).toBe(4);
- expect(mockBeforeUpload.mock.calls[2][1].length).toBe(4);
- expect(mockBeforeUpload.mock.calls[3][1].length).toBe(4);
+ expect(mockBeforeUpload.mock.calls.length).toBe(2);
+ expect(mockBeforeUpload.mock.calls[0][1].length).toBe(2);
+ expect(mockBeforeUpload.mock.calls[1][1].length).toBe(2);
done();
}, 100);
});
From d841736b627087f9536a4be0095ea70c4896d89d Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Wed, 10 Jul 2024 20:22:26 +0800
Subject: [PATCH 3/8] feat: use queue
---
src/traverseFileTree.ts | 41 +++++++++++++++++++----------------------
1 file changed, 19 insertions(+), 22 deletions(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index 57420d4e..a67b3f9a 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -11,9 +11,11 @@ interface InternalDataTransferItem extends DataTransferItem {
}
const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepted) => {
- let restFile = files.length;
const flattenFileList = [];
- function loopFiles(item: InternalDataTransferItem, InnerCallback) {
+ let progressFileList = [];
+ let wipIndex = 0;
+ files.forEach(file => progressFileList.push(file.webkitGetAsEntry() as any));
+ function loopFiles(item: InternalDataTransferItem) {
const dirReader = item.createReader();
let fileList = [];
@@ -26,8 +28,8 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
const isFinished = !entryList.length;
if (isFinished) {
- restFile = restFile - 1 + fileList.length;
- InnerCallback(fileList);
+ wipIndex++;
+ progressFileList = progressFileList.concat(fileList);
} else {
sequence();
}
@@ -39,7 +41,7 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
// eslint-disable-next-line @typescript-eslint/naming-convention
const _traverseFileTree = (item: InternalDataTransferItem, path?: string) => {
if (!item) {
- restFile = restFile - 1;
+ wipIndex++;
return;
}
// eslint-disable-next-line no-param-reassign
@@ -63,28 +65,23 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
});
}
flattenFileList.push(file);
- restFile = restFile - 1;
- if (restFile === 0) {
- callback(flattenFileList);
- }
- } else {
- restFile = restFile - 1;
- if (restFile === 0) {
- callback(flattenFileList);
- }
}
});
+ wipIndex++;
} else if (item.isDirectory) {
- loopFiles(item, (entries: InternalDataTransferItem[]) => {
- entries.forEach(entryItem => {
- _traverseFileTree(entryItem, `${path}${item.name}/`);
- });
- });
+ loopFiles(item);
}
};
- files.forEach(file => {
- _traverseFileTree(file.webkitGetAsEntry() as any);
- });
+
+ function walkFiles() {
+ while (wipIndex < progressFileList.length) {
+ _traverseFileTree(progressFileList[wipIndex]);
+ if (wipIndex === progressFileList.length) {
+ callback(flattenFileList);
+ }
+ }
+ }
+ walkFiles();
};
export default traverseFileTree;
From 1f172a543d890c94b371a26da6965f23289a1c90 Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Thu, 11 Jul 2024 12:37:54 +0800
Subject: [PATCH 4/8] feat: readEntries add errorCallback
---
src/traverseFileTree.ts | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index a67b3f9a..7592c431 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -20,20 +20,25 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
let fileList = [];
function sequence() {
- dirReader.readEntries((entries: InternalDataTransferItem[]) => {
- const entryList = Array.prototype.slice.apply(entries);
- fileList = fileList.concat(entryList);
+ dirReader.readEntries(
+ (entries: InternalDataTransferItem[]) => {
+ const entryList = Array.prototype.slice.apply(entries);
+ fileList = fileList.concat(entryList);
- // Check if all the file has been viewed
- const isFinished = !entryList.length;
+ // Check if all the file has been viewed
+ const isFinished = !entryList.length;
- if (isFinished) {
+ if (isFinished) {
+ wipIndex++;
+ progressFileList = progressFileList.concat(fileList);
+ } else {
+ sequence();
+ }
+ },
+ () => {
wipIndex++;
- progressFileList = progressFileList.concat(fileList);
- } else {
- sequence();
- }
- });
+ },
+ );
}
sequence();
From b381da436361e41d7635dc819078ac9b14c190fa Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Thu, 11 Jul 2024 15:58:24 +0800
Subject: [PATCH 5/8] fix: improve code
---
src/traverseFileTree.ts | 35 +++++++++++++----------------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index 7592c431..53b0555a 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -20,25 +20,19 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
let fileList = [];
function sequence() {
- dirReader.readEntries(
- (entries: InternalDataTransferItem[]) => {
- const entryList = Array.prototype.slice.apply(entries);
- fileList = fileList.concat(entryList);
+ dirReader.readEntries((entries: InternalDataTransferItem[]) => {
+ const entryList = Array.prototype.slice.apply(entries);
+ fileList.push(...entryList);
- // Check if all the file has been viewed
- const isFinished = !entryList.length;
+ // Check if all the file has been viewed
+ const isFinished = !entryList.length;
- if (isFinished) {
- wipIndex++;
- progressFileList = progressFileList.concat(fileList);
- } else {
- sequence();
- }
- },
- () => {
- wipIndex++;
- },
- );
+ if (isFinished) {
+ progressFileList = progressFileList.concat(fileList);
+ } else {
+ sequence();
+ }
+ });
}
sequence();
@@ -46,7 +40,6 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
// eslint-disable-next-line @typescript-eslint/naming-convention
const _traverseFileTree = (item: InternalDataTransferItem, path?: string) => {
if (!item) {
- wipIndex++;
return;
}
// eslint-disable-next-line no-param-reassign
@@ -72,7 +65,6 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
flattenFileList.push(file);
}
});
- wipIndex++;
} else if (item.isDirectory) {
loopFiles(item);
}
@@ -81,10 +73,9 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
function walkFiles() {
while (wipIndex < progressFileList.length) {
_traverseFileTree(progressFileList[wipIndex]);
- if (wipIndex === progressFileList.length) {
- callback(flattenFileList);
- }
+ wipIndex++;
}
+ callback(flattenFileList);
}
walkFiles();
};
From c151816c3baecdea7811dc2d2ed7f07e7e8c4c2c Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Thu, 11 Jul 2024 16:56:40 +0800
Subject: [PATCH 6/8] feat:improve code
---
src/traverseFileTree.ts | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index 53b0555a..18a35b0a 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -13,22 +13,19 @@ interface InternalDataTransferItem extends DataTransferItem {
const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepted) => {
const flattenFileList = [];
let progressFileList = [];
- let wipIndex = 0;
files.forEach(file => progressFileList.push(file.webkitGetAsEntry() as any));
function loopFiles(item: InternalDataTransferItem) {
const dirReader = item.createReader();
- let fileList = [];
function sequence() {
dirReader.readEntries((entries: InternalDataTransferItem[]) => {
const entryList = Array.prototype.slice.apply(entries);
- fileList.push(...entryList);
+ progressFileList.push(...entryList);
// Check if all the file has been viewed
const isFinished = !entryList.length;
-
if (isFinished) {
- progressFileList = progressFileList.concat(fileList);
+ return;
} else {
sequence();
}
@@ -71,6 +68,7 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
};
function walkFiles() {
+ let wipIndex = 0;
while (wipIndex < progressFileList.length) {
_traverseFileTree(progressFileList[wipIndex]);
wipIndex++;
From 56ccb4cca8a22e11a5eeb31d5e7004f161cb9068 Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Thu, 11 Jul 2024 17:35:20 +0800
Subject: [PATCH 7/8] fix:ci
---
src/traverseFileTree.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index 18a35b0a..ad89f055 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -12,7 +12,7 @@ interface InternalDataTransferItem extends DataTransferItem {
const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepted) => {
const flattenFileList = [];
- let progressFileList = [];
+ const progressFileList = [];
files.forEach(file => progressFileList.push(file.webkitGetAsEntry() as any));
function loopFiles(item: InternalDataTransferItem) {
const dirReader = item.createReader();
From 523a319a049ff1423d045fd26f9c90e19a560df3 Mon Sep 17 00:00:00 2001
From: zhwcreate <3331598351@qq.com>
Date: Thu, 11 Jul 2024 17:43:47 +0800
Subject: [PATCH 8/8] feat: improve code
---
src/traverseFileTree.ts | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/traverseFileTree.ts b/src/traverseFileTree.ts
index ad89f055..7b74c0ba 100644
--- a/src/traverseFileTree.ts
+++ b/src/traverseFileTree.ts
@@ -24,9 +24,7 @@ const traverseFileTree = (files: InternalDataTransferItem[], callback, isAccepte
progressFileList.push(...entryList);
// Check if all the file has been viewed
const isFinished = !entryList.length;
- if (isFinished) {
- return;
- } else {
+ if (!isFinished) {
sequence();
}
});