Voice panel: horizontal mic meter and real connection latency #292

Closed
opened 2026-10-07 20:43:07 -04:00 by Salastil · 1 comment
Owner

Reported: the indicator next to "Voice Connected" looks like a phone's signal-strength icon. It is actually the microphone level - three rising bars (VoicePanel.tsx:54-63) polled once a second - and nothing in moho measures the voice connection itself.

Fix:

  • Replace the bars with a thin horizontal level bar that fills as you speak, polled ~10×/second while the panel is shown (thresholds as now: ~0.008 quiet, 0.02–0.05 speech). Reuse the horizontal .voice-meter/.voice-meter-fill style already used by VoiceRecorder.tsx, renamed so the two conflicting .voice-meter rules (app.css:3699 and 5233) stop colliding.
  • Daemon: measure the voice connection's round trip from the heartbeat - op 3 is sent with a nonce t (nobilis/src/backend/discord/voiceconn.rs:855) and op 6 (HEARTBEAT_ACK) echoes it - and expose rttMs via getVoiceLevels.
  • Show "Voice Connected · 42 ms", coloured green/amber/red, with details on hover.
  • Add camera and screen-share buttons to the panel where the service supports them.

Part of the v1.0 UI pass.

Reported: the indicator next to "Voice Connected" looks like a phone's signal-strength icon. It is actually the **microphone level** - three rising bars (`VoicePanel.tsx:54-63`) polled once a second - and nothing in moho measures the voice connection itself. **Fix:** - Replace the bars with a thin horizontal level bar that fills as you speak, polled ~10×/second while the panel is shown (thresholds as now: ~0.008 quiet, 0.02–0.05 speech). Reuse the horizontal `.voice-meter`/`.voice-meter-fill` style already used by `VoiceRecorder.tsx`, renamed so the two conflicting `.voice-meter` rules (app.css:3699 and 5233) stop colliding. - **Daemon:** measure the voice connection's round trip from the heartbeat - op 3 is sent with a nonce `t` (`nobilis/src/backend/discord/voiceconn.rs:855`) and op 6 (HEARTBEAT_ACK) echoes it - and expose `rttMs` via `getVoiceLevels`. - Show "Voice Connected · 42 ms", coloured green/amber/red, with details on hover. - Add camera and screen-share buttons to the panel where the service supports them. _Part of the v1.0 UI pass._
Salastil added this to the v1.0 milestone 2026-10-07 20:43:07 -04:00
Salastil added the feature label 2026-10-07 20:43:07 -04:00
Author
Owner

Finished: ad0f0c0.

Before (left) and after (middle: speaking on a good connection; right: loud on a poor one), from scripts/ui-shots.mjs:

voice panel

  • The bar is horizontal and along the panel. It was never signal strength - it was the microphone level - so it is now a bar under the title that fills as you speak, polled ten times a second (it was once a second) and drawn on a square-root scale between a quiet room and loud speech. It turns amber when you are close to the top.
  • Real latency, in nobilis. The voice websocket's heartbeat is now timed against its acknowledgement (op 3 carries a nonce, op 6 echoes it) and reported as rttMs from getVoiceLevels, per account, forgotten when the connection ends. The panel shows it beside the title - green under 80 ms, amber under 160, red beyond - with the full sentence on hover. It is absent until the first heartbeat has come back, and on services with no such number.
  • Share your screen from the panel for Discord calls, with the on state shown, so a share can be started and stopped from wherever you are reading.

Tested: the heartbeat matching (right nonce, wrong nonce, other opcodes, forgetting on disconnect) has unit tests, the level scale has unit tests, and the picture above uses a test-only override. Not tested against a live Discord call - that account only receives, so the real number on a real call is the thing to look at when you next join one.

Not done: a camera button. Discord video in a call has no control of its own in the store yet, only Matrix does, so it would be a button that does nothing.

Finished: [ad0f0c0](https://git.salastil.com/Salastil/moho/commit/ad0f0c08cf65783da855d0911082586c390ea17e). Before (left) and after (middle: speaking on a good connection; right: loud on a poor one), from `scripts/ui-shots.mjs`: ![voice panel](https://git.salastil.com/attachments/51fad216-fc3f-41bb-9c1e-fc446a35a126) - **The bar is horizontal and along the panel.** It was never signal strength - it was the microphone level - so it is now a bar under the title that fills as you speak, polled ten times a second (it was once a second) and drawn on a square-root scale between a quiet room and loud speech. It turns amber when you are close to the top. - **Real latency, in nobilis.** The voice websocket's heartbeat is now timed against its acknowledgement (`op 3` carries a nonce, `op 6` echoes it) and reported as `rttMs` from `getVoiceLevels`, per account, forgotten when the connection ends. The panel shows it beside the title - green under 80 ms, amber under 160, red beyond - with the full sentence on hover. It is absent until the first heartbeat has come back, and on services with no such number. - **Share your screen** from the panel for Discord calls, with the on state shown, so a share can be started and stopped from wherever you are reading. Tested: the heartbeat matching (right nonce, wrong nonce, other opcodes, forgetting on disconnect) has unit tests, the level scale has unit tests, and the picture above uses a test-only override. **Not tested against a live Discord call** - that account only receives, so the real number on a real call is the thing to look at when you next join one. Not done: a camera button. Discord video in a call has no control of its own in the store yet, only Matrix does, so it would be a button that does nothing.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Salastil/moho#292