Tutorial: drag-and-drop files

In a browser, a dropped file is an upload. In your desktop app it can be a real file on disk: read it in place, write results next to it, and reveal it in Finder or Explorer when you're done. This tutorial wires up the whole path.

1. Accept the drop

The drop itself is standard web platform code; nothing Deskifier-specific yet:

const zone = document.getElementById('drop-zone');

zone.addEventListener('dragover', (e) => {
  e.preventDefault(); // required, or the drop event never fires
  zone.classList.add('active');
});
zone.addEventListener('dragleave', () => zone.classList.remove('active'));

zone.addEventListener('drop', async (e) => {
  e.preventDefault();
  zone.classList.remove('active');
  for (const file of e.dataTransfer.files) {
    await handleDroppedFile(file);
  }
});

Inside a Deskifier app, dropping a file also grants your app access to its real path, which is what unlocks everything below. (Access control is path-based: your app can reach the locations the user has granted through drops and dialogs plus whatever your Filesystem plugin allows; see filesystem.getAllowedPaths.)

2. Work with the real file

With access granted, use the filesystem SDK rather than uploading:

async function handleDroppedFile(file) {
  // Resolve the dropped File object to its real path on disk:
  const { paths } = await window.deskifier.getPathForFile([file]);
  const path = paths[0];

  // Read it in place, no upload round-trip:
  const { data } = await window.deskifier.filesystem.readFile({ path });

  const result = await processLocally(data);

  // Write the output next to the original:
  const outPath = path.replace(/(\.[a-z0-9]+)?$/i, '.processed$1');
  await window.deskifier.filesystem.writeFile({ path: outPath, data: result });

  // Hand the result back to the user in their file manager:
  await window.deskifier.filesystem.showInFolder({ path: outPath });
}

Generate previews for images with filesystem.createThumbnail, watch a dropped folder for changes with filesystem.watch, or move finished work to the trash safely with filesystem.trashFile.

3. Degrade gracefully in the browser

The same drop zone should still work as an upload in browsers:

async function handleDroppedFile(file) {
  if ('deskifier' in window) {
    return handleOnDisk(file);   // the code above
  }
  return uploadViaForm(file);    // your existing browser path
}

Bonus: drop onto the tray icon

Desktop apps can accept drops with no window open at all, straight onto the tray icon:

window.deskifier.tray.onDropFiles(({ files }) => {
  // files are real paths; process without ever showing a window
});

Where to go next