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 => { 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); }); } };