channelFull was computed only in the prescreen; a second click on the channel in the room nav joined a full channel. Extract useVoiceChannelFull, use it in both places, and refuse with a "Channel full (N/N)" toast. Fixes #30 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
import { Room } from 'matrix-js-sdk';
|
|
import { useMemo } from 'react';
|
|
import { useStateEvent } from './useStateEvent';
|
|
import { StateEvent } from '../../types/matrix/room';
|
|
import { VoiceLimitContent } from '../features/common-settings/general/RoomVoiceLimit';
|
|
import { useCallMembers, useCallSession } from './useCall';
|
|
import { useMatrixClient } from './useMatrixClient';
|
|
|
|
export type VoiceChannelFull = {
|
|
channelFull: boolean;
|
|
current: number;
|
|
max: number;
|
|
};
|
|
|
|
/**
|
|
* [Gitea #30] Voice channel user limit (`io.lotus.voice_limit`), shared between
|
|
* `CallPrescreen` and any other join path (e.g. the room-nav second-click join)
|
|
* so they agree on when a channel is full. 0/absent `max_users` means no limit.
|
|
*/
|
|
export const useVoiceChannelFull = (room: Room): VoiceChannelFull => {
|
|
const mx = useMatrixClient();
|
|
const callSession = useCallSession(room);
|
|
const callMembers = useCallMembers(callSession);
|
|
|
|
const limitEvent = useStateEvent(room, StateEvent.LotusVoiceLimit);
|
|
|
|
return useMemo(() => {
|
|
const maxUsers = limitEvent?.getContent<VoiceLimitContent>().max_users ?? 0;
|
|
// A user already counted in the session is rejoining and should not be blocked.
|
|
const alreadyMember = callMembers.some((m) => m.sender === mx.getSafeUserId());
|
|
const channelFull = maxUsers > 0 && !alreadyMember && callMembers.length >= maxUsers;
|
|
return { channelFull, current: callMembers.length, max: maxUsers };
|
|
}, [limitEvent, callMembers, mx]);
|
|
};
|