Skip to content

Commit 6c95dc3

Browse files
author
Aidan Zimmermann
committed
STREAM-777: resolve merge conflict again
2 parents f7765cf + b1ecb68 commit 6c95dc3

7 files changed

Lines changed: 69 additions & 8 deletions

File tree

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
55

66
# [Unreleased](https://github.com/MyPureCloud/genesys-cloud-webrtc-sdk/compare/v11.3.3...HEAD)
77

8+
### Fixed
9+
* [STREAM-978](https://inindca.atlassian.net/browse/STREAM-978) - When the RTCPeerConnection is in a 'failed' state, clean up the session. Filter out voicemail participants from conversation update events. Fix potential TypeError when fetching conversations.
10+
* [STREAM-987](https://inindca.atlassian.net/browse/STREAM-987) - Demo app: Memoize conversations so they don't change every render when nothing has changed
11+
812
# [v11.3.3](https://github.com/MyPureCloud/genesys-cloud-webrtc-sdk/compare/v11.3.2...v11.3.3)
913
#### Changed
1014
* [#937] - Exposes raw webmessage data from conversation topic

react-demo-app/src/components/ActiveConversationsTable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect } from 'react';
1+
import { useState, useEffect, useMemo } from 'react';
22
import useSdk from '../hooks/useSdk';
33
import './ActiveConversationsTable.css';
44
import { GuxButton, GuxTable, GuxRadialLoading } from 'genesys-spark-components-react';
@@ -12,7 +12,7 @@ export default function ActiveConversationsTable() {
1212
const conversationsObj = useSelector(
1313
(state: RootState) => state.conversations.activeConversations
1414
);
15-
const conversations = Object.values(conversationsObj);
15+
const conversations = useMemo(() => Object.values(conversationsObj), [conversationsObj]);
1616
const { endSession, toggleAudioMute, toggleHoldState } = useSdk();
1717
const [holdLabels, setHoldLabels ] = useState<Array<string | JSX.Element>>([]);
1818
const [muteLabels, setMuteLabels ] = useState<Array<string | JSX.Element>>([]);

src/sessions/base-session-handler.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ export default abstract class BaseSessionHandler {
114114
if (state === 'interrupted') {
115115
this.sdk.emit('sessionInterrupted', { sessionId: session.id, sessionType: session.sessionType, conversationId: session.conversationId });
116116
}
117+
118+
/* If the RTCPeerConnection is in a 'failed' state, it is a state of finality and we need to clean up the session. */
119+
if (state === 'failed') {
120+
this.log('warn', 'RTCPeerConnection failed. Cleaning up session.', { state, conversationId: session.conversationId, sid: session.id, sessionType: session.sessionType });
121+
this.forceEndSession(session, Constants.JingleReasonCondition.FailedTransport);
122+
}
117123
});
118124

119125
session.on('terminated', this.onSessionTerminated.bind(this, session));

src/sessions/softphone-session-handler.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export class SoftphoneSessionHandler extends BaseSessionHandler {
185185
getActiveConversations (): IActiveConversationDescription[] {
186186
const currentConversations = this.lastEmittedSdkConversationEvent?.current || [];
187187

188-
return currentConversations.map(currentConvo => ({ conversationId: currentConvo.conversationId, sessionId: currentConvo.session.id, sessionType: this.sessionType }));
188+
return currentConversations.map(currentConvo => ({ conversationId: currentConvo.conversationId, sessionId: currentConvo.session?.id, sessionType: this.sessionType }));
189189
}
190190

191191
handleSoftphoneConversationUpdate (update: ConversationUpdate, participant: IConversationParticipantFromEvent, callState: ICallStateFromParticipant, session?: IExtendedMediaSession): void {
@@ -500,7 +500,8 @@ export class SoftphoneSessionHandler extends BaseSessionHandler {
500500
return;
501501
}
502502

503-
const participantsForUser = update.participants.filter(p => p.userId === this.sdk._personDetails.id).reverse();
503+
// Filter out voicemail participants - user ID can appear multiple times with different purposes.
504+
const participantsForUser = update.participants.filter((p) => p.userId === this.sdk._personDetails.id && p.purpose !== 'voicemail').reverse();
504505
let participant: IConversationParticipantFromEvent;
505506

506507
if (!participantsForUser.length) {

test/unit/client.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,7 @@ import {
2929
IStation,
3030
IPersonDetails,
3131
ISessionIdAndConversationId,
32-
<<<<<<< HEAD
3332
VideoSessionHandler, ScreenRecordingMetadata, IStartScreenConferenceSessionParams
34-
=======
35-
VideoSessionHandler
36-
>>>>>>> 3d567e61595d3f56241eb475ca863cd3f2204ec0
3733
} from '../../src';
3834
import * as utils from '../../src/utils';
3935
import { RetryPromise } from 'genesys-cloud-streaming-client/dist/es/utils';

test/unit/sessions/base-session-handler.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,27 @@ describe('handleSessionInit', () => {
542542
expect(eventSpy).toHaveBeenCalled();
543543
});
544544

545+
it('should terminate session when connectionState becomes failed', async () => {
546+
const session: any = new MockSession();
547+
const forceEndSessionSpy = jest.spyOn(handler, 'forceEndSession');
548+
const logSpy = jest.spyOn(handler, 'log' as any);
549+
550+
session.id = '123abc';
551+
session.conversationId = 'convoabc';
552+
session.state = 'active';
553+
554+
await handler.handleSessionInit(session);
555+
session.emit('connectionState', 'failed');
556+
557+
expect(logSpy).toHaveBeenCalledWith('warn', 'RTCPeerConnection failed. Cleaning up session.', {
558+
state: 'failed',
559+
conversationId: session.conversationId,
560+
sid: session.id,
561+
sessionType: session.sessionType
562+
});
563+
expect(forceEndSessionSpy).toHaveBeenCalledWith(session, 'failed-transport');
564+
});
565+
545566
it('should set conversationId and fromUserId on existing pendingSession and emit sessionStarted', async () => {
546567
const session: any = new MockSession();
547568
session.conversationId = null;

test/unit/sessions/softphone-session-handler.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,6 +1888,39 @@ describe('getUserParticipantFromConversationEvent()', () => {
18881888
it('should return the most recent participant if there are no calls on any of them', () => {
18891889
expect(handler.getUserParticipantFromConversationEvent(converversationUpdate)).toEqual(participant2);
18901890
});
1891+
1892+
it('should filter out voicemail participants and only return non-voicemail participants', () => {
1893+
const userParticipant: IConversationParticipantFromEvent = {
1894+
id: '3a843139-760b-41d8-8ac1-723ac2381280',
1895+
purpose: 'user',
1896+
userId,
1897+
videos: [],
1898+
calls: [{ ...call, state: CommunicationStates.connected }]
1899+
};
1900+
1901+
const voicemailParticipant: IConversationParticipantFromEvent = {
1902+
id: '3a843140-760b-41d8-8ac1-723ac2381290',
1903+
purpose: 'voicemail',
1904+
userId,
1905+
videos: [],
1906+
calls: []
1907+
};
1908+
1909+
const externalParticipant: IConversationParticipantFromEvent = {
1910+
id: 'dcec146d-52f2-4593-874d-d13f1bc3183d',
1911+
purpose: 'external',
1912+
userId: '1234',
1913+
videos: [],
1914+
calls: [{ ...call, state: CommunicationStates.connected }]
1915+
};
1916+
1917+
converversationUpdate.participants = [externalParticipant, userParticipant, voicemailParticipant];
1918+
1919+
const result = handler.getUserParticipantFromConversationEvent(converversationUpdate);
1920+
expect(result).toEqual(userParticipant);
1921+
expect(result?.purpose).toBe('user');
1922+
expect(result?.id).toBe('3a843139-760b-41d8-8ac1-723ac2381280');
1923+
});
18911924
});
18921925

18931926
describe('getCallStateFromParticipant()', () => {

0 commit comments

Comments
 (0)