In call link lobby mute audio by default when peeking many devices
This commit is contained in:
parent
1037fab680
commit
c901f47dd1
3 changed files with 137 additions and 16 deletions
|
@ -76,7 +76,11 @@ import { ToastType } from '../../types/Toast';
|
|||
import type { ShowToastActionType } from './toast';
|
||||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
import { isAnybodyElseInGroupCall } from './callingHelpers';
|
||||
import {
|
||||
isAnybodyElseInGroupCall,
|
||||
isAnybodyInGroupCall,
|
||||
MAX_CALL_PARTICIPANTS_FOR_DEFAULT_MUTE,
|
||||
} from './callingHelpers';
|
||||
import { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
|
||||
import {
|
||||
isGroupOrAdhocCallMode,
|
||||
|
@ -2215,7 +2219,8 @@ const _startCallLinkLobby = async ({
|
|||
const callLobbyData = await calling.startCallLinkLobby({
|
||||
callLinkRootKey,
|
||||
adminPasskey,
|
||||
hasLocalAudio: groupCallDeviceCount < 8,
|
||||
hasLocalAudio:
|
||||
groupCallDeviceCount < MAX_CALL_PARTICIPANTS_FOR_DEFAULT_MUTE,
|
||||
});
|
||||
if (!callLobbyData) {
|
||||
return;
|
||||
|
@ -2314,7 +2319,8 @@ function startCallingLobby({
|
|||
|
||||
const callLobbyData = await calling.startCallingLobby({
|
||||
conversation,
|
||||
hasLocalAudio: groupCallDeviceCount < 8,
|
||||
hasLocalAudio:
|
||||
groupCallDeviceCount < MAX_CALL_PARTICIPANTS_FOR_DEFAULT_MUTE,
|
||||
hasLocalVideo: isVideoCall,
|
||||
});
|
||||
if (!callLobbyData) {
|
||||
|
@ -3114,6 +3120,17 @@ export function reducer(
|
|||
hasLocalAudio,
|
||||
hasLocalVideo,
|
||||
};
|
||||
|
||||
// The first time we detect call participants in the lobby, check participant count
|
||||
// and mute ourselves if over the threshold.
|
||||
if (
|
||||
joinState === GroupCallJoinState.NotJoined &&
|
||||
!isAnybodyInGroupCall(existingCall?.peekInfo) &&
|
||||
newPeekInfo.deviceCount >= MAX_CALL_PARTICIPANTS_FOR_DEFAULT_MUTE &&
|
||||
newActiveCallState?.hasLocalAudio
|
||||
) {
|
||||
newActiveCallState.hasLocalAudio = false;
|
||||
}
|
||||
} else {
|
||||
newActiveCallState = state.activeCallState;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import type {
|
|||
GroupCallStateType,
|
||||
} from './calling';
|
||||
|
||||
export const MAX_CALL_PARTICIPANTS_FOR_DEFAULT_MUTE = 8;
|
||||
|
||||
// In theory, there could be multiple incoming calls, or an incoming call while there's
|
||||
// an active call. In practice, the UI is not ready for this, and RingRTC doesn't
|
||||
// support it for direct calls.
|
||||
|
|
|
@ -137,6 +137,28 @@ describe('calling duck', () => {
|
|||
},
|
||||
};
|
||||
|
||||
const stateWithNotJoinedGroupCall: CallingStateType = {
|
||||
...getEmptyState(),
|
||||
callsByConversation: {
|
||||
'fake-group-call-conversation-id': {
|
||||
callMode: CallMode.Group,
|
||||
conversationId: 'fake-group-call-conversation-id',
|
||||
connectionState: GroupCallConnectionState.NotConnected,
|
||||
joinState: GroupCallJoinState.NotJoined,
|
||||
localDemuxId: 1,
|
||||
peekInfo: {
|
||||
acis: [],
|
||||
pendingAcis: [],
|
||||
creatorAci,
|
||||
eraId: 'xyz',
|
||||
maxDevices: 16,
|
||||
deviceCount: 0,
|
||||
},
|
||||
remoteParticipants: [],
|
||||
} satisfies GroupCallStateType,
|
||||
},
|
||||
};
|
||||
|
||||
const stateWithIncomingGroupCall: CallingStateType = {
|
||||
...stateWithGroupCall,
|
||||
callsByConversation: {
|
||||
|
@ -151,21 +173,23 @@ describe('calling duck', () => {
|
|||
},
|
||||
};
|
||||
|
||||
const groupCallActiveCallState: ActiveCallStateType = {
|
||||
callMode: CallMode.Group,
|
||||
conversationId: 'fake-group-call-conversation-id',
|
||||
hasLocalAudio: true,
|
||||
hasLocalVideo: false,
|
||||
localAudioLevel: 0,
|
||||
viewMode: CallViewMode.Paginated,
|
||||
showParticipantsList: false,
|
||||
outgoingRing: false,
|
||||
pip: false,
|
||||
settingsDialogOpen: false,
|
||||
joinedAt: null,
|
||||
};
|
||||
|
||||
const stateWithActiveGroupCall: CallingStateTypeWithActiveCall = {
|
||||
...stateWithGroupCall,
|
||||
activeCallState: {
|
||||
callMode: CallMode.Group,
|
||||
conversationId: 'fake-group-call-conversation-id',
|
||||
hasLocalAudio: true,
|
||||
hasLocalVideo: false,
|
||||
localAudioLevel: 0,
|
||||
viewMode: CallViewMode.Paginated,
|
||||
showParticipantsList: false,
|
||||
outgoingRing: false,
|
||||
pip: false,
|
||||
settingsDialogOpen: false,
|
||||
joinedAt: null,
|
||||
},
|
||||
activeCallState: groupCallActiveCallState,
|
||||
};
|
||||
|
||||
const ourAci = generateAci();
|
||||
|
@ -1319,6 +1343,84 @@ describe('calling duck', () => {
|
|||
|
||||
assert.isFalse(result.activeCallState?.outgoingRing);
|
||||
});
|
||||
|
||||
it('mutes self in lobby when getting peek info with a lot of devices', () => {
|
||||
const result = reducer(
|
||||
{
|
||||
...stateWithNotJoinedGroupCall,
|
||||
activeCallState: groupCallActiveCallState,
|
||||
},
|
||||
getAction({
|
||||
callMode: CallMode.Group,
|
||||
conversationId: 'fake-group-call-conversation-id',
|
||||
connectionState: GroupCallConnectionState.Connecting,
|
||||
joinState: GroupCallJoinState.NotJoined,
|
||||
localDemuxId: 1,
|
||||
hasLocalAudio: true,
|
||||
hasLocalVideo: true,
|
||||
peekInfo: {
|
||||
acis: Array(20).map(generateAci),
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 20,
|
||||
},
|
||||
remoteParticipants: [],
|
||||
})
|
||||
);
|
||||
|
||||
assert.isFalse(result.activeCallState?.hasLocalAudio);
|
||||
});
|
||||
|
||||
it('does not mute self when getting peek info with few devices', () => {
|
||||
const result = reducer(
|
||||
{
|
||||
...stateWithNotJoinedGroupCall,
|
||||
activeCallState: groupCallActiveCallState,
|
||||
},
|
||||
getAction({
|
||||
callMode: CallMode.Group,
|
||||
conversationId: 'fake-group-call-conversation-id',
|
||||
connectionState: GroupCallConnectionState.Connecting,
|
||||
joinState: GroupCallJoinState.NotJoined,
|
||||
localDemuxId: 1,
|
||||
hasLocalAudio: true,
|
||||
hasLocalVideo: true,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
remoteParticipants: [],
|
||||
})
|
||||
);
|
||||
|
||||
assert.isTrue(result.activeCallState?.hasLocalAudio);
|
||||
});
|
||||
|
||||
it('does not mute self when connected with many devices', () => {
|
||||
const result = reducer(
|
||||
stateWithActiveGroupCall,
|
||||
getAction({
|
||||
callMode: CallMode.Group,
|
||||
conversationId: 'fake-group-call-conversation-id',
|
||||
connectionState: GroupCallConnectionState.Connected,
|
||||
joinState: GroupCallJoinState.Joined,
|
||||
localDemuxId: 1,
|
||||
hasLocalAudio: true,
|
||||
hasLocalVideo: true,
|
||||
peekInfo: {
|
||||
acis: Array(20).map(generateAci),
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 20,
|
||||
},
|
||||
remoteParticipants: [],
|
||||
})
|
||||
);
|
||||
|
||||
assert.isTrue(result.activeCallState?.hasLocalAudio);
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleCallLinkUpdate', () => {
|
||||
|
|
Loading…
Reference in a new issue