Repository navigation
11 ux redesign
Status: implemented in
web/src/. Security architecture unchanged: browser = application, service = data.crates/sphinx-coreremains a reference implementation, never production crypto.
Top-level navigation (always visible, mobile-friendly):
| View | Everyday name | What it holds |
|---|---|---|
| Home | Home | Onboarding card, protection status, "Open a private link" bar (the existing nym:// URI bar, unchanged behaviour), recent people/places shortcuts |
| Messages | Messages | Chat list + conversation view over the existing NymAddressClient inbox. No raw addresses in the list — petnames / short labels only |
| Portal | Portal | Private-site viewer (iframe, URI-bar binding preserved) + community with Timeline / Private messages / About tabs. Identity keys stay in localStorage as before |
| Settings | Settings | Everyday settings (private network on/off, my private link + copy/QR, people, notifications). Technical tools collapsed under Advanced (hidden by default) |
Advanced (hidden by default) keeps the exact previous panels, untouched
behaviour: pure mixnet messaging details, manual private-site fetch, topology /
exit details, raw logs, key import/export, cover-traffic toggles. Nothing was
removed — it moved one tap away. The old PanelId registry (web/src/application/panels.ts)
is preserved so existing tests and persisted state keep working.
View switching is toolbar-controlled; background work (tunnel, inbox, feed polling) keeps running when a view is hidden, same guarantee the old panels had.
Welcome → [Connect privately] → automatic best setup → success state
- First run shows a 3-step onboarding card, no gateway/topology jargon.
- Returning users see a compact status card + one-tap connect.
- Gateway/topology details only appear under Settings → Advanced → Technical details.
Familiar chat pattern: left (or top on mobile) conversation list, right (or
below) conversation thread + composer. Long addresses are shortened to
ABC123…XYZ9 with the full value behind "Show technical details". Reply-via-SURB
is just "Reply" — the SURB detail lives in Advanced.
One "Open a private link" bar (same parseInviteLink → fetchNym → bind
socialService path as before, so URI-bar binding behaviour is preserved).
Successful navigation renders the private site and binds the community to it.
Invite links show a friendly "Someone invited you" card with petname save.
The community (web/src/adapters/driving/social/) has three persisted tabs
(web/src/application/tabs.ts, fly.social.tab):
-
Timeline — composer + global chronological timeline
(
GET /feed?since=<seq>&limit=<n>,POST /post, max 1400 bytes). Opening a portal auto-pulls recent posts you don't have yet (web/src/application/sync.ts: dedupe byseq, cap 200), even before an identity exists — reading needs no key. A sync-status line always shows freshness ("Up to date — checked just now" / "Syncing…" / error + Retry), and the empty state is a friendly "Nothing here yet" card with a "Be the first to post" call to action. Top-level posts show a reply-count pill; opening one switches to the dedicated thread view (web/src/adapters/driving/social/ThreadView.tsx: root on top, transitive replies chronological, missing ancestors auto-pulled viaGET /post/<id>). Replying attachesin_reply_towith a parent preview chip in the composer. Threading model:docs/09-social.md§9.5a — the service stores + verifies the parent link only; all assembly is client-side. -
Private messages — sealed DM composer + received messages
(
POST /dm,GET /dm?for=<pubkey>, self-destruct on read). A self-destruct callout sells the privacy property; received messages carry local timestamps (the envelope has none, by design) and a "Check for new messages" button supplements the 30s poll. -
About — profile editor (
GET /profile/<pubkey>,POST /profile), the service description, and the technical log (logs hidden by default).
Trust is two local layers, both in web/src/domain/trust.ts (colours in one
STANDING_META map, shown with a visible legend): first-hand observations
from signature checks, plus your explicit per-author Trust/Block verdict,
which always wins. Petnames (web/src/domain/petnames.ts, "Name" button per
post) beat profile names beat short hex for display. Everything — scores,
verdicts, petnames — stays in localStorage and never leaves the device.
Identity is one tap ("Create my private ID"), shareable via copy + local QR, and movable with a guided two-step export/import flow (explicit secret reveal with copy, then paste on the other device).
The tabs mirror the provider's landing page (DESCRIPTOR_HTML in
services/social/src/service.rs), which serves the same copy with matching
Timeline / Private messages sections: "Metadata-minimal microblog +
encrypted DMs, reachable only over the Nym mixnet. … No accounts, no follows,
no likes, no read receipts. Your public key is your name."
- Private network: on/off, "Prove I'm protected" (the old IP-comparison proof, renamed).
- My private link: short label + Copy link + Show QR + Show technical details.
- People: petname address book (was Contacts), Visit / Remove.
- Advanced (collapsed): technical panels, raw logs, exit-rotation note, key import, privacy-downgrade toggles.
Persistent, discreet pill in the nav:
| Tunnel state | Pill |
|---|---|
ready |
● Protected (green) |
connecting |
● Connecting… (amber) |
shutdown |
○ Not protected (grey) |
shutting_down |
● Switching off… (amber) |
failed |
● Something went wrong (red) |
Clicking the pill opens a popover with one friendly sentence, what to do next
("Try again"), and a collapsed "Technical details" + "Copy error" for reports.
Raw SDK errors never reach the main view; friendlyError() in
web/src/shared/friendlyErrors.ts maps them.
| Main UI (everyday) | Advanced / technical (exact) |
|---|---|
| Private network | Nym mixnet / mix-tunnel |
| Private address / Private link | nym://identity.encryption@gateway |
| Private site / Portal | Hidden service / fetchNym
|
| People | Contacts / petname registry |
| Not protected / Protected | Tunnel shutdown / ready
|
| Something went wrong | Tunnel failed: <reason>
|
Long cryptographic addresses only appear behind "Show technical details" or in Advanced. Petnames are the primary label everywhere.
ShareCard (web/src/adapters/driving/shared/ShareCard.tsx) shows:
- Short label (
shop • ABC123…XYZ9) — petname first. - Copy link button (clipboard + fallback select).
-
Show QR button — renders a scannable QR of the full
nym://link via theqrcodepackage to a<canvas>/data-URL<img>. No network involved; generation is fully local so the private link never leaves the device. - Show technical details toggle revealing the full address + invite fragment.
- Calm light theme (
web/src/adapters/driving/shared/theme.css): system-ui, generous spacing, 44px+ touch targets, AA contrast, single-column ≤ 860px, two-column chat on wider screens. Respectsprefers-color-schemeandprefers-reduced-motion. - No new network or crypto code: all views reuse
ensureTunnel,NymAddressClient,fetchNym,parseInviteLink,Social, contacts storage. - PWA / desktop launcher / Android paths unchanged; layout is responsive and touch-safe for TWA/Capacitor.
First run: Home shows "Welcome to Nysiris — browse and chat privately." → [Connect privately] → "Connecting… finding the fastest private path." → "You're protected ✓" + [Open a private link] field.
Something went wrong: nav pill turns red, "Something went wrong".
Tap → "We couldn't reach the private network. Check your connection and try
again." [Try again] [Copy error] → details: tunnel failed: ….
Invite: paste link → Portal shows "You've been invited by Maya — 'Join me here'" → [Save as…] → appears in Messages/People as "Maya".
./build.sh check # fmt + clippy + Rust tests + web unit tests + docs
./build.sh web # PWA build (tsc + vite)New pure-logic tests: web/test/views.test.mjs, web/test/friendlyErrors.test.mjs,
web/test/share.test.mjs. Existing panels/contacts tests untouched.
⚠️ Experimental / pre-audit. This repository is under active development and has not had an independent security audit. The Sphinx core incrates/is a reference implementation, never production crypto. Do not rely on it for high-stakes anonymity yet — see the threat model. Apache-2.0 © 2026 odelyzid (tribewarez). Report a security issue.
Nysiris docs
- Home
- 1. High-Level Architecture
- 2. Addressing & Routing Deep-Dive: how "DNS" works in Sphinx/Nym
- 3. Browser & Mobile Client (Web, Android, Desktop)
- 4. Hosting a Web Server / Service Reachable via the Nym Mixnet
- 5. Security Analysis & Recommendations
- 6. Implementation Roadmap
- 7. Desktop on Linux Mint / Debian
- 8. Hidden-Service Abstraction
- 9. nysiris-social: Metadata-Minimal Microblog + Encrypted DMs
- 10. Portal Layers: Data, Replication, Discovery, Reputation
- 11. UX Redesign — Calm, Private-by-Default Client
- 12. Windows build (MSYS2 / MSVC)
- 13. Hosting SDK &
nysirisCLI