@azure/communication-react
Version:
React library for building modern communication user experiences utilizing Azure Communication Services
87 lines • 5.76 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { toFlatCommunicationIdentifier } from "../../acs-ui-common/src";
import { convertSdkRemoteStreamToDeclarativeRemoteStream } from './Converter';
import { RemoteVideoStreamSubscriber } from './RemoteVideoStreamSubscriber';
import { disposeView } from './StreamUtils';
/**
* Keeps track of the listeners assigned to a particular participant because when we get an event from SDK, it doesn't
* tell us which participant it is for. If we keep track of this then we know which participant in the state that needs
* an update and also which property of that participant. Also we can use this when unregistering to a participant.
*/
export class ParticipantSubscriber {
constructor(callIdRef, participant, context, internalContext) {
this.subscribe = () => {
this._participant.on('stateChanged', this.stateChanged);
this._participant.on('isMutedChanged', this.isMutedChanged);
this._participant.on('displayNameChanged', this.displayNameChanged);
this._participant.on('isSpeakingChanged', this.isSpeakingChanged);
this._participant.on('videoStreamsUpdated', this.videoStreamsUpdated);
this._participant.on('roleChanged', this.roleChanged);
if (this._participant.videoStreams.length > 0) {
for (const stream of this._participant.videoStreams) {
this._internalContext.setRemoteRenderInfo(this._callIdRef.callId, this._participantKey, stream.id, stream, 'NotRendered', undefined);
this.addRemoteVideoStreamSubscriber(stream);
}
this._context.setRemoteVideoStreams(this._callIdRef.callId, this._participantKey, this._participant.videoStreams.map(convertSdkRemoteStreamToDeclarativeRemoteStream), []);
}
};
this.unsubscribe = () => {
this._participant.off('stateChanged', this.stateChanged);
this._participant.off('isMutedChanged', this.isMutedChanged);
this._participant.off('displayNameChanged', this.displayNameChanged);
this._participant.off('isSpeakingChanged', this.isSpeakingChanged);
this._participant.off('videoStreamsUpdated', this.videoStreamsUpdated);
this._participant.off('roleChanged', this.roleChanged);
// If unsubscribing it means the participant left the call. If they have any rendering streams we should stop them
// as it doesn't make sense to render for an ended participant.
if (this._participant.videoStreams.length > 0) {
for (const stream of this._participant.videoStreams) {
disposeView(this._context, this._internalContext, this._callIdRef.callId, this._participantKey, convertSdkRemoteStreamToDeclarativeRemoteStream(stream));
this._internalContext.deleteRemoteRenderInfo(this._callIdRef.callId, this._participantKey, stream.id);
}
}
};
this.addRemoteVideoStreamSubscriber = (remoteVideoStream) => {
var _a;
(_a = this._remoteVideoStreamSubscribers.get(remoteVideoStream.id)) === null || _a === void 0 ? void 0 : _a.unsubscribe();
this._remoteVideoStreamSubscribers.set(remoteVideoStream.id, new RemoteVideoStreamSubscriber(this._callIdRef, this._participantKey, remoteVideoStream, this._context));
};
this.stateChanged = () => {
this._context.setParticipantState(this._callIdRef.callId, this._participantKey, this._participant.state);
};
this.isMutedChanged = () => {
this._context.setParticipantIsMuted(this._callIdRef.callId, this._participantKey, this._participant.isMuted);
};
this.roleChanged = () => {
this._context.setParticipantRole(this._callIdRef.callId, this._participantKey, this._participant.role);
};
this.displayNameChanged = () => {
this._context.setParticipantDisplayName(this._callIdRef.callId, this._participantKey, this._participant.displayName || '');
};
this.isSpeakingChanged = () => {
this._context.setParticipantIsSpeaking(this._callIdRef.callId, this._participantKey, this._participant.isSpeaking);
};
this.videoStreamsUpdated = (event) => {
var _a;
for (const stream of event.removed) {
(_a = this._remoteVideoStreamSubscribers.get(stream.id)) === null || _a === void 0 ? void 0 : _a.unsubscribe();
disposeView(this._context, this._internalContext, this._callIdRef.callId, this._participantKey, convertSdkRemoteStreamToDeclarativeRemoteStream(stream));
this._internalContext.deleteRemoteRenderInfo(this._callIdRef.callId, this._participantKey, stream.id);
}
for (const stream of event.added) {
this._internalContext.setRemoteRenderInfo(this._callIdRef.callId, this._participantKey, stream.id, stream, 'NotRendered', undefined);
this.addRemoteVideoStreamSubscriber(stream);
}
this._context.setRemoteVideoStreams(this._callIdRef.callId, this._participantKey, event.added.map(convertSdkRemoteStreamToDeclarativeRemoteStream), event.removed.map((stream) => stream.id));
};
this._callIdRef = callIdRef;
this._participant = participant;
this._context = context;
this._internalContext = internalContext;
this._participantKey = toFlatCommunicationIdentifier(this._participant.identifier);
this._remoteVideoStreamSubscribers = new Map();
this.subscribe();
}
}
//# sourceMappingURL=ParticipantSubscriber.js.map