Companion side of docs/companion-pairing-qr.md (v1 contract): - Connect screen lands on Scan Node's QR / Enter Manually; NESMenu gains an add-server-by-QR icon button - QrScannerOverlay: CameraX + ZXing core (pinned, on-device, no ML Kit) - ServerQrParser: archipelago://pair?v=1&url=..[&pw=..]; unknown major v -> 'update the app'; upsert by origin so re-scans never duplicate - archipelago:// deep link registered (singleTask + onNewIntent) for the modal's 'Open in companion app' button - WebView auto-fills and submits Login.vue's password form when a stored password exists — demo QR is one step to a logged-in session - Web modal + handoff doc copy synced to the real label: Scan Node's QR - v0.4.13 (versionCode 17) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4.1 KiB
4.1 KiB
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:
- Screen 1 (existing): APK download QR (desktop) / download button, plus a new "I've installed it" button to the right of the download button.
- 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
- Scan entry point: the app's action is labeled "Scan Node's QR" (implemented 2026-07-17; the modal copy in CompanionIntroOverlay.vue was updated to match).
- 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). - On success, create/update a saved server entry:
- Server address =
urlexactly as given (respect the scheme — the demo is https, LAN nodes are typically http,.localmDNS names must work). - If
pwpresent, 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.
- Server address =
- 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, passwordentertoexit, no manual typing. - Robustness:
- Tolerate unknown extra query params (forward compat — we may add
name,certfingerprint, etc. underv=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.
- Tolerate unknown extra query params (forward compat — we may add
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
vparam exists so we can bump when this lands. - Optional
nameparam (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.