You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(video-conf): add a layout picker with grid, spotlight, and sidebar modes (NV-11)
A dropdown in the call controls lets users switch the video tile layout
between grid (equal tiles), spotlight (active speaker fills the stage
with a self-view PiP), and sidebar (active speaker large, others in a
strip). The choice is persisted in localStorage across calls.
Active speaker detection uses a single AudioContext with one
AnalyserNode per participant, sampling at ~12 Hz with 1.5 s hysteresis
to avoid flicker.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/features/video-conference-persistent-chat/README.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -213,6 +213,18 @@ The conference is a column: a row holding the call and the chat panel, then `Cal
213
213
214
214
The panel is docked to the inline end, so its close button sits at the far end of its header — matching every other closable surface in the product. Both panels share that header (`CallPanelHeader`, the contextual bar's own header/title/close), so two docked side by side can't disagree about where their own edges are.
215
215
216
+
### Stage layout
217
+
218
+
The call stage (`CallStage`) supports three layouts, cycled by a button in the control bar:
219
+
220
+
-**Grid** (default) — all participants in equal-sized tiles, rows/cols computed by `useTileGridLayout` to fill the stage within a [3:4 .. 16:9] aspect band.
221
+
-**Spotlight** — the active speaker fills the stage; the local user's self-view floats as a small PiP in the bottom-right corner. When the local user *is* the active speaker, the first remote participant is shown large instead.
222
+
-**Sidebar** — the active speaker is large on the left, all other participants are shown in a thumb column on the right (or row at the bottom on narrow stages), reusing the same structure as the screen-share spotlight.
223
+
224
+
Active speaker detection runs in `useActiveSpeakerId`: a single `AudioContext` with one `AnalyserNode` per participant, sampling at ~12 Hz. A 1.5 s hold prevents flickering between speakers during conversational pauses. When nobody is speaking, the fallback is the first remote participant.
225
+
226
+
When a screen share is active, the existing screen-share spotlight takes over regardless of the selected layout — the screen always wins.
227
+
216
228
The bar carries two counts: how many people are in the call, and what is unread in the chat while its panel is
217
229
closed. The unread one goes through `useUnreadDisplay`, the sidebar's own rules, so a mention reads as urgent in
218
230
both places and a muted room stays quiet in both. The members count is deliberately `secondary` — a count of who is
@@ -1002,6 +1014,7 @@ could not be loaded" panel, because the detail panel is contact-call-shaped.
1002
1014
| Conference model |`packages/models/src/models/VideoConference.ts`|
0 commit comments