Skip to content

Commit

Permalink
pass folderName to UploadFile object when dropping folders
Browse files Browse the repository at this point in the history
  • Loading branch information
Glenn Van De Putte committed May 24, 2024
1 parent 3d58723 commit 8770ea8
Show file tree
Hide file tree
Showing 6 changed files with 1,874 additions and 1,896 deletions.
24 changes: 17 additions & 7 deletions ember-file-upload/src/components/file-dropzone.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { getOwner } from '@ember/application';
import DataTransferWrapper from '../system/data-transfer-wrapper.ts';
import DataTransferWrapper, {
type FileWithDirectory,
} from '../system/data-transfer-wrapper.ts';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { UploadFile } from '../upload-file.ts';
Expand Down Expand Up @@ -219,9 +221,9 @@ export default class FileDropzoneComponent extends Component<FileDropzoneSignatu
// }

if (this.dataTransferWrapper) {
const files = this.args.allowFolderDrop
const files: FileWithDirectory[] = this.args.allowFolderDrop
? await this.dataTransferWrapper.getFilesAndDirectories()
: this.files;
: this.files.map((file) => ({ file }));

const addedFiles = this.addFiles(files);
this.args.onDrop?.(addedFiles, this.dataTransferWrapper);
Expand All @@ -230,14 +232,22 @@ export default class FileDropzoneComponent extends Component<FileDropzoneSignatu
}
}

addFiles(files: File[]) {
addFiles(files: FileWithDirectory[]) {
const addedFiles = [];
for (const file of files) {
if (file instanceof File) {
const uploadFile = new UploadFile(file, FileSource.DragAndDrop);
if (file.file instanceof File) {
const uploadFile = new UploadFile(
file.file,
FileSource.DragAndDrop,
file.folderName,
);
if (
this.args.filter &&
!this.args.filter(file, files, files.indexOf(file))
!this.args.filter(
file.file,
files.map((f) => f.file),
files.indexOf(file),
)
) {
continue;
}
Expand Down
36 changes: 22 additions & 14 deletions ember-file-upload/src/system/data-transfer-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ interface FutureProofDataTransferItem extends DataTransferItem {
getAsEntry?: () => FileSystemDirectoryEntry | null;
}

export interface FileWithDirectory {
file: File;
folderName?: string;
}

const getDataSupport = {};

// this will read a filesystementry into a File object, but ignore the entry if it is a directory
Expand Down Expand Up @@ -47,12 +52,16 @@ const readAllFilesInDirectory = (item: DataTransferItem): Promise<File[]> =>

const readDataTransferItem = async (
item: DataTransferItem,
): Promise<File[]> => {
if (getEntry(item)?.isDirectory) {
return readAllFilesInDirectory(item);
): Promise<FileWithDirectory[]> => {
const entry = getEntry(item);
if (entry?.isDirectory) {
return (await readAllFilesInDirectory(item)).map((file) => ({
file,
folderName: entry?.name,
}));
} else {
const fileItem = item.getAsFile() as File;
return [fileItem];
return [{ file: fileItem }];
}
};

Expand Down Expand Up @@ -97,23 +106,22 @@ export default class DataTransferWrapper {
return this.files.length ? this.files : this.items;
}

async getFilesAndDirectories() {
async getFilesAndDirectories(): Promise<FileWithDirectory[]> {
if (this.dataTransfer?.items) {
const allFilesInDataTransferItems: File[][] = await Promise.all(
Array.from(this.dataTransfer?.items).map(readDataTransferItem),
);
const allFilesInDataTransferItems: FileWithDirectory[][] =
await Promise.all(
Array.from(this.dataTransfer?.items).map(readDataTransferItem),
);

const flattenedFileArray: File[] = allFilesInDataTransferItems.reduce(
(flattenedList, fileList) => {
const flattenedFileArray: FileWithDirectory[] =
allFilesInDataTransferItems.reduce((flattenedList, fileList) => {
return [...flattenedList, ...fileList];
},
[],
);
}, []);

return flattenedFileArray;
} else {
const droppedFiles: File[] = Array.from(this.dataTransfer?.files ?? []);
return droppedFiles;
return droppedFiles.map((file) => ({ file }));
}
}

Expand Down
19 changes: 16 additions & 3 deletions ember-file-upload/src/test-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,32 @@ interface FileSystemEntryStub {

export async function dragAndDropDirectory(
target: string | HTMLElement,
folderName: string,
filesInDirectory: (File | Blob)[],
singleFiles: (File | Blob)[],
singleFiles?: (File | Blob)[],
) {
const dropzone = target instanceof HTMLElement ? target : find(target);
assert(`Selector '${dropzone}' could not be found.`, dropzone);
assert(
'All files must be instances of File/Blob type',
'filesInDirectory must be an array',
filesInDirectory instanceof Array,
);
assert(
'All files in directory must be instances of File/Blob type',
filesInDirectory.every((file) => file instanceof Blob),
);
if (singleFiles) {
assert('singleFiles must be an array', singleFiles instanceof Array);
assert(
'All added singleFiles must be instances of File/Blob type',
singleFiles.every((file) => file instanceof Blob),
);
}

const folderItem = {
webkitGetAsEntry: () => ({
isDirectory: true,
name: folderName,
createReader: () => ({
readEntries: (callback: (entries: FileSystemEntryStub[]) => void) => {
const entryFiles = filesInDirectory.map((file) => {
Expand All @@ -135,7 +148,7 @@ export async function dragAndDropDirectory(
});

const dataTransfer = {
items: [folderItem, ...singleFiles.map(singleFileItem)],
items: [folderItem, ...(singleFiles || []).map(singleFileItem)],
};

await triggerEvent(dropzone, 'dragenter', { dataTransfer });
Expand Down
4 changes: 3 additions & 1 deletion ember-file-upload/src/upload-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ import { estimatedRate } from './system/rate.ts';
export class UploadFile {
file: File;
#source: FileSource;
folderName?: string;

queue?: Queue;

constructor(file: File, source: FileSource) {
constructor(file: File, source: FileSource, folderName?: string) {
this.file = file;
this.#source = source;
this.folderName = folderName;
}

/**
Expand Down
Loading

0 comments on commit 8770ea8

Please sign in to comment.