fix: prevent SIP disconnect during active call

disconnectSip() now guards against disconnect when outboundPending
or outboundActive is true. Accepts force=true for intentional
disconnects (logout, page unload, component unmount). Prevents
React re-render cycles from killing the SIP WebSocket mid-dial,
which was causing the call to drop and disposition modal to not appear.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-10 16:20:46 +05:30
parent 6a2fc47226
commit 0fc9375729
2 changed files with 12 additions and 4 deletions

View File

@@ -125,14 +125,14 @@ export const SipProvider = ({ children }: PropsWithChildren) => {
}
};
const handleUnload = () => disconnectSip();
const handleUnload = () => disconnectSip(true);
window.addEventListener('beforeunload', handleBeforeUnload);
window.addEventListener('unload', handleUnload);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
window.removeEventListener('unload', handleUnload);
disconnectSip();
disconnectSip(true); // force — component is unmounting
};
}, []); // empty deps — runs once on mount, cleanup only on unmount

View File

@@ -81,8 +81,16 @@ export function connectSip(config: SIPConfig): void {
sipClient.connect();
}
export function disconnectSip(): void {
console.log('[SIP-MGR] Disconnecting SIP');
export function disconnectSip(force = false): void {
// Guard: don't disconnect SIP during an active or pending call
// unless explicitly forced (e.g., logout, page unload).
// This prevents React re-render cycles from killing the
// SIP WebSocket mid-dial.
if (!force && (outboundPending || outboundActive)) {
console.log('[SIP-MGR] Disconnect blocked — call in progress');
return;
}
console.log('[SIP-MGR] Disconnecting SIP' + (force ? ' (forced)' : ''));
sipClient?.disconnect();
sipClient = null;
connected = false;