Files
latent/README.md
Fredrik Johansson 5a5c0da8a6
All checks were successful
Docker / build-and-push (push) Successful in 3m29s
Initial implementation of latent: film-effects editor + develop-later server
Canvas-based client-side editor (grain, vignette, halation, procedural
light leaks, color-cast presets) plus a small Express/SQLite server for
the two paths that need persistence: instant share links and delayed
"send to develop" links with a randomized reveal time.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 15:19:48 +02:00

2.3 KiB
Raw Blame History

latent

A phone-photo editor with a "develop it later" option. Upload a photo, apply film-style effects (grain, light leaks, vignette, halation, color cast) entirely in the browser, then either download it right away or send it off to "develop" — the server holds it behind a randomized delay (hours to days) before the link actually resolves to the image. Getting your photos back later, on purpose, for no practical reason except that it's a fun mechanic.

Named after the latent image, the photographic term for the picture that already exists on exposed film but is invisible until developed.

See PROPOSAL.md for the original design writeup.

Two finishing paths off one editor

  1. Instant — edit, then download directly, entirely client-side. Optionally generate a share link (explicit action, not automatic).
  2. Delayed — edit, then "send to develop": uploads to server storage, assigns a random develop_at within a configured range, and gives back a link immediately — it just won't resolve to the actual image until that time passes.

Running locally

npm install --prefix server
npm start --prefix server

Then open http://localhost:3000. DATA_DIR defaults to ./data (gitignored) for the SQLite db and image blobs.

Deploying

docker compose up using the provided docker-compose.yml / .env.example (copy .env.example to .env and adjust). CI builds and pushes the image on push to main via .gitea/workflows/docker.yml.

Config

All via env vars, see .env.example:

  • DEVELOP_MIN_HOURS / DEVELOP_MAX_HOURS — randomized delay range for the "send to develop" path (default 248h).
  • INSTANT_TTL_HOURS — retention for share links off the instant path (default 24h; deliberately shorter than the delayed path since it's a more casual "just give me a link" flow).
  • DELAYED_VIEW_WINDOW_HOURS — how long a delayed image stays available after develop_at passes, before the TTL sweep deletes it (default 168h / 7 days).
  • MAX_UPLOAD_BYTES, RATE_LIMIT_PER_HOUR — basic abuse limits; no accounts or auth on any endpoint, the link itself is the credential.

Non-goals

No accounts, no galleries, no e2e encryption (nothing here is sensitive — the whole point is a link other people can open), no collaborative editing.