Calls: screen share, mic/cam toggles, status badges, pin + fullscreen, call timer
Screen sharing swaps the outgoing video track on every peer's sender with replaceTrack (same m-line, no renegotiation); the camera returns when the share stops, including via the browser's own "Stop sharing" bar. Mic and camera toggles flip track.enabled. A new Status signal kind broadcasts mic/cam/screen state so tiles can show badges; newcomers get it directed when their Join arrives. Tiles carry a name label, click to pin as a stage (a peer's screen share pins itself), double-click for fullscreen. The call bar has an elapsed timer and a participant count. Controls are icon-only inline SVGs on currentColor: plain with a strike when off, a soft glow and ticking LED when live. Red is reserved for leave. Also fixed along the way: the peer map was a non-reactive StoredValue, so the tile list never re-rendered when someone joined; ICE candidates that arrive before the remote description are now buffered instead of rejected; a peer whose connection fails or closes is dropped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L3sD29ozDvqA7jozeZXZoB
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
c1c337c2a2
commit
78e9c9ff94
@@ -110,6 +110,8 @@ src/
|
||||
app.rs Leptos UI (login gate + chat console)
|
||||
auth.rs shared User type + current_user server fn
|
||||
chat.rs shared ChatMessage/rooms + send_message server fn (publishes to NATS)
|
||||
call.rs call signaling types + send_signal server fn (call.room.*, never archived)
|
||||
webrtc.rs browser-only mesh WebRTC: peers, mic/cam toggles, screen share
|
||||
server/
|
||||
oidc.rs Kanidm OIDC login/callback/logout handlers
|
||||
sse.rs NATS → browser SSE bridge (one subscription per client)
|
||||
@@ -117,6 +119,30 @@ src/
|
||||
style/main.css the console theme
|
||||
```
|
||||
|
||||
## Calls
|
||||
|
||||
The `lobby` room has a mesh WebRTC call (every pair of browsers connects
|
||||
directly; fine for a handful of people, not more). Signaling rides NATS on
|
||||
`call.room.<room>` via `/call-sse/<room>` and the `send_signal` server fn, so
|
||||
it is never archived. Only a public STUN server is configured: calls across
|
||||
symmetric NATs will not connect without a TURN relay, which this app does not
|
||||
run.
|
||||
|
||||
In a call:
|
||||
|
||||
- **MIC / CAM** toggle your mic and camera (the track stays attached and sends
|
||||
silence/black, so toggling is instant and needs no renegotiation).
|
||||
- **SCR ▶ share** shares a screen, window, or tab. It swaps the outgoing video
|
||||
track on every peer with `replaceTrack`; your camera comes back when you
|
||||
stop, or when the browser's own "Stop sharing" bar is used.
|
||||
- Tiles show the participant's name and MIC ✕ / CAM ✕ / SCR badges, kept in
|
||||
sync by a `Status` signal on the same subject.
|
||||
- **Click** a tile to pin it as the stage (a shared screen pins itself);
|
||||
**double-click** for fullscreen.
|
||||
- A peer whose tab closes without leaving is dropped once their connection
|
||||
fails, and ICE candidates that arrive before the offer are buffered rather
|
||||
than lost.
|
||||
|
||||
## Notes & production hardening
|
||||
|
||||
- Sessions are in-memory (`tower-sessions` `MemoryStore`): restart logs
|
||||
|
||||
Reference in New Issue
Block a user