@@ -112,6 +112,8 @@ import { busyWait } from '../../common/utils';
112112
113113type CallWithChatAdapterStateChangedHandler = ( newState : CallWithChatAdapterState ) => void ;
114114
115+ type Listener = ( ...args : unknown [ ] ) => void ;
116+
115117/**
116118 * For each time that we use the hook {@link useSelector} in the {@link CallWithChatComposite} we add another listener
117119 * to the `stateChanged` event on the this adapter. This number is set in relation to the number of
@@ -181,6 +183,27 @@ export class AzureCommunicationCallWithChatAdapter implements CallWithChatAdapte
181183 private originCallChatAdapter : ChatAdapter | undefined ;
182184 private breakoutRoomChatAdapter : ChatAdapter | undefined ;
183185
186+ // This map is used to store the listeners subscribed to chat events so that we can re-subscribe them
187+ // to the new chat adapter when the thread id changes
188+ private chatEventListeners : Map < string , Set < Listener > > = new Map ( ) ;
189+
190+ // This function is used to store a listener to the internal map of chat event listeners and should be
191+ // used when a listener subscribes to a chat event
192+ private storeChatEventListener ( event : string , listener : Listener ) : void {
193+ if ( ! this . chatEventListeners . has ( event ) ) {
194+ this . chatEventListeners . set ( event , new Set ( ) ) ;
195+ }
196+ this . chatEventListeners . get ( event ) ?. add ( listener ) ;
197+ }
198+
199+ // This function is used to remove a listener from the internal map of chat event listeners and should
200+ // be used when a listener unsubscribes from a chat event
201+ private removeChatEventListener ( event : string , listener : Listener ) : void {
202+ if ( this . chatEventListeners . has ( event ) ) {
203+ this . chatEventListeners . get ( event ) ?. delete ( listener ) ;
204+ }
205+ }
206+
184207 constructor ( callAdapter : CallAdapter , chatAdapter ?: ChatAdapter ) {
185208 this . bindPublicMethods ( ) ;
186209 this . callAdapter = callAdapter ;
@@ -315,12 +338,24 @@ export class AzureCommunicationCallWithChatAdapter implements CallWithChatAdapte
315338
316339 private updateChatAdapter ( chatAdapter : ChatAdapter ) : void {
317340 this . chatAdapter ?. offStateChange ( this . onChatStateChange ) ;
341+ this . updateChatEventListeners ( chatAdapter ) ;
318342 this . chatAdapter = chatAdapter ;
319343 this . chatAdapter . onStateChange ( this . onChatStateChange ) ;
320344 this . context . updateClientStateWithChatState ( chatAdapter . getState ( ) ) ;
321345 this . emitter . emit ( 'chatInitialized' , this . chatAdapter ) ;
322346 }
323347
348+ private updateChatEventListeners ( chatAdapter : ChatAdapter ) : void {
349+ for ( const [ eventName , listeners ] of this . chatEventListeners ) {
350+ for ( const listener of listeners ) {
351+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
352+ this . chatAdapter ?. off ( eventName as any , listener ) ;
353+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
354+ chatAdapter . on ( eventName as any , listener ) ;
355+ }
356+ }
357+ }
358+
324359 private bindPublicMethods ( ) : void {
325360 this . joinCall . bind ( this ) ;
326361 this . leaveCall . bind ( this ) ;
@@ -439,6 +474,8 @@ export class AzureCommunicationCallWithChatAdapter implements CallWithChatAdapte
439474 }
440475 this . callAdapter . offStateChange ( this . onCallStateChange ) ;
441476 this . callAdapter . dispose ( ) ;
477+ // Clear chat event listeners
478+ this . chatEventListeners . clear ( ) ;
442479 }
443480 /** Remove a participant from the Call only. */
444481 public async removeParticipant ( userId : string | CommunicationIdentifier ) : Promise < void > {
@@ -848,36 +885,43 @@ export class AzureCommunicationCallWithChatAdapter implements CallWithChatAdapte
848885 this . callAdapter . on ( 'isSpokenLanguageChanged' , listener ) ;
849886 break ;
850887 case 'messageReceived' :
888+ this . storeChatEventListener ( 'messageReceived' , listener ) ;
851889 this . executeWithResolvedChatAdapter ( ( adapter ) => {
852890 adapter . on ( 'messageReceived' , listener ) ;
853891 } ) ;
854892 break ;
855893 case 'messageEdited' :
894+ this . storeChatEventListener ( 'messageEdited' , listener ) ;
856895 this . executeWithResolvedChatAdapter ( ( adapter ) => {
857896 adapter . on ( 'messageEdited' , listener ) ;
858897 } ) ;
859898 break ;
860899 case 'messageDeleted' :
900+ this . storeChatEventListener ( 'messageDeleted' , listener ) ;
861901 this . executeWithResolvedChatAdapter ( ( adapter ) => {
862902 adapter . on ( 'messageDeleted' , listener ) ;
863903 } ) ;
864904 break ;
865905 case 'messageSent' :
906+ this . storeChatEventListener ( 'messageSent' , listener ) ;
866907 this . executeWithResolvedChatAdapter ( ( adapter ) => {
867908 adapter . on ( 'messageSent' , listener ) ;
868909 } ) ;
869910 break ;
870911 case 'messageRead' :
912+ this . storeChatEventListener ( 'messageRead' , listener ) ;
871913 this . executeWithResolvedChatAdapter ( ( adapter ) => {
872914 adapter . on ( 'messageRead' , listener ) ;
873915 } ) ;
874916 break ;
875917 case 'chatParticipantsAdded' :
918+ this . storeChatEventListener ( 'chatParticipantsAdded' , listener ) ;
876919 this . executeWithResolvedChatAdapter ( ( adapter ) => {
877920 adapter . on ( 'participantsAdded' , listener ) ;
878921 } ) ;
879922 break ;
880923 case 'chatParticipantsRemoved' :
924+ this . storeChatEventListener ( 'chatParticipantsRemoved' , listener ) ;
881925 this . executeWithResolvedChatAdapter ( ( adapter ) => {
882926 adapter . on ( 'participantsRemoved' , listener ) ;
883927 } ) ;
@@ -886,6 +930,7 @@ export class AzureCommunicationCallWithChatAdapter implements CallWithChatAdapte
886930 this . callAdapter . on ( 'error' , listener ) ;
887931 break ;
888932 case 'chatError' :
933+ this . storeChatEventListener ( 'chatError' , listener ) ;
889934 this . executeWithResolvedChatAdapter ( ( adapter ) => {
890935 adapter . on ( 'error' , listener ) ;
891936 } ) ;
@@ -986,36 +1031,43 @@ export class AzureCommunicationCallWithChatAdapter implements CallWithChatAdapte
9861031 this . callAdapter . off ( 'isSpokenLanguageChanged' , listener ) ;
9871032 break ;
9881033 case 'messageReceived' :
1034+ this . removeChatEventListener ( 'messageReceived' , listener ) ;
9891035 this . executeWithResolvedChatAdapter ( ( adapter ) => {
9901036 adapter . off ( 'messageReceived' , listener ) ;
9911037 } ) ;
9921038 break ;
9931039 case 'messageEdited' :
1040+ this . removeChatEventListener ( 'messageEdited' , listener ) ;
9941041 this . executeWithResolvedChatAdapter ( ( adapter ) => {
9951042 adapter . off ( 'messageEdited' , listener ) ;
9961043 } ) ;
9971044 break ;
9981045 case 'messageDeleted' :
1046+ this . removeChatEventListener ( 'messageDeleted' , listener ) ;
9991047 this . executeWithResolvedChatAdapter ( ( adapter ) => {
10001048 adapter . off ( 'messageDeleted' , listener ) ;
10011049 } ) ;
10021050 break ;
10031051 case 'messageSent' :
1052+ this . removeChatEventListener ( 'messageSent' , listener ) ;
10041053 this . executeWithResolvedChatAdapter ( ( adapter ) => {
10051054 adapter . off ( 'messageSent' , listener ) ;
10061055 } ) ;
10071056 break ;
10081057 case 'messageRead' :
1058+ this . removeChatEventListener ( 'messageRead' , listener ) ;
10091059 this . executeWithResolvedChatAdapter ( ( adapter ) => {
10101060 adapter . off ( 'messageRead' , listener ) ;
10111061 } ) ;
10121062 break ;
10131063 case 'chatParticipantsAdded' :
1064+ this . removeChatEventListener ( 'chatParticipantsAdded' , listener ) ;
10141065 this . executeWithResolvedChatAdapter ( ( adapter ) => {
10151066 adapter . off ( 'participantsAdded' , listener ) ;
10161067 } ) ;
10171068 break ;
10181069 case 'chatParticipantsRemoved' :
1070+ this . removeChatEventListener ( 'chatParticipantsRemoved' , listener ) ;
10191071 this . executeWithResolvedChatAdapter ( ( adapter ) => {
10201072 adapter . off ( 'participantsRemoved' , listener ) ;
10211073 } ) ;
@@ -1024,6 +1076,7 @@ export class AzureCommunicationCallWithChatAdapter implements CallWithChatAdapte
10241076 this . callAdapter . off ( 'error' , listener ) ;
10251077 break ;
10261078 case 'chatError' :
1079+ this . removeChatEventListener ( 'chatError' , listener ) ;
10271080 this . executeWithResolvedChatAdapter ( ( adapter ) => {
10281081 adapter . off ( 'error' , listener ) ;
10291082 } ) ;
0 commit comments