@azure/communication-react 1.4.2-alpha-202211240014.0 → 1.4.2-alpha-202211290015.0

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/CHANGELOG.beta.md +47 -1
  2. package/CHANGELOG.json +507 -0
  3. package/dist/communication-react.d.ts +48 -0
  4. package/dist/dist-cjs/communication-react/index.js +258 -87
  5. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  6. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  7. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  8. package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js +12 -9
  9. package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js.map +1 -1
  10. package/dist/dist-esm/react-components/src/components/VideoTile.d.ts +4 -0
  11. package/dist/dist-esm/react-components/src/components/VideoTile.js +25 -2
  12. package/dist/dist-esm/react-components/src/components/VideoTile.js.map +1 -1
  13. package/dist/dist-esm/react-components/src/components/utils/useLongPress.d.ts +12 -10
  14. package/dist/dist-esm/react-components/src/components/utils/useLongPress.js +61 -37
  15. package/dist/dist-esm/react-components/src/components/utils/useLongPress.js.map +1 -1
  16. package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts +44 -0
  17. package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.js.map +1 -1
  18. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/MediaGallery.js +6 -2
  19. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/MediaGallery.js.map +1 -1
  20. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/mediaGallerySelector.d.ts +7 -0
  21. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/mediaGallerySelector.js +9 -1
  22. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/mediaGallerySelector.js.map +1 -1
  23. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.d.ts +29 -0
  24. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js +119 -0
  25. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js.map +1 -0
  26. package/dist/dist-esm/react-composites/src/composites/localization/locales/en-US/strings.json +12 -1
  27. package/package.json +8 -8
@@ -202,7 +202,7 @@ const _toCommunicationIdentifier = (id) => {
202
202
  // Copyright (c) Microsoft Corporation.
203
203
  // Licensed under the MIT license.
204
204
  // GENERATED FILE. DO NOT EDIT MANUALLY.
205
- var telemetryVersion = '1.4.2-alpha-202211240014.0';
205
+ var telemetryVersion = '1.4.2-alpha-202211290015.0';
206
206
 
207
207
  // Copyright (c) Microsoft Corporation.
208
208
  /**
@@ -8043,6 +8043,93 @@ const getVideoTileOverrideColor = (isVideoRendered, theme, color) => {
8043
8043
  return { color: isVideoRendered ? react.DefaultPalette[color] : theme.palette[color] };
8044
8044
  };
8045
8045
 
8046
+ // Copyright (c) Microsoft Corporation.
8047
+ /**
8048
+ * @private
8049
+ */
8050
+ function useLongPress(props) {
8051
+ const { onClick, onLongPress, touchEventsOnly = false } = props;
8052
+ const timerRef = React.useRef();
8053
+ const [isLongPress, setIsLongPress] = React.useState(false);
8054
+ const [action, setAction] = React.useState(false);
8055
+ React.useEffect(() => {
8056
+ if (timerRef.current) {
8057
+ clearTimeout(timerRef.current);
8058
+ }
8059
+ return () => {
8060
+ if (timerRef.current) {
8061
+ clearTimeout(timerRef.current);
8062
+ }
8063
+ };
8064
+ }, [onClick, onLongPress, touchEventsOnly]);
8065
+ const startPressTimer = React.useCallback(() => {
8066
+ setIsLongPress(false);
8067
+ timerRef.current = setTimeout(() => {
8068
+ setIsLongPress(true);
8069
+ onLongPress();
8070
+ }, 500);
8071
+ }, [onLongPress]);
8072
+ const handleOnClick = React.useCallback(() => {
8073
+ if (touchEventsOnly || !onClick) {
8074
+ return;
8075
+ }
8076
+ if (!isLongPress) {
8077
+ onClick();
8078
+ }
8079
+ }, [isLongPress, onClick, touchEventsOnly]);
8080
+ const handleOnKeyDown = React.useCallback(() => {
8081
+ if (touchEventsOnly) {
8082
+ return;
8083
+ }
8084
+ if (action) {
8085
+ setAction(false);
8086
+ startPressTimer();
8087
+ }
8088
+ }, [action, startPressTimer, touchEventsOnly]);
8089
+ const handleOnKeyUp = React.useCallback(() => {
8090
+ if (touchEventsOnly) {
8091
+ return;
8092
+ }
8093
+ setAction(true);
8094
+ timerRef.current && clearTimeout(timerRef.current);
8095
+ }, [touchEventsOnly]);
8096
+ const handleOnMouseDown = React.useCallback(() => {
8097
+ if (touchEventsOnly) {
8098
+ return;
8099
+ }
8100
+ startPressTimer();
8101
+ }, [startPressTimer, touchEventsOnly]);
8102
+ const handleOnMouseUp = React.useCallback(() => {
8103
+ if (touchEventsOnly) {
8104
+ return;
8105
+ }
8106
+ timerRef.current && clearTimeout(timerRef.current);
8107
+ }, [touchEventsOnly]);
8108
+ const handleOnTouchStart = React.useCallback(() => {
8109
+ startPressTimer();
8110
+ }, [startPressTimer]);
8111
+ const handleOnTouchEnd = React.useCallback(() => {
8112
+ timerRef.current && clearTimeout(timerRef.current);
8113
+ }, []);
8114
+ return React.useMemo(() => ({
8115
+ onClick: handleOnClick,
8116
+ onMouseDown: handleOnMouseDown,
8117
+ onMouseUp: handleOnMouseUp,
8118
+ onTouchStart: handleOnTouchStart,
8119
+ onTouchEnd: handleOnTouchEnd,
8120
+ onKeyDown: handleOnKeyDown,
8121
+ onKeyUp: handleOnKeyUp
8122
+ }), [
8123
+ handleOnClick,
8124
+ handleOnKeyDown,
8125
+ handleOnKeyUp,
8126
+ handleOnMouseDown,
8127
+ handleOnMouseUp,
8128
+ handleOnTouchEnd,
8129
+ handleOnTouchStart
8130
+ ]);
8131
+ }
8132
+
8046
8133
  // Copyright (c) Microsoft Corporation.
8047
8134
  // Coin max size is set to PersonaSize.size100
8048
8135
  const DEFAULT_PERSONA_MAX_SIZE_PX = 100;
@@ -8095,6 +8182,26 @@ const VideoTile = (props) => {
8095
8182
  const currentObserver = observer.current;
8096
8183
  return () => currentObserver.disconnect();
8097
8184
  }, [observer, videoTileRef]);
8185
+ /* @conditional-compile-remove(pinned-participants) */
8186
+ const useLongPressProps = React.useMemo(() => {
8187
+ return {
8188
+ onLongPress: () => {
8189
+ var _a;
8190
+ (_a = props.onLongTouch) === null || _a === void 0 ? void 0 : _a.call(props);
8191
+ },
8192
+ touchEventsOnly: true
8193
+ };
8194
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8195
+ }, [props.onLongTouch]);
8196
+ /* @conditional-compile-remove(pinned-participants) */
8197
+ const longPressHandlers = useLongPress(useLongPressProps);
8198
+ const longPressHandlersTrampoline = React.useMemo(() => {
8199
+ /* @conditional-compile-remove(pinned-participants) */
8200
+ return longPressHandlers;
8201
+ }, [
8202
+ /* @conditional-compile-remove(pinned-participants) */
8203
+ longPressHandlers
8204
+ ]);
8098
8205
  const placeholderOptions = {
8099
8206
  userId,
8100
8207
  text: initialsName || displayName,
@@ -8109,7 +8216,7 @@ const VideoTile = (props) => {
8109
8216
  const canShowLabel = showLabel && (displayName || (showMuteIndicator && isMuted));
8110
8217
  const participantStateString = participantStateStringTrampoline(props, locale);
8111
8218
  return (React__default['default'].createElement(reactNorthstar.Ref, { innerRef: videoTileRef },
8112
- React__default['default'].createElement(react.Stack, { "data-ui-id": ids.videoTile, className: react.mergeStyles(rootStyles, {
8219
+ React__default['default'].createElement(react.Stack, Object.assign({ "data-ui-id": ids.videoTile, className: react.mergeStyles(rootStyles, {
8113
8220
  background: theme.palette.neutralLighter,
8114
8221
  borderRadius: theme.effects.roundedCorner4
8115
8222
  }, isSpeaking && {
@@ -8122,7 +8229,7 @@ const VideoTile = (props) => {
8122
8229
  width: '100%',
8123
8230
  height: '100%'
8124
8231
  }
8125
- }, styles === null || styles === void 0 ? void 0 : styles.root) },
8232
+ }, styles === null || styles === void 0 ? void 0 : styles.root) }, longPressHandlersTrampoline),
8126
8233
  isVideoRendered ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(videoContainerStyles, isMirrored && { transform: 'scaleX(-1)' }, styles === null || styles === void 0 ? void 0 : styles.videoContainer) }, renderElement)) : (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(videoContainerStyles), style: { opacity: participantStateString ? 0.4 : 1 } }, onRenderPlaceholder ? (onRenderPlaceholder(userId !== null && userId !== void 0 ? userId : '', placeholderOptions, DefaultPlaceholder)) : (React__default['default'].createElement(DefaultPlaceholder, Object.assign({}, placeholderOptions))))),
8127
8234
  (canShowLabel || participantStateString) && (React__default['default'].createElement(react.Stack, { horizontal: true, className: tileInfoContainerStyle, tokens: tileInfoContainerTokens },
8128
8235
  React__default['default'].createElement(react.Stack, { horizontal: true, className: tileInfoStyle },
@@ -11161,69 +11268,6 @@ const formatPhoneNumber = (phoneNumber) => {
11161
11268
  return `${countryCodeNA}(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3, 6)}-${phoneNumber.slice(6, phoneNumber.length)}`;
11162
11269
  };
11163
11270
 
11164
- // Copyright (c) Microsoft Corporation.
11165
- /**
11166
- * @private
11167
- */
11168
- function useLongPress(onClick, onLongPress, isMobile) {
11169
- const timerRef = React.useRef();
11170
- const [isLongPress, setIsLongPress] = React.useState(false);
11171
- const [action, setAction] = React.useState(false);
11172
- function startPressTimer() {
11173
- setIsLongPress(false);
11174
- timerRef.current = setTimeout(() => {
11175
- setIsLongPress(true);
11176
- }, 500);
11177
- }
11178
- function handleOnClick() {
11179
- // when it's mobile use ontouchstart and ontouchend to fire onclick and onlongpress event
11180
- if (isMobile) {
11181
- return;
11182
- }
11183
- onClick();
11184
- if (isLongPress) {
11185
- onLongPress();
11186
- return;
11187
- }
11188
- }
11189
- function handleOnKeyDown() {
11190
- if (action) {
11191
- setAction(false);
11192
- startPressTimer();
11193
- }
11194
- }
11195
- function handleOnKeyUp() {
11196
- setAction(true);
11197
- timerRef.current && clearTimeout(timerRef.current);
11198
- }
11199
- function handleOnMouseDown() {
11200
- startPressTimer();
11201
- }
11202
- function handleOnMouseUp() {
11203
- timerRef.current && clearTimeout(timerRef.current);
11204
- }
11205
- function handleOnTouchStart() {
11206
- startPressTimer();
11207
- }
11208
- function handleOnTouchEnd() {
11209
- if (isMobile) {
11210
- isLongPress ? onLongPress() : onClick();
11211
- }
11212
- timerRef.current && clearTimeout(timerRef.current);
11213
- }
11214
- return {
11215
- handlers: {
11216
- onClick: handleOnClick,
11217
- onMouseDown: handleOnMouseDown,
11218
- onMouseUp: handleOnMouseUp,
11219
- onTouchStart: handleOnTouchStart,
11220
- onTouchEnd: handleOnTouchEnd,
11221
- onKeyDown: handleOnKeyDown,
11222
- onKeyUp: handleOnKeyUp
11223
- }
11224
- };
11225
- }
11226
-
11227
11271
  // Copyright (c) Microsoft Corporation.
11228
11272
  // Licensed under the MIT license.
11229
11273
  var __awaiter$j = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
@@ -11267,14 +11311,17 @@ const DialpadButton = (props) => {
11267
11311
  var _a, _b, _c, _d;
11268
11312
  const theme = react.useTheme();
11269
11313
  const { digit, index, onClick, onLongPress, isMobile = false } = props;
11270
- const clickFunction = React.useCallback(() => __awaiter$j(void 0, void 0, void 0, function* () {
11271
- onClick(digit, index);
11272
- }), [digit, index, onClick]);
11273
- const longPressFunction = React.useCallback(() => __awaiter$j(void 0, void 0, void 0, function* () {
11274
- onLongPress(digit, index);
11275
- }), [digit, index, onLongPress]);
11276
- const { handlers } = useLongPress(clickFunction, longPressFunction, isMobile);
11277
- return (React__default['default'].createElement(react.DefaultButton, Object.assign({ "data-test-id": `dialpad-button-${props.index}`, styles: react.concatStyleSets(buttonStyles(), (_a = props.styles) === null || _a === void 0 ? void 0 : _a.button) }, handlers),
11314
+ const useLongPressProps = React__default['default'].useMemo(() => ({
11315
+ onClick: () => __awaiter$j(void 0, void 0, void 0, function* () {
11316
+ onClick(digit, index);
11317
+ }),
11318
+ onLongPress: () => __awaiter$j(void 0, void 0, void 0, function* () {
11319
+ onLongPress(digit, index);
11320
+ }),
11321
+ touchEventsOnly: isMobile
11322
+ }), [digit, index, isMobile, onClick, onLongPress]);
11323
+ const longPressHandlers = useLongPress(useLongPressProps);
11324
+ return (React__default['default'].createElement(react.DefaultButton, Object.assign({ "data-test-id": `dialpad-button-${props.index}`, styles: react.concatStyleSets(buttonStyles(), (_a = props.styles) === null || _a === void 0 ? void 0 : _a.button) }, longPressHandlers),
11278
11325
  React__default['default'].createElement(react.Stack, null,
11279
11326
  React__default['default'].createElement(react.Text, { className: react.mergeStyles(digitStyles(theme), (_b = props.styles) === null || _b === void 0 ? void 0 : _b.digit) }, props.digit),
11280
11327
  React__default['default'].createElement(react.Text, { className: react.mergeStyles(letterStyles(theme), (_c = props.styles) === null || _c === void 0 ? void 0 : _c.letter) }, (_d = props.letter) !== null && _d !== void 0 ? _d : ' '))));
@@ -13949,7 +13996,7 @@ const CallCompositeIcon = (props) => (React__default['default'].createElement(re
13949
13996
  */
13950
13997
  const CallWithChatCompositeIcon = (props) => (React__default['default'].createElement(react.FontIcon, Object.assign({}, props)));
13951
13998
 
13952
- var call$d={cameraLabel:"Camera",cameraPermissionDenied:"Your browser is blocking access to your camera",cameraTurnedOff:"Your camera is turned off",chatButtonLabel:"Chat",close:"Close",complianceBannerNowOnlyRecording:"You are now only recording this meeting.",complianceBannerNowOnlyTranscription:"You are now only transcribing this meeting.",complianceBannerRecordingAndTranscriptionSaved:"Recording and transcription are being saved.",complianceBannerRecordingAndTranscriptionStarted:"Recording and transcription have started.",complianceBannerRecordingAndTranscriptionStopped:"Recording and transcription have stopped.",complianceBannerRecordingSaving:"Recording is being saved.",complianceBannerRecordingStarted:"Recording has started.",complianceBannerRecordingStopped:"Recording has stopped.",complianceBannerTranscriptionStarted:"Transcription has started.",complianceBannerTranscriptionConsent:"By joining, you are giving consent for this meeting to be transcribed.",complianceBannerTranscriptionSaving:"Transcription is being saved.",complianceBannerTranscriptionStopped:"Transcription has stopped.",configurationPageTitle:"Start a call",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",defaultPlaceHolder:"Select an option",dismissSidePaneButtonLabel:"Close",failedToJoinCallDueToNoNetworkMoreDetails:"Call was disconnected due to a network issue. Check your connection and join again.",failedToJoinCallDueToNoNetworkTitle:"Call disconnected",failedToJoinTeamsMeetingReasonAccessDeniedMoreDetails:"You were not granted entry in the call. If this was a mistake, re-join the call.",failedToJoinTeamsMeetingReasonAccessDeniedTitle:"Dismissed from lobby",learnMore:"Learn more",leftCallMoreDetails:"If this was a mistake, re-join the call.",leftCallTitle:"You left the call",lobbyScreenConnectingToCallTitle:"Joining call",lobbyScreenWaitingToBeAdmittedTitle:"Waiting to be admitted",microphonePermissionDenied:"Your browser is blocking access to your microphone",microphoneToggleInLobbyNotAllowed:"Cannot mute or unmute while in lobby.",mutedMessage:"You're muted",networkReconnectMoreDetails:"Looks like something went wrong. We're trying to get back into the call.",networkReconnectTitle:"Hold on",deniedPermissionToRoomDetails:"You do not have permission to join this room.",deniedPermissionToRoomTitle:"Permission denied to room",peopleButtonLabel:"People",peoplePaneTitle:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",privacyPolicy:"Privacy policy",rejoinCallButtonLabel:"Re-join call",removedFromCallMoreDetails:"Another participant removed you from the call.",removedFromCallTitle:"You were removed",removeMenuLabel:"Remove",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",roomNotFoundDetails:"Room ID provided is not valid.",roomNotFoundTitle:"Room not found",soundLabel:"Sound",startCallButtonLabel:"Start call",openDialpadButtonLabel:"Dial phone number",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",moreButtonCallingLabel:"More",resumeCallButtonLabel:"Resume",resumingCallButtonLabel:"Resuming...",resumeCallButtonAriaLabel:"Resume call",resumingCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number",outboundCallingNoticeString:"Calling..."};var chat$d={chatListHeader:"In this chat",uploadFile:"Upload File"};var callWithChat$d={chatButtonLabel:"Chat",chatButtonNewMessageNotificationLabel:"New Message",chatButtonTooltipClosedWithMessageCount:"Show chat ({unreadMessagesCount} unread)",chatButtonTooltipClose:"Hide chat",chatButtonTooltipOpen:"Show chat",chatPaneTitle:"Chat",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",dismissSidePaneButtonLabel:"Close",moreDrawerAudioDeviceMenuTitle:"Audio Device",moreDrawerButtonLabel:"More options",moreDrawerButtonTooltip:"More options",moreDrawerMicrophoneMenuTitle:"Microphone",moreDrawerSpeakerMenuTitle:"Speaker",peopleButtonLabel:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",peoplePaneTitle:"People",pictureInPictureTileAriaLabel:"Video Feeds. Click to return to call screen.",removeMenuLabel:"Remove",openDialpadButtonLabel:"Dial phone number",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number"};var en_US = {call:call$d,chat:chat$d,callWithChat:callWithChat$d};
13999
+ var call$d={cameraLabel:"Camera",cameraPermissionDenied:"Your browser is blocking access to your camera",cameraTurnedOff:"Your camera is turned off",chatButtonLabel:"Chat",close:"Close",complianceBannerNowOnlyRecording:"You are now only recording this meeting.",complianceBannerNowOnlyTranscription:"You are now only transcribing this meeting.",complianceBannerRecordingAndTranscriptionSaved:"Recording and transcription are being saved.",complianceBannerRecordingAndTranscriptionStarted:"Recording and transcription have started.",complianceBannerRecordingAndTranscriptionStopped:"Recording and transcription have stopped.",complianceBannerRecordingSaving:"Recording is being saved.",complianceBannerRecordingStarted:"Recording has started.",complianceBannerRecordingStopped:"Recording has stopped.",complianceBannerTranscriptionStarted:"Transcription has started.",complianceBannerTranscriptionConsent:"By joining, you are giving consent for this meeting to be transcribed.",complianceBannerTranscriptionSaving:"Transcription is being saved.",complianceBannerTranscriptionStopped:"Transcription has stopped.",configurationPageTitle:"Start a call",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",defaultPlaceHolder:"Select an option",dismissSidePaneButtonLabel:"Close",failedToJoinCallDueToNoNetworkMoreDetails:"Call was disconnected due to a network issue. Check your connection and join again.",failedToJoinCallDueToNoNetworkTitle:"Call disconnected",failedToJoinTeamsMeetingReasonAccessDeniedMoreDetails:"You were not granted entry in the call. If this was a mistake, re-join the call.",failedToJoinTeamsMeetingReasonAccessDeniedTitle:"Dismissed from lobby",learnMore:"Learn more",leftCallMoreDetails:"If this was a mistake, re-join the call.",leftCallTitle:"You left the call",lobbyScreenConnectingToCallTitle:"Joining call",lobbyScreenWaitingToBeAdmittedTitle:"Waiting to be admitted",microphonePermissionDenied:"Your browser is blocking access to your microphone",microphoneToggleInLobbyNotAllowed:"Cannot mute or unmute while in lobby.",mutedMessage:"You're muted",networkReconnectMoreDetails:"Looks like something went wrong. We're trying to get back into the call.",networkReconnectTitle:"Hold on",deniedPermissionToRoomDetails:"You do not have permission to join this room.",deniedPermissionToRoomTitle:"Permission denied to room",peopleButtonLabel:"People",peoplePaneTitle:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",privacyPolicy:"Privacy policy",rejoinCallButtonLabel:"Re-join call",removedFromCallMoreDetails:"Another participant removed you from the call.",removedFromCallTitle:"You were removed",removeMenuLabel:"Remove",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",roomNotFoundDetails:"Room ID provided is not valid.",roomNotFoundTitle:"Room not found",soundLabel:"Sound",startCallButtonLabel:"Start call",openDialpadButtonLabel:"Dial phone number",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",moreButtonCallingLabel:"More",resumeCallButtonLabel:"Resume",resumingCallButtonLabel:"Resuming...",resumeCallButtonAriaLabel:"Resume call",resumingCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number",outboundCallingNoticeString:"Calling...",participantJoinedNoticeString:"{displayName} joined",twoParticipantJoinedNoticeString:"{displayName1} and {displayName2} have joined",threeParticipantJoinedNoticeString:"{displayName1}, {displayName2} and {displayName3} have joined",participantLeftNoticeString:"{displayName} left",twoParticipantLeftNoticeString:"{displayName1} and {displayName2} have left",threeParticipantLeftNoticeString:"{displayName1}, {displayName2} and {displayName3} have left",unnamedParticipantString:"unnamed participant",manyUnnamedParticipantsJoined:"unnamed participant and {numOfParticipants} other participants joined",manyUnnamedParticipantsLeft:"unnamed participant and {numOfParticipants} other participants left",manyParticipantsJoined:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants joined",manyParticipantsLeft:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants left"};var chat$d={chatListHeader:"In this chat",uploadFile:"Upload File"};var callWithChat$d={chatButtonLabel:"Chat",chatButtonNewMessageNotificationLabel:"New Message",chatButtonTooltipClosedWithMessageCount:"Show chat ({unreadMessagesCount} unread)",chatButtonTooltipClose:"Hide chat",chatButtonTooltipOpen:"Show chat",chatPaneTitle:"Chat",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",dismissSidePaneButtonLabel:"Close",moreDrawerAudioDeviceMenuTitle:"Audio Device",moreDrawerButtonLabel:"More options",moreDrawerButtonTooltip:"More options",moreDrawerMicrophoneMenuTitle:"Microphone",moreDrawerSpeakerMenuTitle:"Speaker",peopleButtonLabel:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",peoplePaneTitle:"People",pictureInPictureTileAriaLabel:"Video Feeds. Click to return to call screen.",removeMenuLabel:"Remove",openDialpadButtonLabel:"Dial phone number",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number"};var en_US = {call:call$d,chat:chat$d,callWithChat:callWithChat$d};
13953
14000
 
13954
14001
  var call$c={cameraLabel:"Camera",cameraPermissionDenied:"Your browser is blocking access to your camera",cameraTurnedOff:"Your camera is turned off",chatButtonLabel:"Chat",close:"Close",complianceBannerNowOnlyRecording:"You are now only recording this meeting.",complianceBannerNowOnlyTranscription:"You are now only transcribing this meeting.",complianceBannerRecordingAndTranscriptionSaved:"Recording and transcription are being saved.",complianceBannerRecordingAndTranscriptionStarted:"Recording and transcription have started.",complianceBannerRecordingAndTranscriptionStopped:"Recording and transcription have stopped.",complianceBannerRecordingSaving:"Recording is being saved.",complianceBannerRecordingStarted:"Recording has started.",complianceBannerRecordingStopped:"Recording has stopped.",complianceBannerTranscriptionStarted:"Transcription has started.",complianceBannerTranscriptionConsent:"By joining, you are giving consent for this meeting to be transcribed.",complianceBannerTranscriptionSaving:"Transcription is being saved.",complianceBannerTranscriptionStopped:"Transcription has stopped.",configurationPageTitle:"Start a call",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",defaultPlaceHolder:"Select an option",dismissSidePaneButtonLabel:"Close",failedToJoinCallDueToNoNetworkMoreDetails:"Call was disconnected due to a network issue. Check your connection and join again.",failedToJoinCallDueToNoNetworkTitle:"Call disconnected",failedToJoinTeamsMeetingReasonAccessDeniedMoreDetails:"You were not granted entry in the call. If this was a mistake, re-join the call.",failedToJoinTeamsMeetingReasonAccessDeniedTitle:"Dismissed from lobby",learnMore:"Learn more",leftCallMoreDetails:"If this was a mistake, re-join the call.",leftCallTitle:"You left the call",lobbyScreenConnectingToCallTitle:"Joining call",lobbyScreenWaitingToBeAdmittedTitle:"Waiting to be admitted",microphonePermissionDenied:"Your browser is blocking access to your microphone",microphoneToggleInLobbyNotAllowed:"Cannot mute or unmute while in lobby.",mutedMessage:"You're muted",networkReconnectMoreDetails:"Looks like something went wrong. We're trying to get back into the call.",networkReconnectTitle:"Hold on",deniedPermissionToRoomDetails:"You do not have permission to join this room.",deniedPermissionToRoomTitle:"Permission denied to room",peopleButtonLabel:"People",peoplePaneTitle:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",privacyPolicy:"Privacy policy",rejoinCallButtonLabel:"Re-join call",removedFromCallMoreDetails:"Another participant removed you from the call.",removedFromCallTitle:"You were removed",removeMenuLabel:"Remove",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",roomNotFoundDetails:"Room ID provided is not valid.",roomNotFoundTitle:"Room not found",soundLabel:"Sound",startCallButtonLabel:"Start call",openDialpadButtonLabel:"Dial phone number",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",moreButtonCallingLabel:"More",resumeCallButtonLabel:"Resume",resumingCallButtonLabel:"Resuming...",resumeCallButtonAriaLabel:"Resume call",resumingCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceHolderText:"Enter number",outboundCallingNoticeString:"Calling..."};var chat$c={chatListHeader:"In this chat",uploadFile:"Upload File"};var callWithChat$c={chatButtonLabel:"Chat",chatButtonNewMessageNotificationLabel:"New Message",chatButtonTooltipClosedWithMessageCount:"Show chat ({unreadMessagesCount} unread)",chatButtonTooltipClose:"Hide chat",chatButtonTooltipOpen:"Show chat",chatPaneTitle:"Chat",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",dismissSidePaneButtonLabel:"Close",moreDrawerAudioDeviceMenuTitle:"Audio Device",moreDrawerButtonLabel:"More options",moreDrawerButtonTooltip:"More options",moreDrawerMicrophoneMenuTitle:"Microphone",moreDrawerSpeakerMenuTitle:"Speaker",peopleButtonLabel:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",peoplePaneTitle:"People",pictureInPictureTileAriaLabel:"Video Feeds. Click to return to call screen.",removeMenuLabel:"Remove",openDialpadButtonLabel:"Dial phone number",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceHolderText:"Enter number"};var en_GB = {call:call$c,chat:chat$c,callWithChat:callWithChat$c};
13955
14002
 
@@ -17718,6 +17765,138 @@ const localVideoCameraCycleButtonSelector = reselect.createSelector([getDeviceMa
17718
17765
  };
17719
17766
  });
17720
17767
 
17768
+ // Copyright (c) Microsoft Corporation.
17769
+ /**
17770
+ * @private
17771
+ */
17772
+ const mediaGallerySelector = reselect__namespace.createSelector([getLocalVideoStreams], (localVideoStreams) => {
17773
+ var _a, _b;
17774
+ return {
17775
+ isVideoStreamOn: !!((_b = (_a = localVideoStreams === null || localVideoStreams === void 0 ? void 0 : localVideoStreams.find((stream) => stream.mediaStreamType === 'Video')) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.target)
17776
+ };
17777
+ });
17778
+ /**
17779
+ * Custom selector for this hook to retrieve all the participants that are currently
17780
+ * connected to the call.
17781
+ */
17782
+ const getRemoteParticipantsConnectedSelector = reselect__namespace.createSelector([getRemoteParticipants], (remoteParticipants) => {
17783
+ const participants = Object.values(remoteParticipants !== null && remoteParticipants !== void 0 ? remoteParticipants : {});
17784
+ return participants.filter((p) => p.state === 'Connected');
17785
+ });
17786
+
17787
+ // Copyright (c) Microsoft Corporation.
17788
+ /**
17789
+ * sets the announcement string whenever a Participant comes or goes from a call to be
17790
+ * used by the system narrator.
17791
+ *
17792
+ * @returns string to be used by the narrator and Announcer component
17793
+ *
17794
+ * @internal
17795
+ */
17796
+ const useParticipantChangedAnnouncement = () => {
17797
+ const locale = useLocale().strings.call;
17798
+ const strings = React.useMemo(() => {
17799
+ return {
17800
+ participantJoinedNoticeString: locale.participantJoinedNoticeString,
17801
+ twoParticipantJoinedNoticeString: locale.twoParticipantJoinedNoticeString,
17802
+ threeParticipantJoinedNoticeString: locale.threeParticipantJoinedNoticeString,
17803
+ participantLeftNoticeString: locale.participantLeftNoticeString,
17804
+ twoParticipantLeftNoticeString: locale.twoParticipantLeftNoticeString,
17805
+ threeParticipantLeftNoticeString: locale.threeParticipantLeftNoticeString,
17806
+ unnamedParticipantString: locale.unnamedParticipantString,
17807
+ manyParticipantsJoined: locale.manyParticipantsJoined,
17808
+ manyParticipantsLeft: locale.manyParticipantsLeft,
17809
+ manyUnnamedParticipantsJoined: locale.manyUnnamedParticipantsJoined,
17810
+ manyUnnamedParticipantsLeft: locale.manyUnnamedParticipantsLeft
17811
+ };
17812
+ }, [locale]);
17813
+ const [announcerString, setAnnouncerString] = React.useState('');
17814
+ const currentParticipants = useSelector$1(getRemoteParticipantsConnectedSelector);
17815
+ /**
17816
+ * We want to use a useRef here since we want to not fire this hook based on the previous participants
17817
+ * this allows this value to be used in the hook without being in the dependency array.
17818
+ *
17819
+ * Note: By definition if this hook is used in another component it is not pure anymore.
17820
+ */
17821
+ const previousParticipants = React.useRef(currentParticipants);
17822
+ const resetAnnoucement = (string) => {
17823
+ setAnnouncerString(string);
17824
+ };
17825
+ React.useMemo(() => {
17826
+ const currentIds = currentParticipants.map((p) => toFlatCommunicationIdentifier(p.identifier));
17827
+ const previousIds = previousParticipants.current.map((p) => toFlatCommunicationIdentifier(p.identifier));
17828
+ const whoJoined = currentParticipants.filter((p) => !previousIds.includes(toFlatCommunicationIdentifier(p.identifier)));
17829
+ const whoLeft = previousParticipants.current.filter((p) => !currentIds.includes(toFlatCommunicationIdentifier(p.identifier)));
17830
+ if (whoJoined.length > 0) {
17831
+ resetAnnoucement(createAnnouncmentString('joined', whoJoined, strings));
17832
+ }
17833
+ if (whoLeft.length > 0) {
17834
+ resetAnnoucement(createAnnouncmentString('left', whoLeft, strings));
17835
+ }
17836
+ // Update cached value at the end.
17837
+ previousParticipants.current = currentParticipants;
17838
+ }, [currentParticipants, strings]);
17839
+ return announcerString;
17840
+ };
17841
+ /**
17842
+ * Generates the announcement string for when a participant joins or leaves a call.
17843
+ */
17844
+ const createAnnouncmentString = (direction, participants, strings) => {
17845
+ var _a, _b, _c;
17846
+ /**
17847
+ * If there are no participants return empty string.
17848
+ */
17849
+ if (participants.length === 0) {
17850
+ return '';
17851
+ }
17852
+ /**
17853
+ * Filter participants into two arrays to put all the unnamed participants at the back of the
17854
+ * names being announced.
17855
+ */
17856
+ const unnamedParticipants = participants.filter((p) => p.displayName === undefined);
17857
+ const namedParicipants = participants.filter((p) => p.displayName);
17858
+ const sortedParticipants = namedParicipants.concat(unnamedParticipants);
17859
+ /**
17860
+ * if there are only unnamed participants present in the array announce a special unnamed participants
17861
+ * only string.
17862
+ */
17863
+ if (sortedParticipants.filter((p) => p.displayName).length === 0 && sortedParticipants.length > 1) {
17864
+ return _formatString(direction === 'joined' ? strings.manyUnnamedParticipantsJoined : strings.manyUnnamedParticipantsLeft, {
17865
+ numOfParticipants: (sortedParticipants.length - 1).toString()
17866
+ });
17867
+ }
17868
+ const participantNames = sortedParticipants.map((p) => { var _a; return (_a = p.displayName) !== null && _a !== void 0 ? _a : strings.unnamedParticipantString; });
17869
+ switch (sortedParticipants.length) {
17870
+ case 1:
17871
+ return _formatString(direction === 'joined' ? strings.participantJoinedNoticeString : strings.participantLeftNoticeString, { displayName: participantNames[0] });
17872
+ case 2:
17873
+ return _formatString(direction === 'joined' ? strings.twoParticipantJoinedNoticeString : strings.twoParticipantLeftNoticeString, {
17874
+ displayName1: participantNames[0],
17875
+ displayName2: participantNames[1]
17876
+ });
17877
+ case 3:
17878
+ return _formatString(direction === 'joined' ? strings.threeParticipantJoinedNoticeString : strings.threeParticipantLeftNoticeString, {
17879
+ displayName1: participantNames[0],
17880
+ displayName2: participantNames[1],
17881
+ displayName3: participantNames[2]
17882
+ });
17883
+ }
17884
+ /**
17885
+ * If we have more than 3 participants joining we need to do something more to announce them
17886
+ * appropriately.
17887
+ *
17888
+ * We don't want to announce every name when more than 3 participants join at once so
17889
+ * we parse out the first 3 names we have and announce those with the number of others.
17890
+ */
17891
+ const numberOfExtraParticipants = sortedParticipants.length - 3;
17892
+ return _formatString(direction === 'joined' ? strings.manyParticipantsJoined : strings.manyParticipantsLeft, {
17893
+ displayName1: (_a = sortedParticipants[0].displayName) !== null && _a !== void 0 ? _a : strings.unnamedParticipantString,
17894
+ displayName2: (_b = sortedParticipants[1].displayName) !== null && _b !== void 0 ? _b : strings.unnamedParticipantString,
17895
+ displayName3: (_c = sortedParticipants[2].displayName) !== null && _c !== void 0 ? _c : strings.unnamedParticipantString,
17896
+ numOfParticipants: numberOfExtraParticipants.toString()
17897
+ });
17898
+ };
17899
+
17721
17900
  // Copyright (c) Microsoft Corporation.
17722
17901
  const VideoGalleryStyles = {
17723
17902
  root: {
@@ -17740,6 +17919,7 @@ const MediaGallery = (props) => {
17740
17919
  const videoGalleryProps = usePropsFor$1(VideoGallery);
17741
17920
  const cameraSwitcherCameras = useSelector$1(localVideoCameraCycleButtonSelector);
17742
17921
  const cameraSwitcherCallback = useHandlers();
17922
+ const announcerString = useParticipantChangedAnnouncement();
17743
17923
  const cameraSwitcherProps = React.useMemo(() => {
17744
17924
  return Object.assign(Object.assign({}, cameraSwitcherCallback), cameraSwitcherCameras);
17745
17925
  }, [cameraSwitcherCallback, cameraSwitcherCameras]);
@@ -17752,7 +17932,9 @@ const MediaGallery = (props) => {
17752
17932
  const VideoGalleryMemoized = React.useMemo(() => {
17753
17933
  return (React__default['default'].createElement(VideoGallery, Object.assign({}, videoGalleryProps, { localVideoViewOptions: localVideoViewOptions$2, remoteVideoViewOptions: remoteVideoViewOptions, styles: VideoGalleryStyles, layout: "floatingLocalVideo", showCameraSwitcherInLocalPreview: props.isMobile, localVideoCameraCycleButtonProps: cameraSwitcherProps, onRenderAvatar: onRenderAvatar })));
17754
17934
  }, [videoGalleryProps, props.isMobile, onRenderAvatar, cameraSwitcherProps]);
17755
- return VideoGalleryMemoized;
17935
+ return (React__default['default'].createElement(React__default['default'].Fragment, null,
17936
+ React__default['default'].createElement(Announcer, { announcementString: announcerString, ariaLive: 'polite' }),
17937
+ VideoGalleryMemoized));
17756
17938
  };
17757
17939
  /**
17758
17940
  * @private
@@ -17917,17 +18099,6 @@ const complianceBannerSelector = reselect__namespace.createSelector([getIsTransc
17917
18099
  };
17918
18100
  });
17919
18101
 
17920
- // Copyright (c) Microsoft Corporation.
17921
- /**
17922
- * @private
17923
- */
17924
- const mediaGallerySelector = reselect__namespace.createSelector([getLocalVideoStreams], (localVideoStreams) => {
17925
- var _a, _b;
17926
- return {
17927
- isVideoStreamOn: !!((_b = (_a = localVideoStreams === null || localVideoStreams === void 0 ? void 0 : localVideoStreams.find((stream) => stream.mediaStreamType === 'Video')) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.target)
17928
- };
17929
- });
17930
-
17931
18102
  // Copyright (c) Microsoft Corporation.
17932
18103
  /**
17933
18104
  * @private