Skip to content

Commit a2b6de0

Browse files
🎉 feat(#60): ignore chrome's file limit per dropped directory.
2 parents 686748b + 527e5b0 commit a2b6de0

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

projects/cdk/src/lib/dropzone/dropzone.service.ts

+48-16
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,62 @@ export class DropzoneService {
3434
return item.webkitGetAsEntry() || item.getAsFile();
3535
}
3636

37-
private _getFilesFromEntry(entry: FileSystemEntry | File): Promise<File[]> {
38-
return new Promise<File[]>((resolve) => {
39-
if (entry instanceof File) {
40-
return resolve([entry]);
41-
}
37+
private async _getFilesFromEntry(entry: FileSystemEntry | File): Promise<File[]> {
38+
if (entry instanceof File) {
39+
return [entry];
40+
}
4241

43-
if (this._isFile(entry)) {
44-
return entry.file((f) => resolve([f]));
45-
}
42+
if (this._isFile(entry)) {
43+
const file = await this._readFilePromise(entry);
44+
return [file];
45+
}
46+
47+
if (this._isDirectory(entry)) {
48+
const entries = await this._readDirectoryWithoutLimit(entry);
49+
const children = entries.map((e) => this._getFilesFromEntry(e));
4650

47-
if (this._isDirectory(entry)) {
48-
const reader = entry.createReader();
51+
const files = await Promise.all(children);
52+
return this._flattenFiles(files);
53+
}
54+
55+
return [];
56+
}
4957

50-
reader.readEntries(async (entries) => {
51-
const children = entries.map((e) => this._getFilesFromEntry(e));
52-
const files = await Promise.all(children);
58+
/**
59+
* In Chrome >= 77, the `readEntries` method returns only 100 files.
60+
* To achieve a consistent behavior across browsers and not restrict user interaction,
61+
* we break the limit by recursively calling `readEntries`.
62+
*/
63+
private async _readDirectoryWithoutLimit(entry: FileSystemDirectoryEntry): Promise<FileSystemEntry[]> {
64+
const reader = entry.createReader();
65+
let entries: FileSystemEntry[] = [];
5366

54-
return resolve(this._flattenFiles(files));
55-
});
67+
const readEntries = async () => {
68+
const children = await this._readDirectoryPromise(reader);
69+
70+
if (children.length) {
71+
entries = entries.concat(children);
72+
await readEntries();
5673
}
57-
});
74+
};
75+
76+
await readEntries();
77+
return entries;
5878
}
5979

6080
private _isFile = (item: FileSystemEntry): item is FileSystemFileEntry => item.isFile;
6181
private _isDirectory = (item: FileSystemEntry): item is FileSystemDirectoryEntry => item.isDirectory;
6282
private _flattenFiles = (files: File[][]) => ([] as File[]).concat(...files);
83+
84+
private _readFilePromise(entry: FileSystemFileEntry) {
85+
return new Promise<File>((resolve) => {
86+
entry.file((file) => resolve(file));
87+
});
88+
}
89+
90+
private _readDirectoryPromise(reader: FileSystemDirectoryReader) {
91+
return new Promise<FileSystemEntry[]>((resolve) => {
92+
reader.readEntries((entries) => resolve(entries));
93+
});
94+
}
6395
}

0 commit comments

Comments
 (0)