JSFiddle - React, Tailwind, and code Playground

by _sir

HTML

<div id="dropzone" ondragover="handleDragOver(event)" ondrop="handleDrop(event)"></div>

CSS

#dropzone {
        width: 100vw;
        height: 100vh;
      }

JavaScript

let files = [];

/**
 * @param {FileSystemDirectoryEntry} entry
 * @returns {Promise[FileSystemEntry]}
 */
const getDirectoryEntries = (entry) => new Promise((res, rej) => entry.createReader().readEntries(res, rej));

const handleDragOver = event => event.preventDefault();





function handleDrop(event) {
  event.preventDefault();
  files = [];

  const dataTransferItems = Object.keys(event.dataTransfer.items);

  Promise.all(dataTransferItems.map(async (key) => {
    const item = event.dataTransfer.items[key];
    const entry = item.webkitGetAsEntry();

    if (!entry) return;

    if (entry.isFile) {
      files.push(entry.fullPath);
      return entry.fullPath;
    } else if (entry.isDirectory) {
    	return getDirectoryEntries(entry).then()
      const directoryReader = entry.createReader();
      return await walkDirRecursively(entry.fullPath, directoryReader);
    }
  })).then(() => console.log(files));
}



function walkDirRecursively(path, directoryReader) {
  const readerPromise = new Promise((resolve, reject) =>
    directoryReader.readEntries(resolve, reject));
  return readerPromise.then((entries) => {
    entries.reduce((acc, entry) => acc.then((data) => {
      if (entry.isFile) {
        const newPath = path + "/" + entry.name;
        files.push(newPath);
        return [...data, newPath];
      }
      if (entry.isDirectory) {
        const newPath = path + "/" + entry.name;
        const newDirectoryReader = entry.createReader();
        return walkDirRecursively(newPath, newDirectoryReader);
      }
      // unlikely case
      return data;
    }), Promise.resolve([]));
  });
}