JSFiddle - React, Tailwind, and code Playground
HTML
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
CSS
#dropzone{
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over{
background-color: rgba(0,0,0,.2);
}
JavaScript
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for(let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
}
else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}