diff --git a/AGENTS.md b/AGENTS.md index eb9f885..53aa6f5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,9 +4,10 @@ ## Current Architecture -- Active frontend: `site/nostr/` +- Active frontend: `site/` (`index.html`, `nostr-client.js`, `nostr-client.css`, `locales.js`) - Static deployment root: `site` -- Browser dependencies: vendored under `site/nostr/vendor/` +- Browser dependencies: vendored under `site/vendor/` +- Legacy path: `site/nostr/index.html` is a redirect stub forwarding old `/nostr/` poster URLs and QR codes to the root - Python helper package: `voxvera/nostr/` - Design plan: `docs/nostr-static-client-spec.md` @@ -21,8 +22,8 @@ ## Localization -- Use `site/nostr/locales.js` for flyer content defaults. -- Use `NOSTR_UI` in `site/nostr/nostr-client.js` for editor/viewer controls and Nostr-specific labels. +- Use `site/locales.js` for flyer content defaults. +- Use `NOSTR_UI` in `site/nostr-client.js` for editor/viewer controls and Nostr-specific labels. - Add translations for every supported language when adding user-facing strings. - Check right-to-left languages when touching layout. @@ -31,8 +32,8 @@ Run: ```bash -node --check site/nostr/nostr-client.js +node --check site/nostr-client.js pytest -q ``` -For visual or print changes, also run a local static server and inspect `/nostr/` in a browser. +For visual or print changes, also run a local static server and inspect the site root (`/`) in a browser. diff --git a/README.md b/README.md index dba7cae..cde6e57 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,15 @@ VoxVera is now a static Nostr-powered flyer client. -The active app lives at [`site/nostr/`](site/nostr/). It lets a user author flyer content, publish it as a public Nostr event, and render the flyer later from an event ID or Nostr address. The frontend is intentionally self-contained: relays store the content, and any static host can serve the client. +The active app lives at the site root ([`site/`](site/)). It lets a user author flyer content, publish it as a public Nostr event, and render the flyer later from an event ID or Nostr address. The frontend is intentionally self-contained: relays store the content, and any static host can serve the client. The previous Tor/OnionShare CLI version is preserved on the `legacy-tor` branch. ## What Is In `main` -- `site/nostr/`: static editor/viewer client -- `site/nostr/vendor/`: vendored browser dependencies for Nostr and QR generation +- `site/index.html`, `site/nostr-client.js`, `site/nostr-client.css`, `site/locales.js`: static editor/viewer client +- `site/vendor/`: vendored browser dependencies for Nostr and QR generation +- `site/nostr/index.html`: redirect stub so legacy `/nostr/` poster URLs and QR codes still resolve - `site/CNAME`: custom-domain target - `voxvera/nostr/`: small Python schema/validation helpers - `docs/nostr-static-client-spec.md`: design notes and development plan @@ -25,7 +26,7 @@ python3 -m http.server 8768 --directory site Then open: ```text -http://127.0.0.1:8768/nostr/ +http://127.0.0.1:8768/ ``` No build command is required for the frontend. @@ -39,12 +40,12 @@ Point Vercel at this repository on `main`. - Build command: leave empty - Output directory: `site` -The root `site/index.html` redirects to `/nostr/`, so the domain can serve the current client without preserving the legacy Tor page. +The client is served from the domain root (`site/index.html`). `site/nostr/index.html` is a redirect stub that forwards the legacy `/nostr/` path to the root while preserving the query/fragment, so older poster URLs and printed QR codes still resolve. ## Verification ```bash -node --check site/nostr/nostr-client.js +node --check site/nostr-client.js pytest -q ``` diff --git a/docs/nostr-static-client-spec.md b/docs/nostr-static-client-spec.md index c70da3d..5692050 100644 --- a/docs/nostr-static-client-spec.md +++ b/docs/nostr-static-client-spec.md @@ -22,16 +22,16 @@ Nostr relays store the flyer source content. Static hosts only serve the client. ```text site/ - index.html + index.html (the client) + nostr-client.css + nostr-client.js + locales.js CNAME + vendor/ + nostr-tools/ + qrcode-generator/ nostr/ - index.html - nostr-client.css - nostr-client.js - locales.js - vendor/ - nostr-tools/ - qrcode-generator/ + index.html (redirect stub for legacy /nostr/ URLs) voxvera/ nostr/ schema.py @@ -49,7 +49,7 @@ No build command is required. Vercel should use: - output directory: `site` - build command: empty -`site/index.html` redirects root traffic to `/nostr/`. +The client is served from the root (`site/index.html`). `site/nostr/index.html` is a redirect stub that forwards the legacy `/nostr/` path to the root, preserving the query string and `#naddr` fragment, so poster URLs and QR codes printed before the move still resolve. ## Event Model @@ -84,7 +84,7 @@ Payload: "content": "Flyer body text", "url_message": "Follow this link to learn more.", "url": "https://creator.example/action", - "tear_off_link": "https://voxvera.org/nostr/?addr=naddr1...", + "tear_off_link": "https://voxvera.org/nostr/#naddr1...", "footer_message": "0110010", "qr_target": "flyer_url" } @@ -102,6 +102,8 @@ When publishing, the client computes the replaceable-event `naddr` and writes th The `naddr` is encoded with a **single relay hint** (the primary configured relay) instead of the full relay list. This keeps the poster URL short and its tear-off QR code easy to scan — a typical poster URL drops from ~233 characters (full list) to ~171 — while still pointing a fresh viewer at a relay that has the event. Viewers also fall back to `DEFAULT_RELAYS`, which is where flyers are published by default. This stays a standard NIP-19 `naddr`, so any Nostr client can resolve it, and older relay-bearing `naddr` URLs continue to decode and resolve unchanged. +The naddr is carried in the URL **fragment** (`#naddr1...`) rather than a `?addr=` query parameter. The fragment is shorter (less QR clutter), needs no URL-encoding, and never reaches the static host. `getUrlEventReference` reads the naddr from query params, the fragment, or anywhere in the full URL, so older `?addr=` poster URLs and printed QR codes still resolve. + Supported values: - `flyer_url`: tear-off QR points to the hosted client URL for the poster @@ -122,9 +124,9 @@ The client and schema helper must: ## Localization -Flyer defaults come from `site/nostr/locales.js`. +Flyer defaults come from `site/locales.js`. -Nostr editor/viewer controls and Nostr-specific flyer labels come from `NOSTR_UI` in `site/nostr/nostr-client.js`. +Nostr editor/viewer controls and Nostr-specific flyer labels come from `NOSTR_UI` in `site/nostr-client.js`. Language changes should: @@ -161,7 +163,7 @@ browser. ## Verification ```bash -node --check site/nostr/nostr-client.js +node --check site/nostr-client.js pytest -q ``` diff --git a/site/index.html b/site/index.html index 126c32c..24108b3 100644 --- a/site/index.html +++ b/site/index.html @@ -1,15 +1,176 @@ - +
- - - -Static editor and viewer for decentralized flyer source events.
+