Skip to content

Instantly share code, notes, and snippets.

@amanchopra95
Last active March 7, 2024 18:17
Show Gist options
  • Save amanchopra95/7e5dd52100837d63386c6fd0bb25e1a1 to your computer and use it in GitHub Desktop.
Save amanchopra95/7e5dd52100837d63386c6fd0bb25e1a1 to your computer and use it in GitHub Desktop.
Extract Files in HTML5 and Javascript. Drop any file or folder. This gist will return the list of files by recursively traversing the directories
/**
* Traversing directory using promises
**/
const traverseDirectory = (entry) => {
const reader = entry.createReader();
return new Promise((resolveDirectory) => {
const iterationAttempts = [];
const errorHandler = () => {};
function readEntries() {
reader.readEntries((batchEntries) => {
if (!batchEntries.length) {
resolveDirectory(Promise.all(iterationAttempts))
} else {
iterationAttempts.push(Promise.all(batchEntries.map((batchEntry) => {
if (batchEntry.isDirectory) {
return traverseDirectory(batchEntry);
}
return Promise.resolve(batchEntry);
})));
readEntries();
}
}, errorHandler);
}
readEntries();
});
}
const packageFile = (file, entry) => {
object = {
fileObject: file,
fullPath: entry ? entry.fullPath : '',
lastModified: file.lastModified,
lastModifiedDate: file.lastModifiedDate,
name: file.name,
size: file.size,
type: file.type,
webkitRelativePath: file.webkitRelativePath
}
return object;
}
const getFile = (entry) => {
return new Promise((resolve) => {
entry.file((file) => {
resolve(packageFile(file, entry));
})
})
}
const handleFilePromises = (promises, fileList) => {
return Promise.all(promises).then((files) => {
files.forEach((file) => {
fileList.push(file);
});
return fileList;
})
}
const getDataTransferFiles = (dataTransfer) => {
const dataTransferFiles = [];
const folderPromises = [];
const filePromises = [];
[].slice.call(dataTransfer.items).forEach((listItem) => {
if (typeof listItem.webkitGetAsEntry === 'function') {
const entry = listItem.webkitGetAsEntry();
if (entry) {
if (entry.isDirectory) {
folderPromises.push(traverseDirectory(entry));
} else {
filePromises.push(getFile(entry));
}
} else {
dataTransferFiles.push(listItem);
}
}
});
if (folderPromises.length) {
const flatten = (array) => array.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
return Promise.all(folderPromises).then((fileEntries) => {
const flattenedEntries = flatten(fileEntries);
flattenedEntries.forEach((fileEntry) => {
filePromises.push(getFile(fileEntry));
});
return handleFilePromises(filePromises, dataTransferFiles);
});
} else if (filePromises.length) {
return handleFilePromises(filePromises, dataTransferFiles);
}
return Promise.resolve(dataTransferFiles);
}
// Use this function by passing the drop or change event.
const getDroppedOrSelectedFiles = (event) => {
const dataTransfer = event.dataTransfer;
if (dataTransfer && dataTransfer.items) {
return getDataTransferFiles(dataTransfer)
.then((fileList) => {
return Promise.resolve(fileList);
})
}
const files = [];
const dragDropFileList = dataTransfer && dataTransfer.files;
const inputFieldFileList = event.target && event.target.files;
const fileList = dragDropFileList || inputFieldFileList || [];
for (let i = 0; i < fileList.length; i++) {
files.push(packageFile(fileList[i]));
}
return Promise.resolve(files);
}
@jodont
Copy link

jodont commented Oct 30, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment