@azure/communication-react 1.28.0-beta.1 → 1.28.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/communication-react.d.ts +4 -0
  2. package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-DRUaZRvX.js → ChatMessageComponentAsRichTextEditBox-DQsJ0ty3.js} +2 -2
  3. package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-DRUaZRvX.js.map → ChatMessageComponentAsRichTextEditBox-DQsJ0ty3.js.map} +1 -1
  4. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-G0IPk_nq.js → RichTextSendBoxWrapper-K8NQvjwe.js} +2 -2
  5. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-G0IPk_nq.js.map → RichTextSendBoxWrapper-K8NQvjwe.js.map} +1 -1
  6. package/dist/dist-cjs/communication-react/{index-DYS7KDhY.js → index-C-rok69c.js} +98 -25
  7. package/dist/dist-cjs/communication-react/index-C-rok69c.js.map +1 -0
  8. package/dist/dist-cjs/communication-react/index.js +1 -1
  9. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  10. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  11. package/dist/dist-esm/calling-component-bindings/src/captionsSelector.js +2 -1
  12. package/dist/dist-esm/calling-component-bindings/src/captionsSelector.js.map +1 -1
  13. package/dist/dist-esm/calling-stateful-client/src/DeviceManagerDeclarative.js +5 -2
  14. package/dist/dist-esm/calling-stateful-client/src/DeviceManagerDeclarative.js.map +1 -1
  15. package/dist/dist-esm/react-components/src/components/CaptionsBanner.d.ts +4 -0
  16. package/dist/dist-esm/react-components/src/components/CaptionsBanner.js +36 -1
  17. package/dist/dist-esm/react-components/src/components/CaptionsBanner.js.map +1 -1
  18. package/dist/dist-esm/react-components/src/components/styles/Captions.style.d.ts +4 -0
  19. package/dist/dist-esm/react-components/src/components/styles/Captions.style.js +13 -0
  20. package/dist/dist-esm/react-components/src/components/styles/Captions.style.js.map +1 -1
  21. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/ConfigurationPage.js +12 -10
  22. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/ConfigurationPage.js.map +1 -1
  23. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.d.ts +1 -1
  24. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js +27 -8
  25. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js.map +1 -1
  26. package/package.json +1 -1
  27. package/dist/dist-cjs/communication-react/index-DYS7KDhY.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DYS7KDhY.js');
3
+ var index = require('./index-C-rok69c.js');
4
4
  require('react');
5
5
  require('@fluentui/react');
6
6
  require('@fluentui/react-components');
@@ -2,5 +2,5 @@
2
2
  // Copyright (c) Microsoft Corporation.
3
3
  // Licensed under the MIT License.
4
4
  // GENERATED FILE. DO NOT EDIT MANUALLY.
5
- module.exports = '1.28.0-beta.1';
5
+ module.exports = '1.28.0-beta.2';
6
6
  //# sourceMappingURL=telemetryVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../preprocess-dist/acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n// GENERATED FILE. DO NOT EDIT MANUALLY.\n\nmodule.exports = '1.28.0-beta.1';\n"]}
1
+ {"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../preprocess-dist/acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n// GENERATED FILE. DO NOT EDIT MANUALLY.\n\nmodule.exports = '1.28.0-beta.2';\n"]}
@@ -54,7 +54,8 @@ export const captionsBannerSelector = reselect.createSelector([getCaptions, getR
54
54
  displayName: finalDisplayName !== null && finalDisplayName !== void 0 ? finalDisplayName : 'Unnamed Participant',
55
55
  captionText: c.captionText,
56
56
  userId,
57
- createdTimeStamp: c.timestamp
57
+ createdTimeStamp: c.timestamp,
58
+ isFinalized: c.resultType === 'Final'
58
59
  };
59
60
  });
60
61
  const completedRealTimeTexts = (_a = realTimeTexts === null || realTimeTexts === void 0 ? void 0 : realTimeTexts.completedMessages) === null || _a === void 0 ? void 0 : _a.filter(rtt => rtt.message !== '').map(rtt => {
@@ -1 +1 @@
1
- {"version":3,"file":"captionsSelector.js","sourceRoot":"","sources":["../../../../preprocess-dist/calling-component-bindings/src/captionsSelector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { CallClientState, CaptionsInfo } from '@internal/calling-stateful-client';\nimport { RealTimeTextInfo, RemoteParticipantState } from '@internal/calling-stateful-client';\nimport { CallingBaseSelectorProps, getDisplayName, getIdentifier, getStartCaptionsInProgress, getSupportedCaptionLanguages } from './baseSelectors';\nimport { allRemoteParticipantsSelector } from './remoteParticipantsSelector';\nimport { getRealTimeTextStatus, getRealTimeText } from './baseSelectors';\nimport { getCaptions, getCaptionsStatus, getCurrentCaptionLanguage, getCurrentSpokenLanguage, getSupportedSpokenLanguages } from './baseSelectors';\nimport * as reselect from 'reselect';\nimport { toFlatCommunicationIdentifier } from '@internal/acs-ui-common';\nimport { CaptionsInformation, SupportedCaptionLanguage, SupportedSpokenLanguage } from '@internal/react-components';\nimport { RealTimeTextInformation } from '@internal/react-components';\nimport { getRemoteParticipantDisplayName } from './utils/callUtils';\n\n/**\n * Selector type for the {@link StartCaptionsButton} component.\n * @public\n */\nexport type StartCaptionsButtonSelector = (state: CallClientState, props: CallingBaseSelectorProps) => {\n checked: boolean;\n currentCaptionLanguage: string;\n currentSpokenLanguage: string;\n};\n\n/**\n * Selector for {@link StartCaptionsButton} component.\n *\n * @public\n */\nexport const startCaptionsButtonSelector: StartCaptionsButtonSelector = reselect.createSelector([getCaptionsStatus, getCurrentCaptionLanguage, getCurrentSpokenLanguage], (isCaptionsFeatureActive, currentCaptionLanguage, currentSpokenLanguage) => {\n return {\n checked: isCaptionsFeatureActive ?? false,\n currentCaptionLanguage: currentCaptionLanguage ?? '',\n currentSpokenLanguage: currentSpokenLanguage ?? 'en-us'\n };\n});\n\n/**\n * Selector type for components for Changing caption language and spoken language\n * @public\n */\nexport type CaptionSettingsSelector = (state: CallClientState, props: CallingBaseSelectorProps) => {\n supportedCaptionLanguages: SupportedCaptionLanguage[];\n currentCaptionLanguage: SupportedCaptionLanguage;\n supportedSpokenLanguages: SupportedSpokenLanguage[];\n currentSpokenLanguage: SupportedSpokenLanguage;\n isCaptionsFeatureActive: boolean;\n};\n\n/**\n * Selector for Changing caption language and spoken language\n *\n * @public\n */\nexport const captionSettingsSelector: CaptionSettingsSelector = reselect.createSelector([getSupportedCaptionLanguages, getCurrentCaptionLanguage, getSupportedSpokenLanguages, getCurrentSpokenLanguage, getCaptionsStatus], (supportedCaptionLanguages, currentCaptionLanguage, supportedSpokenLanguages, currentSpokenLanguage, isCaptionsFeatureActive) => {\n return {\n supportedCaptionLanguages: supportedCaptionLanguages ?? [],\n currentCaptionLanguage: currentCaptionLanguage ?? 'en',\n supportedSpokenLanguages: supportedSpokenLanguages ?? ['en-us'],\n currentSpokenLanguage: currentSpokenLanguage ?? 'en-us',\n isCaptionsFeatureActive: isCaptionsFeatureActive ?? false\n };\n});\n/**\n * Selector type for the {@link CaptionsBanner} component.\n * @public\n */\nexport type CaptionsBannerSelector = (state: CallClientState, props: CallingBaseSelectorProps) => {\n captions: CaptionsInformation[];\n realTimeTexts: {\n completedMessages?: RealTimeTextInformation[];\n currentInProgress?: RealTimeTextInformation[];\n myInProgress?: RealTimeTextInformation;\n };\n isCaptionsOn: boolean;\n startCaptionsInProgress: boolean;\n isRealTimeTextOn: boolean;\n latestLocalRealTimeText: RealTimeTextInformation;\n};\n\n/**\n * Selector for {@link CaptionsBanner} component.\n *\n * @public\n */\nexport const captionsBannerSelector: CaptionsBannerSelector = reselect.createSelector([getCaptions, getRealTimeText, getCaptionsStatus, getRealTimeTextStatus, getStartCaptionsInProgress, allRemoteParticipantsSelector, getDisplayName, getIdentifier], (captions, realTimeTexts, isCaptionsFeatureActive, isRealTimeTextActive, startCaptionsInProgress, allRemoteParticipants, displayName, identifier) => {\n const captionsInfo = captions?.map((c, index) => {\n const userId = getCaptionsSpeakerIdentifier(c);\n let finalDisplayName;\n if (userId === identifier) {\n finalDisplayName = displayName;\n } else {\n finalDisplayName = getRemoteParticipantDisplayName(userId, allRemoteParticipants);\n }\n return {\n id: (finalDisplayName ?? 'Unnamed Participant') + index,\n displayName: finalDisplayName ?? 'Unnamed Participant',\n captionText: c.captionText,\n userId,\n createdTimeStamp: c.timestamp\n };\n });\n const completedRealTimeTexts = realTimeTexts?.completedMessages?.filter(rtt => rtt.message !== '').map(rtt => {\n const userId = getRealTimeTextSpeakerIdentifier(rtt);\n return {\n id: rtt.sequenceId,\n displayName: getRealTimeTextDisplayName(rtt, identifier, allRemoteParticipants, displayName, userId),\n message: rtt.message,\n userId,\n isTyping: rtt.resultType === 'Partial',\n isMe: rtt.isMe,\n finalizedTimeStamp: rtt.updatedTimestamp\n };\n });\n const inProgressRealTimeTexts = realTimeTexts?.currentInProgress?.filter(rtt => rtt.message !== '').map(rtt => {\n const userId = getRealTimeTextSpeakerIdentifier(rtt);\n return {\n id: rtt.sequenceId,\n displayName: getRealTimeTextDisplayName(rtt, identifier, allRemoteParticipants, displayName, userId),\n message: rtt.message,\n userId,\n isTyping: rtt.resultType === 'Partial',\n isMe: rtt.isMe,\n finalizedTimeStamp: rtt.updatedTimestamp\n };\n });\n const myInProgress = realTimeTexts?.myInProgress && realTimeTexts.myInProgress.message !== '' ? {\n id: realTimeTexts.myInProgress.sequenceId,\n displayName: displayName,\n message: realTimeTexts.myInProgress.message,\n userId: identifier,\n isTyping: realTimeTexts.myInProgress.resultType === 'Partial',\n isMe: true,\n finalizedTimeStamp: realTimeTexts.myInProgress.updatedTimestamp\n } : undefined;\n\n // find the last final local real time text caption if myInProgress is not available\n let latestLocalRealTimeText;\n if (!myInProgress) {\n latestLocalRealTimeText = realTimeTexts && realTimeTexts.completedMessages && realTimeTexts.completedMessages.slice().reverse().find(rtt => rtt.isMe);\n }\n return {\n captions: captionsInfo ?? [],\n realTimeTexts: {\n completedMessages: completedRealTimeTexts as RealTimeTextInformation[],\n currentInProgress: inProgressRealTimeTexts as RealTimeTextInformation[],\n myInProgress: myInProgress as RealTimeTextInformation\n },\n isCaptionsOn: isCaptionsFeatureActive ?? false,\n startCaptionsInProgress: startCaptionsInProgress ?? false,\n isRealTimeTextOn: isRealTimeTextActive ?? false,\n latestLocalRealTimeText: (myInProgress ?? latestLocalRealTimeText) as RealTimeTextInformation\n };\n});\nconst getCaptionsSpeakerIdentifier = (captions: CaptionsInfo): string => {\n return captions.speaker.identifier ? toFlatCommunicationIdentifier(captions.speaker.identifier) : '';\n};\nconst getRealTimeTextSpeakerIdentifier = (realTimeText: RealTimeTextInfo): string => {\n return realTimeText.sender.identifier ? toFlatCommunicationIdentifier(realTimeText.sender.identifier) : '';\n};\nconst getRealTimeTextDisplayName = (realTimeText: RealTimeTextInfo, identifier: string, allRemoteParticipants: {\n [keys: string]: RemoteParticipantState;\n} | undefined, displayName: string | undefined, userId: string): string => {\n let finalDisplayName;\n if (userId === identifier) {\n finalDisplayName = displayName;\n } else {\n finalDisplayName = getRemoteParticipantDisplayName(userId, allRemoteParticipants);\n }\n return finalDisplayName ?? 'Unnamed Participant';\n};"]}
1
+ {"version":3,"file":"captionsSelector.js","sourceRoot":"","sources":["../../../../preprocess-dist/calling-component-bindings/src/captionsSelector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { CallClientState, CaptionsInfo } from '@internal/calling-stateful-client';\nimport { RealTimeTextInfo, RemoteParticipantState } from '@internal/calling-stateful-client';\nimport { CallingBaseSelectorProps, getDisplayName, getIdentifier, getStartCaptionsInProgress, getSupportedCaptionLanguages } from './baseSelectors';\nimport { allRemoteParticipantsSelector } from './remoteParticipantsSelector';\nimport { getRealTimeTextStatus, getRealTimeText } from './baseSelectors';\nimport { getCaptions, getCaptionsStatus, getCurrentCaptionLanguage, getCurrentSpokenLanguage, getSupportedSpokenLanguages } from './baseSelectors';\nimport * as reselect from 'reselect';\nimport { toFlatCommunicationIdentifier } from '@internal/acs-ui-common';\nimport { CaptionsInformation, SupportedCaptionLanguage, SupportedSpokenLanguage } from '@internal/react-components';\nimport { RealTimeTextInformation } from '@internal/react-components';\nimport { getRemoteParticipantDisplayName } from './utils/callUtils';\n\n/**\n * Selector type for the {@link StartCaptionsButton} component.\n * @public\n */\nexport type StartCaptionsButtonSelector = (state: CallClientState, props: CallingBaseSelectorProps) => {\n checked: boolean;\n currentCaptionLanguage: string;\n currentSpokenLanguage: string;\n};\n\n/**\n * Selector for {@link StartCaptionsButton} component.\n *\n * @public\n */\nexport const startCaptionsButtonSelector: StartCaptionsButtonSelector = reselect.createSelector([getCaptionsStatus, getCurrentCaptionLanguage, getCurrentSpokenLanguage], (isCaptionsFeatureActive, currentCaptionLanguage, currentSpokenLanguage) => {\n return {\n checked: isCaptionsFeatureActive ?? false,\n currentCaptionLanguage: currentCaptionLanguage ?? '',\n currentSpokenLanguage: currentSpokenLanguage ?? 'en-us'\n };\n});\n\n/**\n * Selector type for components for Changing caption language and spoken language\n * @public\n */\nexport type CaptionSettingsSelector = (state: CallClientState, props: CallingBaseSelectorProps) => {\n supportedCaptionLanguages: SupportedCaptionLanguage[];\n currentCaptionLanguage: SupportedCaptionLanguage;\n supportedSpokenLanguages: SupportedSpokenLanguage[];\n currentSpokenLanguage: SupportedSpokenLanguage;\n isCaptionsFeatureActive: boolean;\n};\n\n/**\n * Selector for Changing caption language and spoken language\n *\n * @public\n */\nexport const captionSettingsSelector: CaptionSettingsSelector = reselect.createSelector([getSupportedCaptionLanguages, getCurrentCaptionLanguage, getSupportedSpokenLanguages, getCurrentSpokenLanguage, getCaptionsStatus], (supportedCaptionLanguages, currentCaptionLanguage, supportedSpokenLanguages, currentSpokenLanguage, isCaptionsFeatureActive) => {\n return {\n supportedCaptionLanguages: supportedCaptionLanguages ?? [],\n currentCaptionLanguage: currentCaptionLanguage ?? 'en',\n supportedSpokenLanguages: supportedSpokenLanguages ?? ['en-us'],\n currentSpokenLanguage: currentSpokenLanguage ?? 'en-us',\n isCaptionsFeatureActive: isCaptionsFeatureActive ?? false\n };\n});\n/**\n * Selector type for the {@link CaptionsBanner} component.\n * @public\n */\nexport type CaptionsBannerSelector = (state: CallClientState, props: CallingBaseSelectorProps) => {\n captions: CaptionsInformation[];\n realTimeTexts: {\n completedMessages?: RealTimeTextInformation[];\n currentInProgress?: RealTimeTextInformation[];\n myInProgress?: RealTimeTextInformation;\n };\n isCaptionsOn: boolean;\n startCaptionsInProgress: boolean;\n isRealTimeTextOn: boolean;\n latestLocalRealTimeText: RealTimeTextInformation;\n};\n\n/**\n * Selector for {@link CaptionsBanner} component.\n *\n * @public\n */\nexport const captionsBannerSelector: CaptionsBannerSelector = reselect.createSelector([getCaptions, getRealTimeText, getCaptionsStatus, getRealTimeTextStatus, getStartCaptionsInProgress, allRemoteParticipantsSelector, getDisplayName, getIdentifier], (captions, realTimeTexts, isCaptionsFeatureActive, isRealTimeTextActive, startCaptionsInProgress, allRemoteParticipants, displayName, identifier) => {\n const captionsInfo = captions?.map((c, index) => {\n const userId = getCaptionsSpeakerIdentifier(c);\n let finalDisplayName;\n if (userId === identifier) {\n finalDisplayName = displayName;\n } else {\n finalDisplayName = getRemoteParticipantDisplayName(userId, allRemoteParticipants);\n }\n return {\n id: (finalDisplayName ?? 'Unnamed Participant') + index,\n displayName: finalDisplayName ?? 'Unnamed Participant',\n captionText: c.captionText,\n userId,\n createdTimeStamp: c.timestamp,\n isFinalized: c.resultType === 'Final'\n };\n });\n const completedRealTimeTexts = realTimeTexts?.completedMessages?.filter(rtt => rtt.message !== '').map(rtt => {\n const userId = getRealTimeTextSpeakerIdentifier(rtt);\n return {\n id: rtt.sequenceId,\n displayName: getRealTimeTextDisplayName(rtt, identifier, allRemoteParticipants, displayName, userId),\n message: rtt.message,\n userId,\n isTyping: rtt.resultType === 'Partial',\n isMe: rtt.isMe,\n finalizedTimeStamp: rtt.updatedTimestamp\n };\n });\n const inProgressRealTimeTexts = realTimeTexts?.currentInProgress?.filter(rtt => rtt.message !== '').map(rtt => {\n const userId = getRealTimeTextSpeakerIdentifier(rtt);\n return {\n id: rtt.sequenceId,\n displayName: getRealTimeTextDisplayName(rtt, identifier, allRemoteParticipants, displayName, userId),\n message: rtt.message,\n userId,\n isTyping: rtt.resultType === 'Partial',\n isMe: rtt.isMe,\n finalizedTimeStamp: rtt.updatedTimestamp\n };\n });\n const myInProgress = realTimeTexts?.myInProgress && realTimeTexts.myInProgress.message !== '' ? {\n id: realTimeTexts.myInProgress.sequenceId,\n displayName: displayName,\n message: realTimeTexts.myInProgress.message,\n userId: identifier,\n isTyping: realTimeTexts.myInProgress.resultType === 'Partial',\n isMe: true,\n finalizedTimeStamp: realTimeTexts.myInProgress.updatedTimestamp\n } : undefined;\n\n // find the last final local real time text caption if myInProgress is not available\n let latestLocalRealTimeText;\n if (!myInProgress) {\n latestLocalRealTimeText = realTimeTexts && realTimeTexts.completedMessages && realTimeTexts.completedMessages.slice().reverse().find(rtt => rtt.isMe);\n }\n return {\n captions: captionsInfo ?? [],\n realTimeTexts: {\n completedMessages: completedRealTimeTexts as RealTimeTextInformation[],\n currentInProgress: inProgressRealTimeTexts as RealTimeTextInformation[],\n myInProgress: myInProgress as RealTimeTextInformation\n },\n isCaptionsOn: isCaptionsFeatureActive ?? false,\n startCaptionsInProgress: startCaptionsInProgress ?? false,\n isRealTimeTextOn: isRealTimeTextActive ?? false,\n latestLocalRealTimeText: (myInProgress ?? latestLocalRealTimeText) as RealTimeTextInformation\n };\n});\nconst getCaptionsSpeakerIdentifier = (captions: CaptionsInfo): string => {\n return captions.speaker.identifier ? toFlatCommunicationIdentifier(captions.speaker.identifier) : '';\n};\nconst getRealTimeTextSpeakerIdentifier = (realTimeText: RealTimeTextInfo): string => {\n return realTimeText.sender.identifier ? toFlatCommunicationIdentifier(realTimeText.sender.identifier) : '';\n};\nconst getRealTimeTextDisplayName = (realTimeText: RealTimeTextInfo, identifier: string, allRemoteParticipants: {\n [keys: string]: RemoteParticipantState;\n} | undefined, displayName: string | undefined, userId: string): string => {\n let finalDisplayName;\n if (userId === identifier) {\n finalDisplayName = displayName;\n } else {\n finalDisplayName = getRemoteParticipantDisplayName(userId, allRemoteParticipants);\n }\n return finalDisplayName ?? 'Unnamed Participant';\n};"]}
@@ -134,8 +134,11 @@ class ProxyDeviceManager {
134
134
  }), navigator.permissions.query({
135
135
  name: 'microphone'
136
136
  })]);
137
- hasCameraPermission = cameraPermissions.state === 'granted';
138
- hasMicPermission = micPermissions.state === 'granted';
137
+ // Use logical OR to combine the SDK state with the Permissions API state.
138
+ // This way we can get a more accurate picture of the device permission state.
139
+ // If the SDK state is 'granted', we don't need to check the Permissions API state.
140
+ hasCameraPermission || (hasCameraPermission = cameraPermissions.state === 'granted');
141
+ hasMicPermission || (hasMicPermission = micPermissions.state === 'granted');
139
142
  }
140
143
  catch (e) {
141
144
  console.info('Permissions API is not supported by browser', e);
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceManagerDeclarative.js","sourceRoot":"","sources":["../../../../preprocess-dist/calling-stateful-client/src/DeviceManagerDeclarative.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AudioDeviceInfo, DeviceAccess, DeviceManager, VideoDeviceInfo } from '@azure/communication-calling';\nimport { CallContext } from './CallContext';\nimport { InternalCallContext } from './InternalCallContext';\nimport { LocalVideoStream } from '@azure/communication-calling';\n\n/**\n * Defines the additional methods added by the stateful on top of {@link @azure/communication-calling#DeviceManager}.\n *\n * @public\n */\nexport interface StatefulDeviceManager extends DeviceManager {\n /**\n * Sets the selectedCamera in the {@link DeviceManagerState}. This is completely developer driven and is not tied in\n * any way to {@link @azure/communication-calling#DeviceManager}. It is entirely contained in\n * {@link StatefulDeviceManager}. See also {@link DeviceManagerState.selectedCamera}.\n */\n selectCamera: (device: VideoDeviceInfo) => void;\n\n /**\n * Gets the list of unparented video streams. This is a list of video streams that have not been added to a\n * {@link @azure/communication-calling#Call}. This is useful for developers who want to interact with rendered\n * video streams before they have started a call. See also {@link @azure/communication-react#CallClient.createView}.\n *\n * @public\n */\n getUnparentedVideoStreams: () => LocalVideoStream[];\n}\n\n/**\n * ProxyDeviceManager proxies DeviceManager and subscribes to all events that affect device manager state. State updates\n * are set on the provided context. Also any queries for state are proxied and stored in state as well. Only one device\n * manager should exist for a given CallClient so if CallClient.getDeviceManager is called multiple times, either a\n * cached ProxyDeviceManager should be returned or the existing ProxyDeviceManager should be destructed via destructor()\n * and a new ProxyDeviceManager created.\n */\nclass ProxyDeviceManager implements ProxyHandler<DeviceManager> {\n private _deviceManager: DeviceManager;\n private _context: CallContext;\n constructor(deviceManager: DeviceManager, context: CallContext) {\n this._deviceManager = deviceManager;\n this._context = context;\n this.setDeviceManager();\n this.subscribe();\n }\n private setDeviceManager = (): void => {\n // isSpeakerSelectionAvailable, selectedMicrophone, and selectedSpeaker are properties on DeviceManager. Since they\n // are not functions we can't proxy them so we'll update whenever we think they may need updating such as at\n // construction time or when certain events happen.\n this._context.setDeviceManagerIsSpeakerSelectionAvailable(this._deviceManager.isSpeakerSelectionAvailable);\n this._context.setDeviceManagerSelectedMicrophone(this._deviceManager.selectedMicrophone);\n this._context.setDeviceManagerSelectedSpeaker(this._deviceManager.selectedSpeaker);\n };\n private subscribe = (): void => {\n this._deviceManager.on('videoDevicesUpdated', this.videoDevicesUpdated);\n this._deviceManager.on('audioDevicesUpdated', this.audioDevicesUpdated);\n this._deviceManager.on('selectedMicrophoneChanged', this.selectedMicrophoneChanged);\n this._deviceManager.on('selectedSpeakerChanged', this.selectedSpeakerChanged);\n\n // Subscribe to browser camera permissions changes\n if (navigator.permissions) {\n try {\n navigator.permissions.query({\n name: 'camera' as PermissionName\n }).then((cameraPermissions): void => {\n cameraPermissions.addEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not subscribe to Permissions API Camera changed events, API is not supported by browser', e);\n }\n\n // Subscribe to browser microphone permissions changes\n try {\n navigator.permissions.query({\n name: 'microphone' as PermissionName\n }).then((micPermissions): void => {\n micPermissions.addEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not subscribe to Permissions API Microphone changed events, API is not supported by browser', e);\n }\n }\n };\n\n /**\n * This is used to unsubscribe DeclarativeDeviceManager from the DeviceManager events.\n */\n public unsubscribe = (): void => {\n this._deviceManager.off('videoDevicesUpdated', this.videoDevicesUpdated);\n this._deviceManager.off('audioDevicesUpdated', this.audioDevicesUpdated);\n this._deviceManager.off('selectedMicrophoneChanged', this.selectedMicrophoneChanged);\n this._deviceManager.off('selectedSpeakerChanged', this.selectedSpeakerChanged);\n if (navigator.permissions) {\n // Unsubscribe from browser camera permissions changes\n try {\n navigator.permissions.query({\n name: 'camera' as PermissionName\n }).then((cameraPermissions): void => {\n cameraPermissions.removeEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not Unsubscribe to Permissions API Camera changed events, API is not supported by browser', e);\n }\n\n // Unsubscribe from browser microphone permissions changes\n try {\n navigator.permissions.query({\n name: 'microphone' as PermissionName\n }).then((micPermissions): void => {\n micPermissions.removeEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not Unsubscribe to Permissions API Camera changed events, API is not supported by browser', e);\n }\n }\n };\n private permissionsApiStateChangeHandler = async (): Promise<void> => {\n await this.updateDevicePermissionState();\n };\n\n /**\n * Used to set a camera inside the proxy device manager.\n *\n * @param videoDeviceInfo VideoDeviceInfo\n */\n public selectCamera = (videoDeviceInfo: VideoDeviceInfo): void => {\n this._context.setDeviceManagerSelectedCamera(videoDeviceInfo);\n };\n private videoDevicesUpdated = async (): Promise<void> => {\n // Device Manager always has a camera with '' name if there are no real camera devices available.\n // We don't want to show that in the UI.\n const realCameras = (await this._deviceManager.getCameras()).filter(c => !!c.name);\n this._context.setDeviceManagerCameras(dedupeById(realCameras));\n };\n private audioDevicesUpdated = async (): Promise<void> => {\n this._context.setDeviceManagerMicrophones(dedupeById(await this._deviceManager.getMicrophones()));\n if (this._deviceManager.isSpeakerSelectionAvailable) {\n this._context.setDeviceManagerSpeakers(dedupeById(await this._deviceManager.getSpeakers()));\n }\n };\n private selectedMicrophoneChanged = (): void => {\n this._context.setDeviceManagerSelectedMicrophone(this._deviceManager.selectedMicrophone);\n };\n private selectedSpeakerChanged = (): void => {\n this._context.setDeviceManagerSelectedSpeaker(this._deviceManager.selectedSpeaker);\n };\n private updateDevicePermissionState = async (sdkDeviceAccessState?: DeviceAccess): Promise<void> => {\n let hasCameraPermission = !!sdkDeviceAccessState?.video;\n let hasMicPermission = !!sdkDeviceAccessState?.audio;\n\n // Supplement the SDK values with values from the Permissions API to get a better understanding of the device\n // permission state. The SDK only uses the getUserMedia API to determine the device permission state. However,\n // this returns false if the camera is in use by another application. The Permissions API can provide more\n // information about the device permission state, but is not supported yet in Firefox or Android WebView.\n // Note: It also has the limitation where it cannot detect if the device is blocked by the Operating System\n // permissions.\n if (navigator.permissions) {\n try {\n const [cameraPermissions, micPermissions] = await Promise.all([navigator.permissions.query({\n name: 'camera' as PermissionName\n }), navigator.permissions.query({\n name: 'microphone' as PermissionName\n })]);\n hasCameraPermission = cameraPermissions.state === 'granted';\n hasMicPermission = micPermissions.state === 'granted';\n } catch (e) {\n console.info('Permissions API is not supported by browser', e);\n }\n }\n this._context.setDeviceManagerDeviceAccess({\n video: hasCameraPermission,\n audio: hasMicPermission\n });\n this.setDeviceManager();\n };\n public get<P extends keyof DeviceManager>(target: DeviceManager, prop: P): any {\n switch (prop) {\n case 'getCameras':\n {\n return this._context.withAsyncErrorTeedToState((): Promise<VideoDeviceInfo[]> => {\n return target.getCameras().then((cameras: VideoDeviceInfo[]) => {\n // Device Manager always has a camera with '' name if there are no real camera devices available.\n // We don't want to show that in the UI.\n const realCameras = cameras.filter(c => !!c.name);\n this._context.setDeviceManagerCameras(dedupeById(realCameras));\n return realCameras;\n });\n }, 'DeviceManager.getCameras');\n }\n case 'getMicrophones':\n {\n return this._context.withAsyncErrorTeedToState((): Promise<AudioDeviceInfo[]> => {\n return target.getMicrophones().then((microphones: AudioDeviceInfo[]) => {\n this._context.setDeviceManagerMicrophones(dedupeById(microphones));\n return microphones;\n });\n }, 'DeviceManager.getMicrophones');\n }\n case 'getSpeakers':\n {\n return this._context.withAsyncErrorTeedToState((): Promise<AudioDeviceInfo[]> => {\n return target.getSpeakers().then((speakers: AudioDeviceInfo[]) => {\n this._context.setDeviceManagerSpeakers(dedupeById(speakers));\n return speakers;\n });\n }, 'DeviceManager.getSpeakers');\n }\n case 'selectMicrophone':\n {\n return this._context.withAsyncErrorTeedToState((...args: Parameters<DeviceManager['selectMicrophone']>): Promise<void> => {\n return target.selectMicrophone(...args).then(() => {\n this._context.setDeviceManagerSelectedMicrophone(target.selectedMicrophone);\n });\n }, 'DeviceManager.selectMicrophone');\n }\n case 'selectSpeaker':\n {\n return this._context.withAsyncErrorTeedToState((...args: Parameters<DeviceManager['selectSpeaker']>): Promise<void> => {\n return target.selectSpeaker(...args).then(() => {\n this._context.setDeviceManagerSelectedSpeaker(target.selectedSpeaker);\n });\n }, 'DeviceManager.selectSpeaker');\n }\n case 'askDevicePermission':\n {\n return this._context.withAsyncErrorTeedToState((...args: Parameters<DeviceManager['askDevicePermission']>): Promise<DeviceAccess> => {\n return target.askDevicePermission(...args).then(async (deviceAccess: DeviceAccess) => {\n await this.updateDevicePermissionState(deviceAccess);\n return deviceAccess;\n });\n }, 'DeviceManager.askDevicePermission');\n }\n default:\n return Reflect.get(target, prop);\n }\n }\n}\n\n// TODO: Remove this when SDK no longer returns duplicate audio and video devices\n/** Helper function to dedupe duplicate audio and video devices obtained from SDK */\nconst dedupeById = <T extends {\n id: string;\n},>(devices: T[]): T[] => {\n const ids = new Set();\n const uniqueDevices: T[] = [];\n devices.forEach((device: T) => {\n if (!ids.has(device.id)) {\n uniqueDevices.push(device);\n ids.add(device.id);\n }\n });\n return uniqueDevices;\n};\n\n/**\n * Creates a declarative DeviceManager by proxying DeviceManager with ProxyDeviceManager. The declarative DeviceManager\n * will put state updates in the given context.\n *\n * @param deviceManager - DeviceManager from SDK\n * @param context - CallContext from StatefulCallClient\n *\n * @private\n */\nexport const deviceManagerDeclaratify = (deviceManager: DeviceManager, context: CallContext, internalContext: InternalCallContext): DeviceManager => {\n const proxyDeviceManager = new ProxyDeviceManager(deviceManager, context);\n Object.defineProperty(deviceManager, 'unsubscribe', {\n configurable: false,\n value: () => proxyDeviceManager.unsubscribe()\n });\n Object.defineProperty(deviceManager, 'selectCamera', {\n configurable: false,\n value: (videoDeviceInfo: VideoDeviceInfo) => proxyDeviceManager.selectCamera(videoDeviceInfo)\n });\n Object.defineProperty(deviceManager, 'getUnparentedVideoStreams', {\n configurable: false,\n value: (): LocalVideoStream[] => internalContext.getUnparentedRenderInfos()\n });\n return new Proxy(deviceManager, proxyDeviceManager) as StatefulDeviceManager;\n};"]}
1
+ {"version":3,"file":"DeviceManagerDeclarative.js","sourceRoot":"","sources":["../../../../preprocess-dist/calling-stateful-client/src/DeviceManagerDeclarative.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AudioDeviceInfo, DeviceAccess, DeviceManager, VideoDeviceInfo } from '@azure/communication-calling';\nimport { CallContext } from './CallContext';\nimport { InternalCallContext } from './InternalCallContext';\nimport { LocalVideoStream } from '@azure/communication-calling';\n\n/**\n * Defines the additional methods added by the stateful on top of {@link @azure/communication-calling#DeviceManager}.\n *\n * @public\n */\nexport interface StatefulDeviceManager extends DeviceManager {\n /**\n * Sets the selectedCamera in the {@link DeviceManagerState}. This is completely developer driven and is not tied in\n * any way to {@link @azure/communication-calling#DeviceManager}. It is entirely contained in\n * {@link StatefulDeviceManager}. See also {@link DeviceManagerState.selectedCamera}.\n */\n selectCamera: (device: VideoDeviceInfo) => void;\n\n /**\n * Gets the list of unparented video streams. This is a list of video streams that have not been added to a\n * {@link @azure/communication-calling#Call}. This is useful for developers who want to interact with rendered\n * video streams before they have started a call. See also {@link @azure/communication-react#CallClient.createView}.\n *\n * @public\n */\n getUnparentedVideoStreams: () => LocalVideoStream[];\n}\n\n/**\n * ProxyDeviceManager proxies DeviceManager and subscribes to all events that affect device manager state. State updates\n * are set on the provided context. Also any queries for state are proxied and stored in state as well. Only one device\n * manager should exist for a given CallClient so if CallClient.getDeviceManager is called multiple times, either a\n * cached ProxyDeviceManager should be returned or the existing ProxyDeviceManager should be destructed via destructor()\n * and a new ProxyDeviceManager created.\n */\nclass ProxyDeviceManager implements ProxyHandler<DeviceManager> {\n private _deviceManager: DeviceManager;\n private _context: CallContext;\n constructor(deviceManager: DeviceManager, context: CallContext) {\n this._deviceManager = deviceManager;\n this._context = context;\n this.setDeviceManager();\n this.subscribe();\n }\n private setDeviceManager = (): void => {\n // isSpeakerSelectionAvailable, selectedMicrophone, and selectedSpeaker are properties on DeviceManager. Since they\n // are not functions we can't proxy them so we'll update whenever we think they may need updating such as at\n // construction time or when certain events happen.\n this._context.setDeviceManagerIsSpeakerSelectionAvailable(this._deviceManager.isSpeakerSelectionAvailable);\n this._context.setDeviceManagerSelectedMicrophone(this._deviceManager.selectedMicrophone);\n this._context.setDeviceManagerSelectedSpeaker(this._deviceManager.selectedSpeaker);\n };\n private subscribe = (): void => {\n this._deviceManager.on('videoDevicesUpdated', this.videoDevicesUpdated);\n this._deviceManager.on('audioDevicesUpdated', this.audioDevicesUpdated);\n this._deviceManager.on('selectedMicrophoneChanged', this.selectedMicrophoneChanged);\n this._deviceManager.on('selectedSpeakerChanged', this.selectedSpeakerChanged);\n\n // Subscribe to browser camera permissions changes\n if (navigator.permissions) {\n try {\n navigator.permissions.query({\n name: 'camera' as PermissionName\n }).then((cameraPermissions): void => {\n cameraPermissions.addEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not subscribe to Permissions API Camera changed events, API is not supported by browser', e);\n }\n\n // Subscribe to browser microphone permissions changes\n try {\n navigator.permissions.query({\n name: 'microphone' as PermissionName\n }).then((micPermissions): void => {\n micPermissions.addEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not subscribe to Permissions API Microphone changed events, API is not supported by browser', e);\n }\n }\n };\n\n /**\n * This is used to unsubscribe DeclarativeDeviceManager from the DeviceManager events.\n */\n public unsubscribe = (): void => {\n this._deviceManager.off('videoDevicesUpdated', this.videoDevicesUpdated);\n this._deviceManager.off('audioDevicesUpdated', this.audioDevicesUpdated);\n this._deviceManager.off('selectedMicrophoneChanged', this.selectedMicrophoneChanged);\n this._deviceManager.off('selectedSpeakerChanged', this.selectedSpeakerChanged);\n if (navigator.permissions) {\n // Unsubscribe from browser camera permissions changes\n try {\n navigator.permissions.query({\n name: 'camera' as PermissionName\n }).then((cameraPermissions): void => {\n cameraPermissions.removeEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not Unsubscribe to Permissions API Camera changed events, API is not supported by browser', e);\n }\n\n // Unsubscribe from browser microphone permissions changes\n try {\n navigator.permissions.query({\n name: 'microphone' as PermissionName\n }).then((micPermissions): void => {\n micPermissions.removeEventListener('change', this.permissionsApiStateChangeHandler);\n });\n } catch (e) {\n console.info('Could not Unsubscribe to Permissions API Camera changed events, API is not supported by browser', e);\n }\n }\n };\n private permissionsApiStateChangeHandler = async (): Promise<void> => {\n await this.updateDevicePermissionState();\n };\n\n /**\n * Used to set a camera inside the proxy device manager.\n *\n * @param videoDeviceInfo VideoDeviceInfo\n */\n public selectCamera = (videoDeviceInfo: VideoDeviceInfo): void => {\n this._context.setDeviceManagerSelectedCamera(videoDeviceInfo);\n };\n private videoDevicesUpdated = async (): Promise<void> => {\n // Device Manager always has a camera with '' name if there are no real camera devices available.\n // We don't want to show that in the UI.\n const realCameras = (await this._deviceManager.getCameras()).filter(c => !!c.name);\n this._context.setDeviceManagerCameras(dedupeById(realCameras));\n };\n private audioDevicesUpdated = async (): Promise<void> => {\n this._context.setDeviceManagerMicrophones(dedupeById(await this._deviceManager.getMicrophones()));\n if (this._deviceManager.isSpeakerSelectionAvailable) {\n this._context.setDeviceManagerSpeakers(dedupeById(await this._deviceManager.getSpeakers()));\n }\n };\n private selectedMicrophoneChanged = (): void => {\n this._context.setDeviceManagerSelectedMicrophone(this._deviceManager.selectedMicrophone);\n };\n private selectedSpeakerChanged = (): void => {\n this._context.setDeviceManagerSelectedSpeaker(this._deviceManager.selectedSpeaker);\n };\n private updateDevicePermissionState = async (sdkDeviceAccessState?: DeviceAccess): Promise<void> => {\n let hasCameraPermission = !!sdkDeviceAccessState?.video;\n let hasMicPermission = !!sdkDeviceAccessState?.audio;\n\n // Supplement the SDK values with values from the Permissions API to get a better understanding of the device\n // permission state. The SDK only uses the getUserMedia API to determine the device permission state. However,\n // this returns false if the camera is in use by another application. The Permissions API can provide more\n // information about the device permission state, but is not supported yet in Firefox or Android WebView.\n // Note: It also has the limitation where it cannot detect if the device is blocked by the Operating System\n // permissions.\n if (navigator.permissions) {\n try {\n const [cameraPermissions, micPermissions] = await Promise.all([navigator.permissions.query({\n name: 'camera' as PermissionName\n }), navigator.permissions.query({\n name: 'microphone' as PermissionName\n })]);\n\n // Use logical OR to combine the SDK state with the Permissions API state.\n // This way we can get a more accurate picture of the device permission state.\n // If the SDK state is 'granted', we don't need to check the Permissions API state.\n hasCameraPermission ||= cameraPermissions.state === 'granted';\n hasMicPermission ||= micPermissions.state === 'granted';\n } catch (e) {\n console.info('Permissions API is not supported by browser', e);\n }\n }\n this._context.setDeviceManagerDeviceAccess({\n video: hasCameraPermission,\n audio: hasMicPermission\n });\n this.setDeviceManager();\n };\n public get<P extends keyof DeviceManager>(target: DeviceManager, prop: P): any {\n switch (prop) {\n case 'getCameras':\n {\n return this._context.withAsyncErrorTeedToState((): Promise<VideoDeviceInfo[]> => {\n return target.getCameras().then((cameras: VideoDeviceInfo[]) => {\n // Device Manager always has a camera with '' name if there are no real camera devices available.\n // We don't want to show that in the UI.\n const realCameras = cameras.filter(c => !!c.name);\n this._context.setDeviceManagerCameras(dedupeById(realCameras));\n return realCameras;\n });\n }, 'DeviceManager.getCameras');\n }\n case 'getMicrophones':\n {\n return this._context.withAsyncErrorTeedToState((): Promise<AudioDeviceInfo[]> => {\n return target.getMicrophones().then((microphones: AudioDeviceInfo[]) => {\n this._context.setDeviceManagerMicrophones(dedupeById(microphones));\n return microphones;\n });\n }, 'DeviceManager.getMicrophones');\n }\n case 'getSpeakers':\n {\n return this._context.withAsyncErrorTeedToState((): Promise<AudioDeviceInfo[]> => {\n return target.getSpeakers().then((speakers: AudioDeviceInfo[]) => {\n this._context.setDeviceManagerSpeakers(dedupeById(speakers));\n return speakers;\n });\n }, 'DeviceManager.getSpeakers');\n }\n case 'selectMicrophone':\n {\n return this._context.withAsyncErrorTeedToState((...args: Parameters<DeviceManager['selectMicrophone']>): Promise<void> => {\n return target.selectMicrophone(...args).then(() => {\n this._context.setDeviceManagerSelectedMicrophone(target.selectedMicrophone);\n });\n }, 'DeviceManager.selectMicrophone');\n }\n case 'selectSpeaker':\n {\n return this._context.withAsyncErrorTeedToState((...args: Parameters<DeviceManager['selectSpeaker']>): Promise<void> => {\n return target.selectSpeaker(...args).then(() => {\n this._context.setDeviceManagerSelectedSpeaker(target.selectedSpeaker);\n });\n }, 'DeviceManager.selectSpeaker');\n }\n case 'askDevicePermission':\n {\n return this._context.withAsyncErrorTeedToState((...args: Parameters<DeviceManager['askDevicePermission']>): Promise<DeviceAccess> => {\n return target.askDevicePermission(...args).then(async (deviceAccess: DeviceAccess) => {\n await this.updateDevicePermissionState(deviceAccess);\n return deviceAccess;\n });\n }, 'DeviceManager.askDevicePermission');\n }\n default:\n return Reflect.get(target, prop);\n }\n }\n}\n\n// TODO: Remove this when SDK no longer returns duplicate audio and video devices\n/** Helper function to dedupe duplicate audio and video devices obtained from SDK */\nconst dedupeById = <T extends {\n id: string;\n},>(devices: T[]): T[] => {\n const ids = new Set();\n const uniqueDevices: T[] = [];\n devices.forEach((device: T) => {\n if (!ids.has(device.id)) {\n uniqueDevices.push(device);\n ids.add(device.id);\n }\n });\n return uniqueDevices;\n};\n\n/**\n * Creates a declarative DeviceManager by proxying DeviceManager with ProxyDeviceManager. The declarative DeviceManager\n * will put state updates in the given context.\n *\n * @param deviceManager - DeviceManager from SDK\n * @param context - CallContext from StatefulCallClient\n *\n * @private\n */\nexport const deviceManagerDeclaratify = (deviceManager: DeviceManager, context: CallContext, internalContext: InternalCallContext): DeviceManager => {\n const proxyDeviceManager = new ProxyDeviceManager(deviceManager, context);\n Object.defineProperty(deviceManager, 'unsubscribe', {\n configurable: false,\n value: () => proxyDeviceManager.unsubscribe()\n });\n Object.defineProperty(deviceManager, 'selectCamera', {\n configurable: false,\n value: (videoDeviceInfo: VideoDeviceInfo) => proxyDeviceManager.selectCamera(videoDeviceInfo)\n });\n Object.defineProperty(deviceManager, 'getUnparentedVideoStreams', {\n configurable: false,\n value: (): LocalVideoStream[] => internalContext.getUnparentedRenderInfos()\n });\n return new Proxy(deviceManager, proxyDeviceManager) as StatefulDeviceManager;\n};"]}
@@ -27,6 +27,10 @@ export type CaptionsInformation = {
27
27
  * If you are using both captions and real time text, please ensure that the createdTimeStamp is populated
28
28
  */
29
29
  createdTimeStamp?: Date;
30
+ /**
31
+ * If caption is finalized
32
+ */
33
+ isFinalized?: boolean;
30
34
  };
31
35
  /**
32
36
  * @public
@@ -5,7 +5,7 @@ import { TextField } from '@fluentui/react';
5
5
  import React, { useEffect, useRef, useState, useCallback } from 'react';
6
6
  import { useMemo } from 'react';
7
7
  import { _Caption } from './Caption';
8
- import { captionContainerClassName, captionsBannerClassName, captionsBannerFullHeightClassName, captionsContainerClassName, loadingBannerFullHeightStyles, loadingBannerStyles } from './styles/Captions.style';
8
+ import { captionContainerClassName, captionsBannerClassName, captionsBannerFullHeightClassName, captionsContainerClassName, hiddenAnnouncementClassName, loadingBannerFullHeightStyles, loadingBannerStyles } from './styles/Captions.style';
9
9
  import { rttDisclosureBannerClassName } from './styles/Captions.style';
10
10
  import { useLocale } from '../localization';
11
11
  import { RealTimeText } from './RealTimeText';
@@ -28,6 +28,10 @@ export const CaptionsBanner = (props) => {
28
28
  const [isAtBottomOfScroll, setIsAtBottomOfScroll] = useState(true);
29
29
  const theme = useTheme();
30
30
  const [expandBannerHeight, setExpandBannerHeight] = useState(false);
31
+ const [announcedRTT, setAnnouncedRTT] = useState([]);
32
+ const [announcedCaption, setAnnouncedCaption] = useState([]);
33
+ const [captionAnnouncementText, setCaptionAnnouncementText] = useState([]);
34
+ const [rttAnnouncementText, setRTTAnnouncementText] = useState([]);
31
35
  const getTitle = () => {
32
36
  var _a, _b, _c;
33
37
  if (isCaptionsOn && isRealTimeTextOn) {
@@ -83,6 +87,24 @@ export const CaptionsBanner = (props) => {
83
87
  setTextFieldValue('');
84
88
  }
85
89
  }, [latestLocalRealTimeText]);
90
+ useEffect(() => {
91
+ if (realTimeTexts === null || realTimeTexts === void 0 ? void 0 : realTimeTexts.completedMessages) {
92
+ //filter out the messages that have already been announced
93
+ const rTTMessagesToAnnounce = realTimeTexts.completedMessages.filter(message => !announcedRTT.includes(message.id));
94
+ if (rTTMessagesToAnnounce.length > 0) {
95
+ setRTTAnnouncementText(rTTMessagesToAnnounce);
96
+ setAnnouncedRTT(prev => [...prev, ...rTTMessagesToAnnounce.map(message => message.id)]);
97
+ }
98
+ }
99
+ if (captions.length > 0) {
100
+ // filter out the captions that have already been announced
101
+ const captionsToAnnounce = captions.filter(caption => !announcedCaption.includes(caption.id) && caption.isFinalized);
102
+ if (captionsToAnnounce.length > 0) {
103
+ setCaptionAnnouncementText(captionsToAnnounce);
104
+ setAnnouncedCaption(prev => [...prev, ...captionsToAnnounce.map(caption => caption.id)]);
105
+ }
106
+ }
107
+ }, [captions, realTimeTexts === null || realTimeTexts === void 0 ? void 0 : realTimeTexts.completedMessages, announcedRTT, announcedCaption]);
86
108
  const handleKeyDown = (event) => {
87
109
  if (event.key === 'Enter') {
88
110
  event.preventDefault();
@@ -108,6 +130,19 @@ export const CaptionsBanner = (props) => {
108
130
  }));
109
131
  };
110
132
  return React.createElement(React.Fragment, null, (startCaptionsInProgress || isCaptionsOn || isRealTimeTextOn) && React.createElement(FocusZone, { shouldFocusOnMount: true, className: captionsContainerClassName, "data-ui-id": "captions-banner" },
133
+ (rttAnnouncementText.length > 0 || (captionAnnouncementText === null || captionAnnouncementText === void 0 ? void 0 : captionAnnouncementText.length) > 0) && React.createElement("div", { "aria-live": "assertive", role: "alert", "aria-atomic": "true", className: hiddenAnnouncementClassName },
134
+ React.createElement("span", null, rttAnnouncementText.map(text => React.createElement("span", null,
135
+ strings.realTimeTextBannerTitle,
136
+ " ",
137
+ text.displayName,
138
+ ": ",
139
+ text.message))),
140
+ React.createElement("span", null, captionAnnouncementText.map(text => React.createElement("span", null,
141
+ strings.captionsOnlyContainerTitle,
142
+ " ",
143
+ text.displayName,
144
+ ": ",
145
+ text.captionText)))),
111
146
  (isCaptionsOn || isRealTimeTextOn) && formFactor === 'compact' && React.createElement(Stack, { horizontal: true, horizontalAlign: "space-between", verticalAlign: "center", className: bannerTitleContainerClassName },
112
147
  React.createElement(Text, { className: titleClassName }, getTitle()),
113
148
  React.createElement(IconButton, { "data-ui-id": "captions-banner-expand-icon", iconProps: {
@@ -1 +1 @@
1
- {"version":3,"file":"CaptionsBanner.js","sourceRoot":"","sources":["../../../../../preprocess-dist/react-components/src/components/CaptionsBanner.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Stack, FocusZone, Spinner, useTheme } from '@fluentui/react';\nimport { TextField } from '@fluentui/react';\nimport React, { useEffect, useRef, useState, useCallback } from 'react';\nimport { useMemo } from 'react';\nimport { _Caption } from './Caption';\nimport { captionContainerClassName, captionsBannerClassName, captionsBannerFullHeightClassName, captionsContainerClassName, loadingBannerFullHeightStyles, loadingBannerStyles } from './styles/Captions.style';\nimport { rttDisclosureBannerClassName } from './styles/Captions.style';\nimport { OnRenderAvatarCallback } from '../types';\nimport { useLocale } from '../localization';\nimport { RealTimeText } from './RealTimeText';\nimport { _RTTDisclosureBanner } from './RTTDisclosureBanner';\nimport { sortCaptionsAndRealTimeTexts } from './utils/sortCaptionsAndRealTimeTexts';\nimport { expandIconClassName, bannerTitleContainerClassName, realTimeTextInputBoxStyles } from './styles/Captions.style';\nimport { titleClassName } from './styles/CaptionsSettingsModal.styles';\nimport { Text, IconButton } from '@fluentui/react';\n\n/**\n * @public\n * information required for each line of caption\n */\nexport type CaptionsInformation = {\n /**\n * unique id for each caption\n */\n id: string;\n /**\n * speaker's display name\n */\n displayName: string;\n /**\n * content of the caption\n */\n captionText: string;\n /**\n * id of the speaker\n */\n userId?: string;\n /**\n * timestamp when the caption was created\n * Please note that this value is essential for determining the order of captions and real time text messages\n * If you are using both captions and real time text, please ensure that the createdTimeStamp is populated\n */\n createdTimeStamp?: Date;\n};\n\n/**\n * @public\n * information required for each line of real time text\n */\nexport type RealTimeTextInformation = {\n /**\n * The id of the real time text.\n */\n id: number;\n /**\n * sender's display name\n */\n displayName: string;\n /**\n * id of the sender\n */\n userId?: string;\n /**\n * The real time text message.\n */\n message: string;\n /**\n * if the real time text received is partial\n */\n isTyping: boolean;\n /**\n * timestamp when the real time text was finalized\n */\n finalizedTimeStamp: Date;\n /**\n * If message originated from the local participant\n * default value is false\n */\n isMe?: boolean;\n};\n/**\n * @public\n * strings for captions banner\n */\nexport interface CaptionsBannerStrings {\n /**\n * Spinner text for captions banner\n */\n captionsBannerSpinnerText?: string;\n\n /**\n * Default text for RTT input text box\n */\n realTimeTextInputBoxDefaultText?: string;\n\n /**\n * Error message for RTT input text box when the size exceeds the limit 2000\n */\n realTimeTextInputErrorMessage?: string;\n\n /**\n * Real time text disclosure banner title\n */\n realTimeTextBannerTitle?: string;\n\n /**\n * Real time text disclosure banner content\n */\n realTimeTextBannerContent?: string;\n\n /**\n * Real time text disclosure banner link label\n */\n realTimeTextBannerLinkLabel?: string;\n\n /**\n * Title for the container when only captions is enabled\n */\n captionsOnlyContainerTitle?: string;\n /**\n * Title for the container when only real time text is enabled\n */\n realTimeTextOnlyContainerTitle?: string;\n /**\n * Title for the container when both captions and real time text is enabled\n */\n captionsAndRealTimeTextContainerTitle?: string;\n /**\n * Expand button aria label\n */\n expandButtonAriaLabel?: string;\n /**\n * Minimize button aria label\n */\n minimizeButtonAriaLabel?: string;\n}\n\n/**\n * @public\n * CaptionsBanner Component Props.\n */\nexport interface CaptionsBannerProps {\n /**\n * Array of captions to be displayed\n */\n captions: CaptionsInformation[];\n /**\n * Array of finalized and partial real time text messages\n */\n realTimeTexts?: {\n completedMessages?: RealTimeTextInformation[];\n currentInProgress?: RealTimeTextInformation[];\n myInProgress?: RealTimeTextInformation;\n };\n /**\n * Flag to indicate if captions are on\n */\n isCaptionsOn?: boolean;\n\n /**\n * Flag to indicate if real time text is on\n */\n isRealTimeTextOn?: boolean;\n /**\n * Flag to indicate if captions are being started\n * This is used to show spinner while captions are being started\n */\n startCaptionsInProgress?: boolean;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n /**\n * Optional strings for the component\n */\n strings?: CaptionsBannerStrings;\n /**\n * Optional form factor for the component.\n * @defaultValue 'default'\n */\n formFactor?: 'default' | 'compact';\n /**\n * Optional options for the component.\n */\n captionsOptions?: {\n height: 'full' | 'default';\n };\n\n /**\n * Optional callback to send real time text.\n */\n onSendRealTimeText?: (text: string, isFinalized: boolean) => Promise<void>;\n\n /**\n * Latest local real time text\n */\n latestLocalRealTimeText?: RealTimeTextInformation;\n}\nconst SCROLL_OFFSET_ALLOWANCE = 20;\n\n/**\n * @public\n * A component for displaying a CaptionsBanner with user icon, displayName and captions text.\n */\nexport const CaptionsBanner = (props: CaptionsBannerProps): JSX.Element => {\n const {\n captions,\n realTimeTexts,\n isCaptionsOn,\n startCaptionsInProgress,\n onRenderAvatar,\n formFactor = 'default',\n captionsOptions,\n isRealTimeTextOn,\n onSendRealTimeText,\n latestLocalRealTimeText\n } = props;\n const localeStrings = useLocale().strings.captionsBanner;\n const strings = {\n ...localeStrings,\n ...props.strings\n };\n const captionsScrollDivRef = useRef<HTMLDivElement>(null);\n const [isAtBottomOfScroll, setIsAtBottomOfScroll] = useState<boolean>(true);\n const theme = useTheme();\n const [expandBannerHeight, setExpandBannerHeight] = useState<boolean>(false);\n const getTitle = (): string => {\n if (isCaptionsOn && isRealTimeTextOn) {\n return strings.captionsAndRealTimeTextContainerTitle ?? '';\n } else if (isCaptionsOn) {\n return strings.captionsOnlyContainerTitle ?? '';\n } else if (isRealTimeTextOn) {\n return strings.realTimeTextOnlyContainerTitle ?? '';\n }\n return '';\n };\n\n // merge realtimetexts and captions into one array based on timestamp\n // Combine captions and realTimeTexts into one list\n const combinedList: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return sortCaptionsAndRealTimeTexts(captions, realTimeTexts?.completedMessages ?? []);\n }, [captions, realTimeTexts?.completedMessages]);\n const mergedCaptions: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return [...combinedList, ...(realTimeTexts?.currentInProgress ?? []), realTimeTexts?.myInProgress].slice(-50) as (CaptionsInformation | RealTimeTextInformation)[];\n }, [combinedList, realTimeTexts]);\n const scrollToBottom = (): void => {\n if (captionsScrollDivRef.current) {\n captionsScrollDivRef.current.scrollTop = captionsScrollDivRef.current.scrollHeight;\n }\n };\n const handleScrollToTheBottom = useCallback((): void => {\n if (!captionsScrollDivRef.current) {\n return;\n }\n const atBottom = Math.ceil(captionsScrollDivRef.current.scrollTop) >= captionsScrollDivRef.current.scrollHeight - captionsScrollDivRef.current.clientHeight - SCROLL_OFFSET_ALLOWANCE;\n setIsAtBottomOfScroll(atBottom);\n }, []);\n useEffect(() => {\n const captionsScrollDiv = captionsScrollDivRef.current;\n captionsScrollDiv?.addEventListener('scroll', handleScrollToTheBottom);\n return () => {\n captionsScrollDiv?.removeEventListener('scroll', handleScrollToTheBottom);\n };\n }, [handleScrollToTheBottom, isCaptionsOn, isRealTimeTextOn]);\n useEffect(() => {\n // only auto scroll to bottom is already is at bottom of scroll before new caption comes in\n if (isAtBottomOfScroll) {\n scrollToBottom();\n }\n }, [captions, realTimeTexts, isAtBottomOfScroll]);\n const [textFieldValue, setTextFieldValue] = useState<string>('');\n useEffect(() => {\n // if the latest real time text sent by myself is final, clear the text field\n if (latestLocalRealTimeText && !latestLocalRealTimeText.isTyping) {\n setTextFieldValue('');\n }\n }, [latestLocalRealTimeText]);\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>): void => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (textFieldValue && onSendRealTimeText) {\n onSendRealTimeText(textFieldValue, true);\n setTextFieldValue('');\n }\n }\n };\n const realTimeTextDisclosureBannerStrings = {\n bannerTitle: strings.realTimeTextBannerTitle ?? '',\n bannerContent: strings.realTimeTextBannerContent ?? '',\n bannerLinkLabel: strings.realTimeTextBannerLinkLabel ?? ''\n };\n const captionsAndRealTimeText = (): JSX.Element => {\n return <>\n {mergedCaptions.filter(caption => caption).map(caption => {\n if ('message' in caption) {\n return <div key={`RealTimeText - ${caption.id}`} className={captionContainerClassName} data-is-focusable={true}>\n <RealTimeText {...caption as RealTimeTextInformation} />\n </div>;\n }\n return <div key={`Captions - ${caption.id}`} className={captionContainerClassName} data-is-focusable={true}>\n <_Caption {...caption as CaptionsInformation} onRenderAvatar={onRenderAvatar} />\n </div>;\n })}\n </>;\n };\n return <>\n {(startCaptionsInProgress || isCaptionsOn || isRealTimeTextOn) && <FocusZone shouldFocusOnMount className={captionsContainerClassName} data-ui-id=\"captions-banner\">\n {(isCaptionsOn || isRealTimeTextOn) && formFactor === 'compact' && <Stack horizontal horizontalAlign=\"space-between\" verticalAlign=\"center\" className={bannerTitleContainerClassName}>\n <Text className={titleClassName}>{getTitle()}</Text>\n <IconButton data-ui-id=\"captions-banner-expand-icon\" iconProps={{\n iconName: expandBannerHeight ? 'MinimizeIcon' : 'ExpandIcon'\n }} ariaLabel={expandBannerHeight ? strings.minimizeButtonAriaLabel : strings.expandButtonAriaLabel} onClick={() => setExpandBannerHeight(!expandBannerHeight)} styles={expandIconClassName(theme)} />\n </Stack>}\n {(isCaptionsOn || isRealTimeTextOn) && <div ref={captionsScrollDivRef} className={captionsOptions?.height === 'full' ? captionsBannerFullHeightClassName(theme) : captionsBannerClassName(formFactor, expandBannerHeight)} data-ui-id=\"captions-banner-inner\" data-is-focusable={true}>\n {isRealTimeTextOn && <Stack className={rttDisclosureBannerClassName()}>\n <_RTTDisclosureBanner strings={realTimeTextDisclosureBannerStrings} />\n </Stack>}\n {captionsAndRealTimeText()}\n </div>}\n {isRealTimeTextOn && onSendRealTimeText && <TextField styles={realTimeTextInputBoxStyles(theme)} placeholder={strings.realTimeTextInputBoxDefaultText} value={textFieldValue} onKeyDown={handleKeyDown} onChange={(_, newValue) => {\n setTextFieldValue(newValue || '');\n onSendRealTimeText(newValue || '', false);\n }} maxLength={2000} errorMessage={textFieldValue.length >= 2000 ? strings.realTimeTextInputErrorMessage : undefined} />}\n {!isCaptionsOn && !isRealTimeTextOn && <Stack verticalAlign=\"center\" styles={captionsOptions?.height === 'full' ? loadingBannerFullHeightStyles(theme) : loadingBannerStyles(formFactor)} data-is-focusable={true}>\n <Spinner label={strings?.captionsBannerSpinnerText} ariaLive=\"assertive\" labelPosition=\"right\" />\n </Stack>}\n </FocusZone>}\n </>;\n};"]}
1
+ {"version":3,"file":"CaptionsBanner.js","sourceRoot":"","sources":["../../../../../preprocess-dist/react-components/src/components/CaptionsBanner.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Stack, FocusZone, Spinner, useTheme } from '@fluentui/react';\nimport { TextField } from '@fluentui/react';\nimport React, { useEffect, useRef, useState, useCallback } from 'react';\nimport { useMemo } from 'react';\nimport { _Caption } from './Caption';\nimport { captionContainerClassName, captionsBannerClassName, captionsBannerFullHeightClassName, captionsContainerClassName, hiddenAnnouncementClassName, loadingBannerFullHeightStyles, loadingBannerStyles } from './styles/Captions.style';\nimport { rttDisclosureBannerClassName } from './styles/Captions.style';\nimport { OnRenderAvatarCallback } from '../types';\nimport { useLocale } from '../localization';\nimport { RealTimeText } from './RealTimeText';\nimport { _RTTDisclosureBanner } from './RTTDisclosureBanner';\nimport { sortCaptionsAndRealTimeTexts } from './utils/sortCaptionsAndRealTimeTexts';\nimport { expandIconClassName, bannerTitleContainerClassName, realTimeTextInputBoxStyles } from './styles/Captions.style';\nimport { titleClassName } from './styles/CaptionsSettingsModal.styles';\nimport { Text, IconButton } from '@fluentui/react';\n\n/**\n * @public\n * information required for each line of caption\n */\nexport type CaptionsInformation = {\n /**\n * unique id for each caption\n */\n id: string;\n /**\n * speaker's display name\n */\n displayName: string;\n /**\n * content of the caption\n */\n captionText: string;\n /**\n * id of the speaker\n */\n userId?: string;\n /**\n * timestamp when the caption was created\n * Please note that this value is essential for determining the order of captions and real time text messages\n * If you are using both captions and real time text, please ensure that the createdTimeStamp is populated\n */\n createdTimeStamp?: Date;\n /**\n * If caption is finalized\n */\n isFinalized?: boolean;\n};\n\n/**\n * @public\n * information required for each line of real time text\n */\nexport type RealTimeTextInformation = {\n /**\n * The id of the real time text.\n */\n id: number;\n /**\n * sender's display name\n */\n displayName: string;\n /**\n * id of the sender\n */\n userId?: string;\n /**\n * The real time text message.\n */\n message: string;\n /**\n * if the real time text received is partial\n */\n isTyping: boolean;\n /**\n * timestamp when the real time text was finalized\n */\n finalizedTimeStamp: Date;\n /**\n * If message originated from the local participant\n * default value is false\n */\n isMe?: boolean;\n};\n/**\n * @public\n * strings for captions banner\n */\nexport interface CaptionsBannerStrings {\n /**\n * Spinner text for captions banner\n */\n captionsBannerSpinnerText?: string;\n\n /**\n * Default text for RTT input text box\n */\n realTimeTextInputBoxDefaultText?: string;\n\n /**\n * Error message for RTT input text box when the size exceeds the limit 2000\n */\n realTimeTextInputErrorMessage?: string;\n\n /**\n * Real time text disclosure banner title\n */\n realTimeTextBannerTitle?: string;\n\n /**\n * Real time text disclosure banner content\n */\n realTimeTextBannerContent?: string;\n\n /**\n * Real time text disclosure banner link label\n */\n realTimeTextBannerLinkLabel?: string;\n\n /**\n * Title for the container when only captions is enabled\n */\n captionsOnlyContainerTitle?: string;\n /**\n * Title for the container when only real time text is enabled\n */\n realTimeTextOnlyContainerTitle?: string;\n /**\n * Title for the container when both captions and real time text is enabled\n */\n captionsAndRealTimeTextContainerTitle?: string;\n /**\n * Expand button aria label\n */\n expandButtonAriaLabel?: string;\n /**\n * Minimize button aria label\n */\n minimizeButtonAriaLabel?: string;\n}\n\n/**\n * @public\n * CaptionsBanner Component Props.\n */\nexport interface CaptionsBannerProps {\n /**\n * Array of captions to be displayed\n */\n captions: CaptionsInformation[];\n /**\n * Array of finalized and partial real time text messages\n */\n realTimeTexts?: {\n completedMessages?: RealTimeTextInformation[];\n currentInProgress?: RealTimeTextInformation[];\n myInProgress?: RealTimeTextInformation;\n };\n /**\n * Flag to indicate if captions are on\n */\n isCaptionsOn?: boolean;\n\n /**\n * Flag to indicate if real time text is on\n */\n isRealTimeTextOn?: boolean;\n /**\n * Flag to indicate if captions are being started\n * This is used to show spinner while captions are being started\n */\n startCaptionsInProgress?: boolean;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n /**\n * Optional strings for the component\n */\n strings?: CaptionsBannerStrings;\n /**\n * Optional form factor for the component.\n * @defaultValue 'default'\n */\n formFactor?: 'default' | 'compact';\n /**\n * Optional options for the component.\n */\n captionsOptions?: {\n height: 'full' | 'default';\n };\n\n /**\n * Optional callback to send real time text.\n */\n onSendRealTimeText?: (text: string, isFinalized: boolean) => Promise<void>;\n\n /**\n * Latest local real time text\n */\n latestLocalRealTimeText?: RealTimeTextInformation;\n}\nconst SCROLL_OFFSET_ALLOWANCE = 20;\n\n/**\n * @public\n * A component for displaying a CaptionsBanner with user icon, displayName and captions text.\n */\nexport const CaptionsBanner = (props: CaptionsBannerProps): JSX.Element => {\n const {\n captions,\n realTimeTexts,\n isCaptionsOn,\n startCaptionsInProgress,\n onRenderAvatar,\n formFactor = 'default',\n captionsOptions,\n isRealTimeTextOn,\n onSendRealTimeText,\n latestLocalRealTimeText\n } = props;\n const localeStrings = useLocale().strings.captionsBanner;\n const strings = {\n ...localeStrings,\n ...props.strings\n };\n const captionsScrollDivRef = useRef<HTMLDivElement>(null);\n const [isAtBottomOfScroll, setIsAtBottomOfScroll] = useState<boolean>(true);\n const theme = useTheme();\n const [expandBannerHeight, setExpandBannerHeight] = useState<boolean>(false);\n const [announcedRTT, setAnnouncedRTT] = useState<number[]>([]);\n const [announcedCaption, setAnnouncedCaption] = useState<string[]>([]);\n const [captionAnnouncementText, setCaptionAnnouncementText] = useState<CaptionsInformation[]>([]);\n const [rttAnnouncementText, setRTTAnnouncementText] = useState<RealTimeTextInformation[]>([]);\n const getTitle = (): string => {\n if (isCaptionsOn && isRealTimeTextOn) {\n return strings.captionsAndRealTimeTextContainerTitle ?? '';\n } else if (isCaptionsOn) {\n return strings.captionsOnlyContainerTitle ?? '';\n } else if (isRealTimeTextOn) {\n return strings.realTimeTextOnlyContainerTitle ?? '';\n }\n return '';\n };\n\n // merge realtimetexts and captions into one array based on timestamp\n // Combine captions and realTimeTexts into one list\n const combinedList: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return sortCaptionsAndRealTimeTexts(captions, realTimeTexts?.completedMessages ?? []);\n }, [captions, realTimeTexts?.completedMessages]);\n const mergedCaptions: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return [...combinedList, ...(realTimeTexts?.currentInProgress ?? []), realTimeTexts?.myInProgress].slice(-50) as (CaptionsInformation | RealTimeTextInformation)[];\n }, [combinedList, realTimeTexts]);\n const scrollToBottom = (): void => {\n if (captionsScrollDivRef.current) {\n captionsScrollDivRef.current.scrollTop = captionsScrollDivRef.current.scrollHeight;\n }\n };\n const handleScrollToTheBottom = useCallback((): void => {\n if (!captionsScrollDivRef.current) {\n return;\n }\n const atBottom = Math.ceil(captionsScrollDivRef.current.scrollTop) >= captionsScrollDivRef.current.scrollHeight - captionsScrollDivRef.current.clientHeight - SCROLL_OFFSET_ALLOWANCE;\n setIsAtBottomOfScroll(atBottom);\n }, []);\n useEffect(() => {\n const captionsScrollDiv = captionsScrollDivRef.current;\n captionsScrollDiv?.addEventListener('scroll', handleScrollToTheBottom);\n return () => {\n captionsScrollDiv?.removeEventListener('scroll', handleScrollToTheBottom);\n };\n }, [handleScrollToTheBottom, isCaptionsOn, isRealTimeTextOn]);\n useEffect(() => {\n // only auto scroll to bottom is already is at bottom of scroll before new caption comes in\n if (isAtBottomOfScroll) {\n scrollToBottom();\n }\n }, [captions, realTimeTexts, isAtBottomOfScroll]);\n const [textFieldValue, setTextFieldValue] = useState<string>('');\n useEffect(() => {\n // if the latest real time text sent by myself is final, clear the text field\n if (latestLocalRealTimeText && !latestLocalRealTimeText.isTyping) {\n setTextFieldValue('');\n }\n }, [latestLocalRealTimeText]);\n useEffect(() => {\n if (realTimeTexts?.completedMessages) {\n //filter out the messages that have already been announced\n const rTTMessagesToAnnounce = realTimeTexts.completedMessages.filter(message => !announcedRTT.includes(message.id));\n if (rTTMessagesToAnnounce.length > 0) {\n setRTTAnnouncementText(rTTMessagesToAnnounce);\n setAnnouncedRTT(prev => [...prev, ...rTTMessagesToAnnounce.map(message => message.id)]);\n }\n }\n if (captions.length > 0) {\n // filter out the captions that have already been announced\n const captionsToAnnounce = captions.filter(caption => !announcedCaption.includes(caption.id) && caption.isFinalized);\n if (captionsToAnnounce.length > 0) {\n setCaptionAnnouncementText(captionsToAnnounce);\n setAnnouncedCaption(prev => [...prev, ...captionsToAnnounce.map(caption => caption.id)]);\n }\n }\n }, [captions, realTimeTexts?.completedMessages, announcedRTT, announcedCaption]);\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>): void => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (textFieldValue && onSendRealTimeText) {\n onSendRealTimeText(textFieldValue, true);\n setTextFieldValue('');\n }\n }\n };\n const realTimeTextDisclosureBannerStrings = {\n bannerTitle: strings.realTimeTextBannerTitle ?? '',\n bannerContent: strings.realTimeTextBannerContent ?? '',\n bannerLinkLabel: strings.realTimeTextBannerLinkLabel ?? ''\n };\n const captionsAndRealTimeText = (): JSX.Element => {\n return <>\n {mergedCaptions.filter(caption => caption).map(caption => {\n if ('message' in caption) {\n return <div key={`RealTimeText - ${caption.id}`} className={captionContainerClassName} data-is-focusable={true}>\n <RealTimeText {...caption as RealTimeTextInformation} />\n </div>;\n }\n return <div key={`Captions - ${caption.id}`} className={captionContainerClassName} data-is-focusable={true}>\n <_Caption {...caption as CaptionsInformation} onRenderAvatar={onRenderAvatar} />\n </div>;\n })}\n </>;\n };\n return <>\n {(startCaptionsInProgress || isCaptionsOn || isRealTimeTextOn) && <FocusZone shouldFocusOnMount className={captionsContainerClassName} data-ui-id=\"captions-banner\">\n {/* ARIA live region */}\n {(rttAnnouncementText.length > 0 || captionAnnouncementText?.length > 0) && <div aria-live=\"assertive\" role=\"alert\" aria-atomic=\"true\" className={hiddenAnnouncementClassName}>\n <span>\n {rttAnnouncementText.map(text => <span>\n {strings.realTimeTextBannerTitle} {text.displayName}: {text.message}\n </span>)}\n </span>\n <span>\n {captionAnnouncementText.map(text => <span>\n {strings.captionsOnlyContainerTitle} {text.displayName}: {text.captionText}\n </span>)}\n </span>\n </div>}\n\n {(isCaptionsOn || isRealTimeTextOn) && formFactor === 'compact' && <Stack horizontal horizontalAlign=\"space-between\" verticalAlign=\"center\" className={bannerTitleContainerClassName}>\n <Text className={titleClassName}>{getTitle()}</Text>\n <IconButton data-ui-id=\"captions-banner-expand-icon\" iconProps={{\n iconName: expandBannerHeight ? 'MinimizeIcon' : 'ExpandIcon'\n }} ariaLabel={expandBannerHeight ? strings.minimizeButtonAriaLabel : strings.expandButtonAriaLabel} onClick={() => setExpandBannerHeight(!expandBannerHeight)} styles={expandIconClassName(theme)} />\n </Stack>}\n {(isCaptionsOn || isRealTimeTextOn) && <div ref={captionsScrollDivRef} className={captionsOptions?.height === 'full' ? captionsBannerFullHeightClassName(theme) : captionsBannerClassName(formFactor, expandBannerHeight)} data-ui-id=\"captions-banner-inner\" data-is-focusable={true}>\n {isRealTimeTextOn && <Stack className={rttDisclosureBannerClassName()}>\n <_RTTDisclosureBanner strings={realTimeTextDisclosureBannerStrings} />\n </Stack>}\n {captionsAndRealTimeText()}\n </div>}\n {isRealTimeTextOn && onSendRealTimeText && <TextField styles={realTimeTextInputBoxStyles(theme)} placeholder={strings.realTimeTextInputBoxDefaultText} value={textFieldValue} onKeyDown={handleKeyDown} onChange={(_, newValue) => {\n setTextFieldValue(newValue || '');\n onSendRealTimeText(newValue || '', false);\n }} maxLength={2000} errorMessage={textFieldValue.length >= 2000 ? strings.realTimeTextInputErrorMessage : undefined} />}\n {!isCaptionsOn && !isRealTimeTextOn && <Stack verticalAlign=\"center\" styles={captionsOptions?.height === 'full' ? loadingBannerFullHeightStyles(theme) : loadingBannerStyles(formFactor)} data-is-focusable={true}>\n <Spinner label={strings?.captionsBannerSpinnerText} ariaLive=\"assertive\" labelPosition=\"right\" />\n </Stack>}\n </FocusZone>}\n </>;\n};"]}
@@ -40,6 +40,10 @@ export declare const captionClassName: string;
40
40
  * @private
41
41
  */
42
42
  export declare const captionsContainerClassName: string;
43
+ /**
44
+ * @private
45
+ */
46
+ export declare const hiddenAnnouncementClassName: string;
43
47
  /**
44
48
  * @private
45
49
  */
@@ -101,6 +101,19 @@ export const captionsContainerClassName = mergeStyles({
101
101
  padding: 0,
102
102
  overflowX: 'hidden'
103
103
  });
104
+ /**
105
+ * @private
106
+ */
107
+ export const hiddenAnnouncementClassName = mergeStyles({
108
+ position: 'absolute',
109
+ width: '1px',
110
+ height: '1px',
111
+ padding: 0,
112
+ overflow: 'hidden',
113
+ clip: 'rect(0, 0, 0, 0)',
114
+ whiteSpace: 'nowrap',
115
+ border: 0
116
+ });
104
117
  /**
105
118
  * @private
106
119
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Captions.style.js","sourceRoot":"","sources":["../../../../../../preprocess-dist/react-components/src/components/styles/Captions.style.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { IStackStyles, ITheme, mergeStyles } from '@fluentui/react';\nimport { _pxToRem } from '@internal/acs-ui-common';\nimport { IButtonStyles, ITextFieldStyles } from '@fluentui/react';\n\n/**\n * @private\n */\nexport const iconClassName = mergeStyles({\n marginRight: _pxToRem(8)\n});\n\n/**\n * @private\n */\nexport const displayNameClassName = mergeStyles({\n fontWeight: 400,\n fontSize: _pxToRem(12),\n lineHeight: _pxToRem(16)\n});\n\n/**\n * @private\n */\nexport const bannerTitleContainerClassName = mergeStyles({\n paddingBottom: _pxToRem(10)\n});\n\n/**\n * @private\n */\nexport const isTypingClassName = (theme: ITheme): string => {\n return mergeStyles({\n backgroundColor: theme.palette.themeLighter,\n color: theme.palette.themeDarker,\n borderRadius: _pxToRem(4),\n marginLeft: _pxToRem(4),\n fontWeight: 400,\n paddingLeft: _pxToRem(4),\n paddingRight: _pxToRem(4),\n fontSize: _pxToRem(11),\n lineHeight: _pxToRem(16)\n });\n};\n\n/**\n * @private\n */\nexport const rttContainerClassName = (theme: ITheme, isTyping: boolean): string => {\n return mergeStyles({\n borderLeft: isTyping ? `2px solid ${theme.palette.themeLighter}` : 'none'\n });\n};\n\n/**\n * @private\n */\nexport const rttDisclosureBannerClassName = (): string => {\n return mergeStyles({\n padding: '0.25rem',\n paddingTop: '0.5rem'\n });\n};\n\n/**\n * @private\n */\nexport const realTimeTextInputBoxStyles = (theme: ITheme): Partial<ITextFieldStyles> => ({\n root: {\n marginBottom: _pxToRem(8)\n },\n fieldGroup: {\n borderRadius: _pxToRem(4),\n borderColor: theme.palette.neutralQuaternaryAlt\n }\n});\n\n/**\n * @private\n */\nexport const expandIconClassName = (theme: ITheme): IButtonStyles => {\n return {\n root: {\n color: theme.palette.neutralPrimary,\n width: '1rem',\n height: '1rem'\n },\n rootHovered: {\n color: theme.palette.neutralDark\n }\n };\n};\n\n/**\n * @private\n */\nexport const captionClassName = mergeStyles({\n fontWeight: 400,\n fontSize: _pxToRem(16),\n lineHeight: _pxToRem(22),\n width: '100%'\n});\n\n/**\n * @private\n */\nexport const captionsContainerClassName = mergeStyles({\n height: '100%',\n margin: 0,\n overflow: 'auto',\n padding: 0,\n overflowX: 'hidden'\n});\n\n/**\n * @private\n */\nexport const captionContainerClassName = mergeStyles({\n marginTop: _pxToRem(6),\n marginBottom: _pxToRem(6),\n textAlign: 'unset',\n // ensure RTL spoken language captions are appropriately aligned to the right\n overflowAnchor: 'auto',\n overflowWrap: 'break-word',\n wordBreak: 'break-word',\n // Additional breaking control for long words\n maxWidth: '100%',\n // Ensure it never expands beyond 100% of the container\n width: '100%',\n overflow: 'hidden',\n boxSizing: 'border-box',\n // Include padding in the width calculation\n whiteSpace: 'normal' // Ensure text wraps\n});\n\n/** Reset styling set by the `ul` element */\nconst resetUlStyling = {\n listStyleType: 'none',\n padding: 0,\n margin: 0\n};\n\n/**\n * @private\n */\nexport const captionsBannerClassName = (formFactor: 'default' | 'compact', isExpanded?: boolean): string => {\n return mergeStyles({\n ...resetUlStyling,\n overflowX: 'hidden',\n height: formFactor === 'compact' ? isExpanded ? '40vh' : '4.5rem' : '8.75rem',\n overflowY: 'auto'\n });\n};\n\n/**\n * @private\n */\nexport const captionsBannerFullHeightClassName = (theme: ITheme): string => {\n return mergeStyles({\n ...resetUlStyling,\n overflowX: 'hidden',\n overflowY: 'auto',\n height: '100%',\n width: '100%',\n position: 'absolute',\n backgroundColor: theme.palette.white,\n left: 0\n });\n};\n\n/**\n * @private\n */\nexport const loadingBannerStyles = (formFactor: 'default' | 'compact'): IStackStyles => {\n return {\n root: {\n height: formFactor === 'compact' ? '4.5rem' : '8.75rem'\n }\n };\n};\n\n/**\n * @private\n */\nexport const loadingBannerFullHeightStyles = (theme: ITheme): IStackStyles => {\n return {\n root: {\n height: '100%',\n width: '100%',\n position: 'absolute',\n left: 0,\n backgroundColor: theme.palette.white\n }\n };\n};\n\n/**\n * @private\n */\nexport const captionsContentContainerClassName = mergeStyles({\n width: '100%',\n paddingInlineEnd: _pxToRem(4)\n});\n\n/**\n * @private\n */\nexport const displayNameContainerClassName = mergeStyles({\n overflow: 'hidden',\n textOverflow: 'ellipsis'\n});"]}
1
+ {"version":3,"file":"Captions.style.js","sourceRoot":"","sources":["../../../../../../preprocess-dist/react-components/src/components/styles/Captions.style.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { IStackStyles, ITheme, mergeStyles } from '@fluentui/react';\nimport { _pxToRem } from '@internal/acs-ui-common';\nimport { IButtonStyles, ITextFieldStyles } from '@fluentui/react';\n\n/**\n * @private\n */\nexport const iconClassName = mergeStyles({\n marginRight: _pxToRem(8)\n});\n\n/**\n * @private\n */\nexport const displayNameClassName = mergeStyles({\n fontWeight: 400,\n fontSize: _pxToRem(12),\n lineHeight: _pxToRem(16)\n});\n\n/**\n * @private\n */\nexport const bannerTitleContainerClassName = mergeStyles({\n paddingBottom: _pxToRem(10)\n});\n\n/**\n * @private\n */\nexport const isTypingClassName = (theme: ITheme): string => {\n return mergeStyles({\n backgroundColor: theme.palette.themeLighter,\n color: theme.palette.themeDarker,\n borderRadius: _pxToRem(4),\n marginLeft: _pxToRem(4),\n fontWeight: 400,\n paddingLeft: _pxToRem(4),\n paddingRight: _pxToRem(4),\n fontSize: _pxToRem(11),\n lineHeight: _pxToRem(16)\n });\n};\n\n/**\n * @private\n */\nexport const rttContainerClassName = (theme: ITheme, isTyping: boolean): string => {\n return mergeStyles({\n borderLeft: isTyping ? `2px solid ${theme.palette.themeLighter}` : 'none'\n });\n};\n\n/**\n * @private\n */\nexport const rttDisclosureBannerClassName = (): string => {\n return mergeStyles({\n padding: '0.25rem',\n paddingTop: '0.5rem'\n });\n};\n\n/**\n * @private\n */\nexport const realTimeTextInputBoxStyles = (theme: ITheme): Partial<ITextFieldStyles> => ({\n root: {\n marginBottom: _pxToRem(8)\n },\n fieldGroup: {\n borderRadius: _pxToRem(4),\n borderColor: theme.palette.neutralQuaternaryAlt\n }\n});\n\n/**\n * @private\n */\nexport const expandIconClassName = (theme: ITheme): IButtonStyles => {\n return {\n root: {\n color: theme.palette.neutralPrimary,\n width: '1rem',\n height: '1rem'\n },\n rootHovered: {\n color: theme.palette.neutralDark\n }\n };\n};\n\n/**\n * @private\n */\nexport const captionClassName = mergeStyles({\n fontWeight: 400,\n fontSize: _pxToRem(16),\n lineHeight: _pxToRem(22),\n width: '100%'\n});\n\n/**\n * @private\n */\nexport const captionsContainerClassName = mergeStyles({\n height: '100%',\n margin: 0,\n overflow: 'auto',\n padding: 0,\n overflowX: 'hidden'\n});\n\n/**\n * @private\n */\nexport const hiddenAnnouncementClassName = mergeStyles({\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: 0,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: 0\n});\n\n/**\n * @private\n */\nexport const captionContainerClassName = mergeStyles({\n marginTop: _pxToRem(6),\n marginBottom: _pxToRem(6),\n textAlign: 'unset',\n // ensure RTL spoken language captions are appropriately aligned to the right\n overflowAnchor: 'auto',\n overflowWrap: 'break-word',\n wordBreak: 'break-word',\n // Additional breaking control for long words\n maxWidth: '100%',\n // Ensure it never expands beyond 100% of the container\n width: '100%',\n overflow: 'hidden',\n boxSizing: 'border-box',\n // Include padding in the width calculation\n whiteSpace: 'normal' // Ensure text wraps\n});\n\n/** Reset styling set by the `ul` element */\nconst resetUlStyling = {\n listStyleType: 'none',\n padding: 0,\n margin: 0\n};\n\n/**\n * @private\n */\nexport const captionsBannerClassName = (formFactor: 'default' | 'compact', isExpanded?: boolean): string => {\n return mergeStyles({\n ...resetUlStyling,\n overflowX: 'hidden',\n height: formFactor === 'compact' ? isExpanded ? '40vh' : '4.5rem' : '8.75rem',\n overflowY: 'auto'\n });\n};\n\n/**\n * @private\n */\nexport const captionsBannerFullHeightClassName = (theme: ITheme): string => {\n return mergeStyles({\n ...resetUlStyling,\n overflowX: 'hidden',\n overflowY: 'auto',\n height: '100%',\n width: '100%',\n position: 'absolute',\n backgroundColor: theme.palette.white,\n left: 0\n });\n};\n\n/**\n * @private\n */\nexport const loadingBannerStyles = (formFactor: 'default' | 'compact'): IStackStyles => {\n return {\n root: {\n height: formFactor === 'compact' ? '4.5rem' : '8.75rem'\n }\n };\n};\n\n/**\n * @private\n */\nexport const loadingBannerFullHeightStyles = (theme: ITheme): IStackStyles => {\n return {\n root: {\n height: '100%',\n width: '100%',\n position: 'absolute',\n left: 0,\n backgroundColor: theme.palette.white\n }\n };\n};\n\n/**\n * @private\n */\nexport const captionsContentContainerClassName = mergeStyles({\n width: '100%',\n paddingInlineEnd: _pxToRem(4)\n});\n\n/**\n * @private\n */\nexport const displayNameContainerClassName = mergeStyles({\n overflow: 'hidden',\n textOverflow: 'ellipsis'\n});"]}
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  step((generator = generator.apply(thisArg, _arguments || [])).next());
10
10
  });
11
11
  };
12
- import React, { useCallback, useMemo, useRef } from 'react';
13
- import { useState } from 'react';
12
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
13
+ import { useEffect } from 'react';
14
14
  import { useAdaptedSelector } from '../hooks/useAdaptedSelector';
15
15
  import { useHandlers } from '../hooks/useHandlers';
16
16
  import { LocalDeviceSettings } from '../components/LocalDeviceSettings';
@@ -49,10 +49,11 @@ export const ConfigurationPage = (props) => {
49
49
  const theme = useTheme();
50
50
  const options = useAdaptedSelector(getCallingSelector(DevicesButton));
51
51
  const localDeviceSettingsHandlers = useHandlers(LocalDeviceSettings);
52
- const { video: cameraPermissionGranted, audio: microphonePermissionGranted } = useSelector(devicePermissionSelector); // use permission API to get video and audio permission state
52
+ const { video: cameraPermissionGranted, audio: microphonePermissionGranted } = useSelector(devicePermissionSelector);
53
+ const environmentInfo = useSelector(getEnvironmentInfo); // use permission API to get video and audio permission state
53
54
  const [videoState, setVideoState] = useState(undefined);
54
55
  const [audioState, setAudioState] = useState(undefined);
55
- getDevicePermissionState(setVideoState, setAudioState);
56
+ getDevicePermissionState(environmentInfo, setVideoState, setAudioState, videoState, audioState);
56
57
  const configContainerRef = useRef(null);
57
58
  const configWidth = _useContainerWidth(configContainerRef);
58
59
  /**
@@ -62,7 +63,6 @@ export const ConfigurationPage = (props) => {
62
63
  const stackConfig = !!configWidth && configWidth < 450;
63
64
  const errorBarProps = usePropsFor(ErrorBar);
64
65
  const microphones = useSelector(getMicrophones);
65
- const environmentInfo = useSelector(getEnvironmentInfo);
66
66
  let disableStartCallButton = (!microphonePermissionGranted || (microphones === null || microphones === void 0 ? void 0 : microphones.length) === 0) && joinCallOptions.microphoneCheck === 'requireMicrophoneAvailable';
67
67
  const role = useSelector(getRole);
68
68
  const isCameraOn = useSelector(localVideoSelector).isAvailable;
@@ -115,19 +115,21 @@ export const ConfigurationPage = (props) => {
115
115
  React.createElement(SvgWithWordWrapping, { width: mobileView ? 325 : 445, lineHeightPx: 16 * 1.5, bufferHeightPx: 16, text: locale.strings.call.configurationPageTitle, role: "heading" })) : React.createElement(React.Fragment, null);
116
116
  const callDescription = locale.strings.call.configurationPageCallDetails && React.createElement(Stack.Item, { className: mobileView ? callDetailsStyleMobile(theme) : callDetailsStyleDesktop(theme) }, locale.strings.call.configurationPageCallDetails);
117
117
  const mobileWithPreview = mobileView && role !== 'Consumer';
118
- const permissionsState = {
118
+ const permissionsState = useMemo(() => ({
119
119
  // fall back to using cameraPermissionGranted and microphonePermissionGranted if permission API is not supported
120
120
  camera: videoState && videoState !== 'unsupported' ? cameraPermissionGranted !== false ? videoState : 'denied' : cameraPermissionGranted !== false ? cameraPermissionGranted ? 'granted' : 'prompt' : 'denied',
121
121
  microphone: audioState && audioState !== 'unsupported' ? microphonePermissionGranted !== false ? audioState : 'denied' : microphonePermissionGranted !== false ? microphonePermissionGranted ? 'granted' : 'prompt' : 'denied'
122
- };
122
+ }), [videoState, audioState, cameraPermissionGranted, microphonePermissionGranted]);
123
123
  const networkErrors = errorBarProps.activeErrorMessages.filter(message => message.type === 'callNetworkQualityLow');
124
124
  const [isPermissionsModalDismissed, setIsPermissionsModalDismissed] = useState(true);
125
125
  // When permission API is not available, we want to show screen saying checking for access (disappears on its own)
126
126
  // then based on permission setting, we show permission denied or nothing
127
127
  const [minimumFallbackTimerElapsed, setMinimumFallbackTimerElapsed] = useState(false);
128
- setTimeout(() => {
129
- setMinimumFallbackTimerElapsed(true);
130
- }, 2000);
128
+ useEffect(() => {
129
+ setTimeout(() => {
130
+ setMinimumFallbackTimerElapsed(true);
131
+ }, 2000);
132
+ }, []);
131
133
  const forceShowingCheckPermissions = !minimumFallbackTimerElapsed;
132
134
  const { toggleVideoEffectsPane, closeVideoEffectsPane, isVideoEffectsPaneOpen } = useVideoEffectsPane(props.updateSidePaneRenderer, mobileView, props.latestErrors, props.onDismissError);
133
135
  const startCall = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {