feat(calls): redesign voice control bar + call view (LC-416) #432

Merged
longjacksonle merged 1 commit from feat/lc-416-voice-callbar-redesign into main 2026-06-21 21:55:20 +02:00

Redesigns the enclave voice-call control bar and call view (and the shared 1:1 call bar + transcript drawer). See data/ref1.png (panel closed) and data/ref2.png (panel open). Closes LC-416 (sub-tasks LC-417..LC-421).

Primary bug fixed

The "This call is being transcribed" pill was a position:fixed top-center element that floated OVER the header controls. When the transcript drawer opened it reserved 20rem of right padding on #lc-voice-root, shrinking the header, and the pill collided with Share screen / Transcribe (the overlap in ref2.png). The control bar also didn't reflow when the panel took width.

What changed

  • Removed the floating pill (overlap source + a duplicate of the Transcribe toggle's on-state). Recording awareness now lives in the red Transcribe toggle (record glyph whose core pulses while live) and the drawer header dot, which share one state.
  • Control bar regrouped into media / transcription / isolated Leave. Every action is an icon + collapsible label; a container query on .lc-callbar collapses labels to icon-only when the bar is narrow (incl. while the drawer reserves width), so controls compress instead of overlapping. Pure CSS; applies to both the voice page and the 1:1 modal bar.
  • Transcribe vs Transcript made distinct: Transcribe = red recording toggle (slashed-mic / record glyph), Transcript = blue panel-open toggle.
  • Transcript drawer: empty state until the first line lands (pure CSS via :has(#lc-caption-log:empty)); header + scrollable body + export footer kept; the drawer slides in and the #lc-voice-root width reservation transitions instead of squeezing the header (prefers-reduced-motion disables both).
  • Participant tiles: animated equalizer speaking indicator in the name pill, consistent with mute / YOU / quality styling.
  • voice.js / call.js label swaps now target the .lc-cbtn-label span (icon survives); voice screen-share label moved onto the shared __lcS catalog.

Drive-by

A stray committed NUL byte in layout.html (emoji-recents recents.join) made file(1) report the template binary and silently broke grep over it; replaced with the equivalent unicode escape (identical runtime value).

Stack / safety

Askama + HTMX + Tailwind, WebSocket-driven, no client framework. All data-lc-* / id hooks preserved, so the WebRTC mesh + signaling are untouched. Frontend only - no Rust/route/schema change.

Verification

just check, just test, just test-saas all pass; voice.js / call.js / transcribe.js / live.js syntax-checked; Tailwind rebuilt. Note: the live dev server is Bunyip-SSO-gated, so visual confirmation in-browser is best done by the reviewer.

🤖 Generated with Claude Code

Redesigns the enclave voice-call control bar and call view (and the shared 1:1 call bar + transcript drawer). See data/ref1.png (panel closed) and data/ref2.png (panel open). Closes LC-416 (sub-tasks LC-417..LC-421). ## Primary bug fixed The "This call is being transcribed" pill was a position:fixed top-center element that floated OVER the header controls. When the transcript drawer opened it reserved 20rem of right padding on #lc-voice-root, shrinking the header, and the pill collided with Share screen / Transcribe (the overlap in ref2.png). The control bar also didn't reflow when the panel took width. ## What changed - Removed the floating pill (overlap source + a duplicate of the Transcribe toggle's on-state). Recording awareness now lives in the red Transcribe toggle (record glyph whose core pulses while live) and the drawer header dot, which share one state. - Control bar regrouped into media / transcription / isolated Leave. Every action is an icon + collapsible label; a container query on .lc-callbar collapses labels to icon-only when the bar is narrow (incl. while the drawer reserves width), so controls compress instead of overlapping. Pure CSS; applies to both the voice page and the 1:1 modal bar. - Transcribe vs Transcript made distinct: Transcribe = red recording toggle (slashed-mic / record glyph), Transcript = blue panel-open toggle. - Transcript drawer: empty state until the first line lands (pure CSS via :has(#lc-caption-log:empty)); header + scrollable body + export footer kept; the drawer slides in and the #lc-voice-root width reservation transitions instead of squeezing the header (prefers-reduced-motion disables both). - Participant tiles: animated equalizer speaking indicator in the name pill, consistent with mute / YOU / quality styling. - voice.js / call.js label swaps now target the .lc-cbtn-label span (icon survives); voice screen-share label moved onto the shared __lcS catalog. ## Drive-by A stray committed NUL byte in layout.html (emoji-recents `recents.join`) made file(1) report the template binary and silently broke grep over it; replaced with the equivalent unicode escape (identical runtime value). ## Stack / safety Askama + HTMX + Tailwind, WebSocket-driven, no client framework. All data-lc-* / id hooks preserved, so the WebRTC mesh + signaling are untouched. Frontend only - no Rust/route/schema change. ## Verification just check, just test, just test-saas all pass; voice.js / call.js / transcribe.js / live.js syntax-checked; Tailwind rebuilt. Note: the live dev server is Bunyip-SSO-gated, so visual confirmation in-browser is best done by the reviewer. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(calls): redesign voice control bar + call view (LC-416)
All checks were successful
check-secrets / TruffleHog (push) Successful in 7s
check-secrets / Nosey parker (push) Successful in 8s
check-secrets / Kingfisher (push) Successful in 10s
check-secrets / Nosey parker (pull_request) Successful in 6s
check-secrets / TruffleHog (pull_request) Successful in 8s
check-secrets / Kingfisher (pull_request) Successful in 11s
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Successful in 6m34s
cc1f8b7a7a
Fixes the header overlap bug and the rough edges in the enclave voice-call UI (and the shared 1:1 call bar + transcript drawer), on the existing Askama + HTMX + Tailwind, WebSocket-driven stack. All data-lc-* / id hooks are preserved, so the WebRTC mesh + signaling are untouched.

Primary bug (LC-417/LC-418): the "This call is being transcribed" pill was a position:fixed top-center element that floated OVER the header controls; when the transcript drawer opened it reserved 20rem of right padding on #lc-voice-root, shrinking the header, and the pill collided with Share screen / Transcribe. Removed that floating pill entirely - it also merely duplicated the Transcribe toggle's on-state. Recording awareness now lives in the red Transcribe toggle (a record glyph whose core pulses while live) and the drawer header dot, which share one state.

Control bar (LC-417): restructured into three clear clusters - media (devices / Mute / Start video / Share screen), transcription (Transcribe + Transcript), and the isolated destructive Leave. Every action is now an icon + a collapsible .lc-cbtn-label. A container query on .lc-callbar drops the labels to icon-only when the bar is narrow (notably while the drawer reserves width), so the controls compress instead of overlapping - no JS, works for both the voice page and the 1:1 modal bar. Mute swaps to a slashed-mic icon by aria-pressed; Transcribe is the red recording toggle, Transcript the blue panel-open toggle, so the two are visually distinct.

Transcript panel (LC-419): added an empty state (shown until the first caption line lands, pure-CSS via :has(#lc-caption-log:empty)); kept the header + scrollable body + export footer. The drawer now slides in from the right and the #lc-voice-root width reservation transitions, so opening it reads as reserving space rather than squeezing the header; prefers-reduced-motion disables both.

Participant tiles (LC-420): added an animated equalizer speaking indicator in the name pill (shown on data-speaking), consistent with the existing mute / YOU / quality styling; the grid balance for 1-2 and scaling is unchanged.

JS (voice.js / call.js): control-button label swaps now target the .lc-cbtn-label span (via a small setLabel helper) so the leading icon survives; the voice screen-share label also moved off hardcoded strings onto the shared __lcS catalog.

Drive-by (LC-421): a stray committed NUL byte in layout.html (emoji-recents script, recents.join) made file(1) report the template binary and silently broke grep over it; replaced with the equivalent unicode escape (identical runtime value).

Frontend only (templates / CSS / JS / i18n), no Rust/route/schema change. just check, just test, just test-saas all pass; voice.js / call.js / transcribe.js / live.js syntax-checked; Tailwind rebuilt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/lc-416-voice-callbar-redesign 2026-06-21 21:55:21 +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!432
No description provided.