communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
141 lines • 9.63 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { getDeviceManager, getDiagnostics, getLatestErrors, getEnvironmentInfo } from './baseSelectors';
import { createSelector } from 'reselect';
import { DiagnosticQuality } from '@azure/communication-calling';
/**
* Select the first 3 active errors from the state for the `ErrorBar` component.
*
* In case there are many errors, only the first three errors are returned to avoid
* filling up the UI with too many errors.
*
* Invariants:
* - `ErrorType` is never repeated in the returned errors.
* - Errors are returned in a fixed order by `ErrorType`.
*
* @public
*/
export const errorBarSelector = createSelector([getLatestErrors, getDiagnostics, getDeviceManager, getEnvironmentInfo], (latestErrors, diagnostics, deviceManager, environmentInfo) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
// The order in which the errors are returned is significant: The `ErrorBar` shows errors on the UI in that order.
// There are several options for the ordering:
// - Sorted by when the errors happened (latest first / oldest first).
// - Stable sort by error type.
//
// We chose to stable sort by error type: We intend to show only a small number of errors on the UI and we do not
// have timestamps for errors.
const activeErrorMessages = [];
const isSafari = () => {
return (environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.environment.browser) === 'safari';
};
const isMacOS = () => {
return (environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.environment.platform) === 'mac';
};
if (((_a = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.network.latest.networkReceiveQuality) === null || _a === void 0 ? void 0 : _a.value) === DiagnosticQuality.Bad ||
((_b = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.network.latest.networkReceiveQuality) === null || _b === void 0 ? void 0 : _b.value) === DiagnosticQuality.Poor) {
activeErrorMessages.push({ type: 'callNetworkQualityLow' });
}
if (((_c = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.noSpeakerDevicesEnumerated) === null || _c === void 0 ? void 0 : _c.value) === true) {
activeErrorMessages.push({ type: 'callNoSpeakerFound' });
}
if (((_d = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.noMicrophoneDevicesEnumerated) === null || _d === void 0 ? void 0 : _d.value) === true) {
activeErrorMessages.push({ type: 'callNoMicrophoneFound' });
}
if (((_e = deviceManager.deviceAccess) === null || _e === void 0 ? void 0 : _e.audio) === false && isSafari()) {
activeErrorMessages.push({ type: 'callMicrophoneAccessDeniedSafari' });
}
if (((_f = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.microphonePermissionDenied) === null || _f === void 0 ? void 0 : _f.value) === true && isMacOS()) {
activeErrorMessages.push({ type: 'callMacOsMicrophoneAccessDenied' });
}
else if ((((_g = deviceManager.deviceAccess) === null || _g === void 0 ? void 0 : _g.audio) === false && !isSafari()) ||
(((_h = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.microphonePermissionDenied) === null || _h === void 0 ? void 0 : _h.value) === true && !isMacOS())) {
activeErrorMessages.push({ type: 'callMicrophoneAccessDenied' });
}
const microphoneMuteUnexpectedlyDiagnostic = (diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.microphoneMuteUnexpectedly) || (diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.microphoneNotFunctioning);
if (microphoneMuteUnexpectedlyDiagnostic) {
if (microphoneMuteUnexpectedlyDiagnostic.value === DiagnosticQuality.Bad) {
// Inform the user that microphone stopped working and inform them to start microphone again
activeErrorMessages.push({ type: 'callMicrophoneMutedBySystem' });
}
else if (microphoneMuteUnexpectedlyDiagnostic.value === DiagnosticQuality.Good) {
// Inform the user that microphone recovered
activeErrorMessages.push({ type: 'callMicrophoneUnmutedBySystem' });
}
}
const cameraStoppedUnexpectedlyDiagnostic = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.cameraStoppedUnexpectedly;
if (cameraStoppedUnexpectedlyDiagnostic) {
if (cameraStoppedUnexpectedlyDiagnostic.value === DiagnosticQuality.Bad) {
// Inform the user that camera stopped working and inform them to start video again
activeErrorMessages.push({ type: 'callVideoStoppedBySystem' });
}
else if (cameraStoppedUnexpectedlyDiagnostic.value === DiagnosticQuality.Good) {
// Inform the user that camera recovered
activeErrorMessages.push({ type: 'callVideoRecoveredBySystem' });
}
}
if (((_j = deviceManager.deviceAccess) === null || _j === void 0 ? void 0 : _j.video) === false && isSafari()) {
activeErrorMessages.push({ type: 'callCameraAccessDeniedSafari' });
}
else if (((_k = deviceManager.deviceAccess) === null || _k === void 0 ? void 0 : _k.video) === false) {
activeErrorMessages.push({ type: 'callCameraAccessDenied' });
}
else {
if (((_l = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.cameraFreeze) === null || _l === void 0 ? void 0 : _l.value) === true) {
activeErrorMessages.push({ type: 'cameraFrozenForRemoteParticipants' });
}
}
/**
* show the Mac specific strings if the platform is detected as mac
*/
if (((_m = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.cameraPermissionDenied) === null || _m === void 0 ? void 0 : _m.value) === true && isMacOS()) {
activeErrorMessages.push({ type: 'callMacOsCameraAccessDenied' });
}
/**
* This UFD only works on mac still so we should only see it fire on mac.
*/
if (((_o = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.screenshareRecordingDisabled) === null || _o === void 0 ? void 0 : _o.value) === true && isMacOS()) {
activeErrorMessages.push({ type: 'callMacOsScreenShareAccessDenied' });
}
else if (((_p = diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.media.latest.screenshareRecordingDisabled) === null || _p === void 0 ? void 0 : _p.value) === true) {
activeErrorMessages.push({ type: 'startScreenShareGeneric' });
}
// Prefer to show errors with privacy implications.
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.stopVideo', 'stopVideoGeneric');
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.mute', 'muteGeneric');
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.stopScreenSharing', 'stopScreenShareGeneric');
if (((_q = latestErrors['Call.startVideo']) === null || _q === void 0 ? void 0 : _q.message) === 'Call.startVideo: Video operation failure SourceUnavailableError') {
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.startVideo', 'callCameraAlreadyInUse');
}
else if (((_r = latestErrors['Call.startVideo']) === null || _r === void 0 ? void 0 : _r.message) === 'Call.startVideo: Video operation failure permissionDeniedError') {
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.startVideo', 'callCameraAccessDenied');
}
else {
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.startVideo', 'startVideoGeneric');
}
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.unmute', 'unmuteGeneric');
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.mutedByOthers', 'mutedByRemoteParticipant');
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'VideoEffectsFeature.startEffects', 'unableToStartVideoEffect');
if (((_s = latestErrors['CallAgent.join']) === null || _s === void 0 ? void 0 : _s.message) === 'CallAgent.join: Invalid meeting link') {
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'CallAgent.join', 'failedToJoinCallInvalidMeetingLink');
}
else {
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'CallAgent.join', 'failedToJoinCallGeneric');
}
if ((_t = latestErrors['Call.feature']) === null || _t === void 0 ? void 0 : _t.message.match(/Call\.feature: startSpotlight failed\. \d+ is the max number of participants that can be Spotlighted/g)) {
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.feature', 'startSpotlightWhileMaxParticipantsAreSpotlighted');
}
// We only return the first few errors to avoid filling up the UI with too many `MessageBar`s.
activeErrorMessages.splice(maxErrorCount);
return { activeErrorMessages: activeErrorMessages };
});
const appendActiveErrorIfDefined = (activeErrorMessages, latestErrors, target, activeErrorType) => {
if (latestErrors[target] === undefined) {
return;
}
activeErrorMessages.push({
type: activeErrorType,
timestamp: latestErrors[target].timestamp
});
};
const maxErrorCount = 3;
//# sourceMappingURL=errorBarSelector.js.map