feat(call): ask before joining when your usual mic / headphones are missing (#121) #450

Merged
jared merged 2 commits from feat/expected-devices into lotus 2026-10-24 21:30:23 -04:00
Owner

Fixes #121. Owner decisions 2026-10-25: ask before joining, and "usual" = the device you last picked. The fork side is element-call #62, released as 0.28.0-lotus.2 and bumped here.

What users see

  • Before joining, when the mic or output they last picked isn't plugged in, a dialog (the call waits):

    Your usual microphone isn't connected
    Arctis 7 isn't connected. Join with Laptop Mic instead?
    Plug it in and choose Cancel to start over with it.
    [Join anyway] [Cancel]

  • Join anyway: not asked again this session for the same device(s).
  • Cancel: closes the call before it starts; nothing joins.
  • Re-plugged under a new id but the same name: picked up silently, no dialog.
  • During a call: a toast, e.g. "Arctis 7 disconnected — now using Laptop Mic." No dialog.

Changes

  • CallEmbed: passes lotusDeviceCheck=true.
  • CallControl.sendDeviceDecision(join).
  • ExpectedDevicesPrompt (rendered per call in CallUtils) handles io.lotus.device_missing and io.lotus.device_lost.
  • expectedDevices.ts: pure parsing, wording, and the session memory.

Tested

  • End to end against a local Synapse + LiveKit, with Chrome fake devices and the build from #62 (usual mic "Arctis 7" seeded):
    • the dialog shows with the right names;
    • nothing joins while asking;
    • Cancel leaves no call frame and no membership;
    • Join anyway joins, and the next start that session doesn't ask;
    • re-plug: no dialog, joins on the right device;
    • baseline (nothing missing): joins and the call-bar controls work.
  • Unit tests: 3 new; the suite has 1,431 passing. Lint is at 29.

🤖 Generated with Claude Code

https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5

Fixes #121. Owner decisions 2026-10-25: **ask before joining**, and **"usual" = the device you last picked**. The fork side is element-call #62, released as 0.28.0-lotus.2 and bumped here. **What users see** - **Before joining,** when the mic or output they last picked isn't plugged in, a dialog (the call waits): > **Your usual microphone isn't connected** > **Arctis 7** isn't connected. Join with **Laptop Mic** instead? > Plug it in and choose Cancel to start over with it. > [Join anyway] [Cancel] - **Join anyway:** not asked again this session for the same device(s). - **Cancel:** closes the call before it starts; nothing joins. - **Re-plugged under a new id but the same name:** picked up silently, no dialog. - **During a call:** a toast, e.g. "Arctis 7 disconnected — now using Laptop Mic." No dialog. **Changes** - `CallEmbed`: passes `lotusDeviceCheck=true`. - `CallControl.sendDeviceDecision(join)`. - `ExpectedDevicesPrompt` (rendered per call in `CallUtils`) handles `io.lotus.device_missing` and `io.lotus.device_lost`. - `expectedDevices.ts`: pure parsing, wording, and the session memory. **Tested** - **End to end** against a local Synapse + LiveKit, with Chrome fake devices and the build from #62 (usual mic "Arctis 7" seeded): - the dialog shows with the right names; - nothing joins while asking; - Cancel leaves no call frame and no membership; - Join anyway joins, and the next start that session doesn't ask; - re-plug: no dialog, joins on the right device; - baseline (nothing missing): joins and the call-bar controls work. - **Unit tests:** 3 new; the suite has 1,431 passing. Lint is at 29. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared added 2 commits 2026-10-24 19:59:01 -04:00
The fork now checks, before joining (lotusDeviceCheck=1), that the mic /
output the user last picked are plugged in. When one is missing it asks
us (io.lotus.device_missing): "Your usual microphone isn't connected.
Arctis 7 isn't connected. Join with Laptop Mic instead?" [Join anyway]
[Cancel]. Join anyway isn't asked again this session for the same
device(s); Cancel closes the call before it starts. A device lost during
a call is a toast ("Arctis 7 disconnected — now using Laptop Mic").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
chore(deps): Element Call 0.28.0-lotus.2 (expected-device check, #121)
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Build & Quality Checks (pull_request) Successful in 3m25s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 21s
CI / Playwright smoke (e2e) (pull_request) Successful in 17m34s
17ebddb159
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared merged commit 5379eb046d into lotus 2026-10-24 21:30:23 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#450