fix(voice): fix race conditions, broken icons, and null deref in call UI#8
Merged
Conversation
…n call UI - Fix mic enable race: move setMicrophoneEnabled outside batch and guard the .then() callback against stale room reference - Add reconnecting/reconnected event listeners so status indicator shows correct state during network interruptions - Fix camera icon: camera_video is not a valid Material Symbol, use videocam - Fix PiP snap: use innerWidth/innerHeight instead of outerWidth/outerHeight so corner detection matches clientX/clientY coordinate space - Guard user().user null dereference in voice participant tile to prevent crash when participant User object hasn't been fetched yet
Greptile SummaryThis PR fixes multiple critical voice call issues: race conditions in microphone state management, missing network reconnection status, broken camera icons, incorrect PiP positioning, and null pointer crashes.
All changes are defensive improvements with no breaking changes to the API surface. Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant Voice
participant Room1 as Room (old)
participant Room2 as Room (new)
Note over User,Room2: Race Condition Scenario
User->>Voice: joinCall()
Voice->>Room1: room.connect()
Voice->>Room1: setMicrophoneEnabled(true)
Note over Voice,Room1: User quickly disconnects
User->>Voice: disconnect()
Note over Voice,Room2: User reconnects immediately
User->>Voice: joinCall() again
Voice->>Room2: room.connect()
Voice->>Room2: setMicrophoneEnabled(true)
Note over Room1,Voice: ❌ OLD: Stale callback fires
Room1-->>Voice: .then() callback (no guard)
Room1->>Voice: setMicrophone(true) for wrong room
Note over Room2,Voice: ✅ NEW: Guard prevents stale state
Room1-->>Voice: .then() callback
Voice->>Voice: if (this.room() === room)
Note over Voice: Guard rejects stale room
Room2-->>Voice: .then() callback
Voice->>Voice: if (this.room() === room)
Room2->>Voice: setMicrophone(true) for correct room
Last reviewed commit: 4ebad53 |
* gh/main: feat(e2e): implement LiveKit mocking layer (#5) fix(voice): fix spotlight and hide-members features fix(voice): remove incorrect prevTracks parameter from autoSpotlightId memo fix(voice): make track dependencies explicit in spotlight memo fix(voice): remove unused spotlightControls to fix linting feat(voice): implement auto-spotlight and manual pinning chore: generate i18n catalog feat(voice): add hide members toggle in call actions # Conflicts: # packages/client/components/rtc/state.tsx
Author
|
@greptile |
Address review feedback: the mock path's setTimeout callback could set mic state on a stale room if disconnect/reconnect happens within the 10ms window. Add the same room() === room check used in the non-mock path.
Author
|
Addressed @greptile feedback: added stale room guards to the mock connection path (both the @greptile |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
setMicrophoneEnabledwas called insidebatch()beforeroom.connect(), and the.then()callback didn't verify the room was still current — could set stale mic state after quick disconnect/reconnectRECONNECTINGbecause no LiveKit event listeners were registered, so users always saw "Connected" during network interruptionscamera_videois not a valid Material Symbol name — changed tovideocamin VoiceCallCardActions and VoiceStatefulUserIconswindow.outerWidth/outerHeightinstead ofinnerWidth/innerHeight, causing PiP card to snap to wrong corner when browser has toolbars/devtoolsuser().user!in voice participant tile crashes when User object hasn't been fetched yet — added conditional spreadTest plan
videocamicon renders correctly🔗 Related beads: chat-d25, chat-aad, chat-3f6, chat-8mh, chat-92p