Commit Graph
41 Commits
Author SHA1 Message Date
thePR0M3TH3ANandClaude Opus 4.8 9b03ada43a Flyers: edit, re-publish (keep-alive), and delete (tombstone + NIP-09)
Authors can now manage a published flyer from the editor when it's loaded from
an event (author-only — the active signing key must match the flyer's author):

- Edit: change fields and publish again; the same d-tag replaces in place.
- Re-publish (keep-alive): re-sign + re-broadcast the current content so relays
  that prune app-data don't age the flyer out. Partially addresses roadmap #4.
- Delete: belt-and-suspenders across relay behaviors —
  1) a replaceable TOMBSTONE (same kind+d, payload deleted:true + a ["deleted"]
     tag) that overwrites the flyer's content, so the board/viewer hide it even
     on relays that ignore deletions, and
  2) a NIP-09 deletion request (kind 5) for the addressable a-tag + event id.
  Confirmed via a modal; framed as best-effort, not a guarantee.

Tombstone recognition: the board's parseFlyers keeps the newest event per
(pubkey, d) and skips it when that newest version is a tombstone (so a delete
can't be reversed by an older copy arriving later); the viewer renders a
localized "This flyer was removed." state.

Adds the loaded-flyer actions UI + a delete-confirm modal, 11 new strings ×
14 languages, a Python schema test for the tombstone payload, and e2e for the
delete flow, board hiding, and the viewer removed state. 216 e2e across all six
engines; docs (spec/roadmap/README) updated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-10 19:39:23 -04:00
thePR0M3TH3ANandClaude Opus 4.8 23badb03ae Add an SVG favicon (no more /favicon.ico 404)
Link a small inline SVG (site/favicon.svg, a red tile with a white "V") from
both index.html and board.html via a root-absolute href, so it resolves from
"/" and from "/board/" under Vercel cleanUrls. With an icon link present,
browsers stop auto-requesting (and 404ing on) /favicon.ico. No binary asset and
no external dependency, consistent with the self-contained client.

e2e asserts both pages declare the favicon and that /favicon.svg is served as
valid SVG. Closes the last code-finishable item in the roadmap's smaller list.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-10 19:19:06 -04:00
thePR0M3TH3ANandClaude Opus 4.8 861407cbf6 Editor: publish under your own identity (NIP-07 / nsec) with PIN-encrypted nsec
Let authors publish a flyer under a stable, identifiable key when they want
one, while keeping anonymous-by-default. The editor now signs under one of
three identities, routed through activeIdentity()/signActiveEvent():

- Anonymous (default, unchanged): the per-device key, signed locally.
- NIP-07 extension: signs via window.nostr.signEvent; the secret never
  enters the page.
- Imported nsec: decoded to a key used to sign. By default the secret lives
  only in memory for the session. "Remember on this device" stores it
  encrypted with a PIN (PBKDF2 SHA-256, 600k iterations, random salt ->
  AES-GCM-256); the plaintext secret is never written to storage. On reload a
  remembered key is locked until the PIN is entered; a session-only key falls
  back to anonymous.

The signer pill, author npub, naddr, and poster URL all follow the active
identity. New identity controls are localized across all 14 languages.

Security note (also in docs): a short numeric PIN is brute-forceable offline
if the encrypted blob leaks, so it guards casual snooping, not a targeted
attacker — the NIP-07 path is stronger, and NIP-46 is a documented follow-up.
The minimum PIN is 4 digits but longer is allowed and encouraged.

Also updates README, the client spec (new "Publishing identity" section),
the roadmap (#1/#2 marked in progress with phases shipped), and the e2e
README. Covered by the cross-engine Playwright suite (default-anonymous,
NIP-07 connect + publish, session-only nsec without persistence, invalid
nsec, PIN encrypt -> lock on reload -> wrong/right PIN -> unlock, and forget).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-10 10:16:53 -04:00
thePR0M3TH3ANandClaude Opus 4.8 7ab7e412ec Show a publish confirmation modal with the flyer URL
After Sign and publish succeeds, open a modal that tells the author the
flyer is published and shows its URL (pre-selected) with Copy and Close
buttons, so they know the process completed and where to view/share it.

- New modal markup in index.html + overlay/box styles (hidden in print).
- Closes on the Close button, backdrop click, or Escape; Copy writes the URL
  to the clipboard with a "Copied" confirmation.
- Localized for all 14 languages (published_title / published_message /
  close); the URL is result.posterUrl.
- Playwright: add a test that stubs the relay socket, publishes, and asserts
  the modal shows the localized text and the naddr poster URL. 84 tests pass
  across all engines.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-09 22:06:30 -04:00
thePR0M3TH3ANandClaude Opus 4.8 98086a0ad4 Add bulletin board page listing recent flyers from the relays
A small screen-only link below the flyer preview (outside the printable
sheet, hidden in print) opens board.html: a spreadsheet-style list of the
most recent VoxVera flyers found on the default relays.

- Columns: title, link (the poster URL shown as "link"), posting npub,
  language, and posted date; every column is sortable (default date
  descending). Replaceable events are de-duplicated per author+d identifier,
  keeping the latest.
- board.js is independent of nostr-client.js (which exports nothing): its UI
  strings live in BOARD_UI for all 14 languages, and it reuses the vendored
  nostr-tools and locales.js (language names + RTL direction).
- The board has its own language selector that reads/writes the same
  voxvera_nostr_lang localStorage key as the main client, so the choice
  carries across pages; switching it re-localizes the chrome, headers,
  language labels, and date formatting and flips RTL.
- Untrusted relay content is escaped, and link URLs are rejected unless
  http(s) so javascript:/data: never render as a link.

Docs updated (README, spec, AGENTS). Playwright: add tests for the
out-of-sheet print-hidden link, the localized sortable columns, and the
board language selector (incl. RTL + persistence). 72 tests pass across
Chromium, Firefox, WebKit, and Android/iOS mobile emulations.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-09 16:28:32 -04:00
thePR0M3TH3ANandClaude Opus 4.8 127f9c3134 Locale-aware defaults: browser language list + US Letter/A4 paper size
Language inference:
- Walk navigator.languages (the full ordered preference list), not just
  navigator.language, and pick the first base language we support. A user who
  prefers e.g. Dutch then German now gets German instead of the English
  fallback. De-duplicates the default-language resolution into setDefaultText.

Paper size (US Letter + A4):
- Add A4 (210x297mm) alongside US Letter (8.5x11in). Sheet dimensions move to
  CSS custom properties (--sheet-w/--sheet-h) toggled by a paper-letter/paper-a4
  class on <html>; the tear-off column and QR codes stay fixed physical sizes
  and the content column flexes.
- @page size is injected by JS (id voxvera-page-size) since @page cannot read
  CSS variables across engines; the print block keeps margin:0 and a Letter
  default for the pre-JS state.
- Default paper is chosen from the browser locale's region subtag
  (en-US -> Letter, en-GB/de-DE -> A4) — "by location" without geolocation,
  falling back to Letter when no region is present. A manual override selector
  (topbar + viewer controls) persists in localStorage and wins over the default.
- Paper size is a local print/view preference and is never written into the
  Nostr event, so a flyer reprints on either size unchanged.
- Add paper_size/paper_letter/paper_a4 labels for all 14 languages.

Docs + tests:
- Spec gains a "Print paper size" section; AGENTS.md records the
  not-in-payload invariant; README adds a feature bullet; the field-limits
  cheat sheet gains Letter/A4 columns (re-measured per paper size).
- Playwright: add tests for navigator.languages inference, region-based paper
  default (A4 and Letter), and override persistence. 54 tests pass across
  Chromium, Firefox, WebKit, and Android/iOS mobile emulations.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-09 15:56:25 -04:00
thePR0M3TH3ANandClaude Opus 4.8 77bfef1bbe Serve client at site root; redirect legacy /nostr/
The /nostr/ path was a leftover from when the site also hosted a Tor
client. The app is Nostr-only now, so move the client to the site root
and shorten poster URLs to https://voxvera.org/#naddr1... (drops both
/nostr/ and the ?addr= query key, for a cleaner/smaller tear-off QR).

- Move site/nostr/{nostr-client.js,css,locales.js,vendor} to site/.
- site/index.html is now the client; site/nostr/index.html is a redirect
  stub that forwards /nostr/ to / while preserving the query string and
  #naddr fragment, so older poster URLs and printed QR codes still
  resolve.
- Carry the naddr in the URL fragment (#) instead of ?addr=; the viewer
  reads query, fragment, or the full URL, so old links keep working.
- Update README, AGENTS.md, and the spec to the new paths.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-09 10:49:36 -04:00
thePR0M3TH3AN 9aa90773e6 Remove legacy Tor app from main 2026-06-05 10:13:41 -04:00
thePR0M3TH3AN e6ff21c069 chore: release v0.3.6 2026-03-17 16:16:17 -04:00
thePR0M3TH3AN 1fcb86ac8b chore: release v0.3.5 2026-03-17 15:35:17 -04:00
thePR0M3TH3ANandClaude Opus 4.6 ee5024678d fix(ui): tighten header spacing, preserve body edits on retry, add over-limit warning
- Switch content panel from space-between to flex-start so header
  elements (title, subtitle, headline) pack tightly instead of
  spreading across the full height
- Message area uses flex:1 to fill remaining space and keep footer
  at the bottom
- Body editor now preserves user text when re-editing after exceeding
  the 1000 character limit (previously reset to default)
- Show a yellow warning when user proceeds with over-limit body text
- Add body_over_limit_warning locale key across all 14 languages

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-16 19:41:40 -04:00
thePR0M3TH3ANandClaude Opus 4.6 9067596083 bump(v0.3.1): version bump, prefer tarball install, translate locale names
- Bump version to 0.3.1 for new release with all content fixes
- Reorder install strategies: tarball first (always current with main),
  pre-built binary last (can lag behind)
- Translate the "name" field across all 14 locale files
- Rebuild HTML files with updated locales

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-16 14:57:08 -04:00
thePR0M3TH3ANandClaude Opus 4.6 bcc8616851 fix(content): apply newline-to-br conversion in build_site locale embedding and rebuild HTML
The build_site() path was missing the _newlines_to_br() call when
embedding user content into the locales JSON, causing literal \n to
appear in the generated index.html files. Fixed and rebuilt both
site/index.html and voxvera/host/voxvera/index.html.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-16 13:54:04 -04:00
thePR0M3TH3AN 4717304e1e Restore localized landing page content in build system
- Modified voxvera/cli.py to avoid overriding localized landing content if user config matches English defaults.
- Synchronized voxvera/src/config.json with site/config.json defaults for reliable comparison.
- Refreshed site/index.html and source bundle to reflect these changes.
2026-03-14 22:04:39 -04:00
thePR0M3TH3AN c5573075b6 chore: release v0.1.7 2026-03-14 17:10:03 -04:00
thePR0M3TH3AN 193345e616 feat: simplify viral distribution to source ZIP and add uninstall scripts 2026-03-14 16:48:55 -04:00
thePR0M3TH3AN 2535c55670 docs: regenerate localized documentation and site assets, update binaries 2026-03-14 09:35:12 -04:00
thePR0M3TH3AN 60e4d6bcea feat: add download dropdown with OS-specific binaries and source zip 2026-03-13 22:43:26 -04:00
thePR0M3TH3AN 4e0bc20f88 feat: Final global expansion to 14 languages including Portuguese, Chinese, Farsi, and Turkish 2026-03-13 16:27:53 -04:00
thePR0M3TH3AN 053ad79736 feat: Expand to 10 languages including French, Japanese, Hindi, and Swahili with full RTL/CJK/Devanagari support 2026-03-13 16:20:45 -04:00
thePR0M3TH3AN ece805a6d2 feat: Add support for Russian, Hebrew (RTL), and Arabic (RTL) with visual width validation 2026-03-13 16:17:54 -04:00
thePR0M3TH3AN 6afbe29552 feat: Implement bulletproof layout system with precise char limits and CSS boundaries 2026-03-13 16:14:00 -04:00
thePR0M3TH3AN c3d2b284cd fix: Align strike-through logic across all languages to redact 'NO/NOT' 2026-03-13 16:08:53 -04:00
thePR0M3TH3AN ec409bece3 feat: Support Markdown-style ~~ redaction syntax in locales and build logic 2026-03-13 16:04:32 -04:00
thePR0M3TH3AN 553a7d42c1 fix: Ensure HTML markup in landing content is rendered correctly by the JS engine 2026-03-13 16:03:21 -04:00
thePR0M3TH3AN 973b8262e0 fix: Add landing tokens to locales and ensure build_site pre-renders them correctly 2026-03-13 15:58:15 -04:00
thePR0M3TH3AN b4d8852c3e fix: Restore data-i18n attributes to re-enable language selector while preserving zero-JS support 2026-03-13 15:55:53 -04:00
thePR0M3TH3AN 1783d55973 security: Implement static translation injection for zero-JS Tor compatibility 2026-03-13 15:52:35 -04:00
thePR0M3TH3AN d22fb0c9bd feat: Implement Smart Translation to allow landing page content to be localized 2026-03-13 15:50:56 -04:00
thePR0M3TH3AN b0ad915a62 feat: Add build-site command to automate public website maintenance and mirroring 2026-03-13 15:41:49 -04:00
thePR0M3TH3AN a3ebfe26c8 ui: Update download button to be more descriptive and serve from local path 2026-03-13 15:23:54 -04:00
thePR0M3TH3AN c55ed24f2b feat: Add German locale and localized CLI language aliases (--sprache, --idioma) 2026-03-13 15:14:13 -04:00
thePR0M3TH3AN c706172dc3 feat: Add multi-language support to the main landing page 2026-03-13 15:10:08 -04:00
thePR0M3TH3AN e0f210d249 fix: Ensure print layout is preserved by resetting flex display in @media print 2026-03-13 09:43:00 -04:00
thePR0M3TH3AN 92128d2aad feat: Add no-JS mobile scaling and centering 2026-03-13 09:40:12 -04:00
thePR0M3TH3AN ae905edc69 fix: Disable HTML minification to resolve bad layout issues on Tor Browser 2026-03-13 09:09:38 -04:00
thePR0M3TH3AN 956a836ff0 fix: Improve static generation by preserving newlines and fixing HTML quote escaping 2026-03-13 08:48:04 -04:00
thePR0M3TH3AN 7c0d6b041c feat: Add voxvera manage command and convert html generator to static site rendering 2026-03-13 08:14:01 -04:00
thePR0M3TH3AN 97323c80e3 Remove form/Nostr/Cashu footer text, add button padding
- Remove the paragraph about filling out forms, Nostr, Cashu eCash
  from the flyer footer (both generated flyers and landing site)
- Wrap Print/Download buttons in a button-bar div with padding
- Keep 'built with voxvera' credit line
2026-03-13 07:14:37 -04:00
thePR0M3TH3AN 294eb52534 Fix web scrolling and point download button to repo zip
- Change body from height:100vh/overflow:hidden to min-height:100vh/overflow:auto
  so the full flyer is scrollable on screen
- Lock overflow:hidden inside @media print only to preserve print layout
- Site download button now points to GitHub archive (main.zip)
2026-03-13 07:10:52 -04:00
thePR0M3TH3AN 444a60fb44 Simplify setup: auto Tor config, remove HTTPS hosting, add e2e tests and landing site
- Remove HTTPS hosting option; flyers are served exclusively over Tor
- Auto-detect Tor SOCKS/control ports (no manual env vars needed)
- Auto-set tear-off links to .onion address from serve; keep content
  link user-configurable
- Fix onionshare-cli flags (remove nonexistent --use-running-tor)
- Graceful QR generation when URLs not yet configured
- Add get_tor_ports() with port probing and sensible defaults
- Add e2e test suite including live Tor reachability test
- Add unit tests for port detection, partial URLs, backward compat
- Add site/ directory with VoxVera-generated landing page for voxvera.org
- Rewrite all documentation to reflect simplified workflow
- Add flyer config field reference with char limits and layout diagram
2026-03-13 07:06:35 -04:00