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.
This commit is contained in:
+46
-2
@@ -45,11 +45,29 @@ work for any adapter that implements the contract below.
|
||||
// Reverse applyAction() using the record it returned.
|
||||
}
|
||||
|
||||
// Optional, only if items have a file-like preview:
|
||||
async resolvePreviewPath(itemId) {
|
||||
// Optional: write a full-size preview straight to the Express response.
|
||||
// Return true if you handled it, false to let the server 404.
|
||||
async streamPreview(itemId, res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Optional: same, but for a smaller/faster thumbnail (used for the
|
||||
// card image and as a video poster frame). Falls back to streamPreview
|
||||
// in the UI if omitted or it returns false.
|
||||
async streamThumbnail(itemId, res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Optional: describe a reversible "trash" so the UI offers a
|
||||
// confirm-guarded "Empty trash" action. Return null if you don't have one.
|
||||
async describeTrash() {
|
||||
return null;
|
||||
}
|
||||
|
||||
async emptyTrash() {
|
||||
throw new Error('not supported');
|
||||
}
|
||||
|
||||
describeSource() {
|
||||
return ''; // short string shown in the UI header
|
||||
}
|
||||
@@ -58,6 +76,11 @@ work for any adapter that implements the contract below.
|
||||
module.exports = { YourAdapter };
|
||||
```
|
||||
|
||||
See `adapters/folder.js` for a local-filesystem implementation (`res.sendFile`
|
||||
+ a Quick Look thumbnail cache) and `adapters/immich.js` for a remote-API
|
||||
implementation (proxying a fetch response straight into `res`) of
|
||||
`streamPreview`/`streamThumbnail`.
|
||||
|
||||
2. Register it in `adapters/registry.js`:
|
||||
|
||||
```js
|
||||
@@ -97,6 +120,27 @@ npm start
|
||||
There's no build step — edit files under `public/` or `adapters/` and
|
||||
refresh the browser.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
Runs Node's built-in test runner (`node --test`) against `test/`. No extra
|
||||
dev dependencies, no separate test server to start.
|
||||
|
||||
- `test/folder-adapter.test.js` exercises the filesystem adapter against real
|
||||
temp directories (list/reject/undo/emptyTrash/path-traversal guard).
|
||||
- `test/immich-adapter.test.js` exercises the API-based adapter with
|
||||
`global.fetch` mocked out — no live Immich server needed. Follow this
|
||||
pattern for other network-backed adapters.
|
||||
- `test/api.test.js` boots the real Express app (`server.start(0)`) against an
|
||||
isolated config/session file (via the `SWIPEANYTHING_CONFIG_PATH` /
|
||||
`SWIPEANYTHING_SESSION_PATH` env vars) and drives it over real HTTP.
|
||||
|
||||
Please add or extend tests for new adapters and API changes — a fetch-mocked
|
||||
adapter test is usually enough; you don't need a live backend to contribute one.
|
||||
|
||||
## Pull requests
|
||||
|
||||
Keep adapters self-contained in their own file. Include a short section in
|
||||
|
||||
Reference in New Issue
Block a user