/** * [Gitea #342] Whether a voice channel with an `io.lotus.voice_limit` is full. * Counts distinct PEOPLE, not call memberships: a MatrixRTC membership is per * device, so one user on desktop + phone (or with a crashed tab's membership * not yet expired) used to fill two slots. This matches the server-side guard * (matrix `voice-limit-guard.py`, which reduces LiveKit identities to users). */ export type VoiceChannelOccupancy = { channelFull: boolean; /** Distinct users in the call. */ current: number; max: number; }; export const voiceChannelOccupancy = ( memberSenders: Array, myUserId: string, maxUsers: number, ): VoiceChannelOccupancy => { const users = new Set(memberSenders.filter((s): s is string => !!s)); // A user already in the call (another device, or rejoining) is never blocked. const alreadyMember = users.has(myUserId); const channelFull = maxUsers > 0 && !alreadyMember && users.size >= maxUsers; return { channelFull, current: users.size, max: maxUsers }; };