communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
154 lines • 9.55 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { memoizeFnAll, toFlatCommunicationIdentifier } from "../../../acs-ui-common/src";
import memoizeOne from 'memoize-one';
import { _convertParticipantState } from './callUtils';
import { maskDisplayNameWithRole } from './callUtils';
import { checkIsSpeaking } from './SelectorUtils';
import { isPhoneNumberIdentifier } from '@azure/communication-common';
import { memoizedConvertToVideoTileReaction } from './participantListSelectorUtils';
/** @internal */
export const _dominantSpeakersWithFlatId = (dominantSpeakers) => {
var _a;
return (_a = dominantSpeakers === null || dominantSpeakers === void 0 ? void 0 : dominantSpeakers.speakersList) === null || _a === void 0 ? void 0 : _a.map(toFlatCommunicationIdentifier);
};
/** @internal */
export const _videoGalleryRemoteParticipantsMemo = (remoteParticipants, isHideAttendeeNamesEnabled, localUserRole) => {
if (!remoteParticipants) {
return [];
}
return memoizedAllConvertRemoteParticipant((memoizedFn) => {
return (Object.values(remoteParticipants)
/**
* hiding participants who are inLobby, idle, or connecting in ACS clients till we can admit users through ACS clients.
* phone users will be in the connecting state until they are connected to the call.
*/
.filter((participant) => {
return (!['InLobby', 'Idle', 'Connecting', 'Disconnected'].includes(participant.state) ||
isPhoneNumberIdentifier(participant.identifier));
})
.map((participant) => {
var _a, _b, _c, _d, _e, _f;
const state = _convertParticipantState(participant);
const displayName = maskDisplayNameWithRole(participant.displayName, localUserRole, participant.role, isHideAttendeeNamesEnabled);
const remoteParticipantReaction = memoizedConvertToVideoTileReaction(participant.reactionState);
const spotlight = participant.spotlight;
return memoizedFn(toFlatCommunicationIdentifier(participant.identifier), participant.isMuted, checkIsSpeaking(participant), participant.videoStreams, state, displayName, participant.raisedHand, participant.contentSharingStream, remoteParticipantReaction, spotlight, participant.mediaAccess, participant.role,
/* @conditional-compile-remove(remote-ufd) */
Math.max(((_c = (_b = (_a = participant.diagnostics) === null || _a === void 0 ? void 0 : _a.networkReceiveQuality) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 0), ((_f = (_e = (_d = participant.diagnostics) === null || _d === void 0 ? void 0 : _d.networkSendQuality) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : 0)));
}));
});
};
const memoizedAllConvertRemoteParticipant = memoizeFnAll((userId, isMuted, isSpeaking, videoStreams, state, displayName, raisedHand, contentSharingStream, reaction, spotlight, mediaAccess, role, signalStrength) => {
return convertRemoteParticipantToVideoGalleryRemoteParticipant(userId, isMuted, isSpeaking, videoStreams, state, displayName, raisedHand, contentSharingStream, reaction, spotlight, signalStrength, mediaAccess, role);
});
/** @private */
export const convertRemoteParticipantToVideoGalleryRemoteParticipant = (userId, isMuted, isSpeaking, videoStreams, state, displayName, raisedHand, contentSharingStream, reaction, spotlight, signalStrength, mediaAccess, role) => {
const rawVideoStreamsArray = Object.values(videoStreams);
let videoStream = undefined;
let screenShareStream = undefined;
/**
* There is a bug from the calling sdk where if a user leaves and rejoins immediately
* it adds 2 more potential streams this remote participant can use. The old 2 streams
* still show as available and that is how we got a frozen stream in this case. The stopgap
* until streams accurately reflect their availability is to always prioritize the latest streams of a certain type
* e.g findLast instead of find
*/
const sdkRemoteVideoStream = Object.values(rawVideoStreamsArray).findLast((i) => i.mediaStreamType === 'Video' && i.isAvailable) ||
Object.values(rawVideoStreamsArray).findLast((i) => i.mediaStreamType === 'Video');
const sdkScreenShareStream = Object.values(rawVideoStreamsArray).findLast((i) => i.mediaStreamType === 'ScreenSharing' && i.isAvailable) ||
Object.values(rawVideoStreamsArray).findLast((i) => i.mediaStreamType === 'ScreenSharing');
if (sdkRemoteVideoStream) {
videoStream = convertRemoteVideoStreamToVideoGalleryStream(sdkRemoteVideoStream);
}
if (sdkScreenShareStream) {
screenShareStream = convertRemoteVideoStreamToVideoGalleryStream(sdkScreenShareStream);
}
if (contentSharingStream) {
screenShareStream = convertRemoteContentSharingStreamToVideoGalleryStream(contentSharingStream);
}
return {
userId,
displayName,
isMuted,
isSpeaking,
videoStream,
screenShareStream,
isScreenSharingOn: screenShareStream !== undefined && screenShareStream.isAvailable,
state,
raisedHand,
reaction,
spotlight,
mediaAccess,
canAudioBeForbidden: role === 'Attendee',
canVideoBeForbidden: role === 'Attendee',
/* @conditional-compile-remove(remote-ufd) */
signalStrength
};
};
const convertRemoteVideoStreamToVideoGalleryStream = (stream) => {
var _a, _b, _c;
return {
id: stream.id,
isAvailable: stream.isAvailable,
isReceiving: stream.isReceiving,
isMirrored: (_a = stream.view) === null || _a === void 0 ? void 0 : _a.isMirrored,
renderElement: (_b = stream.view) === null || _b === void 0 ? void 0 : _b.target,
scalingMode: (_c = stream.view) === null || _c === void 0 ? void 0 : _c.scalingMode,
streamSize: stream.streamSize
};
};
const convertRemoteContentSharingStreamToVideoGalleryStream = (stream) => {
return {
isAvailable: !!stream,
isReceiving: true,
isMirrored: false,
renderElement: stream
};
};
/** @private */
export const memoizeLocalParticipant = memoizeOne((identifier, displayName, isMuted, isScreenSharingOn, localVideoStream, localScreenSharingStream, role, raisedHand, reaction, localSpotlight, capabilities) => {
var _a, _b, _c;
return ({
userId: identifier,
displayName: displayName !== null && displayName !== void 0 ? displayName : '',
isMuted: isMuted,
isScreenSharingOn: isScreenSharingOn,
videoStream: {
isAvailable: !!localVideoStream,
isMirrored: (_a = localVideoStream === null || localVideoStream === void 0 ? void 0 : localVideoStream.view) === null || _a === void 0 ? void 0 : _a.isMirrored,
renderElement: (_b = localVideoStream === null || localVideoStream === void 0 ? void 0 : localVideoStream.view) === null || _b === void 0 ? void 0 : _b.target
},
screenShareStream: {
isAvailable: !!localScreenSharingStream,
renderElement: (_c = localScreenSharingStream === null || localScreenSharingStream === void 0 ? void 0 : localScreenSharingStream.view) === null || _c === void 0 ? void 0 : _c.target
},
role,
raisedHand: raisedHand,
reaction,
spotlight: localSpotlight,
capabilities,
mediaAccess: {
isAudioPermitted: (capabilities === null || capabilities === void 0 ? void 0 : capabilities.unmuteMic) ? capabilities.unmuteMic.isPresent : true,
isVideoPermitted: (capabilities === null || capabilities === void 0 ? void 0 : capabilities.turnVideoOn) ? capabilities.turnVideoOn.isPresent : true
}
});
});
/** @private */
export const memoizeSpotlightedParticipantIds = memoizeOne((spotlightedParticipants) => spotlightedParticipants === null || spotlightedParticipants === void 0 ? void 0 : spotlightedParticipants.map((p) => toFlatCommunicationIdentifier(p.identifier)));
/** @private */
export const memoizeTogetherModeStreams = memoizeOne((togetherModeStreams) => {
var _a, _b, _c, _d, _e, _f;
return ({
mainVideoStream: {
id: (_a = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _a === void 0 ? void 0 : _a.id,
isReceiving: (_b = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _b === void 0 ? void 0 : _b.isReceiving,
isAvailable: (_c = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _c === void 0 ? void 0 : _c.isAvailable,
renderElement: (_e = (_d = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _d === void 0 ? void 0 : _d.view) === null || _e === void 0 ? void 0 : _e.target,
streamSize: (_f = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _f === void 0 ? void 0 : _f.streamSize
}
});
});
/** @private */
export const memoizeTogetherModeSeatingPositions = memoizeOne((togetherModeSeatingCoordinates) => togetherModeSeatingCoordinates);
//# sourceMappingURL=videoGalleryUtils.js.map