Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug #13501: Read all files when drag&drop instead of stopping at 100 #2111

Merged
merged 1 commit into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck
this.hasDropZoneOver = false;
}

async onDropped(event: any) {
async onDropped(event: DragEvent) {
this.hasDropZoneOver = false;
event.preventDefault();
const items = event.dataTransfer.items;
Expand All @@ -232,7 +232,7 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck

async handleFile(event: any) {
event.preventDefault();
const items = event.target.files;
const items: FileList = event.target.files;
const exists = this.uploadService.directoryExistInZipFile(items, false);
if (exists) {
this.snackBar.open(this.translationService.instant('COLLECT.UPLOAD_FILE_ALREADY_IMPORTED'), null, { duration: 3000 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class CollectUploadService {
this.zipFile = new JSZip();
}

private static uploadFilesInfo(files: any) {
private static uploadFilesInfo(files: FileList) {
let size = 0;
for (let i = 0; i < files.length; i++) {
size += files[i].size;
Expand All @@ -58,15 +58,15 @@ export class CollectUploadService {
return { name, size, dragged: false } as CollectUploadFile;
}

private static uploadFilesDirectoryName(files: any) {
private static uploadFilesDirectoryName(files: FileList) {
let name = files[0].webkitRelativePath;
if (name.indexOf('/') !== -1) {
name = name.split('/')[0];
}
return name;
}

private static dragAndDropUploadFilesDirectoryName(files: any) {
private static dragAndDropUploadFilesDirectoryName(files: DataTransferItemList) {
return files[0].webkitGetAsEntry().fullPath.substring(1);
}

Expand All @@ -89,12 +89,12 @@ export class CollectUploadService {
this.uploadingFiles$.next(this.filesToUpload);
}

directoryExistInZipFile(files: any, dragged: boolean) {
directoryExistInZipFile(files: DataTransferItemList | FileList, dragged: boolean) {
let name: string;
if (dragged) {
name = CollectUploadService.dragAndDropUploadFilesDirectoryName(files);
name = CollectUploadService.dragAndDropUploadFilesDirectoryName(files as DataTransferItemList);
} else {
name = CollectUploadService.uploadFilesDirectoryName(files);
name = CollectUploadService.uploadFilesDirectoryName(files as FileList);
}
const indexName = Object.values(this.zipFile.files)
.filter((f) => f.dir)
Expand Down Expand Up @@ -147,7 +147,7 @@ export class CollectUploadService {
this.uploadingFiles$.next(this.filesToUpload);
}

async handleUpload(files: any) {
async handleUpload(files: FileList) {
if (files.length === 0) {
return;
}
Expand All @@ -158,9 +158,9 @@ export class CollectUploadService {
}
}

async handleDragAndDropUpload(files: any[]) {
const [uploadFile] = await Promise.all([this.dragAndDropUploadFilesInfo(files), this.buildAsyncZip(files)]);
this.uploadInfo(uploadFile);
async handleDragAndDropUpload(files: DataTransferItemList) {
const [filesInfo] = await Promise.all([this.dragAndDropUploadFilesInfo(files), this.buildAsyncZip(files)]);
this.uploadInfo(filesInfo);
}

/*** Private methods ***/
Expand All @@ -186,7 +186,7 @@ export class CollectUploadService {
this.watchZippedFile$.next(this.zippedFile);
}

private async buildAsyncZip(files: any) {
private async buildAsyncZip(files: DataTransferItemList) {
for (let i = 0; i < files.length; i++) {
const item = files[i].webkitGetAsEntry();
if (item) {
Expand All @@ -195,7 +195,7 @@ export class CollectUploadService {
}
}

private async dragAndDropUploadFilesInfo(files: any) {
private async dragAndDropUploadFilesInfo(files: DataTransferItemList) {
const name = CollectUploadService.dragAndDropUploadFilesDirectoryName(files);
let size = 0;
for (let i = 0; i < files.length; i++) {
Expand All @@ -207,60 +207,48 @@ export class CollectUploadService {
return { name, size, dragged: true } as CollectUploadFile;
}

private async calcDragAndDropUploadFilesSize(item: any) {
private async calcDragAndDropUploadFilesSize(item: FileSystemEntry) {
if (item.isDirectory) {
let size = 0;
const dirEntries: any[] = await this.parseDirectoryEntry(item);
const dirEntries: FileSystemEntry[] = await this.parseDirectoryEntry(item as FileSystemDirectoryEntry);
for (const entry of dirEntries) {
size += await this.calcDragAndDropUploadFilesSize(entry);
}
return size;
} else {
const f = await this.parseFileEntry(item);
const f = await this.parseFileEntry(item as FileSystemFileEntry);
return f.size;
}
}

private async parse(zip: JSZip, item: any) {
private async parse(zip: JSZip, item: FileSystemEntry) {
if (item.isDirectory) {
const dirEntries: any[] = await this.parseDirectoryEntry(item);
const dirEntries: any[] = await this.parseDirectoryEntry(item as FileSystemDirectoryEntry);
if (dirEntries.length === 0) {
zip.folder(item.fullPath.substring(1));
}
for (const entry of dirEntries) {
await this.parse(zip, entry);
}
} else {
const f = await this.parseFileEntry(item);
const f = await this.parseFileEntry(item as FileSystemFileEntry);
zip.file(item.fullPath.substring(1), f);
}
}

private parseFileEntry(fileEntry: any): Promise<any> {
return new Promise((resolve, reject) => {
fileEntry.file(
(file: any) => {
resolve(file);
},
(err: any) => {
reject(err);
},
);
});
private parseFileEntry(fileEntry: FileSystemFileEntry): Promise<File> {
return new Promise((resolve, reject) => fileEntry.file(resolve, reject));
}

private parseDirectoryEntry(directoryEntry: any): Promise<any[]> {
private async parseDirectoryEntry(directoryEntry: FileSystemDirectoryEntry): Promise<FileSystemEntry[]> {
const directoryReader = directoryEntry.createReader();
return new Promise((resolve, reject) => {
directoryReader.readEntries(
(entries: any) => {
resolve(entries);
},
(err: any) => {
reject(err);
},
);
});
const entries: FileSystemEntry[] = [];
let batch;
// We have to call readEntries several times until it returns an empty list to make sure we read all entries (otherwise it is limited to 100 entries)
while ((batch = await new Promise<FileSystemEntry[]>((resolve, reject) => directoryReader.readEntries(resolve, reject))).length) {
entries.push(...batch);
}
return entries;
}

private uploadInfo(uploadFile: CollectUploadFile) {
Expand Down