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
Before (left) and after (middle: speaking on a good connection; right: loud on a poor one), from scripts/ui-shots.mjs:
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`:

- **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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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:
.voice-meter/.voice-meter-fillstyle already used byVoiceRecorder.tsx, renamed so the two conflicting.voice-meterrules (app.css:3699 and 5233) stop colliding.t(nobilis/src/backend/discord/voiceconn.rs:855) and op 6 (HEARTBEAT_ACK) echoes it - and exposerttMsviagetVoiceLevels.Part of the v1.0 UI pass.
Finished: ad0f0c0.
Before (left) and after (middle: speaking on a good connection; right: loud on a poor one), from
scripts/ui-shots.mjs:op 3carries a nonce,op 6echoes it) and reported asrttMsfromgetVoiceLevels, 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.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.