@azure/communication-react 1.3.3-alpha-202208170014.0 → 1.3.3-alpha-202208180014.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 (78) hide show
  1. package/dist/communication-react.d.ts +16 -0
  2. package/dist/dist-cjs/communication-react/index.js +477 -458
  3. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  4. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  5. package/dist/dist-esm/calling-component-bindings/src/utils/callUtils.js +1 -1
  6. package/dist/dist-esm/calling-component-bindings/src/utils/callUtils.js.map +1 -1
  7. package/dist/dist-esm/react-components/src/components/ParticipantList.d.ts.map +1 -1
  8. package/dist/dist-esm/react-components/src/components/ParticipantList.js +8 -1
  9. package/dist/dist-esm/react-components/src/components/ParticipantList.js.map +1 -1
  10. package/dist/dist-esm/react-components/src/components/ParticipantsButton.d.ts.map +1 -1
  11. package/dist/dist-esm/react-components/src/components/ParticipantsButton.js +1 -5
  12. package/dist/dist-esm/react-components/src/components/ParticipantsButton.js.map +1 -1
  13. package/dist/dist-esm/react-components/src/components/RemoteVideoTile.d.ts.map +1 -1
  14. package/dist/dist-esm/react-components/src/components/RemoteVideoTile.js +47 -6
  15. package/dist/dist-esm/react-components/src/components/RemoteVideoTile.js.map +1 -1
  16. package/dist/dist-esm/react-components/src/components/VideoTile.d.ts +2 -1
  17. package/dist/dist-esm/react-components/src/components/VideoTile.d.ts.map +1 -1
  18. package/dist/dist-esm/react-components/src/components/VideoTile.js +34 -40
  19. package/dist/dist-esm/react-components/src/components/VideoTile.js.map +1 -1
  20. package/dist/dist-esm/react-components/src/components/styles/VideoTile.styles.d.ts +3 -3
  21. package/dist/dist-esm/react-components/src/components/styles/VideoTile.styles.d.ts.map +1 -1
  22. package/dist/dist-esm/react-components/src/components/styles/VideoTile.styles.js +19 -9
  23. package/dist/dist-esm/react-components/src/components/styles/VideoTile.styles.js.map +1 -1
  24. package/dist/dist-esm/react-components/src/components/utils/common.d.ts +5 -0
  25. package/dist/dist-esm/react-components/src/components/utils/common.d.ts.map +1 -1
  26. package/dist/dist-esm/react-components/src/components/utils/common.js +6 -0
  27. package/dist/dist-esm/react-components/src/components/utils/common.js.map +1 -1
  28. package/dist/dist-esm/react-components/src/permissions/PermissionsProvider.d.ts +1 -1
  29. package/dist/dist-esm/react-components/src/permissions/PermissionsProvider.d.ts.map +1 -1
  30. package/dist/dist-esm/react-components/src/permissions/PermissionsProvider.js +3 -3
  31. package/dist/dist-esm/react-components/src/permissions/PermissionsProvider.js.map +1 -1
  32. package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts +8 -0
  33. package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts.map +1 -1
  34. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.d.ts.map +1 -1
  35. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js +4 -3
  36. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js.map +1 -1
  37. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallControls.d.ts.map +1 -1
  38. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallControls.js +15 -2
  39. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallControls.js.map +1 -1
  40. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/MediaGallery.d.ts.map +1 -1
  41. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/MediaGallery.js +2 -23
  42. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/MediaGallery.js.map +1 -1
  43. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/People.d.ts.map +1 -1
  44. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/People.js +1 -11
  45. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/People.js.map +1 -1
  46. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.d.ts.map +1 -1
  47. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js +2 -1
  48. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js.map +1 -1
  49. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.d.ts.map +1 -1
  50. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js +33 -2
  51. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js.map +1 -1
  52. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.d.ts +1 -0
  53. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.d.ts.map +1 -1
  54. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.js +6 -23
  55. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.js.map +1 -1
  56. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/PreparedMoreDrawer.d.ts +1 -0
  57. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/PreparedMoreDrawer.d.ts.map +1 -1
  58. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/PreparedMoreDrawer.js.map +1 -1
  59. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/Strings.d.ts +8 -0
  60. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/Strings.d.ts.map +1 -1
  61. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/DesktopMoreButton.d.ts +5 -1
  62. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/DesktopMoreButton.d.ts.map +1 -1
  63. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/DesktopMoreButton.js +14 -0
  64. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/DesktopMoreButton.js.map +1 -1
  65. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/MoreDrawer.d.ts +1 -0
  66. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/MoreDrawer.d.ts.map +1 -1
  67. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/MoreDrawer.js +11 -0
  68. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/MoreDrawer.js.map +1 -1
  69. package/dist/dist-esm/react-composites/src/composites/common/SendDtmfDialpad.d.ts +1 -0
  70. package/dist/dist-esm/react-composites/src/composites/common/SendDtmfDialpad.d.ts.map +1 -1
  71. package/dist/dist-esm/react-composites/src/composites/common/SendDtmfDialpad.js +2 -5
  72. package/dist/dist-esm/react-composites/src/composites/common/SendDtmfDialpad.js.map +1 -1
  73. package/dist/dist-esm/react-composites/src/composites/localization/locales/en-US/strings.json +6 -2
  74. package/package.json +8 -8
  75. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/MediaGallery.styles.d.ts +0 -40
  76. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/MediaGallery.styles.d.ts.map +0 -1
  77. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/MediaGallery.styles.js +0 -64
  78. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/MediaGallery.styles.js.map +0 -1
@@ -192,7 +192,7 @@ const fromFlatCommunicationIdentifier = (id) => {
192
192
  // Copyright (c) Microsoft Corporation.
193
193
  // Licensed under the MIT license.
194
194
  // GENERATED FILE. DO NOT EDIT MANUALLY.
195
- var telemetryVersion = '1.3.3-alpha-202208170014.0';
195
+ var telemetryVersion = '1.3.3-alpha-202208180014.0';
196
196
 
197
197
  // Copyright (c) Microsoft Corporation.
198
198
  /**
@@ -405,7 +405,7 @@ var __awaiter$u = (window && window.__awaiter) || function (thisArg, _arguments,
405
405
  *
406
406
  * @internal
407
407
  */
408
- const _isInCall = (callStatus) => !!callStatus && !['None', 'Disconnected', 'Connecting', 'LocalHold', 'RemoteHold', 'Ringing'].includes(callStatus);
408
+ const _isInCall = (callStatus) => !!callStatus && !['None', 'Disconnected', 'Connecting', 'LocalHold', 'Ringing', 'EarlyMedia'].includes(callStatus);
409
409
  /**
410
410
  * Check if the call state represents being in the lobby or waiting to be admitted.
411
411
  *
@@ -2271,6 +2271,12 @@ const useLocaleFileCardStringsTrampoline = () => {
2271
2271
  /* @conditional-compile-remove(file-sharing) */
2272
2272
  return useLocale$1().strings.sendBox;
2273
2273
  };
2274
+ /**
2275
+ * Identify if a participant state if part of the Calling states or Hold states.
2276
+ */
2277
+ const _isParticipantStateCallingOrHold = (participantState) => {
2278
+ return !!participantState && ['Idle', 'Connecting', 'EarlyMedia', 'Ringing', 'Hold'].includes(participantState);
2279
+ };
2274
2280
 
2275
2281
  // Copyright (c) Microsoft Corporation.
2276
2282
  /**
@@ -4348,7 +4354,7 @@ const participantStateMaxWidth = '5rem';
4348
4354
  /**
4349
4355
  * @private
4350
4356
  */
4351
- const participantStateStringStyles = {
4357
+ const participantStateStringStyles$1 = {
4352
4358
  maxWidth: participantStateMaxWidth,
4353
4359
  overflow: 'hidden',
4354
4360
  textOverflow: 'ellipsis',
@@ -4421,7 +4427,7 @@ const ParticipantItem = (props) => {
4421
4427
  setItemHovered(false);
4422
4428
  setMenuHidden(true);
4423
4429
  };
4424
- const participantStateString = participantStateStringTrampoline(props, strings);
4430
+ const participantStateString = participantStateStringTrampoline$1(props, strings);
4425
4431
  return (React__default['default'].createElement("div", { ref: containerRef, role: 'menuitem', "data-is-focusable": true, className: react.mergeStyles(participantItemContainerStyle({ localparticipant: me, clickable: !!menuItems }), styles === null || styles === void 0 ? void 0 : styles.root), onMouseEnter: () => setItemHovered(true), onMouseLeave: () => setItemHovered(false), onClick: () => {
4426
4432
  if (!participantStateString) {
4427
4433
  setItemHovered(true);
@@ -4436,13 +4442,13 @@ const ParticipantItem = (props) => {
4436
4442
  avatar,
4437
4443
  me && React__default['default'].createElement(react.Text, { className: meTextStyle }, strings.isMeText),
4438
4444
  React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(infoContainerStyle) }, onRenderIcon && onRenderIcon(props))),
4439
- !me && participantStateString ? (React__default['default'].createElement(react.Text, { "data-ui-id": "participant-item-state-string", className: react.mergeStyles(participantStateStringStyles) }, participantStateString)) : (React__default['default'].createElement("div", null, menuItems && menuItems.length > 0 && (React__default['default'].createElement(React__default['default'].Fragment, null,
4445
+ !me && participantStateString ? (React__default['default'].createElement(react.Text, { "data-ui-id": "participant-item-state-string", className: react.mergeStyles(participantStateStringStyles$1) }, participantStateString)) : (React__default['default'].createElement("div", null, menuItems && menuItems.length > 0 && (React__default['default'].createElement(React__default['default'].Fragment, null,
4440
4446
  menuButton,
4441
4447
  React__default['default'].createElement(react.ContextualMenu, { items: menuItems, hidden: menuHidden, target: containerRef, onItemClick: onDismissMenu, onDismiss: onDismissMenu, directionalHint: react.DirectionalHint.bottomRightEdge, className: contextualMenuStyle, calloutProps: {
4442
4448
  preventDismissOnEvent: _preventDismissOnEvent
4443
4449
  } })))))));
4444
4450
  };
4445
- const participantStateStringTrampoline = (props, strings) => {
4451
+ const participantStateStringTrampoline$1 = (props, strings) => {
4446
4452
  /* @conditional-compile-remove(one-to-n-calling) */
4447
4453
  /* @conditional-compile-remove(PSTN-calls) */
4448
4454
  return props.participantState === 'Idle' || props.participantState === 'Connecting'
@@ -4454,6 +4460,65 @@ const participantStateStringTrampoline = (props, strings) => {
4454
4460
  : undefined;
4455
4461
  };
4456
4462
 
4463
+ // Copyright (c) Microsoft Corporation.
4464
+ /**
4465
+ * @internal
4466
+ */
4467
+ const presenterPermissions = {
4468
+ cameraButton: true,
4469
+ microphoneButton: true,
4470
+ screenShare: true,
4471
+ removeParticipantButton: true
4472
+ };
4473
+ /**
4474
+ * @internal
4475
+ */
4476
+ const consumerPermissions = {
4477
+ cameraButton: false,
4478
+ microphoneButton: false,
4479
+ screenShare: false,
4480
+ removeParticipantButton: false
4481
+ };
4482
+ /**
4483
+ * @internal
4484
+ */
4485
+ const attendeePermissions = {
4486
+ cameraButton: true,
4487
+ microphoneButton: true,
4488
+ screenShare: false,
4489
+ removeParticipantButton: false
4490
+ };
4491
+ /**
4492
+ * @internal
4493
+ */
4494
+ const PermissionsContext = React.createContext(presenterPermissions);
4495
+ /**
4496
+ * @internal
4497
+ */
4498
+ const _PermissionsProvider = (props) => {
4499
+ const { permissions, children } = props;
4500
+ return React__default['default'].createElement(PermissionsContext.Provider, { value: permissions }, children);
4501
+ };
4502
+ /**
4503
+ * @internal
4504
+ * React hook to access permissions
4505
+ */
4506
+ const _usePermissions = () => React.useContext(PermissionsContext);
4507
+ /**
4508
+ * @internal
4509
+ */
4510
+ const _getPermissions = (role) => {
4511
+ if (role === 'Consumer') {
4512
+ return consumerPermissions;
4513
+ }
4514
+ else if (role === 'Attendee') {
4515
+ return attendeePermissions;
4516
+ }
4517
+ else {
4518
+ return presenterPermissions;
4519
+ }
4520
+ };
4521
+
4457
4522
  // Copyright (c) Microsoft Corporation.
4458
4523
  /**
4459
4524
  * @private
@@ -4534,6 +4599,11 @@ const ParticipantList = (props) => {
4534
4599
  const createParticipantMenuItems = (participant) => {
4535
4600
  var _a, _b;
4536
4601
  let menuItems = [];
4602
+ let disabled = !participant.isRemovable;
4603
+ /* @conditional-compile-remove(rooms) */
4604
+ const isRemovable = _usePermissions().removeParticipantButton;
4605
+ /* @conditional-compile-remove(rooms) */
4606
+ disabled = !isRemovable || disabled;
4537
4607
  if (participant.userId !== myUserId && onRemoveParticipant) {
4538
4608
  menuItems.push({
4539
4609
  key: 'remove',
@@ -4542,7 +4612,7 @@ const ParticipantList = (props) => {
4542
4612
  itemProps: {
4543
4613
  styles: (_b = (_a = props.styles) === null || _a === void 0 ? void 0 : _a.participantItemStyles) === null || _b === void 0 ? void 0 : _b.participantSubMenuItemsStyles
4544
4614
  },
4545
- disabled: !participant.isRemovable,
4615
+ disabled: disabled,
4546
4616
  'data-ui-id': ids.participantListRemoveParticipantButton
4547
4617
  });
4548
4618
  }
@@ -4769,15 +4839,6 @@ const displayNameStyle = {
4769
4839
  textOverflow: 'ellipsis',
4770
4840
  maxWidth: '100%'
4771
4841
  };
4772
- /**
4773
- * @private
4774
- */
4775
- const participantStateStyle$1 = {
4776
- textAlign: 'center',
4777
- paddingTop: '0.5rem',
4778
- fontWeight: 600,
4779
- fontSize: '0.75rem'
4780
- };
4781
4842
  /**
4782
4843
  * @private
4783
4844
  */
@@ -4801,6 +4862,25 @@ const isSpeakingBorderDiv = {
4801
4862
  // Ensure the isSpeaking element does not steal any pointer events such as onClick events
4802
4863
  pointerEvents: 'none'
4803
4864
  };
4865
+ /**
4866
+ * @private
4867
+ */
4868
+ const participantStateStringStyles = (showLabel) => {
4869
+ return {
4870
+ textAlign: 'center',
4871
+ minWidth: '3rem',
4872
+ color: 'inherit',
4873
+ width: showLabel ? 'auto' : '100%',
4874
+ marginRight: showLabel ? 0 : 'none',
4875
+ marginLeft: showLabel ? 'auto' : 'none',
4876
+ fontSize: '0.75rem',
4877
+ lineHeight: 'normal',
4878
+ overflow: 'hidden',
4879
+ textOverflow: 'ellipsis',
4880
+ whiteSpace: 'nowrap',
4881
+ padding: '0.25rem'
4882
+ };
4883
+ };
4804
4884
 
4805
4885
  // Copyright (c) Microsoft Corporation.
4806
4886
  /**
@@ -4817,26 +4897,10 @@ const DEFAULT_PERSONA_MAX_SIZE_PX = 100;
4817
4897
  // Coin min size is set PersonaSize.size32
4818
4898
  const DEFAULT_PERSONA_MIN_SIZE_PX = 32;
4819
4899
  const DefaultPlaceholder = (props) => {
4820
- const { text, noVideoAvailableAriaLabel, coinSize, hidePersonaDetails, participantState, strings } = props;
4821
- const participantStateString = React__default['default'].useMemo(() => {
4822
- if (!strings) {
4823
- return;
4824
- }
4825
- if (participantState === 'Idle' || participantState === 'Connecting') {
4826
- return strings === null || strings === void 0 ? void 0 : strings.participantStateConnecting;
4827
- }
4828
- else if (participantState === 'EarlyMedia' || participantState === 'Ringing') {
4829
- return strings === null || strings === void 0 ? void 0 : strings.participantStateRinging;
4830
- }
4831
- else if (participantState === 'Hold') {
4832
- return strings === null || strings === void 0 ? void 0 : strings.participantStateHold;
4833
- }
4834
- return;
4835
- }, [participantState, strings]);
4900
+ const { text, noVideoAvailableAriaLabel, coinSize, hidePersonaDetails } = props;
4836
4901
  return (React__default['default'].createElement(react.Stack, { className: react.mergeStyles({ position: 'absolute', height: '100%', width: '100%' }) },
4837
4902
  React__default['default'].createElement(react.Stack, { styles: defaultPersonaStyles },
4838
- React__default['default'].createElement(react.Persona, { coinSize: coinSize, hidePersonaDetails: hidePersonaDetails, text: text !== null && text !== void 0 ? text : '', initialsTextColor: "white", "aria-label": noVideoAvailableAriaLabel !== null && noVideoAvailableAriaLabel !== void 0 ? noVideoAvailableAriaLabel : '', showOverflowTooltip: false }),
4839
- participantStateString && React__default['default'].createElement(react.Text, { className: react.mergeStyles(participantStateStyle$1) }, participantStateString))));
4903
+ React__default['default'].createElement(react.Persona, { coinSize: coinSize, hidePersonaDetails: hidePersonaDetails, text: text !== null && text !== void 0 ? text : '', initialsTextColor: "white", "aria-label": noVideoAvailableAriaLabel !== null && noVideoAvailableAriaLabel !== void 0 ? noVideoAvailableAriaLabel : '', showOverflowTooltip: false }))));
4840
4904
  };
4841
4905
  const defaultPersonaStyles = { root: { margin: 'auto', maxHeight: '100%' } };
4842
4906
  /**
@@ -4847,15 +4911,10 @@ const defaultPersonaStyles = { root: { margin: 'auto', maxHeight: '100%' } };
4847
4911
  * @public
4848
4912
  */
4849
4913
  const VideoTile = (props) => {
4850
- const { children, displayName, initialsName, isMirrored, isMuted, onRenderPlaceholder, renderElement, showLabel = true, showMuteIndicator = true, styles, userId, noVideoAvailableAriaLabel, isSpeaking, personaMinSize = DEFAULT_PERSONA_MIN_SIZE_PX, personaMaxSize = DEFAULT_PERSONA_MAX_SIZE_PX,
4851
- /* @conditional-compile-remove(one-to-n-calling) */
4852
- /* @conditional-compile-remove(PSTN-calls) */
4853
- participantState } = props;
4854
- /* @conditional-compile-remove(one-to-n-calling) */
4855
- // @conditional-compile-remove(PSTN-calls)
4856
- const strings = Object.assign(Object.assign({}, useLocale$1().strings.videoTile), props.strings);
4914
+ const { children, displayName, initialsName, isMirrored, isMuted, onRenderPlaceholder, renderElement, showLabel = true, showMuteIndicator = true, styles, userId, noVideoAvailableAriaLabel, isSpeaking, personaMinSize = DEFAULT_PERSONA_MIN_SIZE_PX, personaMaxSize = DEFAULT_PERSONA_MAX_SIZE_PX } = props;
4857
4915
  const [personaSize, setPersonaSize] = React.useState(100);
4858
4916
  const videoTileRef = React.useRef(null);
4917
+ const locale = useLocale$1();
4859
4918
  const theme = useTheme();
4860
4919
  const isVideoRendered = !!renderElement;
4861
4920
  const observer = React.useRef(new ResizeObserver((entries) => {
@@ -4876,14 +4935,13 @@ const VideoTile = (props) => {
4876
4935
  noVideoAvailableAriaLabel,
4877
4936
  coinSize: personaSize,
4878
4937
  styles: defaultPersonaStyles,
4879
- hidePersonaDetails: true,
4880
- /* @conditional-compile-remove(one-to-n-calling) */
4881
- /* @conditional-compile-remove(PSTN-calls) */
4882
- participantState: participantState
4938
+ hidePersonaDetails: true
4883
4939
  };
4884
4940
  const videoHintWithBorderRadius = react.mergeStyles(videoHint, { borderRadius: theme.effects.roundedCorner4 });
4885
4941
  const tileInfoStyle = React.useMemo(() => react.mergeStyles(isVideoRendered ? videoHintWithBorderRadius : disabledVideoHint, getVideoTileOverrideColor(isVideoRendered, theme, 'neutralPrimary'), styles === null || styles === void 0 ? void 0 : styles.displayNameContainer), [isVideoRendered, videoHintWithBorderRadius, theme, styles === null || styles === void 0 ? void 0 : styles.displayNameContainer]);
4886
4942
  const ids = useIdentifiers();
4943
+ const canShowLabel = showLabel && (displayName || (showMuteIndicator && isMuted));
4944
+ const participantStateString = participantStateStringTrampoline(props, locale);
4887
4945
  return (React__default['default'].createElement(reactNorthstar.Ref, { innerRef: videoTileRef },
4888
4946
  React__default['default'].createElement(react.Stack, { "data-ui-id": ids.videoTile, className: react.mergeStyles(rootStyles, {
4889
4947
  background: theme.palette.neutralLighter,
@@ -4893,216 +4951,33 @@ const VideoTile = (props) => {
4893
4951
  borderRadius: theme.effects.roundedCorner4,
4894
4952
  border: `0.25rem solid ${isSpeaking ? theme.palette.themePrimary : 'transparent'}`
4895
4953
  }) }),
4896
- 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) }, onRenderPlaceholder ? (onRenderPlaceholder(userId !== null && userId !== void 0 ? userId : '', placeholderOptions, DefaultPlaceholder)) : (React__default['default'].createElement(DefaultPlaceholder, Object.assign({}, placeholderOptions, {
4897
- /* @conditional-compile-remove(one-to-n-calling) */
4898
- // @conditional-compile-remove(PSTN-calls)
4899
- strings: strings }))))),
4900
- showLabel && (displayName || (showMuteIndicator && isMuted)) && (React__default['default'].createElement(react.Stack, { horizontal: true, className: tileInfoContainerStyle },
4901
- React__default['default'].createElement(react.Stack, { horizontal: true, className: tileInfoStyle },
4902
- displayName && (React__default['default'].createElement(react.Text, { className: react.mergeStyles(displayNameStyle), title: displayName }, displayName)),
4954
+ 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) }, onRenderPlaceholder ? (onRenderPlaceholder(userId !== null && userId !== void 0 ? userId : '', placeholderOptions, DefaultPlaceholder)) : (React__default['default'].createElement(DefaultPlaceholder, Object.assign({}, placeholderOptions))))),
4955
+ (canShowLabel || participantStateString) && (React__default['default'].createElement(react.Stack, { horizontal: true, className: tileInfoContainerStyle, tokens: tileInfoContainerTokens },
4956
+ canShowLabel && (React__default['default'].createElement(react.Stack, { horizontal: true, className: tileInfoStyle },
4957
+ React__default['default'].createElement(react.Text, { className: react.mergeStyles(displayNameStyle), title: displayName }, displayName),
4903
4958
  showMuteIndicator && isMuted && (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(iconContainerStyle) },
4904
- React__default['default'].createElement(react.Icon, { iconName: "VideoTileMicOff" })))))),
4959
+ React__default['default'].createElement(react.Icon, { iconName: "VideoTileMicOff" }))))),
4960
+ participantStateString && (React__default['default'].createElement(react.Text, { className: react.mergeStyles(participantStateStringStyles(showLabel)) }, participantStateString)))),
4905
4961
  children && (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(overlayContainerStyles, styles === null || styles === void 0 ? void 0 : styles.overlayContainer) }, children)))));
4906
4962
  };
4907
-
4908
- // Copyright (c) Microsoft Corporation.
4909
- /**
4910
- * A memoized version of VideoTile for rendering remote participants. React.memo is used for a performance
4911
- * boost by memoizing the same rendered component to avoid rerendering a VideoTile when its position in the
4912
- * array changes causing a rerender in the parent component. https://reactjs.org/docs/react-api.html#reactmemo
4913
- *
4914
- * @internal
4915
- */
4916
- const _RemoteVideoTile = React__default['default'].memo((props) => {
4917
- const { isAvailable, isReceiving = true, // default to true to prevent any breaking change
4918
- isMuted, isSpeaking, isScreenSharingOn, onCreateRemoteStreamView, onDisposeRemoteStreamView, remoteVideoViewOptions, renderElement, userId, displayName, onRenderAvatar, showMuteIndicator,
4963
+ const participantStateStringTrampoline = (props, locale) => {
4919
4964
  /* @conditional-compile-remove(one-to-n-calling) */
4920
4965
  /* @conditional-compile-remove(PSTN-calls) */
4921
- participantState } = props;
4922
- const remoteVideoStreamProps = React.useMemo(() => ({
4923
- isMirrored: remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.isMirrored,
4924
- isScreenSharingOn,
4925
- isStreamAvailable: isAvailable,
4926
- isStreamReceiving: isReceiving,
4927
- onCreateRemoteStreamView,
4928
- onDisposeRemoteStreamView,
4929
- remoteParticipantId: userId,
4930
- renderElementExists: !!renderElement,
4931
- scalingMode: remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.scalingMode
4932
- }), [
4933
- isAvailable,
4934
- isReceiving,
4935
- isScreenSharingOn,
4936
- onCreateRemoteStreamView,
4937
- onDisposeRemoteStreamView,
4938
- remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.isMirrored,
4939
- remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.scalingMode,
4940
- renderElement,
4941
- userId
4942
- ]);
4943
- // Handle creating, destroying and updating the video stream as necessary
4944
- useRemoteVideoStreamLifecycleMaintainer(remoteVideoStreamProps);
4945
- const renderVideoStreamElement = React.useMemo(() => {
4946
- // Checking if renderElement is well defined or not as calling SDK has a number of video streams limitation which
4947
- // implies that, after their threshold, all streams have no child (blank video)
4948
- if (!renderElement || !renderElement.childElementCount) {
4949
- // Returning `undefined` results in the placeholder with avatar being shown
4950
- return undefined;
4951
- }
4952
- return (React__default['default'].createElement(StreamMedia, { videoStreamElement: renderElement, loadingState: isReceiving === false ? 'loading' : 'none' }));
4953
- }, [renderElement, isReceiving]);
4954
- return (React__default['default'].createElement(VideoTile, { key: userId, userId: userId, renderElement: renderVideoStreamElement, displayName: displayName, onRenderPlaceholder: onRenderAvatar, isMuted: isMuted, isSpeaking: isSpeaking, showMuteIndicator: showMuteIndicator, showLabel: props.showLabel, personaMinSize: props.personaMinSize,
4955
- /* @conditional-compile-remove(one-to-n-calling) */
4956
- /* @conditional-compile-remove(PSTN-calls) */
4957
- participantState: participantState }));
4958
- });
4959
-
4960
- // Copyright (c) Microsoft Corporation.
4961
- // Licensed under the MIT license.
4962
- /**
4963
- * Horizontal Gallery button width in rem
4964
- */
4965
- const HORIZONTAL_GALLERY_BUTTON_WIDTH = 1.75;
4966
- /**
4967
- * @private
4968
- */
4969
- const leftRightButtonStyles = (theme) => {
4970
- return {
4971
- background: 'none',
4972
- padding: 0,
4973
- height: 'auto',
4974
- minWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
4975
- maxWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
4976
- border: `1px solid ${theme.palette.neutralLight}`,
4977
- borderRadius: theme.effects.roundedCorner4
4978
- };
4979
- };
4980
- /**
4981
- * Horizontal Gallery gap size in rem between tiles and buttons
4982
- */
4983
- const HORIZONTAL_GALLERY_GAP = 0.5;
4984
- /**
4985
- * @private
4986
- */
4987
- const rootStyle = {
4988
- height: '100%',
4989
- width: '100%',
4990
- gap: `${HORIZONTAL_GALLERY_GAP}rem`
4991
- };
4992
- /**
4993
- * @private
4994
- */
4995
- const childrenContainerStyle = {
4996
- height: '100%',
4997
- gap: `${HORIZONTAL_GALLERY_GAP}rem`
4998
- };
4999
-
5000
- // Copyright (c) Microsoft Corporation.
5001
- /**
5002
- * {@link HorizontalGallery} default children per page
5003
- */
5004
- const DEFAULT_CHILDREN_PER_PAGE = 5;
5005
- /**
5006
- * Renders a horizontal gallery that parents children horizontally. Handles pagination based on the childrenPerPage prop.
5007
- * @param props - HorizontalGalleryProps {@link @azure/communication-react#HorizontalGalleryProps}
5008
- * @returns
5009
- */
5010
- const HorizontalGallery = (props) => {
5011
- var _a, _b;
5012
- const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles } = props;
5013
- const ids = useIdentifiers();
5014
- const [page, setPage] = React.useState(0);
5015
- const numberOfChildren = React__default['default'].Children.count(children);
5016
- const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
5017
- const paginatedChildren = React.useMemo(() => {
5018
- return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
5019
- }, [children, childrenPerPage]);
5020
- // If children per page is 0 or less return empty element
5021
- if (childrenPerPage <= 0) {
5022
- return React__default['default'].createElement(React__default['default'].Fragment, null);
5023
- }
5024
- const firstIndexOfCurrentPage = page * childrenPerPage;
5025
- const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
5026
- const childrenOnCurrentPage = paginatedChildren[clippedPage];
5027
- const showButtons = numberOfChildren > childrenPerPage;
5028
- const disablePreviousButton = page === 0;
5029
- const disableNextButton = page === lastPage;
5030
- return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
5031
- showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "previous-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryLeftButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.previousButton, onClick: () => setPage(Math.max(0, Math.min(lastPage, page - 1))), disabled: disablePreviousButton, identifier: ids.horizontalGalleryLeftNavButton })),
5032
- React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
5033
- showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "next-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryRightButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.nextButton, onClick: () => setPage(Math.min(lastPage, page + 1)), disabled: disableNextButton, identifier: ids.horizontalGalleryRightNavButton }))));
5034
- };
5035
- const HorizontalGalleryNavigationButton = (props) => {
5036
- const theme = useTheme();
5037
- return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
5038
- };
5039
- function bucketize(arr, bucketSize) {
5040
- const bucketArray = [];
5041
- if (bucketSize <= 0) {
5042
- return bucketArray;
5043
- }
5044
- for (let i = 0; i < arr.length; i += bucketSize) {
5045
- bucketArray.push(arr.slice(i, i + bucketSize));
5046
- }
5047
- return bucketArray;
5048
- }
5049
-
5050
- // Copyright (c) Microsoft Corporation.
5051
- /**
5052
- * Wrapped HorizontalGallery that adjusts the number of items per page based on the
5053
- * available width obtained from a ResizeObserver, width per child, gap width, and button width
5054
- */
5055
- const ResponsiveHorizontalGallery = (props) => {
5056
- const { childWidthRem, gapWidthRem, buttonWidthRem = 0 } = props;
5057
- const containerRef = React.useRef(null);
5058
- const containerWidth = _useContainerWidth(containerRef);
5059
- const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
5060
- const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
5061
- const childrenPerPage = calculateChildrenPerPage({
5062
- numberOfChildren: React__default['default'].Children.count(props.children),
5063
- containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
5064
- childWidthRem,
5065
- gapWidthRem,
5066
- buttonWidthRem
5067
- });
5068
- return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(props.containerStyles) },
5069
- React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles }, props.children)));
4966
+ const strings = Object.assign(Object.assign({}, locale.strings.videoTile), props.strings);
4967
+ /* @conditional-compile-remove(one-to-n-calling) */
4968
+ /* @conditional-compile-remove(PSTN-calls) */
4969
+ return props.participantState === 'Idle' || props.participantState === 'Connecting'
4970
+ ? strings === null || strings === void 0 ? void 0 : strings.participantStateConnecting
4971
+ : props.participantState === 'EarlyMedia' || props.participantState === 'Ringing'
4972
+ ? strings === null || strings === void 0 ? void 0 : strings.participantStateRinging
4973
+ : props.participantState === 'Hold'
4974
+ ? strings === null || strings === void 0 ? void 0 : strings.participantStateHold
4975
+ : undefined;
5070
4976
  };
5071
- /**
5072
- * Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
5073
- * gaps in between
5074
- */
5075
- const calculateChildrenPerPage = (args) => {
5076
- const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
5077
- const childWidth = _convertRemToPx(childWidthRem);
5078
- const gapWidth = _convertRemToPx(gapWidthRem);
5079
- /** First check how many children can fit in containerWidth.
5080
- * __________________________________
5081
- * | || |
5082
- * | || |
5083
- * |________________||________________|
5084
- * <-----------containerWidth--------->
5085
- * containerWidth = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
5086
- */
5087
- const numberOfChildrenInContainer = Math.floor((containerWidth + gapWidth) / (childWidth + gapWidth));
5088
- // If all children fit then return numberOfChildrenInContainer
5089
- if (numberOfChildren <= numberOfChildrenInContainer) {
5090
- return numberOfChildrenInContainer;
5091
- }
5092
- const buttonWidth = _convertRemToPx(buttonWidthRem);
5093
- /** We know we need to paginate. So we need to subtract the buttonWidth twice and gapWidth twice from
5094
- * containerWidth to compute childrenSpace
5095
- * <-----------containerWidth--------->
5096
- * __________________________________
5097
- * | || || || |
5098
- * |<|| || ||>|
5099
- * |_||_____________||_____________||_|
5100
- * <-------childrenSpace------>
5101
- */
5102
- const childrenSpace = containerWidth - 2 * buttonWidth - 2 * gapWidth;
5103
- // Now that we have childrenSpace width we can figure out how many children can fit in childrenSpace.
5104
- // childrenSpace = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
5105
- return Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth));
4977
+ const tileInfoContainerTokens = {
4978
+ // A horizontal Stack sets the left margin to 0 for all it's children.
4979
+ // We need to allow the children to set their own margins
4980
+ childrenGap: 'none'
5106
4981
  };
5107
4982
 
5108
4983
  // Copyright (c) Microsoft Corporation.
@@ -5244,44 +5119,278 @@ const layerHostStyle = {
5244
5119
  pointerEvents: 'none'
5245
5120
  };
5246
5121
  /**
5247
- * @private
5122
+ * @private
5123
+ */
5124
+ const localVideoCameraCycleButtonStyles = (theme) => {
5125
+ return {
5126
+ root: {
5127
+ position: 'absolute',
5128
+ width: _pxToRem(32),
5129
+ height: _pxToRem(32),
5130
+ right: '0rem',
5131
+ top: '0rem',
5132
+ color: '#FFFFFF',
5133
+ zIndex: 2,
5134
+ background: 'rgba(0,0,0,0.4)',
5135
+ borderRadius: theme.effects.roundedCorner2
5136
+ },
5137
+ rootFocused: {
5138
+ // styles to remove the unwanted white highlight and blue colour after tapping on button.
5139
+ color: '#FFFFFF',
5140
+ background: 'rgba(0,0,0,0.4)' // sets opacity of background to be visible on all backdrops in video stream.
5141
+ },
5142
+ icon: {
5143
+ paddingLeft: _pxToRem(3),
5144
+ paddingRight: _pxToRem(3),
5145
+ margin: 0
5146
+ },
5147
+ flexContainer: {
5148
+ paddingBottom: _pxToRem(8)
5149
+ }
5150
+ };
5151
+ };
5152
+ /**
5153
+ * Styles for the local video tile modal when it is focused, will cause keyboard move icon to appear over video
5154
+ * @private
5155
+ */
5156
+ const localVideoModalStyles = {
5157
+ keyboardMoveIconContainer: {
5158
+ zIndex: LOCAL_VIDEO_TILE_ZINDEX + 1 // zIndex to set the keyboard movement Icon above the other layers in the video tile.
5159
+ }
5160
+ };
5161
+
5162
+ // Copyright (c) Microsoft Corporation.
5163
+ /**
5164
+ * A memoized version of VideoTile for rendering remote participants. React.memo is used for a performance
5165
+ * boost by memoizing the same rendered component to avoid rerendering a VideoTile when its position in the
5166
+ * array changes causing a rerender in the parent component. https://reactjs.org/docs/react-api.html#reactmemo
5167
+ *
5168
+ * @internal
5169
+ */
5170
+ const _RemoteVideoTile = React__default['default'].memo((props) => {
5171
+ const { isAvailable, isReceiving = true, // default to true to prevent any breaking change
5172
+ isMuted, isSpeaking, isScreenSharingOn, onCreateRemoteStreamView, onDisposeRemoteStreamView, remoteVideoViewOptions, renderElement, userId, displayName, onRenderAvatar, showMuteIndicator } = props;
5173
+ const containerRef = React__default['default'].useRef(null);
5174
+ /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
5175
+ const containerWidth = _useContainerWidth(containerRef);
5176
+ const remoteVideoStreamProps = React.useMemo(() => ({
5177
+ isMirrored: remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.isMirrored,
5178
+ isScreenSharingOn,
5179
+ isStreamAvailable: isAvailable,
5180
+ isStreamReceiving: isReceiving,
5181
+ onCreateRemoteStreamView,
5182
+ onDisposeRemoteStreamView,
5183
+ remoteParticipantId: userId,
5184
+ renderElementExists: !!renderElement,
5185
+ scalingMode: remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.scalingMode
5186
+ }), [
5187
+ isAvailable,
5188
+ isReceiving,
5189
+ isScreenSharingOn,
5190
+ onCreateRemoteStreamView,
5191
+ onDisposeRemoteStreamView,
5192
+ remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.isMirrored,
5193
+ remoteVideoViewOptions === null || remoteVideoViewOptions === void 0 ? void 0 : remoteVideoViewOptions.scalingMode,
5194
+ renderElement,
5195
+ userId
5196
+ ]);
5197
+ // Handle creating, destroying and updating the video stream as necessary
5198
+ useRemoteVideoStreamLifecycleMaintainer(remoteVideoStreamProps);
5199
+ const renderVideoStreamElement = React.useMemo(() => {
5200
+ // Checking if renderElement is well defined or not as calling SDK has a number of video streams limitation which
5201
+ // implies that, after their threshold, all streams have no child (blank video)
5202
+ if (!renderElement || !renderElement.childElementCount) {
5203
+ // Returning `undefined` results in the placeholder with avatar being shown
5204
+ return undefined;
5205
+ }
5206
+ return (React__default['default'].createElement(StreamMedia, { videoStreamElement: renderElement, loadingState: isReceiving === false ? 'loading' : 'none' }));
5207
+ }, [renderElement, isReceiving]);
5208
+ const showLabelTrampoline = React.useMemo(() => {
5209
+ /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
5210
+ return canShowLabel(props.participantState, props.showLabel, containerWidth);
5211
+ }, [
5212
+ /* @conditional-compile-remove(one-to-n-calling) */
5213
+ /* @conditional-compile-remove(PSTN-calls) */
5214
+ containerWidth,
5215
+ props
5216
+ ]);
5217
+ return (
5218
+ // IMPORTANT: This div needs to be a flex so that the children take up its full width and height
5219
+ React__default['default'].createElement("div", { ref: containerRef, style: { display: 'flex', flexGrow: 1 } },
5220
+ React__default['default'].createElement(VideoTile, { key: userId, userId: userId, renderElement: renderVideoStreamElement, displayName: displayName, onRenderPlaceholder: onRenderAvatar, isMuted: isMuted, isSpeaking: isSpeaking, showMuteIndicator: showMuteIndicator, personaMinSize: props.personaMinSize, showLabel: showLabelTrampoline,
5221
+ /* @conditional-compile-remove(one-to-n-calling) */
5222
+ /* @conditional-compile-remove(PSTN-calls) */
5223
+ participantState: props.participantState })));
5224
+ });
5225
+ /* @conditional-compile-remove(one-to-n-calling) */
5226
+ /* @conditional-compile-remove(PSTN-calls) */
5227
+ /**
5228
+ * Determines if a label should be shown for a remote video tile.
5229
+ * When the remote video tile is rendered as a small tile in horizontal gallery,
5230
+ * we hide the participants name if they are in hold/connecting states.
5231
+ */
5232
+ const canShowLabel = (participantState, showLabel, containerWidth) => {
5233
+ // if showLabel has been explicitly set to false, don't show the label
5234
+ if (showLabel === false) {
5235
+ return showLabel;
5236
+ }
5237
+ // If the participant state is in calling or hold and
5238
+ // the container width is less than the small horizontal gallery tile size,
5239
+ // don't show the label (participant name)
5240
+ if (_isParticipantStateCallingOrHold(participantState)) {
5241
+ if (containerWidth && containerWidth / 16 <= SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width) {
5242
+ return false;
5243
+ }
5244
+ }
5245
+ return showLabel;
5246
+ };
5247
+
5248
+ // Copyright (c) Microsoft Corporation.
5249
+ // Licensed under the MIT license.
5250
+ /**
5251
+ * Horizontal Gallery button width in rem
5252
+ */
5253
+ const HORIZONTAL_GALLERY_BUTTON_WIDTH = 1.75;
5254
+ /**
5255
+ * @private
5256
+ */
5257
+ const leftRightButtonStyles = (theme) => {
5258
+ return {
5259
+ background: 'none',
5260
+ padding: 0,
5261
+ height: 'auto',
5262
+ minWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
5263
+ maxWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
5264
+ border: `1px solid ${theme.palette.neutralLight}`,
5265
+ borderRadius: theme.effects.roundedCorner4
5266
+ };
5267
+ };
5268
+ /**
5269
+ * Horizontal Gallery gap size in rem between tiles and buttons
5270
+ */
5271
+ const HORIZONTAL_GALLERY_GAP = 0.5;
5272
+ /**
5273
+ * @private
5274
+ */
5275
+ const rootStyle = {
5276
+ height: '100%',
5277
+ width: '100%',
5278
+ gap: `${HORIZONTAL_GALLERY_GAP}rem`
5279
+ };
5280
+ /**
5281
+ * @private
5282
+ */
5283
+ const childrenContainerStyle = {
5284
+ height: '100%',
5285
+ gap: `${HORIZONTAL_GALLERY_GAP}rem`
5286
+ };
5287
+
5288
+ // Copyright (c) Microsoft Corporation.
5289
+ /**
5290
+ * {@link HorizontalGallery} default children per page
5291
+ */
5292
+ const DEFAULT_CHILDREN_PER_PAGE = 5;
5293
+ /**
5294
+ * Renders a horizontal gallery that parents children horizontally. Handles pagination based on the childrenPerPage prop.
5295
+ * @param props - HorizontalGalleryProps {@link @azure/communication-react#HorizontalGalleryProps}
5296
+ * @returns
5297
+ */
5298
+ const HorizontalGallery = (props) => {
5299
+ var _a, _b;
5300
+ const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles } = props;
5301
+ const ids = useIdentifiers();
5302
+ const [page, setPage] = React.useState(0);
5303
+ const numberOfChildren = React__default['default'].Children.count(children);
5304
+ const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
5305
+ const paginatedChildren = React.useMemo(() => {
5306
+ return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
5307
+ }, [children, childrenPerPage]);
5308
+ // If children per page is 0 or less return empty element
5309
+ if (childrenPerPage <= 0) {
5310
+ return React__default['default'].createElement(React__default['default'].Fragment, null);
5311
+ }
5312
+ const firstIndexOfCurrentPage = page * childrenPerPage;
5313
+ const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
5314
+ const childrenOnCurrentPage = paginatedChildren[clippedPage];
5315
+ const showButtons = numberOfChildren > childrenPerPage;
5316
+ const disablePreviousButton = page === 0;
5317
+ const disableNextButton = page === lastPage;
5318
+ return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
5319
+ showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "previous-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryLeftButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.previousButton, onClick: () => setPage(Math.max(0, Math.min(lastPage, page - 1))), disabled: disablePreviousButton, identifier: ids.horizontalGalleryLeftNavButton })),
5320
+ React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
5321
+ showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "next-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryRightButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.nextButton, onClick: () => setPage(Math.min(lastPage, page + 1)), disabled: disableNextButton, identifier: ids.horizontalGalleryRightNavButton }))));
5322
+ };
5323
+ const HorizontalGalleryNavigationButton = (props) => {
5324
+ const theme = useTheme();
5325
+ return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
5326
+ };
5327
+ function bucketize(arr, bucketSize) {
5328
+ const bucketArray = [];
5329
+ if (bucketSize <= 0) {
5330
+ return bucketArray;
5331
+ }
5332
+ for (let i = 0; i < arr.length; i += bucketSize) {
5333
+ bucketArray.push(arr.slice(i, i + bucketSize));
5334
+ }
5335
+ return bucketArray;
5336
+ }
5337
+
5338
+ // Copyright (c) Microsoft Corporation.
5339
+ /**
5340
+ * Wrapped HorizontalGallery that adjusts the number of items per page based on the
5341
+ * available width obtained from a ResizeObserver, width per child, gap width, and button width
5248
5342
  */
5249
- const localVideoCameraCycleButtonStyles = (theme) => {
5250
- return {
5251
- root: {
5252
- position: 'absolute',
5253
- width: _pxToRem(32),
5254
- height: _pxToRem(32),
5255
- right: '0rem',
5256
- top: '0rem',
5257
- color: '#FFFFFF',
5258
- zIndex: 2,
5259
- background: 'rgba(0,0,0,0.4)',
5260
- borderRadius: theme.effects.roundedCorner2
5261
- },
5262
- rootFocused: {
5263
- // styles to remove the unwanted white highlight and blue colour after tapping on button.
5264
- color: '#FFFFFF',
5265
- background: 'rgba(0,0,0,0.4)' // sets opacity of background to be visible on all backdrops in video stream.
5266
- },
5267
- icon: {
5268
- paddingLeft: _pxToRem(3),
5269
- paddingRight: _pxToRem(3),
5270
- margin: 0
5271
- },
5272
- flexContainer: {
5273
- paddingBottom: _pxToRem(8)
5274
- }
5275
- };
5343
+ const ResponsiveHorizontalGallery = (props) => {
5344
+ const { childWidthRem, gapWidthRem, buttonWidthRem = 0 } = props;
5345
+ const containerRef = React.useRef(null);
5346
+ const containerWidth = _useContainerWidth(containerRef);
5347
+ const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
5348
+ const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
5349
+ const childrenPerPage = calculateChildrenPerPage({
5350
+ numberOfChildren: React__default['default'].Children.count(props.children),
5351
+ containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
5352
+ childWidthRem,
5353
+ gapWidthRem,
5354
+ buttonWidthRem
5355
+ });
5356
+ return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(props.containerStyles) },
5357
+ React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles }, props.children)));
5276
5358
  };
5277
5359
  /**
5278
- * Styles for the local video tile modal when it is focused, will cause keyboard move icon to appear over video
5279
- * @private
5360
+ * Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
5361
+ * gaps in between
5280
5362
  */
5281
- const localVideoModalStyles = {
5282
- keyboardMoveIconContainer: {
5283
- zIndex: LOCAL_VIDEO_TILE_ZINDEX + 1 // zIndex to set the keyboard movement Icon above the other layers in the video tile.
5363
+ const calculateChildrenPerPage = (args) => {
5364
+ const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
5365
+ const childWidth = _convertRemToPx(childWidthRem);
5366
+ const gapWidth = _convertRemToPx(gapWidthRem);
5367
+ /** First check how many children can fit in containerWidth.
5368
+ * __________________________________
5369
+ * | || |
5370
+ * | || |
5371
+ * |________________||________________|
5372
+ * <-----------containerWidth--------->
5373
+ * containerWidth = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
5374
+ */
5375
+ const numberOfChildrenInContainer = Math.floor((containerWidth + gapWidth) / (childWidth + gapWidth));
5376
+ // If all children fit then return numberOfChildrenInContainer
5377
+ if (numberOfChildren <= numberOfChildrenInContainer) {
5378
+ return numberOfChildrenInContainer;
5284
5379
  }
5380
+ const buttonWidth = _convertRemToPx(buttonWidthRem);
5381
+ /** We know we need to paginate. So we need to subtract the buttonWidth twice and gapWidth twice from
5382
+ * containerWidth to compute childrenSpace
5383
+ * <-----------containerWidth--------->
5384
+ * __________________________________
5385
+ * | || || || |
5386
+ * |<|| || ||>|
5387
+ * |_||_____________||_____________||_|
5388
+ * <-------childrenSpace------>
5389
+ */
5390
+ const childrenSpace = containerWidth - 2 * buttonWidth - 2 * gapWidth;
5391
+ // Now that we have childrenSpace width we can figure out how many children can fit in childrenSpace.
5392
+ // childrenSpace = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
5393
+ return Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth));
5285
5394
  };
5286
5395
 
5287
5396
  // Copyright (c) Microsoft Corporation.
@@ -6542,65 +6651,6 @@ const HighContrastAwareIcon = (props) => {
6542
6651
  }) }));
6543
6652
  };
6544
6653
 
6545
- // Copyright (c) Microsoft Corporation.
6546
- /**
6547
- * @internal
6548
- */
6549
- const presenterPermissions = {
6550
- cameraButton: true,
6551
- microphoneButton: true,
6552
- screenShare: true,
6553
- participantList: true
6554
- };
6555
- /**
6556
- * @internal
6557
- */
6558
- const consumerPermissions = {
6559
- cameraButton: false,
6560
- microphoneButton: false,
6561
- screenShare: false,
6562
- participantList: false
6563
- };
6564
- /**
6565
- * @internal
6566
- */
6567
- const attendeePermissions = {
6568
- cameraButton: true,
6569
- microphoneButton: true,
6570
- screenShare: false,
6571
- participantList: true
6572
- };
6573
- /**
6574
- * @internal
6575
- */
6576
- const PermissionsContext = React.createContext(presenterPermissions);
6577
- /**
6578
- * @internal
6579
- */
6580
- const _PermissionsProvider = (props) => {
6581
- const { permissions, children } = props;
6582
- return React__default['default'].createElement(PermissionsContext.Provider, { value: permissions }, children);
6583
- };
6584
- /**
6585
- * @internal
6586
- * React hook to access permissions
6587
- */
6588
- const _usePermissions = () => React.useContext(PermissionsContext);
6589
- /**
6590
- * @internal
6591
- */
6592
- const _getPermissions = (role) => {
6593
- if (role === 'Consumer') {
6594
- return consumerPermissions;
6595
- }
6596
- else if (role === 'Attendee') {
6597
- return attendeePermissions;
6598
- }
6599
- else {
6600
- return presenterPermissions;
6601
- }
6602
- };
6603
-
6604
6654
  // Copyright (c) Microsoft Corporation.
6605
6655
  /**
6606
6656
  * Generates default {@link IContextualMenuProps} for buttons that
@@ -6995,9 +7045,7 @@ const MicrophoneButton = (props) => {
6995
7045
  const ParticipantsButton = (props) => {
6996
7046
  var _a, _b, _c, _d;
6997
7047
  const { callInvitationURL, styles, onMuteAll, onRenderIcon, onRenderParticipantList, participants, myUserId, excludeMe, onRenderParticipant, onRenderAvatar, onRemoveParticipant, onFetchParticipantMenuItems, showParticipantOverflowTooltip } = props;
6998
- let disabled = props.disabled;
6999
- /* @conditional-compile-remove(rooms) */
7000
- disabled = disabled || !_usePermissions().participantList;
7048
+ const disabled = props.disabled;
7001
7049
  const onRenderPeopleIcon = () => (React__default['default'].createElement(HighContrastAwareIcon, { disabled: disabled, iconName: "ControlButtonParticipants" }));
7002
7050
  const ids = useIdentifiers();
7003
7051
  const onMuteAllCallback = React.useCallback(() => {
@@ -12663,7 +12711,7 @@ const CallCompositeIcon = (props) => (React__default['default'].createElement(re
12663
12711
  */
12664
12712
  const CallWithChatCompositeIcon = (props) => (React__default['default'].createElement(react.FontIcon, Object.assign({}, props)));
12665
12713
 
12666
- 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",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",peopleButtonLabel:"People",peoplePaneTitle:"People",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",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",resumeCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold"};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",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"};var en_US = {call:call$d,chat:chat$d,callWithChat:callWithChat$d};
12714
+ 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",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",peopleButtonLabel:"People",peoplePaneTitle:"People",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",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",resumeCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold",openDtmfDialpad:"Show Dialpad",dtmfDialpadPlaceHolderText:"Enter number"};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",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",openDtmfDialpad:"Show Dialpad",dtmfDialpadPlaceHolderText:"Enter number"};var en_US = {call:call$d,chat:chat$d,callWithChat:callWithChat$d};
12667
12715
 
12668
12716
  var call$c={cameraLabel:"Camera",cameraPermissionDenied:"Your browser is blocking access to your camera",cameraTurnedOff:"Your camera is turned off",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",defaultPlaceHolder:"Select an option",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",mutedMessage:"You're muted",networkReconnectMoreDetails:"Looks like something went wrong. We're trying to get back into the call.",networkReconnectTitle:"Hold on",privacyPolicy:"Privacy policy",rejoinCallButtonLabel:"Re-join call",removedFromCallMoreDetails:"Another participant removed you from the call.",removedFromCallTitle:"You were removed",soundLabel:"Sound",startCallButtonLabel:"Start call",microphoneToggleInLobbyNotAllowed:"Cannot mute or unmute while in lobby."};var chat$c={chatListHeader:"In this chat"};var callWithChat$c={peopleButtonLabel:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",chatButtonLabel:"Chat",chatButtonTooltipClosedWithMessageCount:"Show chat ({unreadMessagesCount} unread)",chatButtonTooltipOpen:"Show chat",chatButtonTooltipClose:"Hide chat",moreDrawerAudioDeviceMenuTitle:"Audio Device",moreDrawerMicrophoneMenuTitle:"Microphone",moreDrawerSpeakerMenuTitle:"Speaker",moreDrawerButtonLabel:"More options",moreDrawerButtonTooltip:"More options",peoplePaneTitle:"People",peoplePaneSubTitle:"In this call",chatPaneTitle:"Chat",chatButtonNewMessageNotificationLabel:"New Message",pictureInPictureTileAriaLabel:"Video Feeds. Click to return to call screen.",removeMenuLabel:"Remove",copyInviteLinkButtonLabel:"Copy invite link",dismissSidePaneButton:"Close",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back"};var en_GB = {call:call$c,chat:chat$c,callWithChat:callWithChat$c};
12669
12717
 
@@ -14828,12 +14876,6 @@ const icon$2 = () => React__default['default'].createElement(CallCompositeIcon,
14828
14876
  /** @beta */
14829
14877
  const People = (props) => {
14830
14878
  const { strings, onRenderOnIcon, onRenderOffIcon, onClick } = props;
14831
- /* @conditional-compile-remove(rooms) */
14832
- let disabled = props.disabled;
14833
- /* @conditional-compile-remove(rooms) */
14834
- const permissions = _usePermissions();
14835
- /* @conditional-compile-remove(rooms) */
14836
- disabled = disabled || !permissions.participantList;
14837
14879
  const theme = useTheme();
14838
14880
  const styles = React.useMemo(() => {
14839
14881
  var _a;
@@ -14843,9 +14885,7 @@ const People = (props) => {
14843
14885
  }
14844
14886
  }, (_a = props.styles) !== null && _a !== void 0 ? _a : {}, controlButtonBaseStyle);
14845
14887
  }, [props.styles, theme.palette.neutralLight]);
14846
- return (React__default['default'].createElement(ControlBarButton, Object.assign({}, props, { "data-ui-id": "call-composite-participants-button", strings: strings, labelKey: 'peopleButtonLabelKey', onRenderOnIcon: onRenderOnIcon !== null && onRenderOnIcon !== void 0 ? onRenderOnIcon : icon$2, onRenderOffIcon: onRenderOffIcon !== null && onRenderOffIcon !== void 0 ? onRenderOffIcon : icon$2, onClick: onClick, styles: styles,
14847
- /* @conditional-compile-remove(rooms) */
14848
- disabled: disabled })));
14888
+ return (React__default['default'].createElement(ControlBarButton, Object.assign({}, props, { "data-ui-id": "call-composite-participants-button", strings: strings, labelKey: 'peopleButtonLabelKey', onRenderOnIcon: onRenderOnIcon !== null && onRenderOnIcon !== void 0 ? onRenderOnIcon : icon$2, onRenderOffIcon: onRenderOffIcon !== null && onRenderOffIcon !== void 0 ? onRenderOffIcon : icon$2, onClick: onClick, styles: styles })));
14849
14889
  };
14850
14890
 
14851
14891
  // Copyright (c) Microsoft Corporation.
@@ -14948,20 +14988,17 @@ const SendDtmfDialpad = (props) => {
14948
14988
  };
14949
14989
  const dialpadModalStyle = React.useMemo(() => themeddialpadModalStyle$1(theme), [theme]);
14950
14990
  const dialpadStyle = React.useMemo(() => themedDialpadStyle$1(isMobile, theme), [theme, isMobile]);
14951
- const dialpadStrings = {
14952
- placeholderText: ''
14953
- };
14954
14991
  if (isMobile) {
14955
14992
  return (React__default['default'].createElement(react.Stack, null, showDialpad && (React__default['default'].createElement(react.Stack, { styles: drawerContainerStyles$1 },
14956
14993
  React__default['default'].createElement(_DrawerSurface, { onLightDismiss: onDismissTriggered },
14957
14994
  React__default['default'].createElement(react.Stack, { style: { padding: '1rem' } },
14958
- React__default['default'].createElement(Dialpad, Object.assign({ styles: dialpadStyle }, dialpadProps, { showDeleteButton: false }))))))));
14995
+ React__default['default'].createElement(Dialpad, Object.assign({ styles: dialpadStyle }, dialpadProps, { showDeleteButton: false, strings: strings }))))))));
14959
14996
  }
14960
14997
  return (React__default['default'].createElement(React__default['default'].Fragment, null, React__default['default'].createElement(react.Modal, { titleAriaId: strings.dialpadModalAriaLabel, isOpen: showDialpad, onDismiss: onDismissTriggered, isBlocking: true, styles: dialpadModalStyle },
14961
14998
  React__default['default'].createElement(react.Stack, { horizontal: true, horizontalAlign: "end", verticalAlign: "center" },
14962
14999
  React__default['default'].createElement(react.IconButton, { iconProps: { iconName: 'Cancel' }, ariaLabel: strings.dialpadCloseModalButtonAriaLabel, onClick: onDismissTriggered, style: { color: theme.palette.black } })),
14963
15000
  React__default['default'].createElement(react.Stack, null,
14964
- React__default['default'].createElement(Dialpad, Object.assign({ styles: dialpadStyle }, dialpadProps, { showDeleteButton: false, strings: dialpadStrings }))))));
15001
+ React__default['default'].createElement(Dialpad, Object.assign({ styles: dialpadStyle }, dialpadProps, { showDeleteButton: false, strings: strings }))))));
14965
15002
  };
14966
15003
 
14967
15004
  // Copyright (c) Microsoft Corporation.
@@ -14988,11 +15025,12 @@ const CallControls = (props) => {
14988
15025
  /* @conditional-compile-remove(PSTN-calls) */
14989
15026
  const dialpadStrings = React.useMemo(() => ({
14990
15027
  dialpadModalAriaLabel: localeStrings.strings.call.dialpadModalAriaLabel,
14991
- dialpadCloseModalButtonAriaLabel: localeStrings.strings.call.dialpadCloseModalButtonAriaLabel
15028
+ dialpadCloseModalButtonAriaLabel: localeStrings.strings.call.dialpadCloseModalButtonAriaLabel,
15029
+ placeholderText: localeStrings.strings.call.dtmfDialpadPlaceHolderText
14992
15030
  }), [localeStrings]);
14993
15031
  /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
14994
15032
  const holdButtonProps = usePropsFor$1(HoldButton);
14995
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(one-to-n-calling) */
15033
+ /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
14996
15034
  const moreButtonContextualMenuItems = () => {
14997
15035
  const items = [];
14998
15036
  if (props.isMobile && props.onPeopleButtonClicked) {
@@ -15021,6 +15059,18 @@ const CallControls = (props) => {
15021
15059
  styles: buttonFlyoutIncreasedSizeStyles
15022
15060
  }
15023
15061
  });
15062
+ /* @conditional-compile-remove(PSTN-calls) */
15063
+ items.push({
15064
+ key: 'showDialpadKey',
15065
+ text: localeStrings.strings.call.openDtmfDialpad,
15066
+ onClick: () => {
15067
+ setShowDialpad(true);
15068
+ },
15069
+ iconProps: { iconName: 'Dialpad', styles: { root: { lineHeight: 0 } } },
15070
+ itemProps: {
15071
+ styles: buttonFlyoutIncreasedSizeStyles
15072
+ }
15073
+ });
15024
15074
  return items;
15025
15075
  };
15026
15076
  /* @conditional-compile-remove(PSTN-calls) */
@@ -16092,7 +16142,7 @@ const CallArrangement = (props) => {
16092
16142
  const isMobileWithActivePane = props.mobileView && activePane !== 'none';
16093
16143
  /* @conditional-compile-remove(one-to-n-calling) */
16094
16144
  const togglePeople = React.useCallback(() => {
16095
- if (activePane === 'people' || !(callStatus === 'Connected')) {
16145
+ if (activePane === 'people' || !_isInCall(callStatus)) {
16096
16146
  setActivePane('none');
16097
16147
  }
16098
16148
  else {
@@ -16101,7 +16151,7 @@ const CallArrangement = (props) => {
16101
16151
  }, [activePane, setActivePane, callStatus]);
16102
16152
  /* @conditional-compile-remove(one-to-n-calling) */
16103
16153
  const selectPeople = React.useCallback(() => {
16104
- if (callStatus === 'Connected') {
16154
+ if (_isInCall(callStatus)) {
16105
16155
  setActivePane('people');
16106
16156
  }
16107
16157
  }, [setActivePane, callStatus]);
@@ -16118,7 +16168,7 @@ const CallArrangement = (props) => {
16118
16168
  /* @conditional-compile-remove(one-to-n-calling) */
16119
16169
  const callPaneContent = () => {
16120
16170
  var _a;
16121
- if (adapter && callStatus === 'Connected') {
16171
+ if (adapter && _isInCall(callStatus)) {
16122
16172
  return (React__default['default'].createElement(CallPane, { callAdapter: adapter, onClose: closePane, onFetchAvatarPersonaData: props.onFetchAvatarPersonaData, onFetchParticipantMenuItems: (_a = props.callControlProps) === null || _a === void 0 ? void 0 : _a.onFetchParticipantMenuItems, onPeopleButtonClicked: showShowPeopleTabHeaderButton$1(props.callControlProps.options) ? selectPeople : undefined, modalLayerHostId: props.modalLayerHostId, activePane: activePane, mobileView: props.mobileView, inviteLink: props.callControlProps.callInvitationURL }));
16123
16173
  }
16124
16174
  return React__default['default'].createElement(React__default['default'].Fragment, null);
@@ -16166,61 +16216,6 @@ const localVideoCameraCycleButtonSelector = reselect.createSelector([getDeviceMa
16166
16216
  };
16167
16217
  });
16168
16218
 
16169
- // Copyright (c) Microsoft Corporation.
16170
- const videoBaseStyle = react.mergeStyles({
16171
- border: 0
16172
- });
16173
- /**
16174
- * @private
16175
- */
16176
- react.mergeStyles(videoBaseStyle, {
16177
- width: '100%',
16178
- height: '100%'
16179
- });
16180
- /**
16181
- * @private
16182
- */
16183
- react.mergeStyles(videoBaseStyle, {
16184
- width: '100%',
16185
- height: 0,
16186
- position: 'relative',
16187
- paddingTop: '56.25%' /* default to 16:9 Aspect Ratio for now*/
16188
- });
16189
- /**
16190
- * @private
16191
- */
16192
- react.mergeStyles({
16193
- position: 'absolute',
16194
- top: 0,
16195
- left: 0,
16196
- width: '100%',
16197
- height: '100%'
16198
- });
16199
- /**
16200
- * @private
16201
- */
16202
- react.mergeStyles({
16203
- height: '100%',
16204
- width: '15%'
16205
- });
16206
- /**
16207
- * @private
16208
- */
16209
- react.mergeStyles({
16210
- height: '100%',
16211
- width: '85%',
16212
- position: 'relative'
16213
- });
16214
- /**
16215
- * @private
16216
- */
16217
- const participantStateStyle = {
16218
- textAlign: 'center',
16219
- paddingTop: '0.5rem',
16220
- fontWeight: 400,
16221
- fontSize: '0.75rem'
16222
- };
16223
-
16224
16219
  // Copyright (c) Microsoft Corporation.
16225
16220
  const VideoGalleryStyles = {
16226
16221
  root: {
@@ -16246,26 +16241,11 @@ const MediaGallery = (props) => {
16246
16241
  const cameraSwitcherProps = React.useMemo(() => {
16247
16242
  return Object.assign(Object.assign({}, cameraSwitcherCallback), cameraSwitcherCameras);
16248
16243
  }, [cameraSwitcherCallback, cameraSwitcherCameras]);
16249
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
16250
- const locale = useLocale().component;
16251
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
16252
- const videoTileStrings = locale.strings.videoTile;
16253
16244
  const onRenderAvatar = React.useCallback((userId, options) => {
16254
16245
  return (React__default['default'].createElement(react.Stack, { className: react.mergeStyles({ position: 'absolute', height: '100%', width: '100%' }) },
16255
16246
  React__default['default'].createElement(react.Stack, { styles: { root: { margin: 'auto', maxHeight: '100%' } } },
16256
- React__default['default'].createElement(AvatarPersona, Object.assign({ userId: userId }, options, { dataProvider: props.onFetchAvatarPersonaData })),
16257
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
16258
- (options === null || options === void 0 ? void 0 : options.participantState) === 'Ringing' && (React__default['default'].createElement(react.Text, { className: react.mergeStyles(participantStateStyle) }, videoTileStrings.participantStateConnecting)),
16259
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
16260
- (options === null || options === void 0 ? void 0 : options.participantState) === 'Connecting' && (React__default['default'].createElement(react.Text, { className: react.mergeStyles(participantStateStyle) }, videoTileStrings.participantStateRinging)),
16261
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
16262
- (options === null || options === void 0 ? void 0 : options.participantState) === 'Hold' && (React__default['default'].createElement(react.Text, { className: react.mergeStyles(participantStateStyle) }, videoTileStrings.participantStateHold)))));
16263
- }, [
16264
- props.onFetchAvatarPersonaData,
16265
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */ videoTileStrings.participantStateConnecting,
16266
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */ videoTileStrings.participantStateRinging,
16267
- /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */ videoTileStrings.participantStateHold
16268
- ]);
16247
+ React__default['default'].createElement(AvatarPersona, Object.assign({ userId: userId }, options, { dataProvider: props.onFetchAvatarPersonaData })))));
16248
+ }, [props.onFetchAvatarPersonaData]);
16269
16249
  useLocalVideoStartTrigger(!!props.isVideoStreamOn);
16270
16250
  const VideoGalleryMemoized = React.useMemo(() => {
16271
16251
  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 })));
@@ -16506,7 +16486,7 @@ const CallPage = (props) => {
16506
16486
  /* @conditional-compile-remove(one-to-n-calling) */
16507
16487
  onFetchAvatarPersonaData: onFetchAvatarPersonaData, mobileView: mobileView,
16508
16488
  /* @conditional-compile-remove(one-to-n-calling) */
16509
- modalLayerHostId: props.modalLayerHostId, onRenderGalleryContent: () => callStatus === 'Connected' ? (isNetworkHealthy(networkReconnectTileProps.networkReconnectValue) ? (React__default['default'].createElement(MediaGallery, Object.assign({ isMobile: mobileView }, mediaGalleryProps, mediaGalleryHandlers, { onRenderAvatar: onRenderAvatar, onFetchAvatarPersonaData: onFetchAvatarPersonaData }))) : (React__default['default'].createElement(NetworkReconnectTile, Object.assign({}, networkReconnectTileProps)))) : (React__default['default'].createElement(React__default['default'].Fragment, null)), dataUiId: 'call-page' }));
16489
+ modalLayerHostId: props.modalLayerHostId, onRenderGalleryContent: () => _isInCall(callStatus) ? (isNetworkHealthy(networkReconnectTileProps.networkReconnectValue) ? (React__default['default'].createElement(MediaGallery, Object.assign({ isMobile: mobileView }, mediaGalleryProps, mediaGalleryHandlers, { onRenderAvatar: onRenderAvatar, onFetchAvatarPersonaData: onFetchAvatarPersonaData }))) : (React__default['default'].createElement(NetworkReconnectTile, Object.assign({}, networkReconnectTileProps)))) : (React__default['default'].createElement(React__default['default'].Fragment, null)), dataUiId: 'call-page' }));
16510
16490
  };
16511
16491
  /**
16512
16492
  * @private
@@ -18345,6 +18325,20 @@ const DesktopMoreButton = (props) => {
18345
18325
  styles: buttonFlyoutIncreasedSizeStyles
18346
18326
  }
18347
18327
  });
18328
+ /*@conditional-compile-remove(PSTN-calls) */
18329
+ if (props.onClickShowDialpad) {
18330
+ items.push({
18331
+ key: 'showDialpadKey',
18332
+ text: localeStrings.strings.callWithChat.openDtmfDialpad,
18333
+ onClick: () => {
18334
+ props.onClickShowDialpad && props.onClickShowDialpad();
18335
+ },
18336
+ iconProps: { iconName: 'Dialpad', styles: { root: { lineHeight: 0 } } },
18337
+ itemProps: {
18338
+ styles: buttonFlyoutIncreasedSizeStyles
18339
+ }
18340
+ });
18341
+ }
18348
18342
  return items;
18349
18343
  };
18350
18344
  return (React__default['default'].createElement(MoreButton, Object.assign({}, props, { "data-ui-id": "call-with-chat-composite-more-button",
@@ -18373,7 +18367,7 @@ const inferCallWithChatControlOptions$1 = (mobileView, callWithChatControls) =>
18373
18367
  * @private
18374
18368
  */
18375
18369
  const CallWithChatControlBar = (props) => {
18376
- var _a, _b, _c;
18370
+ var _a, _b;
18377
18371
  const theme = react.useTheme();
18378
18372
  const callWithChatStrings = useCallWithChatCompositeStrings();
18379
18373
  const options = inferCallWithChatControlOptions$1(props.mobileView, props.callControls);
@@ -18405,27 +18399,14 @@ const CallWithChatControlBar = (props) => {
18405
18399
  const endCallButtonStyles = React.useMemo(() => (!props.mobileView ? getDesktopEndCallButtonStyles(theme) : undefined), [props.mobileView, theme]);
18406
18400
  /* @conditional-compile-remove(control-bar-button-injection) */
18407
18401
  const customButtons = React.useMemo(() => generateCustomCallWithChatControlBarButton(onFetchCustomButtonPropsTrampoline(options !== false ? options : undefined), options !== false ? options === null || options === void 0 ? void 0 : options.displayType : undefined), [options]);
18408
- /* @conditional-compile-remove(PSTN-calls) */
18409
- const dialpadStrings = React.useMemo(() => ({
18410
- dialpadModalAriaLabel: callWithChatStrings.dialpadModalAriaLabel,
18411
- dialpadCloseModalButtonAriaLabel: callWithChatStrings.dialpadCloseModalButtonAriaLabel
18412
- }), [callWithChatStrings]);
18413
- /* @conditional-compile-remove(PSTN-calls) */
18414
- const [showDialpad, setShowDialpad] = React.useState(false);
18415
18402
  // when options is false then we want to hide the whole control bar.
18416
18403
  if (options === false) {
18417
18404
  return React__default['default'].createElement(React__default['default'].Fragment, null);
18418
18405
  }
18419
18406
  const chatButton = (React__default['default'].createElement(ChatButtonWithUnreadMessagesBadge, { chatAdapter: props.chatAdapter, checked: props.chatButtonChecked, showLabel: options.displayType !== 'compact', isChatPaneVisible: props.chatButtonChecked, onClick: props.onChatButtonClicked, disabled: props.disableButtonsForLobbyPage, strings: chatButtonStrings, styles: commonButtonStyles, newMessageLabel: callWithChatStrings.chatButtonNewMessageNotificationLabel }));
18420
- /* @conditional-compile-remove(PSTN-calls) */
18421
- const onDismissDialpad = () => {
18422
- setShowDialpad(false);
18423
- };
18424
18407
  return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(callControlsContainerStyles, controlBarContainerStyles) },
18425
18408
  React__default['default'].createElement(react.Stack.Item, { grow: true },
18426
18409
  React__default['default'].createElement(CallAdapterProvider, { adapter: props.callAdapter },
18427
- /* @conditional-compile-remove(PSTN-calls) */
18428
- React__default['default'].createElement(SendDtmfDialpad, { isMobile: (_a = props.mobileView) !== null && _a !== void 0 ? _a : false, strings: dialpadStrings, showDialpad: showDialpad, onDismissDialpad: onDismissDialpad }),
18429
18410
  React__default['default'].createElement(react.Stack, { horizontalAlign: "center" },
18430
18411
  React__default['default'].createElement(react.Stack.Item, null,
18431
18412
  React__default['default'].createElement(ControlBar, { layout: "horizontal", styles: centerContainerStyles },
@@ -18434,8 +18415,8 @@ const CallWithChatControlBar = (props) => {
18434
18415
  props.mobileView && isEnabled$1(options === null || options === void 0 ? void 0 : options.chatButton) && chatButton,
18435
18416
  isEnabled$1(options.screenShareButton) && (React__default['default'].createElement(ScreenShare, { option: options.screenShareButton, displayType: options.displayType, styles: screenShareButtonStyles })),
18436
18417
  /* @conditional-compile-remove(control-bar-button-injection) */
18437
- (_b = customButtons['primary']) === null || _b === void 0 ? void 0 :
18438
- _b.props.children.slice(0, props.mobileView
18418
+ (_a = customButtons['primary']) === null || _a === void 0 ? void 0 :
18419
+ _a.props.children.slice(0, props.mobileView
18439
18420
  ? CUSTOM_BUTTON_OPTIONS.MAX_PRIMARY_MOBILE_CUSTOM_BUTTONS
18440
18421
  : CUSTOM_BUTTON_OPTIONS.MAX_PRIMARY_DESKTOP_CUSTOM_BUTTONS).map((element) => {
18441
18422
  return (React__default['default'].createElement(element.type, Object.assign({}, element.props, { key: element.props.strings.label, styles: commonButtonStyles, displayType: options.displayType, showLabel: options.displayType !== 'compact' })));
@@ -18443,12 +18424,12 @@ const CallWithChatControlBar = (props) => {
18443
18424
  props.mobileView && (React__default['default'].createElement(MoreButton, { "data-ui-id": "call-with-chat-composite-more-button", strings: moreButtonStrings, onClick: props.onMoreButtonClicked, disabled: props.disableButtonsForLobbyPage })),
18444
18425
  /*@conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ isEnabled$1(options === null || options === void 0 ? void 0 : options.moreButton) &&
18445
18426
  /*@conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ isEnabled$1(options === null || options === void 0 ? void 0 : options.holdButton) &&
18446
- !props.mobileView && (React__default['default'].createElement(DesktopMoreButton, { disabled: props.disableButtonsForLobbyPage, styles: commonButtonStyles })),
18427
+ !props.mobileView && (React__default['default'].createElement(DesktopMoreButton, { disabled: props.disableButtonsForLobbyPage, styles: commonButtonStyles, onClickShowDialpad: props.onClickShowDialpad })),
18447
18428
  React__default['default'].createElement(EndCall, { displayType: "compact", styles: endCallButtonStyles })))))),
18448
18429
  !props.mobileView && (React__default['default'].createElement(react.Stack, { horizontal: true, className: !props.mobileView ? react.mergeStyles(desktopButtonContainerStyle) : undefined },
18449
18430
  /* @conditional-compile-remove(control-bar-button-injection) */
18450
- (_c = customButtons['secondary']) === null || _c === void 0 ? void 0 :
18451
- _c.props.children.slice(0, CUSTOM_BUTTON_OPTIONS.MAX_SECONDARY_DESKTOP_CUSTOM_BUTTONS).map((element) => {
18431
+ (_b = customButtons['secondary']) === null || _b === void 0 ? void 0 :
18432
+ _b.props.children.slice(0, CUSTOM_BUTTON_OPTIONS.MAX_SECONDARY_DESKTOP_CUSTOM_BUTTONS).map((element) => {
18452
18433
  return (React__default['default'].createElement(element.type, Object.assign({}, element.props, { key: element.props.key, styles: commonButtonStyles, displayType: options.displayType, showLabel: options.displayType !== 'compact' })));
18453
18434
  }),
18454
18435
  isEnabled$1(options === null || options === void 0 ? void 0 : options.peopleButton) && (React__default['default'].createElement(PeopleButton, { checked: props.peopleButtonChecked, showLabel: options.displayType !== 'compact', onClick: props.onPeopleButtonClicked, "data-ui-id": "call-with-chat-composite-people-button", disabled: props.disableButtonsForLobbyPage, strings: peopleButtonStrings, styles: commonButtonStyles })),
@@ -18862,6 +18843,17 @@ const MoreDrawer = (props) => {
18862
18843
  iconProps: { iconName: 'HoldCall', styles: { root: { lineHeight: 0 } } }
18863
18844
  });
18864
18845
  }
18846
+ /*@conditional-compile-remove(PSTN-calls) */
18847
+ if (drawerSelectionOptions !== false && isEnabled(drawerSelectionOptions === null || drawerSelectionOptions === void 0 ? void 0 : drawerSelectionOptions.peopleButton) && props.onClickShowDialpad) {
18848
+ drawerMenuItems.push({
18849
+ itemKey: 'showDialpadKey',
18850
+ text: localeStrings.strings.callWithChat.openDtmfDialpad,
18851
+ onItemClick: () => {
18852
+ props.onClickShowDialpad && props.onClickShowDialpad();
18853
+ },
18854
+ iconProps: { iconName: 'Dialpad', styles: { root: { lineHeight: 0 } } }
18855
+ });
18856
+ }
18865
18857
  /* @conditional-compile-remove(control-bar-button-injection) */
18866
18858
  const customDrawerButtons = React.useMemo(() => generateCustomCallWithChatDrawerButtons(onFetchCustomButtonPropsTrampoline(drawerSelectionOptions !== false ? drawerSelectionOptions : undefined), drawerSelectionOptions !== false ? drawerSelectionOptions === null || drawerSelectionOptions === void 0 ? void 0 : drawerSelectionOptions.displayType : undefined), [drawerSelectionOptions]);
18867
18859
  /* @conditional-compile-remove(control-bar-button-injection) */
@@ -19073,6 +19065,24 @@ const CallWithChatScreen = (props) => {
19073
19065
  const callCompositeContainerCSS = React.useMemo(() => {
19074
19066
  return { display: isMobileWithActivePane ? 'none' : 'flex' };
19075
19067
  }, [isMobileWithActivePane]);
19068
+ /* @conditional-compile-remove(PSTN-calls) */
19069
+ const [showDtmfDialpad, setShowDtmfDialpad] = React.useState(false);
19070
+ /* @conditional-compile-remove(PSTN-calls) */
19071
+ const onDismissDtmfDialpad = () => {
19072
+ setShowDtmfDialpad(false);
19073
+ };
19074
+ /* @conditional-compile-remove(PSTN-calls) */
19075
+ const onClickShowDialpad = () => {
19076
+ setShowDtmfDialpad(true);
19077
+ };
19078
+ /* @conditional-compile-remove(PSTN-calls) */
19079
+ const callWithChatStrings = useCallWithChatCompositeStrings();
19080
+ /* @conditional-compile-remove(PSTN-calls) */
19081
+ const dialpadStrings = React.useMemo(() => ({
19082
+ dialpadModalAriaLabel: callWithChatStrings.dialpadModalAriaLabel,
19083
+ dialpadCloseModalButtonAriaLabel: callWithChatStrings.dialpadCloseModalButtonAriaLabel,
19084
+ placeholderText: callWithChatStrings.dtmfDialpadPlaceHolderText
19085
+ }), [callWithChatStrings]);
19076
19086
  return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(containerDivStyles) },
19077
19087
  React__default['default'].createElement(react.Stack, { verticalFill: true, grow: true, styles: compositeOuterContainerStyles, id: compositeParentDivId },
19078
19088
  React__default['default'].createElement(react.Stack, { horizontal: true, grow: true },
@@ -19085,11 +19095,20 @@ const CallWithChatScreen = (props) => {
19085
19095
  fileSharing: props.fileSharing, rtl: props.rtl }))),
19086
19096
  showControlBar && !isMobileWithActivePane && (React__default['default'].createElement(ChatAdapterProvider, { adapter: chatProps.adapter },
19087
19097
  React__default['default'].createElement(react.Stack.Item, { styles: controlBarContainerStyles$1 },
19088
- React__default['default'].createElement(CallWithChatControlBar, { callAdapter: callAdapter, chatAdapter: chatProps.adapter, chatButtonChecked: activePane === 'chat', onChatButtonClicked: toggleChat, peopleButtonChecked: activePane === 'people', onPeopleButtonClicked: togglePeople, onMoreButtonClicked: onMoreButtonClicked, mobileView: mobileView, disableButtonsForLobbyPage: isInLobbyOrConnecting, callControls: props.callControls, containerHeight: containerHeight, containerWidth: containerWidth })))),
19098
+ React__default['default'].createElement(CallWithChatControlBar, { callAdapter: callAdapter, chatAdapter: chatProps.adapter, chatButtonChecked: activePane === 'chat', onChatButtonClicked: toggleChat, peopleButtonChecked: activePane === 'people', onPeopleButtonClicked: togglePeople, onMoreButtonClicked: onMoreButtonClicked, mobileView: mobileView, disableButtonsForLobbyPage: isInLobbyOrConnecting, callControls: props.callControls, containerHeight: containerHeight, containerWidth: containerWidth,
19099
+ /* @conditional-compile-remove(PSTN-calls) */
19100
+ onClickShowDialpad: onClickShowDialpad })))),
19089
19101
  showControlBar && showDrawer && (React__default['default'].createElement(ChatAdapterProvider, { adapter: chatProps.adapter },
19090
19102
  React__default['default'].createElement(CallAdapterProvider, { adapter: callAdapter },
19091
19103
  React__default['default'].createElement(react.Stack, { styles: drawerContainerStyles$1 },
19092
- React__default['default'].createElement(PreparedMoreDrawer, { callControls: props.callControls, onLightDismiss: closeDrawer, onPeopleButtonClicked: onMoreDrawerPeopleClicked }))))),
19104
+ React__default['default'].createElement(PreparedMoreDrawer, { callControls: props.callControls, onLightDismiss: closeDrawer, onPeopleButtonClicked: onMoreDrawerPeopleClicked,
19105
+ /* @conditional-compile-remove(PSTN-calls) */
19106
+ onClickShowDialpad: onClickShowDialpad }))))),
19107
+ /* @conditional-compile-remove(PSTN-calls) */
19108
+ showControlBar && showDtmfDialpad && (React__default['default'].createElement(ChatAdapterProvider, { adapter: chatProps.adapter },
19109
+ React__default['default'].createElement(CallAdapterProvider, { adapter: callAdapter },
19110
+ React__default['default'].createElement(react.Stack, { styles: drawerContainerStyles$1 },
19111
+ React__default['default'].createElement(SendDtmfDialpad, { isMobile: mobileView, strings: dialpadStrings, showDialpad: showDtmfDialpad, onDismissDialpad: onDismissDtmfDialpad }))))),
19093
19112
  // This layer host is for ModalLocalAndRemotePIP in CallWithChatPane. This LayerHost cannot be inside the CallWithChatPane
19094
19113
  // because when the CallWithChatPane is hidden, ie. style property display is 'none', it takes up no space. This causes problems when dragging
19095
19114
  // the Modal because the draggable bounds thinks it has no space and will always return to its initial position after dragging.