Skip to content

Commit

Permalink
runfix: calls in mls 1:1 conversations (#16255)
Browse files Browse the repository at this point in the history
* runfix: mls conference calls for mls group conversations only

* refactor: improve naming

* test: mls 1:1 conversation calls
  • Loading branch information
PatrykBuniX authored Nov 22, 2023
1 parent b9e3926 commit f4daa27
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 13 deletions.
51 changes: 50 additions & 1 deletion src/script/calling/CallingRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ describe('CallingRepository', () => {
afterEach(() => {
callingRepository['callState'].calls([]);
callingRepository['conversationState'].conversations([]);
callingRepository.destroy();
jest.clearAllMocks();
});

Expand All @@ -105,7 +106,7 @@ describe('CallingRepository', () => {

describe('startCall', () => {
it.each([ConversationProtocol.PROTEUS, ConversationProtocol.MLS])(
'starts a normal call in a 1:1 conversation for proteus or MLS conversation',
'starts a ONEONONE call for proteus or MLS 1:1 conversation',
async protocol => {
const conversation = createConversation(CONVERSATION_TYPE.ONE_TO_ONE, protocol);
const callType = CALL_TYPE.NORMAL;
Expand Down Expand Up @@ -153,6 +154,22 @@ describe('CallingRepository', () => {
expect.any(Function),
);
});

it('does not subscribe to epoch updates after initiating a call in 1:1 mls conversation', async () => {
const conversationId = {domain: 'example.com', id: 'conversation1'};

const groupId = 'groupId';
const mlsConversation = createConversation(
CONVERSATION_TYPE.ONE_TO_ONE,
ConversationProtocol.MLS,
conversationId,
groupId,
);

await callingRepository.startCall(mlsConversation, CALL_TYPE.NORMAL);

expect(container.resolve(Core).service?.subconversation.subscribeToEpochUpdates).not.toHaveBeenCalled();
});
});

describe('answerCall', () => {
Expand Down Expand Up @@ -192,6 +209,38 @@ describe('CallingRepository', () => {
expect.any(Function),
);
});

it('does not subscribe to epoch updates after answering a call in mls 1:1 conversation', async () => {
const conversationId = {domain: 'example.com', id: 'conversation2'};
const selfParticipant = createSelfParticipant();
const userId = {domain: '', id: ''};

const groupId = 'groupId';
const mlsConversation = createConversation(
CONVERSATION_TYPE.ONE_TO_ONE,
ConversationProtocol.MLS,
conversationId,
groupId,
);

const incomingCall = new Call(
userId,
mlsConversation.qualifiedId,
CONV_TYPE.ONEONONE,
selfParticipant,
CALL_TYPE.NORMAL,
{
currentAvailableDeviceId: mediaDevices,
} as unknown as MediaDevicesHandler,
);

jest.spyOn(callingRepository, 'pushClients').mockResolvedValueOnce(true);
callingRepository['conversationState'].conversations.push(mlsConversation);

await callingRepository.answerCall(incomingCall);

expect(container.resolve(Core).service?.subconversation.subscribeToEpochUpdates).not.toHaveBeenCalled();
});
});

describe('joinedCall', () => {
Expand Down
20 changes: 10 additions & 10 deletions src/script/calling/CallingRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import {ClientId, Participant, UserId} from './Participant';

import {PrimaryModal} from '../components/Modals/PrimaryModal';
import {Config} from '../Config';
import {isMLSConversation, MLSConversation} from '../conversation/ConversationSelectors';
import {isGroupMLSConversation, isMLSConversation, MLSConversation} from '../conversation/ConversationSelectors';
import {ConversationState} from '../conversation/ConversationState';
import {CallingEvent, EventBuilder} from '../conversation/EventBuilder';
import {CONSENT_TYPE, MessageRepository, MessageSendingOptions} from '../conversation/MessageRepository';
Expand Down Expand Up @@ -343,7 +343,7 @@ export class CallingRepository {
}
const allClients = await this.core.service!.conversation.fetchAllParticipantsClients(call.conversationId);

if (!isMLSConversation(conversation)) {
if (!isGroupMLSConversation(conversation)) {
const qualifiedClients = flattenUserMap(allClients);

const clients: Clients = flatten(
Expand Down Expand Up @@ -663,7 +663,7 @@ export class CallingRepository {
this.serializeQualifiedId(conversationId),
this.serializeQualifiedId(userId),
conversation && isMLSConversation(conversation) ? senderClientId : clientId,
conversation && isMLSConversation(conversation) ? CONV_TYPE.CONFERENCE_MLS : CONV_TYPE.CONFERENCE,
conversation && isGroupMLSConversation(conversation) ? CONV_TYPE.CONFERENCE_MLS : CONV_TYPE.CONFERENCE,
);

if (res !== 0) {
Expand All @@ -687,7 +687,7 @@ export class CallingRepository {
return CONV_TYPE.ONEONONE;
}

if (isMLSConversation(conversation)) {
if (isGroupMLSConversation(conversation)) {
return CONV_TYPE.CONFERENCE_MLS;
}
return this.supportsConferenceCalling ? CONV_TYPE.CONFERENCE : CONV_TYPE.GROUP;
Expand Down Expand Up @@ -747,7 +747,7 @@ export class CallingRepository {
this.removeCall(call);
}

if (isMLSConversation(conversation)) {
if (isGroupMLSConversation(conversation)) {
await this.joinMlsConferenceSubconversation(conversation);
}

Expand Down Expand Up @@ -855,7 +855,7 @@ export class CallingRepository {

const conversation = this.getConversationById(call.conversationId);

if (!conversation || !isMLSConversation(conversation)) {
if (!conversation || !isGroupMLSConversation(conversation)) {
return;
}

Expand Down Expand Up @@ -890,7 +890,7 @@ export class CallingRepository {

private readonly updateConferenceSubconversationEpoch = async (conversationId: QualifiedId) => {
const conversation = this.getConversationById(conversationId);
if (!conversation || !isMLSConversation(conversation)) {
if (!conversation || !isGroupMLSConversation(conversation)) {
return;
}

Expand All @@ -909,7 +909,7 @@ export class CallingRepository {

private readonly handleCallParticipantChange = (conversationId: QualifiedId, members: QualifiedWcallMember[]) => {
const conversation = this.getConversationById(conversationId);
if (!conversation || !isMLSConversation(conversation)) {
if (!conversation || !isGroupMLSConversation(conversation)) {
return;
}

Expand Down Expand Up @@ -1211,12 +1211,12 @@ export class CallingRepository {
const content = typeof payload === 'string' ? payload : JSON.stringify(payload);

/**
* @note If myClientsOnly option is true, the message should be sent via the self-conversation.
* @note If myClientsOnly option is true, the message should be sent via the mls self-conversation.
* This message is used to tell your other clients you have answered or
* rejected a call and to stop ringing.
*/
if (typeof payload === 'string' && isMLSConversation(conversation) && myClientsOnly) {
return void this.messageRepository.sendSelfCallingMessage(payload, conversation.qualifiedId);
return void this.messageRepository.sendCallingMessageToSelfMLSConversation(payload, conversation.qualifiedId);
}

const message = await this.messageRepository.sendCallingMessage(conversation, content, options);
Expand Down
4 changes: 4 additions & 0 deletions src/script/conversation/ConversationSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export function isMLSCapableConversation(conversation: Conversation): conversati
return isMixedConversation(conversation) || isMLSConversation(conversation);
}

export function isGroupMLSConversation(conversation: Conversation): conversation is MLSConversation {
return isMLSConversation(conversation) && conversation.isGroup();
}

export function isSelfConversation(conversation: Conversation): boolean {
return conversation.type() === CONVERSATION_TYPE.SELF;
}
Expand Down
4 changes: 2 additions & 2 deletions src/script/conversation/MessageRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1356,11 +1356,11 @@ export class MessageRepository {
}

/**
* Sends a call message only to self conversation (eg. REJECT message that warn the user's other clients that the call has been picked up)
* Sends a call message only to self MLS conversation (eg. REJECT message that warn the user's other clients that the call has been picked up)
* @param payload
* @returns
*/
public sendSelfCallingMessage(payload: string, targetConversation: QualifiedId) {
public sendCallingMessageToSelfMLSConversation(payload: string, targetConversation: QualifiedId) {
return this.sendCallingMessage(this.conversationState.getSelfMLSConversation(), {
content: payload,
qualifiedConversationId: targetConversation,
Expand Down

0 comments on commit f4daa27

Please sign in to comment.