Conversation
✅ Deploy Preview for hoppdocs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughUpdates to call-center introduce remote-participant disconnection tracking via LiveKit room events, show a WiFi-off badge on the remote avatar, require both LiveKit and socket connectivity for reconnection, propagate socketConnected into reconnection/device logic, and raise local track maxBitrate. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as "Client UI"
participant Socket as "Socket Server"
participant LiveKit as "LiveKit Room"
participant State as "Local State"
UI->>Socket: maintain socketConnected (ping/connection)
UI->>LiveKit: join room / register event handlers
LiveKit-->>UI: RoomEvent.ParticipantDisconnected / Connected
Socket-->>UI: socket disconnected / reconnected events
UI->>State: set isRemoteDisconnected (based on LiveKit events)
UI->>State: set isReconnecting (requires !LiveKitConnected or !socketConnected)
State-->>UI: render avatar badge (wifi-off) when isRemoteDisconnected
State-->>UI: clear isReconnecting when LiveKit AND socketConnected are true
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@tauri/src/components/ui/call-center.tsx`:
- Around line 767-774: The useEffect that sets isReconnecting via
updateCallTokens when socketConnected is false can leave the banner stuck
because we never clear isReconnecting when the socket recovers but LiveKit
(roomState) didn't transition; update that effect (the useEffect around
socketConnected, callTokens, updateCallTokens, roomState) to also handle the
recovery path: if socketConnected becomes true and callTokens.isReconnecting is
true and the roomState indicates LiveKit is connected (use the same
roomState/enum you use in handleConnectionStateChange), call updateCallTokens({
isReconnecting: false }) so the banner is cleared even when only the socket
reconnects.
- Around line 115-143: The effect currently resets isRemoteDisconnected to false
on every re-run and depends on the full callParticipant object; change the
dependency to callParticipant?.id (and room) to avoid re-running when teammates
produce a new object, and replace the unconditional
setIsRemoteDisconnected(false) with a real check against the room's current
participants to determine if the audio participant for callParticipant.id is
present (use room.participants or room.participants.values() and match
participant.identity.includes("audio") &&
participant.identity.includes(callParticipant.id)); keep the existing handlers
(handleParticipantDisconnected/Connected) and the RoomEvent
registrations/teardowns but initialize isRemoteDisconnected based on that
derived check instead of always false.
🧹 Nitpick comments (1)
tauri/src/components/ui/call-center.tsx (1)
29-29: Unused import:EngineEvent
EngineEventis imported but never referenced anywhere in this file. This looks like a leftover from development.🧹 Remove unused import
RoomEvent, VideoPresets, LocalTrack, ParticipantEvent, AudioPresets, - EngineEvent, RemoteParticipant, } from "livekit-client";
| // Listen for participant disconnection events | ||
| useEffect(() => { | ||
| if (!callParticipant) return; | ||
|
|
||
| const handleParticipantDisconnected = (participant: RemoteParticipant) => { | ||
| if (participant.identity.includes("audio") && participant.identity.includes(callParticipant.id)) { | ||
| console.log("Remote participant disconnected:", participant.identity); | ||
| setIsRemoteDisconnected(true); | ||
| } | ||
| }; | ||
|
|
||
| const handleParticipantConnected = (participant: RemoteParticipant) => { | ||
| if (participant.identity.includes("audio") && participant.identity.includes(callParticipant.id)) { | ||
| console.log("Remote participant connected:", participant.identity); | ||
| setIsRemoteDisconnected(false); | ||
| } | ||
| }; | ||
|
|
||
| room.on(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected); | ||
| room.on(RoomEvent.ParticipantConnected, handleParticipantConnected); | ||
|
|
||
| // Initialize state based on current participants | ||
| setIsRemoteDisconnected(false); | ||
|
|
||
| return () => { | ||
| room.off(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected); | ||
| room.off(RoomEvent.ParticipantConnected, handleParticipantConnected); | ||
| }; | ||
| }, [room, callParticipant]); |
There was a problem hiding this comment.
State reset on every effect re-run loses the disconnection signal
callParticipant is derived via teammates?.find(...) (line 99), which yields a new object reference whenever teammates changes, causing this effect to re-run. Each re-run unconditionally resets isRemoteDisconnected to false (line 137), which will hide the wifi-off badge even if the remote participant is still disconnected.
The comment on line 136 says "Initialize state based on current participants" but the code doesn't actually check — it blindly sets false.
Two fixes needed:
- Stabilize the dependency — depend on
callParticipant?.idinstead of the full object. - Derive the initial state from the room's current participant list.
Proposed fix
- }, [room, callParticipant]);
+ }, [room, callParticipant?.id]);And replace the blind reset with an actual check:
- // Initialize state based on current participants
- setIsRemoteDisconnected(false);
+ // Initialize state based on current participants
+ const audioParticipantPresent = Array.from(room.remoteParticipants.values()).some(
+ (p) => p.identity.includes("audio") && p.identity.includes(callParticipant.id),
+ );
+ setIsRemoteDisconnected(!audioParticipantPresent);🤖 Prompt for AI Agents
In `@tauri/src/components/ui/call-center.tsx` around lines 115 - 143, The effect
currently resets isRemoteDisconnected to false on every re-run and depends on
the full callParticipant object; change the dependency to callParticipant?.id
(and room) to avoid re-running when teammates produce a new object, and replace
the unconditional setIsRemoteDisconnected(false) with a real check against the
room's current participants to determine if the audio participant for
callParticipant.id is present (use room.participants or
room.participants.values() and match participant.identity.includes("audio") &&
participant.identity.includes(callParticipant.id)); keep the existing handlers
(handleParticipantDisconnected/Connected) and the RoomEvent
registrations/teardowns but initialize isRemoteDisconnected based on that
derived check instead of always false.
closes: #208
Summary by CodeRabbit
New Features
Bug Fixes
Style