feat(ui): companion modal pairing screen — scan a QR to auto-connect the app
Demo images / Build & push demo images (push) Successful in 2m45s
Demo images / Build & push demo images (push) Successful in 2m45s
The Remote Companion intro modal gains a second screen: an "I've installed it" button next to the download button slides over to a pairing QR the companion app scans to load the server details automatically, with a Back button to return. The QR is an archipelago://pair deep link carrying the server URL — the demo embeds https://demo.archipelago-foundation.org plus the shared demo password so a scan lands in a logged-in demo session; real nodes send only the address (kiosk advertises the mDNS .local name since its own origin is localhost). Phones also get a tap-to-open deep-link button since you can't scan your own screen. App-side contract + requirements handed off in docs/companion-pairing-qr.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1a3170f1c3
commit
3028685e6b
@@ -0,0 +1,81 @@
|
||||
# Companion app pairing QR — integration handoff
|
||||
|
||||
**Status:** web-UI side SHIPPED (CompanionIntroOverlay.vue, 2026-07-16). This doc is
|
||||
the contract + requirements for the companion-app side (worked on separately, on
|
||||
the Mac).
|
||||
|
||||
## What the web UI now does
|
||||
|
||||
The "Remote Companion" intro modal (shown once after first dashboard login, and in
|
||||
the public demo) gained a second screen:
|
||||
|
||||
1. **Screen 1 (existing):** APK download QR (desktop) / download button, plus a new
|
||||
**"I've installed it"** button to the right of the download button.
|
||||
2. **Screen 2 (new, slide transition):** a **pairing QR** the companion app scans to
|
||||
auto-fill the server entry, with a **Back** button returning to screen 1. On
|
||||
small screens (where you can't scan your own display) an
|
||||
**"Open in companion app"** deep-link button is shown above Back, using the same
|
||||
URI as the QR.
|
||||
|
||||
## The QR payload / deep link (the contract)
|
||||
|
||||
A single URI, also usable as an OS deep link:
|
||||
|
||||
```
|
||||
archipelago://pair?v=1&url=<percent-encoded server URL>[&pw=<percent-encoded password>]
|
||||
```
|
||||
|
||||
Query parameters:
|
||||
|
||||
| param | required | meaning |
|
||||
|-------|----------|---------|
|
||||
| `v` | yes | Payload version, currently `1`. Reject/ignore unknown majors gracefully — show "please update the app". |
|
||||
| `url` | yes | Full origin the app should connect to, scheme included: `https://demo.archipelago-foundation.org`, `http://archipelago.local`, `http://192.168.1.228`, etc. No trailing slash guaranteed either way — normalize. |
|
||||
| `pw` | no | Login password. **Only present in the public demo** (shared demo password `entertoexit`). Real nodes never embed a password — the frontend doesn't have it. |
|
||||
|
||||
Examples the web UI actually emits:
|
||||
|
||||
- Demo: `archipelago://pair?v=1&url=https%3A%2F%2Fdemo.archipelago-foundation.org&pw=entertoexit`
|
||||
- Real node, browsed via LAN IP: `archipelago://pair?v=1&url=http%3A%2F%2F192.168.1.228`
|
||||
- Real node kiosk (UI runs on localhost, so it advertises the mDNS name from
|
||||
`system.get-hostname`): `archipelago://pair?v=1&url=http%3A%2F%2Farchipelago.local`
|
||||
|
||||
## Companion app requirements
|
||||
|
||||
1. **Scan entry point:** a "Scan node code" action (screen-2 copy in the web UI
|
||||
says: *"In the companion app, choose 'Scan node code' and point your phone
|
||||
here"* — keep that wording or tell me the real label so I update the modal).
|
||||
2. **Parse the URI** (from camera scan AND from an OS deep-link intent —
|
||||
register the `archipelago://` scheme so the "Open in companion app" button on
|
||||
phones works).
|
||||
3. On success, **create/update a saved server entry**:
|
||||
- Server address = `url` exactly as given (respect the scheme — the demo is
|
||||
https, LAN nodes are typically http, `.local` mDNS names must work).
|
||||
- If `pw` present, prefill the password and attempt auto-login; otherwise land
|
||||
on the password prompt for that server.
|
||||
- If an entry with the same origin already exists, update it rather than
|
||||
duplicating.
|
||||
4. **Demo flow (the showcase):** scanning the demo QR should take a fresh install
|
||||
to a logged-in demo session in one step — url `https://demo.archipelago-foundation.org`,
|
||||
password `entertoexit`, no manual typing.
|
||||
5. **Robustness:**
|
||||
- Tolerate unknown extra query params (forward compat — we may add `name`,
|
||||
`cert` fingerprint, etc. under `v=1`).
|
||||
- Self-signed HTTPS on `.local`/LAN addresses may appear later; don't hard-fail
|
||||
the parse on scheme.
|
||||
- Bad/foreign QR → clear error, stay on the scan screen.
|
||||
|
||||
## Notes / future extensions (not in v1)
|
||||
|
||||
- A real-node pairing **token** instead of a password (backend mints a one-time
|
||||
token, QR carries it, app exchanges it for a session) — needs a backend RPC;
|
||||
the `v` param exists so we can bump when this lands.
|
||||
- Optional `name` param (node display name) so the app labels the entry nicely.
|
||||
|
||||
## Testing checklist (app side)
|
||||
|
||||
- [ ] Scan demo QR from https://demo.archipelago-foundation.org → auto-connected demo session.
|
||||
- [ ] Scan a real node's QR (LAN IP origin) → entry created, password prompt shown.
|
||||
- [ ] Scan a kiosk node's QR (`http://<name>.local`) → mDNS resolution works on the phone.
|
||||
- [ ] Tap "Open in companion app" on a phone browser → deep link opens the app with the same behavior.
|
||||
- [ ] Re-scan same node → no duplicate entry.
|
||||
Reference in New Issue
Block a user