feat(demo): auto-firing device-detection modal + transport pills on most peers

- ~8s into a session a second "freshly plugged" RNode appears on
  /dev/ttyACM0, so the global mesh setup modal (and its flash step)
  demos itself shortly after opening the Mesh page. Fixed plugged_at
  means "Not now" sticks for the whole browser session.
- Transport pills (LoRa/FIPS/Tor) now offered for every demo peer
  except mountain-node, which stays radio-only for contrast.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago 2026-07-29 10:36:43 -04:00
parent 9e77a4229c
commit 00f1892bf8

View File

@ -2988,10 +2988,22 @@ app.post('/rpc/v1', (req, res) => {
channel_name: mc.channel_name,
messages_sent: 23,
messages_received: 47,
detected_devices: ['/dev/ttyUSB0'],
// Demo device-detection: ~8s into the session a second, freshly
// "plugged-in" radio appears on /dev/ttyACM0. The frontend's
// 2-sighting debounce then pops the global setup modal a few
// seconds later. plugged_at is FIXED so dismissing it ("Not now")
// sticks for the whole browser session — the modal shows once.
detected_devices: (() => {
mockState.meshFirstStatusAt ||= Date.now()
const demoPlug = Date.now() - mockState.meshFirstStatusAt > 8000
return demoPlug ? ['/dev/ttyUSB0', '/dev/ttyACM0'] : ['/dev/ttyUSB0']
})(),
device_present: true,
detected_device_info: [
{ path: '/dev/ttyUSB0', vid: '10c4', pid: 'ea60', product: 'HELTEC LoRa 32 V3', manufacturer: 'Heltec' },
{ path: '/dev/ttyUSB0', vid: '10c4', pid: 'ea60', product: 'HELTEC LoRa 32 V3', manufacturer: 'Heltec', plugged_at: 1753790000 },
...(Date.now() - (mockState.meshFirstStatusAt || Date.now()) > 8000
? [{ path: '/dev/ttyACM0', vid: '303a', pid: '1001', product: 'Heltec V4 (RNode)', manufacturer: 'Espressif', plugged_at: 1753790001 }]
: []),
],
lora_region: mc.lora_region,
device_kind: mc.device_kind,
@ -4272,10 +4284,11 @@ app.post('/rpc/v1', (req, res) => {
// ── Mesh chat polish + flash flow (v1.7.117/118 demo coverage) ──────
// Image-modal "Send via" pills: peer 1 is federation-reachable (LoRa +
// FIPS + Tor all offered), everyone else is radio-only.
// Image-modal "Send via" pills: most demo peers are federation-reachable
// (LoRa + FIPS + Tor pills all offered); mountain-node (3) stays
// radio-only to show the contrast.
case 'mesh.transport-advice': {
const federated = params?.contact_id === 1
const federated = params?.contact_id !== 3
return res.json({
result: {
tier: federated ? 'choose' : 'auto-mesh',