Skip to content

Comments

improvement: Improve disconnection ux#255

Merged
iparaskev merged 3 commits intomainfrom
improve_disconnection_ux
Feb 11, 2026
Merged

improvement: Improve disconnection ux#255
iparaskev merged 3 commits intomainfrom
improve_disconnection_ux

Conversation

@iparaskev
Copy link
Contributor

@iparaskev iparaskev commented Feb 9, 2026

  • Fires faster the ui indication that a user disconnected.
  • Shows an indication when the remote participant disconnects in a direct call.

closes: #208

Summary by CodeRabbit

  • New Features

    • Added an inline wifi-off badge on remote avatars to show when a participant loses connectivity.
  • Bug Fixes

    • Reconnection now requires both signaling and media links before clearing reconnect state.
    • Media/device reconnection flow improved to wait for signaling before retrying.
    • Increased local track bitrate ceiling for better A/V quality.
  • Style

    • Centered and tightened layout of the reconnecting status banner.

@iparaskev iparaskev requested a review from konsalex as a code owner February 9, 2026 08:23
@netlify
Copy link

netlify bot commented Feb 9, 2026

Deploy Preview for hoppdocs ready!

Name Link
🔨 Latest commit 4daedf5
🔍 Latest deploy log https://app.netlify.com/projects/hoppdocs/deploys/69899ce721026b00085c6c52
😎 Deploy Preview https://deploy-preview-255--hoppdocs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Feb 9, 2026

📝 Walkthrough

Walkthrough

Updates 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

Cohort / File(s) Summary
Call center UI & logic
tauri/src/components/ui/call-center.tsx
Added isRemoteDisconnected state, subscribed to RoomEvent.ParticipantDisconnected/ParticipantConnected, render inline WiFi-off badge near remote avatar; adjusted reconnecting banner layout and wrapped avatar block for badge.
Connectivity & reconnection flows
tauri/src/components/ui/call-center.tsx
Wired socketConnected into reconnection detection and clearing; require both LiveKit and socket connectivity to clear isReconnecting; added RoomEvent.Connected handling and socket-based disconnection handling across effects.
Media/device & bitrate
tauri/src/components/ui/call-center.tsx
MediaDevicesSettings now depends on socketConnected for reconnection flow; increased local track maxBitrate from 1,300,000 to 1,700,000 in local track config(s).
Types & imports
tauri/src/components/ui/call-center.tsx
Imported LuWifiOff icon and extended LiveKit imports with EngineEvent and RemoteParticipant types; updated related imports.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • fix: livekit disconnect issue #240: Modifies call-center.tsx to add/manage LiveKit reconnection state and RoomEvent effects; strong overlap in reconnection logic and event wiring.

Suggested reviewers

  • konsalex

Poem

🐰
I sniffed the wire, a sudden hush,
A tiny badge—a wifi blush.
I hop and watch the room’s heartbeat,
Rejoin when sockets and signals meet.
Bitrate higher, bounce complete. 🎚️📶

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes in the PR, which focus on improving disconnection handling and user experience.
Linked Issues check ✅ Passed The PR addresses the bug by detecting internet disconnections faster and attempting to resume calls, matching issue #208 requirements.
Out of Scope Changes check ✅ Passed All changes focus on disconnection handling, reconnection logic, and UX improvements directly related to issue #208.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch improve_disconnection_ux

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
tauri/src/components/ui/call-center.tsx (2)

29-29: Unused import: EngineEvent

EngineEvent is imported but never referenced anywhere in this file.

Proposed fix
-  EngineEvent,

767-777: Consider narrowing the callTokens dependency to avoid unnecessary effect re-runs

This effect only reads callTokens.isReconnecting, yet it depends on the entire callTokens object. Every unrelated callTokens mutation (mic toggle, camera toggle, etc.) will re-trigger this effect. Not a bug thanks to the guards, but unnecessarily noisy.

Proposed fix
-  }, [socketConnected, callTokens, updateCallTokens, roomState]);
+  }, [socketConnected, callTokens?.isReconnecting, updateCallTokens, roomState]);

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

EngineEvent is 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";

Comment on lines 115 to 143
// 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]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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:

  1. Stabilize the dependency — depend on callParticipant?.id instead of the full object.
  2. 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.

@iparaskev iparaskev merged commit 89cb53c into main Feb 11, 2026
16 checks passed
@iparaskev iparaskev deleted the improve_disconnection_ux branch February 11, 2026 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Call active after internet loss

2 participants