import { MatrixEvent } from 'matrix-js-sdk'; import { IRTCNotificationContent } from 'matrix-js-sdk/lib/matrixrtc/types'; export const RTC_NOTIFICATION_DEFAULT_LIFETIME = 30_000; export const getNotificationEventSendTs = (ev: MatrixEvent): number => { const content = ev.getContent(); const sendTs = content.sender_ts; const eventTs = ev.getTs(); if (sendTs && Math.abs(sendTs - eventTs) >= 15_000) return eventTs; return sendTs ?? eventTs; }; export const isRtcNotificationExpired = (ev: MatrixEvent, now = Date.now()): boolean => { const content = ev.getContent(); const lifetime = content.lifetime ?? RTC_NOTIFICATION_DEFAULT_LIFETIME; return now - getNotificationEventSendTs(ev) > lifetime; }; // Normalize the legacy '' ↔ 'ROOM' equivalence for room-scoped DM call slots. // matrix-js-sdk 40.2 introduced a `slotDescription.id` compat hack that // surfaces 'ROOM' for room-scoped m.call.member memberships (which still go on // the wire as `call_id: ''`); pre-40.2 SDKs and direct raw-event reads in // `findCallIdSync` race-recovery paths still yield ''. Without this normalize // step, a single logical ring acquires three distinct dedup keys depending on // peer SDK version and whether we read happy-path vs fallback — and registry // dedup, decline-IDs and atom REMOVE/ADD all key on the result. export const getIncomingCallKey = (callId: string, roomId: string): string => { const normalized = callId === '' ? 'ROOM' : callId; return `call_${normalized}_${roomId}`; };