Improve gallery video UX and add upload-to-publish media workflow.

Stage raw files in upload/, publish with make sync-media/publish, and polish the lightbox: autoplay, remembered volume, Escape to close, and image/video icons without poster or caption clutter.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-04 23:55:43 +12:00
parent 6c215d40e6
commit 3f5235daaf
22 changed files with 644 additions and 119 deletions

View File

@@ -24,6 +24,9 @@ make dev # live reload → http://localhost:7331
| `make generate` | Run `templ generate` in dev container |
| `make tidy` | Run `go mod tidy` in dev container |
| `make logs` | Follow dev container logs |
| `make sync-media` | Copy photos and convert videos from `upload/``app/images/` |
| `make thumbs` | Generate gallery thumbnails and video posters under `app/images/` |
| `make publish` | `sync-media` then `thumbs` |
## Features
@@ -31,7 +34,7 @@ make dev # live reload → http://localhost:7331
- Gallery loads via HTMX (`hx-get="/gallery"`)
- Lightbox modal with previous/next navigation
- Contact form with SMTP relay (HTMX submit, no page reload)
- Serves photos from `app/images/` (not in git — mount or copy locally)
- Serves gallery media from `app/images/` (published copy; not in git)
- Password-protected gallery admin at `/admin/`
## Gallery admin
@@ -60,13 +63,13 @@ If SMTP is not configured, the page shows a mailto fallback instead of the form.
## Dev container
`make dev` mounts `./app` and your host Go caches (`~/go/pkg/mod`, `~/.cache/go-build` by default). Override with `GOMODCACHE` / `GOCACHE` in `.env`.
`make dev` mounts `./app` and `./upload` (raw media staging) plus your host Go caches (`~/go/pkg/mod`, `~/.cache/go-build` by default). Override with `GOMODCACHE` / `GOCACHE` in `.env`.
**Use [http://localhost:7331](http://localhost:7331)** in the browser — the templ proxy injects live reload on `.templ`, `.go`, and `.css` changes. Port 8080 hits the app directly without auto-reload.
Only run **`dev`** or **`website`** at a time if you map both to the same host ports.
Production `website` mounts `./app/images` into the container (photos stay on the host). It joins the external `caddy` Docker network for reverse proxy labels.
Production `website` mounts `./app/images` into the container. It joins the external `caddy` Docker network for reverse proxy labels.
## Project layout
@@ -79,17 +82,22 @@ app/
internal/handlers/ Routes and HTMX partials
templates/ templ components (.templ → generated Go)
static/ CSS
images/ Gallery photos (served at /images/)
images/ Published gallery (served at /images/)
upload/ Raw media — run `make sync-media` to publish into app/images/
Dockerfile Production image
Dockerfile.dev Dev image (Go + templ + Air)
docker-compose.yaml
.env.example
```
## Gallery images
## Gallery media
On startup the server generates missing derivatives under `app/images/thumbs/` (and `hero/` for JPEGs only). Photos get resized JPEG thumbs; videos (`.mp4`, `.webm`, `.mov`) get a poster frame JPEG via `ffmpeg` when installed. The lightbox plays full videos or shows full-resolution photos. Derivatives are gitignored and rebuilt when source files are newer.
1. Drop photos and videos into repo-root **`upload/`** (album folders, same layout as the gallery).
2. Run **`make sync-media`** — JPEGs are copied; videos are converted to H.264 MP4 in **`app/images/`**.
3. Run **`make thumbs`** (or **`make publish`** for both steps) — builds `thumbs/` and `hero/` derivatives under `app/images/`.
The site serves files from `app/images/` at `/images/…`. Thumbnails and hero images are gitignored and rebuilt when sources are newer.
## Deploy notes
First request after deploy may take a moment while thumbnails are generated under the mounted `app/images/` directory.
After adding media, run `make publish` on the host before or after deploy. First request may take a moment while any missing thumbnails are generated.