feat(calls): per-peer connection-quality indicator (LC-410) #424

Merged
longjacksonle merged 1 commit from feat/lc-410-connection-quality into main 2026-06-21 01:34:05 +02:00

Implements LC-410 (subtask of the LC-402 call redesign): surface per-participant connection health so a bad link is visible instead of silent audio dropouts.

What

Each remote tile shows a small signal-bars glyph in the name pill, coloured by state:

  • good (green), degraded (amber), reconnecting (amber, pulsing), failed (red).

The self tile has no peer connection, so it shows no indicator.

How

  • RTCPeerConnection.onconnectionstatechange updates the tile immediately: connected -> good, disconnected/connecting/checking -> reconnecting, failed -> failed.
  • A 3s getStats() loop refines a connected peer to good vs degraded from the inbound packet-loss ratio (per-interval delta of packetsLost/packetsReceived) and the nominated candidate pair's currentRoundTripTime (degraded at >3% loss or >350ms RTT).
  • The tile carries data-quality; CSS recolours the glyph (--success/--warning/--danger) and pulses the reconnecting state (killed under prefers-reduced-motion). A localized title/aria-label names the state.
  • The monitor starts/stops alongside the active-speaker loop on join/leave.

Scope

Frontend only: assets/voice.js (monitor + tile glyph), assets/main.css (glyph styles + reduced-motion), templates/base.html + locales/{en,es}/js.ftl (four state strings). No Rust, route, or schema change.

Tests

just check (standalone + saas compile, clippy, fmt), just test, just test-saas all pass. voice.js syntax-checked; just build-css regenerated.

Implements LC-410 (subtask of the LC-402 call redesign): surface per-participant connection health so a bad link is visible instead of silent audio dropouts. ## What Each remote tile shows a small **signal-bars glyph** in the name pill, coloured by state: - **good** (green), **degraded** (amber), **reconnecting** (amber, pulsing), **failed** (red). The self tile has no peer connection, so it shows no indicator. ## How - `RTCPeerConnection.onconnectionstatechange` updates the tile immediately: `connected` -> good, `disconnected`/`connecting`/`checking` -> reconnecting, `failed` -> failed. - A 3s `getStats()` loop refines a connected peer to **good vs degraded** from the inbound packet-loss ratio (per-interval delta of `packetsLost`/`packetsReceived`) and the nominated candidate pair's `currentRoundTripTime` (degraded at >3% loss or >350ms RTT). - The tile carries `data-quality`; CSS recolours the glyph (`--success`/`--warning`/`--danger`) and pulses the reconnecting state (killed under `prefers-reduced-motion`). A localized `title`/`aria-label` names the state. - The monitor starts/stops alongside the active-speaker loop on join/leave. ## Scope Frontend only: `assets/voice.js` (monitor + tile glyph), `assets/main.css` (glyph styles + reduced-motion), `templates/base.html` + `locales/{en,es}/js.ftl` (four state strings). No Rust, route, or schema change. ## Tests `just check` (standalone + saas compile, clippy, fmt), `just test`, `just test-saas` all pass. `voice.js` syntax-checked; `just build-css` regenerated.
feat(calls): per-peer connection-quality indicator (LC-410)
All checks were successful
check-secrets / TruffleHog (push) Successful in 5s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / Nosey parker (push) Successful in 3s
check-secrets / TruffleHog (pull_request) Successful in 6s
check-secrets / Kingfisher (pull_request) Successful in 6s
check-secrets / Nosey parker (pull_request) Successful in 6s
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Successful in 2m58s
d48c506586
Each remote participant tile now shows a connection-health glyph (signal bars in the name pill) driven off the peer's RTCPeerConnection: good / degraded / reconnecting / failed.

- connectionstatechange updates immediately: connected -> good, disconnected/connecting/checking -> reconnecting (pulsing), failed -> failed.
- A 3s getStats loop refines a connected peer to good vs degraded from inbound packet-loss ratio (per-interval delta) and the nominated candidate pair's round-trip time.
- The glyph is recoloured by data-quality via CSS (success/warning/danger), reconnecting pulses (killed under prefers-reduced-motion), and carries a localized title/aria-label. Self has no peer connection so its tile shows no indicator. The loop starts/stops with the active-speaker loop on join/leave.

Frontend only: voice.js (monitor + tile glyph), main.css (glyph styles), base.html + locales/{en,es}/js.ftl (four state strings). No Rust/schema change. just check, just test, just test-saas all pass; voice.js syntax-checked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/lc-410-connection-quality 2026-06-21 01:34:06 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!424
No description provided.