Files
SwipeAnything/CHANGELOG.md
T
ilia 0c9919f93c Add second adapter, thumbnails, a11y pass, and a real test suite
- Immich adapter (adapters/immich.js): swipe a self-hosted photo library
  over its REST API, proving the adapter contract works for remote
  sources, not just the filesystem.
- Refactor the preview contract from resolvePreviewPath() to
  streamPreview()/streamThumbnail(), so adapters can serve previews from
  anywhere (local file, proxied fetch, etc).
- macOS Quick Look-backed thumbnail cache (lib/thumbnails.js): real
  resized thumbnails, HEIC/HEIF, and video poster frames, with a hard
  timeout and graceful fallback to the original file everywhere else.
- Native "Browse..." folder picker (osascript) in Settings, with manual
  typing as the fallback on other platforms.
- Confirm-guarded "Empty trash" action -- the only place this project
  permanently deletes anything.
- Session resume: progress now survives a server restart and an
  unchanged Rescan via .swipeanything-session.json.
- Accessibility pass: live region item announcements, aria-labels on
  action buttons, focus-trapped shortcuts dialog with focus restore,
  visible focus rings, a real role="progressbar", and <button>s instead
  of <a href="#"> in the header.
- node:test suite (23 tests) covering the folder adapter, the Immich
  adapter (mocked fetch, no live server needed), and the HTTP API
  end-to-end; wired up as `npm test`.
- Also includes the keyboard shortcuts (up/down undo/skip), swipe stamps,
  and shortcuts modal from the previous session that hadn't been
  committed yet.
2026-07-25 19:41:47 -04:00

2.9 KiB

Changelog

All notable changes to this project are documented here. Format loosely follows Keep a Changelog.

[Unreleased]

Added

  • Immich adapter (adapters/immich.js): swipe through a self-hosted Immich photo library. Reject moves the asset to Immich's own trash; undo restores it. Second reference implementation of the adapter contract, demonstrating a remote-API source alongside the local filesystem.
  • Real thumbnails on macOS via a qlmanage (Quick Look)-backed cache (lib/thumbnails.js), covering HEIC/HEIF images and video poster frames for free. Falls back to the original file on any failure/timeout or on non-macOS platforms.
  • Native folder picker: a "Browse…" button next to folder-type settings fields opens a real macOS Finder dialog (POST /api/browse-folder, via osascript). Falls back to manual typing elsewhere.
  • Empty trash: a separate, confirm-guarded action (shown in the header once the folder adapter's trash is non-empty) that permanently deletes what "Reject" has moved aside. The only place this project deletes anything outright.
  • Session resume: review progress now persists to .swipeanything-session.json and survives a server restart (and a same-folder "Rescan"), as long as the underlying item set hasn't changed.
  • Accessibility pass: a live region announces "Item X of Y: name" on every card change, action buttons get full aria-labels (e.g. "Keep, right arrow"), the shortcuts dialog traps and restores focus, focus rings are visible everywhere, the progress bar is a real role="progressbar"/aria-valuenow, and header actions are <button>s instead of <a href="#">.
  • Test suite (test/, npm test) using Node's built-in test runner: the folder adapter against real temp directories, the Immich adapter against a mocked fetch, and the HTTP API end-to-end.
  • password and select settings field types (used by the Immich adapter's API key and order fields).

Changed

  • Adapter contract: resolvePreviewPath(itemId) replaced with streamPreview(itemId, res) / streamThumbnail(itemId, res), so adapters can serve previews from anywhere (local file, proxied remote fetch, etc.), not just a local path handed to res.sendFile.
  • server.js now exports { app, start } instead of calling app.listen() at import time, and reads its config/session file paths from SWIPEANYTHING_CONFIG_PATH / SWIPEANYTHING_SESSION_PATH when set — both needed to make the app testable in-process.

[0.1.0] - initial version

  • Local folder adapter: swipe local files, reject moves to .swipeanything-trash/, undo restores.
  • Pluggable adapter framework (adapters/base.js) with a generic, schema-driven settings UI.
  • Vanilla HTML/CSS/JS swipe UI: drag gestures, keyboard shortcuts (keep/reject/skip/undo), visual keep/reject stamps, shortcuts help modal.
  • Zero-build-step Node.js + Express server.