fix(calls): hang up explicitly when answering another call while in one (#195)
Answering from the in-call banner is the only call-to-call switch path; it started the new embed and let the atom dispose the old one, which just removed the iframe — our m.call.member in the old room lingered ~17 s (until the delayed leave expired), so everyone there still saw us in the call. hangupAndWait moves out of LogoutDialog into plugins/call/hangup.ts and handleAnswer now hangs up, waits for our membership to clear (bounded 4 s), disposes the old embed itself (its HangupCall echo would otherwise land after startCall and clear the NEW embed from the atom — seen in testing), then joins the new call. Measured headless: old membership gone in 1 s, new call live with both participants. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { MatrixClient } from 'matrix-js-sdk';
|
||||
import { CallEmbed } from './CallEmbed';
|
||||
|
||||
/**
|
||||
* Ask EC to hang up and wait (bounded) until our own RTC membership has left
|
||||
* the room's session. Used wherever the embed is about to be torn down for a
|
||||
* reason other than the user pressing End — logout (#29) and answering another
|
||||
* call while in one (#195) — because disposing the iframe alone leaves a ghost
|
||||
* `m.call.member` for everyone else until the delayed leave event expires
|
||||
* (~17–30 s measured).
|
||||
*/
|
||||
export const hangupCallAndWait = async (
|
||||
mx: MatrixClient,
|
||||
embed: CallEmbed,
|
||||
timeoutMs = 4000,
|
||||
): Promise<void> => {
|
||||
const myUserId = mx.getUserId();
|
||||
const myDeviceId = mx.getDeviceId();
|
||||
const stillIn = (): boolean =>
|
||||
mx.matrixRTC
|
||||
.getRoomSession(embed.room)
|
||||
.memberships.some((m) => m.sender === myUserId && m.deviceId === myDeviceId);
|
||||
try {
|
||||
await embed.hangup();
|
||||
} catch {
|
||||
// widget already gone — fall through to the wait/timeout
|
||||
}
|
||||
const deadline = Date.now() + timeoutMs;
|
||||
while (stillIn() && Date.now() < deadline) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await new Promise((r) => {
|
||||
setTimeout(r, 150);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user