resworbDownload resworb
Back

cull.lmth

All 39 lines. No libraries, nothing hidden. Read it before you run it.

cull.lmth
<!doctype html>
<meta charset="utf-8">
<meta name="resworb-write" content=".">
<title>Cull</title>
<style>
  html, body { height: 100%; margin: 0; background: #111; color: #eee; font: 14px system-ui, sans-serif; }
  img { display: block; width: 100%; height: 100%; object-fit: contain; }
  p { position: fixed; left: 1rem; bottom: 1rem; margin: 0; }
</style>
<img id="photo" alt="">
<p id="progress"></p>
<script type="module">
  // → keeps the photo, ← moves it to ./rejects, Z takes back the last choice.
  const photos = (await resworb.readdir('.')).filter(name => /\.(jpe?g|png|gif|webp)$/i.test(name)).sort();
  const choices = [];
  await resworb.mkdir('rejects');
  show();

  addEventListener('keydown', async ({ key }) => {
    const name = photos[choices.length];
    if (key === 'ArrowRight' && name) {
      choices.push({ name, kept: true });
    } else if (key === 'ArrowLeft' && name) {
      choices.push({ name, kept: false });
      await resworb.rename(name, `rejects/${name}`);
    } else if (key === 'z' && choices.length) {
      const last = choices.pop();
      if (!last.kept) await resworb.rename(`rejects/${last.name}`, last.name);
    }
    show();
  });

  function show() {
    const name = photos[choices.length];
    const kept = choices.filter(choice => choice.kept).length;
    photo.src = name ? encodeURIComponent(name) : '';
    progress.textContent = name ? `${choices.length + 1} / ${photos.length}, kept ${kept} · ${name}` : `Done. Kept ${kept} of ${photos.length}.`;
  }
</script>
Download cull.lmth