fix(ui): auto-dismiss call screen when peer hangs up

Previously: peer hangs up → Rust emits signal-event {type:hangup}
→ JS clears callStatusText + hides incoming panel, but the call
screen stays on with a dangling Hangup button the user has to
press to acknowledge a call that's already over. Dead UX.

Now: the hangup event handler tears down our side of the media
engine via `invoke("disconnect")` and transitions back to the
connect screen when we're currently in the call screen.
Incoming-call panel still hides as before.

`userDisconnected = true` is set so the existing call-event
"disconnected" auto-reconnect path (which fires on transport
drop) doesn't kick in — the peer-hangup signal is an intentional
end-of-call, not a transport blip worth retrying.

Also documented: "not connected" errors from the `disconnect`
command are silently swallowed because they happen when there's
no engine to tear down (e.g. incoming call that was never
answered — caller bailed), which is the correct outcome there.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-11 18:41:26 +04:00
parent 20375eceb9
commit e75b045470

View File

@@ -1261,8 +1261,34 @@ listen("signal-event", (event: any) => {
})();
break;
case "hangup":
// Peer (or the relay) ended the call. Tear down OUR side
// of the media engine and return to the connect screen
// automatically — the user shouldn't have to hit End Call
// on a call that's already over.
//
// Scenarios this handles:
// * active direct call, peer hung up → disconnect + back
// to connect screen
// * incoming call was ringing but caller bailed → hide
// incoming panel (no engine to disconnect)
// * setup failure mid-handshake → same as above
callStatusText.textContent = "";
incomingCallPanel.classList.add("hidden");
(async () => {
try {
// disconnect errors out with "not connected" if there's
// no active engine — safe to ignore, we just want to
// make sure any engine IS torn down.
await invoke("disconnect");
} catch {}
// Suppress the call-event "disconnected" auto-reconnect
// path since this was a peer-initiated hangup, not a
// transport drop.
userDisconnected = true;
if (!callScreen.classList.contains("hidden")) {
showConnectScreen();
}
})();
break;
case "reconnecting":
// Signal supervisor is retrying the relay connection. Show