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 { ShowToastActionType } from './toast';
|
||||||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } 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 { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
|
||||||
import {
|
import {
|
||||||
isGroupOrAdhocCallMode,
|
isGroupOrAdhocCallMode,
|
||||||
|
@ -2215,7 +2219,8 @@ const _startCallLinkLobby = async ({
|
||||||
const callLobbyData = await calling.startCallLinkLobby({
|
const callLobbyData = await calling.startCallLinkLobby({
|
||||||
callLinkRootKey,
|
callLinkRootKey,
|
||||||
adminPasskey,
|
adminPasskey,
|
||||||
hasLocalAudio: groupCallDeviceCount < 8,
|
hasLocalAudio:
|
||||||
|
groupCallDeviceCount < MAX_CALL_PARTICIPANTS_FOR_DEFAULT_MUTE,
|
||||||
});
|
});
|
||||||
if (!callLobbyData) {
|
if (!callLobbyData) {
|
||||||
return;
|
return;
|
||||||
|
@ -2314,7 +2319,8 @@ function startCallingLobby({
|
||||||
|
|
||||||
const callLobbyData = await calling.startCallingLobby({
|
const callLobbyData = await calling.startCallingLobby({
|
||||||
conversation,
|
conversation,
|
||||||
hasLocalAudio: groupCallDeviceCount < 8,
|
hasLocalAudio:
|
||||||
|
groupCallDeviceCount < MAX_CALL_PARTICIPANTS_FOR_DEFAULT_MUTE,
|
||||||
hasLocalVideo: isVideoCall,
|
hasLocalVideo: isVideoCall,
|
||||||
});
|
});
|
||||||
if (!callLobbyData) {
|
if (!callLobbyData) {
|
||||||
|
@ -3114,6 +3120,17 @@ export function reducer(
|
||||||
hasLocalAudio,
|
hasLocalAudio,
|
||||||
hasLocalVideo,
|
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 {
|
} else {
|
||||||
newActiveCallState = state.activeCallState;
|
newActiveCallState = state.activeCallState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ import type {
|
||||||
GroupCallStateType,
|
GroupCallStateType,
|
||||||
} from './calling';
|
} 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
|
// 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
|
// an active call. In practice, the UI is not ready for this, and RingRTC doesn't
|
||||||
// support it for direct calls.
|
// 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 = {
|
const stateWithIncomingGroupCall: CallingStateType = {
|
||||||
...stateWithGroupCall,
|
...stateWithGroupCall,
|
||||||
callsByConversation: {
|
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 = {
|
const stateWithActiveGroupCall: CallingStateTypeWithActiveCall = {
|
||||||
...stateWithGroupCall,
|
...stateWithGroupCall,
|
||||||
activeCallState: {
|
activeCallState: groupCallActiveCallState,
|
||||||
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 ourAci = generateAci();
|
const ourAci = generateAci();
|
||||||
|
@ -1319,6 +1343,84 @@ describe('calling duck', () => {
|
||||||
|
|
||||||
assert.isFalse(result.activeCallState?.outgoingRing);
|
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', () => {
|
describe('handleCallLinkUpdate', () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue