Skip to content

Commit 740c358

Browse files
intendednullclaude
andauthored
docs(video-call): close out spec — flip [active]→[landed] + Realised-state addendum (#659)
Audit-and-align pass surfaced 7 findings against docs/specs/2026-03-26-screen-sharing-call-page-design.md. Core functionality is implemented (call page, participant tiles, camera, screen share, speaking detection, grid/focus layout, perfect negotiation, video track management); 6 of 7 findings are documentation drift; the 7th is a substantive limitation tracked in code for follow-up. Added "Realised state" addendum at the top covering: - **Substantive (deferred):** Remote video tiles default to screen-share CSS class regardless of source. Camera-vs-screen-share distinction requires extending signaling to carry a VideoSource enum. Limitation acknowledged at crates/web/src/components/participant_tile.rs:110-118. - File path drift: components/sidebar.rs → channel_sidebar.rs (plan file is already correct; spec was not updated). - VoiceState carries `local_video_stream` signal (spec §6 omits) because VoiceManager doesn't expose the local stream synchronously to Leptos. - Perfect negotiation simplified — making_offer flag + peer_id comparison, no RtcSignalingState check. The speculative signaling_state path was not needed. - handle_offer + create_offer use get_or_create_connection rather than pure reuse (necessary because remote-initiated calls can arrive before any local outbound state). - Speaking-tile glow values tuned during implementation (style.css uses larger blur radius + halo ring than the spec values). - Trust badge + presence dot rendered on participant tiles by Phase 1d/1e (legitimate cross-spec affordances; spec §Visual design omits). Body preserved as original target. Realised-state addendum is authoritative for current implementation shape. Added Date/Status/Implementation plan header per the docs-organization convention. README master index flipped [active] → [landed]. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 057f3b0 commit 740c358

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ Every entry below carries one of:
107107
- [Willow UI — target UX bundle](specs/2026-04-19-ui-design/README.md) — 20+ child specs covering desktop and mobile target UX across layout, components, and interactions. `[active]`
108108
- [Pinned-message metadata](specs/2026-05-21-pinned-message-metadata-design.md) — extends Channel pinned_messages to carry pinner + pin-time. `[landed]`
109109
- [UX navigation improvements](specs/2026-03-25-ux-navigation-improvements-design.md) — unifies settings, adds confirmation dialogs, breadcrumbs, and command palette. `[landed]`
110-
- [Video, screen sharing + call page](specs/2026-03-26-screen-sharing-call-page-design.md) — adds camera video, screen sharing, and full call page UI to voice chat. `[active]`
110+
- [Video, screen sharing + call page](specs/2026-03-26-screen-sharing-call-page-design.md) — adds camera video, screen sharing, and full call page UI to voice chat. `[landed]`
111111
- [Async client + UI refactor](specs/2026-03-24-async-client-ui-refactor-design.md) — eliminates polling by splitting `Client` into `ClientHandle` + async event loop. `[landed]`
112112

113113
**Plans**

docs/specs/2026-03-26-screen-sharing-call-page-design.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,67 @@
11
# Video, Screen Sharing + Call Page Design
22

3+
**Date:** 2026-03-26
4+
**Status:** landed — call page, participant tiles, camera, screen share, speaking detection, grid/focus layout, perfect-negotiation collision avoidance, video track management all shipped via [`docs/plans/2026-03-26-video-screen-sharing-call-page.md`](../plans/2026-03-26-video-screen-sharing-call-page.md). One substantive limitation remains in §Realised state below: remote video tiles cannot distinguish camera vs screen-share at render time (no source-type signaling yet).
5+
**Implementation plan:** [`docs/plans/2026-03-26-video-screen-sharing-call-page.md`](../plans/2026-03-26-video-screen-sharing-call-page.md)
6+
7+
> **Realised state (post-2026-05 audit).** The system works as designed.
8+
> The body below drifts from the realised implementation in several
9+
> places, and one substantive limitation is tracked for follow-up:
10+
>
11+
> - **Source-type signaling for remote video (deferred).** Remote tiles
12+
> currently default to the `screen-share` CSS class regardless of
13+
> whether the inbound track is camera or screen share. This means
14+
> remote cameras get `object-fit: contain` (letterboxed) instead of
15+
> `object-fit: cover` (filled), which the spec's §Visual design
16+
> promises. The remote-source-type distinction requires extending
17+
> signaling to carry a `VideoSource` enum (camera | screen-share)
18+
> alongside the SDP. Tracked as follow-up; the file comment at
19+
> `crates/web/src/components/participant_tile.rs:110-118`
20+
> acknowledges this limitation in code.
21+
> - **File path drift.** §Modify section references
22+
> `components/sidebar.rs`; the actual file is
23+
> `crates/web/src/components/channel_sidebar.rs`. The plan file is
24+
> already correct; the spec was not updated.
25+
> - **`local_video_stream` signal added beyond spec.** `VoiceState`
26+
> in `crates/web/src/state.rs:314` carries
27+
> `local_video_stream: ReadSignal<Option<SendWrapper<MediaStream>>>`
28+
> to drive the local preview tile, because `VoiceManager` does not
29+
> expose the local stream synchronously to Leptos. The spec's §6
30+
> State Additions enumerates only `video_source`, `speaking_peers`,
31+
> `remote_video_streams`.
32+
> - **Perfect negotiation simplified.** §4 implies
33+
> `RtcSignalingState`-driven collision detection. The realised code
34+
> relies only on the `making_offer` flag + `local_peer_id <
35+
> remote_peer` comparison; `signaling_state()` is never called.
36+
> `RtcSignalingState` was speculative; the realised approach is
37+
> sufficient for the current use case.
38+
> - **`handle_offer` get-or-create.** §Camera handling at L58 says
39+
> "sets remote description on the *existing* peer connection."
40+
> `crates/web/src/voice.rs:611-619`'s `handle_offer` calls
41+
> `get_or_create_connection`, which DOES create a new PC if none
42+
> exists — necessary because remote-initiated calls may arrive before
43+
> any local outbound state exists. Same applies to the analogous
44+
> `create_offer` claim. The realised behaviour (reuse if exists,
45+
> create otherwise) is correct in both directions.
46+
> - **Speaking-tile glow values tuned.** §Visual design at L174 and
47+
> the keyframes at L294-297 list `0 0 8px` / `0 0 12px → 0 0 20px`.
48+
> `crates/web/style.css:3671` uses
49+
> `0 0 0 3px <halo>, 0 0 16px <halo>, 0 4px 24px rgba(0,0,0,0.4)`
50+
> plus keyframes `0 0 16px → 0 0 24px` (halo ring 3px → 5px). Values
51+
> were tuned during implementation; treat the spec numbers as
52+
> indicative.
53+
> - **Trust badge + presence dot on participant tiles** (not mentioned
54+
> in spec). `crates/web/src/components/participant_tile.rs:166-194`
55+
> renders `<TrustBadge … context=TileCorner/>` in the top-left and
56+
> `<StatusDot state=presence …/>` in the bottom-right. Both are
57+
> legitimate cross-spec affordances introduced by Phase 1d
58+
> (trust-verification) and Phase 1e (presence); the visual-design
59+
> section of this spec does not document them.
60+
>
61+
> The body below is preserved as the original target. The *Realised
62+
> state* list above is authoritative for current implementation shape;
63+
> do not edit the body in place to match it.
64+
365
## Problem
466

567
Willow's voice chat is audio-only with minimal UI — just mute/deafen/disconnect buttons in the sidebar. There's no camera video, no screen sharing, no visual call page, no speaking indicators, and no way to see who's in the call at a glance.

0 commit comments

Comments
 (0)