@azure/communication-react 1.5.1-alpha-202303210051 → 1.5.1-alpha-202303230013

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 (58) hide show
  1. package/dist/communication-react.d.ts +6 -0
  2. package/dist/dist-cjs/communication-react/index.js +373 -274
  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/acs-ui-common/src/telemetryVersion.js.map +1 -1
  6. package/dist/dist-esm/react-components/src/components/CameraButton.d.ts +4 -0
  7. package/dist/dist-esm/react-components/src/components/CameraButton.js +12 -0
  8. package/dist/dist-esm/react-components/src/components/CameraButton.js.map +1 -1
  9. package/dist/dist-esm/react-components/src/components/HorizontalGallery.d.ts +4 -0
  10. package/dist/dist-esm/react-components/src/components/HorizontalGallery.js +19 -10
  11. package/dist/dist-esm/react-components/src/components/HorizontalGallery.js.map +1 -1
  12. package/dist/dist-esm/react-components/src/components/ResponsiveHorizontalGallery.d.ts +2 -1
  13. package/dist/dist-esm/react-components/src/components/ResponsiveHorizontalGallery.js +4 -40
  14. package/dist/dist-esm/react-components/src/components/ResponsiveHorizontalGallery.js.map +1 -1
  15. package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.d.ts +2 -0
  16. package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js +4 -53
  17. package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js.map +1 -1
  18. package/dist/dist-esm/react-components/src/components/VerticalGallery.d.ts +2 -0
  19. package/dist/dist-esm/react-components/src/components/VerticalGallery.js +15 -6
  20. package/dist/dist-esm/react-components/src/components/VerticalGallery.js.map +1 -1
  21. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js +15 -4
  22. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js.map +1 -1
  23. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js +22 -9
  24. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js.map +1 -1
  25. package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.d.ts +1 -1
  26. package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.js.map +1 -1
  27. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.d.ts +8 -7
  28. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js +4 -4
  29. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js.map +1 -1
  30. package/dist/dist-esm/react-components/src/components/VideoGallery/ScrollableHorizontalGallery.d.ts +2 -1
  31. package/dist/dist-esm/react-components/src/components/VideoGallery/ScrollableHorizontalGallery.js +8 -2
  32. package/dist/dist-esm/react-components/src/components/VideoGallery/ScrollableHorizontalGallery.js.map +1 -1
  33. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.d.ts +2 -0
  34. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.js +5 -3
  35. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.js.map +1 -1
  36. package/dist/dist-esm/react-components/src/components/VideoGallery/utils/OverflowGalleryUtils.d.ts +26 -0
  37. package/dist/dist-esm/react-components/src/components/VideoGallery/utils/OverflowGalleryUtils.js +93 -0
  38. package/dist/dist-esm/react-components/src/components/VideoGallery/utils/OverflowGalleryUtils.js.map +1 -0
  39. package/dist/dist-esm/react-components/src/components/VideoGallery.js +2 -1
  40. package/dist/dist-esm/react-components/src/components/VideoGallery.js.map +1 -1
  41. package/dist/dist-esm/react-components/src/theming/icons.d.ts +1 -0
  42. package/dist/dist-esm/react-components/src/theming/icons.js +5 -1
  43. package/dist/dist-esm/react-components/src/theming/icons.js.map +1 -1
  44. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallControls.js +1 -1
  45. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallControls.js.map +1 -1
  46. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Camera.d.ts +5 -4
  47. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Camera.js +3 -1
  48. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Camera.js.map +1 -1
  49. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js +13 -1
  50. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js.map +1 -1
  51. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.d.ts +1 -0
  52. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.js +4 -2
  53. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.js.map +1 -1
  54. package/dist/dist-esm/react-composites/src/composites/common/VideoEffectsPane.d.ts +11 -0
  55. package/dist/dist-esm/react-composites/src/composites/common/VideoEffectsPane.js +19 -0
  56. package/dist/dist-esm/react-composites/src/composites/common/VideoEffectsPane.js.map +1 -0
  57. package/dist/dist-esm/react-composites/src/composites/common/icons.d.ts +1 -0
  58. package/package.json +8 -8
@@ -162,7 +162,7 @@ const _toCommunicationIdentifier = (id) => {
162
162
  // Copyright (c) Microsoft Corporation.
163
163
  // Licensed under the MIT license.
164
164
  // GENERATED FILE. DO NOT EDIT MANUALLY.
165
- var telemetryVersion = '1.5.1-alpha-202303210051';
165
+ var telemetryVersion = '1.5.1-alpha-202303230013';
166
166
 
167
167
  // Copyright (c) Microsoft Corporation.
168
168
  /**
@@ -5332,7 +5332,9 @@ const DEFAULT_COMPONENT_ICONS = {
5332
5332
  /* @conditional-compile-remove(vertical-gallery) */
5333
5333
  VerticalGalleryLeftButton: React__default['default'].createElement(reactIcons.ChevronLeft20Regular, null),
5334
5334
  /* @conditional-compile-remove(vertical-gallery) */
5335
- VerticalGalleryRightButton: React__default['default'].createElement(reactIcons.ChevronRight20Regular, null)
5335
+ VerticalGalleryRightButton: React__default['default'].createElement(reactIcons.ChevronRight20Regular, null),
5336
+ /* @conditional-compile-remove(video-background-effects) */
5337
+ OptionsVideoBackgroundEffect: React__default['default'].createElement(reactIcons.VideoBackgroundEffect20Regular, null)
5336
5338
  };
5337
5339
 
5338
5340
  // Copyright (c) Microsoft Corporation.
@@ -9443,24 +9445,33 @@ const DEFAULT_CHILDREN_PER_PAGE = 5;
9443
9445
  */
9444
9446
  const HorizontalGallery = (props) => {
9445
9447
  var _a, _b;
9446
- const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles } = props;
9448
+ const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles, onFetchTilesToRender } = props;
9447
9449
  const ids = useIdentifiers();
9448
9450
  const [page, setPage] = React.useState(0);
9449
9451
  const numberOfChildren = React__default['default'].Children.count(children);
9450
9452
  const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
9451
- const paginatedChildren = React.useMemo(() => {
9452
- return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
9453
- }, [children, childrenPerPage]);
9454
- // If children per page is 0 or less return empty element
9455
- if (childrenPerPage <= 0) {
9456
- return React__default['default'].createElement(React__default['default'].Fragment, null);
9457
- }
9453
+ const indexesArray = React.useMemo(() => {
9454
+ return bucketize([...Array(numberOfChildren).keys()], childrenPerPage);
9455
+ }, [numberOfChildren, childrenPerPage]);
9456
+ React.useEffect(() => {
9457
+ if (onFetchTilesToRender && indexesArray) {
9458
+ onFetchTilesToRender(indexesArray[page]);
9459
+ }
9460
+ }, [indexesArray, onFetchTilesToRender, page]);
9458
9461
  const firstIndexOfCurrentPage = page * childrenPerPage;
9459
9462
  const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
9460
- const childrenOnCurrentPage = paginatedChildren[clippedPage];
9463
+ const childrenOnCurrentPage = React.useMemo(() => {
9464
+ return indexesArray[clippedPage].map((index) => {
9465
+ return React__default['default'].Children.toArray(children)[index];
9466
+ });
9467
+ }, [indexesArray, clippedPage, children]);
9461
9468
  const showButtons = numberOfChildren > childrenPerPage;
9462
9469
  const disablePreviousButton = page === 0;
9463
9470
  const disableNextButton = page === lastPage;
9471
+ // If children per page is 0 or less return empty element
9472
+ if (childrenPerPage <= 0) {
9473
+ return React__default['default'].createElement(React__default['default'].Fragment, null);
9474
+ }
9464
9475
  return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle$1, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
9465
9476
  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.overflowGalleryLeftNavButton })),
9466
9477
  React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle$1, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
@@ -9471,224 +9482,6 @@ const HorizontalGalleryNavigationButton = (props) => {
9471
9482
  return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles$1(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
9472
9483
  };
9473
9484
 
9474
- // Copyright (c) Microsoft Corporation.
9475
- /**
9476
- * Wrapped HorizontalGallery that adjusts the number of items per page based on the
9477
- * available width obtained from a ResizeObserver, width per child, gap width, and button width
9478
- */
9479
- const ResponsiveHorizontalGallery = (props) => {
9480
- const { childWidthRem, gapWidthRem, buttonWidthRem = 0 } = props;
9481
- const containerRef = React.useRef(null);
9482
- const containerWidth = _useContainerWidth(containerRef);
9483
- const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
9484
- const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
9485
- const childrenPerPage = calculateChildrenPerPage$1({
9486
- numberOfChildren: React__default['default'].Children.count(props.children),
9487
- containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
9488
- childWidthRem,
9489
- gapWidthRem,
9490
- buttonWidthRem
9491
- });
9492
- return (React__default['default'].createElement("div", { "data-ui-id": "responsive-horizontal-gallery", ref: containerRef, className: react.mergeStyles(props.containerStyles) },
9493
- React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles }, props.children)));
9494
- };
9495
- /**
9496
- * Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
9497
- * gaps in between
9498
- */
9499
- const calculateChildrenPerPage$1 = (args) => {
9500
- const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
9501
- const childWidth = _convertRemToPx(childWidthRem);
9502
- const gapWidth = _convertRemToPx(gapWidthRem);
9503
- /** First check how many children can fit in containerWidth.
9504
- * __________________________________
9505
- * | || |
9506
- * | || |
9507
- * |________________||________________|
9508
- * <-----------containerWidth--------->
9509
- * containerWidth = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
9510
- */
9511
- const numberOfChildrenInContainer = Math.floor((containerWidth + gapWidth) / (childWidth + gapWidth));
9512
- // If all children fit then return numberOfChildrenInContainer
9513
- if (numberOfChildren <= numberOfChildrenInContainer) {
9514
- return numberOfChildrenInContainer;
9515
- }
9516
- const buttonWidth = _convertRemToPx(buttonWidthRem);
9517
- /** We know we need to paginate. So we need to subtract the buttonWidth twice and gapWidth twice from
9518
- * containerWidth to compute childrenSpace
9519
- * <-----------containerWidth--------->
9520
- * __________________________________
9521
- * | || || || |
9522
- * |<|| || ||>|
9523
- * |_||_____________||_____________||_|
9524
- * <-------childrenSpace------>
9525
- */
9526
- const childrenSpace = containerWidth - 2 * buttonWidth - 2 * gapWidth;
9527
- // Now that we have childrenSpace width we can figure out how many children can fit in childrenSpace.
9528
- // childrenSpace = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
9529
- return Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth));
9530
- };
9531
-
9532
- // Copyright (c) Microsoft Corporation.
9533
- // Licensed under the MIT license.
9534
- /**
9535
- * Vertical Gallery gap size in rem between tiles and buttons
9536
- *
9537
- * @private
9538
- */
9539
- const VERTICAL_GALLERY_GAP = 0.5;
9540
- /**
9541
- * @private
9542
- */
9543
- const childrenContainerStyle = (pageControlBarHeight) => {
9544
- return {
9545
- width: '100%',
9546
- height: `calc(100% - ${pageControlBarHeight + VERTICAL_GALLERY_GAP}rem)`,
9547
- gap: `${VERTICAL_GALLERY_GAP}rem`
9548
- };
9549
- };
9550
- /**
9551
- * @private
9552
- */
9553
- const rootStyle = {
9554
- height: '100%',
9555
- width: '100%',
9556
- gap: `${VERTICAL_GALLERY_GAP}rem`,
9557
- position: 'relative'
9558
- };
9559
- /**
9560
- * @private
9561
- */
9562
- const pageNavigationControlBarContainerStyle = {
9563
- height: '2rem',
9564
- width: '100%',
9565
- position: 'absolute',
9566
- bottom: '0'
9567
- };
9568
- /**
9569
- * @private
9570
- */
9571
- const leftRightButtonStyles = (theme) => {
9572
- return {
9573
- background: 'none',
9574
- padding: 0,
9575
- height: 'auto',
9576
- borderRadius: theme.effects.roundedCorner4,
9577
- border: 'none',
9578
- minWidth: '2rem'
9579
- };
9580
- };
9581
- /**
9582
- * @private
9583
- */
9584
- const participantPageCounter = {
9585
- lineHeight: '2rem',
9586
- width: '100%',
9587
- textAlign: 'center'
9588
- };
9589
- /**
9590
- * @private
9591
- */
9592
- const navIconStyles = {
9593
- root: {
9594
- lineHeight: '0'
9595
- }
9596
- };
9597
-
9598
- // Copyright (c) Microsoft Corporation.
9599
- /**
9600
- * VerticalGallery is a overflow gallery for participants in the {@link VideoGallery} component. Stacks
9601
- * participants on the Y-axis of the VideoGallery for better use of horizontal space.
9602
- *
9603
- * @beta
9604
- */
9605
- const VerticalGallery = (props) => {
9606
- const { children, styles, childrenPerPage } = props;
9607
- const [page, setPage] = React.useState(1);
9608
- const [buttonState, setButtonState] = React.useState({ previous: true, next: true });
9609
- /* @conditional-compile-remove(vertical-gallery) */
9610
- const ids = useIdentifiers();
9611
- const numberOfChildren = React__default['default'].Children.count(children);
9612
- const lastPage = Math.ceil(numberOfChildren / childrenPerPage);
9613
- const paginatedChildren = React.useMemo(() => {
9614
- return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
9615
- }, [children, childrenPerPage]);
9616
- const firstIndexOfCurrentPage = (page - 1) * childrenPerPage;
9617
- const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
9618
- const childrenOnCurrentPage = paginatedChildren[clippedPage - 1];
9619
- const showButtons = numberOfChildren > childrenPerPage;
9620
- const onPreviousButtonClick = () => {
9621
- setPage(page - 1);
9622
- };
9623
- const onNextButtonClick = () => {
9624
- setPage(page + 1);
9625
- };
9626
- if (page > lastPage && lastPage > 0) {
9627
- setPage(lastPage);
9628
- }
9629
- React.useEffect(() => {
9630
- if (page > 1 && page < lastPage && showButtons) {
9631
- // we are somewhere in between first and last pages.
9632
- setButtonState({ previous: false, next: false });
9633
- }
9634
- else if (page === 1 && showButtons) {
9635
- // we are on the first page.
9636
- setButtonState({ previous: true, next: false });
9637
- }
9638
- else if (page === lastPage && showButtons) {
9639
- // we are on the last page.
9640
- setButtonState({ previous: false, next: true });
9641
- }
9642
- }, [page, numberOfChildren, lastPage, showButtons]);
9643
- const childContainerStyle = React.useMemo(() => {
9644
- return { root: childrenContainerStyle(2) };
9645
- }, []);
9646
- const childrenStyles = React.useMemo(() => {
9647
- return { root: styles === null || styles === void 0 ? void 0 : styles.children };
9648
- }, [styles === null || styles === void 0 ? void 0 : styles.children]);
9649
- if (childrenPerPage <= 0) {
9650
- return React__default['default'].createElement(React__default['default'].Fragment, null);
9651
- }
9652
- return (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(rootStyle, styles === null || styles === void 0 ? void 0 : styles.root) },
9653
- React__default['default'].createElement(react.Stack, { styles: childContainerStyle }, childrenOnCurrentPage.map((child, i) => {
9654
- return (React__default['default'].createElement(react.Stack.Item, { key: i, styles: childrenStyles, "data-ui-id": ids.verticalGalleryVideoTile }, child));
9655
- })),
9656
- showButtons && (React__default['default'].createElement(VerticalGalleryControlBar, { buttonsDisabled: buttonState, onPreviousButtonClick: onPreviousButtonClick, onNextButtonClick: onNextButtonClick, totalPages: lastPage, currentPage: page }))));
9657
- };
9658
- const VerticalGalleryControlBar = (props) => {
9659
- const { onNextButtonClick, onPreviousButtonClick, buttonsDisabled, currentPage, totalPages, styles } = props;
9660
- const theme = useTheme();
9661
- /* @conditional-compile-remove(vertical-gallery) */
9662
- const ids = useIdentifiers();
9663
- /* @conditional-compile-remove(vertical-gallery) */
9664
- const strings = useLocale$1().strings.VerticalGallery;
9665
- const pageCounterContainerStyles = React.useMemo(() => {
9666
- return react.mergeStyles(pageNavigationControlBarContainerStyle, styles === null || styles === void 0 ? void 0 : styles.root);
9667
- }, [styles === null || styles === void 0 ? void 0 : styles.root]);
9668
- const previousButtonSyles = React.useMemo(() => {
9669
- return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.previousButton);
9670
- }, [styles === null || styles === void 0 ? void 0 : styles.previousButton, theme]);
9671
- const pageCounterStyles = React.useMemo(() => {
9672
- return react.mergeStyles(participantPageCounter, styles === null || styles === void 0 ? void 0 : styles.counter);
9673
- }, [styles === null || styles === void 0 ? void 0 : styles.counter]);
9674
- const nextButtonsStyles = React.useMemo(() => {
9675
- return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.nextButton);
9676
- }, [styles === null || styles === void 0 ? void 0 : styles.nextButton, theme]);
9677
- const controlBarSpacing = { childrenGap: '0.5rem' };
9678
- return (React__default['default'].createElement(react.Stack, { horizontalAlign: "center", tokens: controlBarSpacing, horizontal: true, className: pageCounterContainerStyles },
9679
- React__default['default'].createElement(react.DefaultButton, { className: previousButtonSyles, onClick: onPreviousButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.previous,
9680
- /* @conditional-compile-remove(vertical-gallery) */
9681
- ariaLabel: strings.leftNavButtonAriaLabel, "data-ui-id": ids.overflowGalleryLeftNavButton },
9682
- React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryLeftButton", styles: navIconStyles })),
9683
- React__default['default'].createElement(react.Text
9684
- /* @conditional-compile-remove(vertical-gallery) */
9685
- , { "data-ui-id": ids.verticalGalleryPageCounter, className: pageCounterStyles }, `${currentPage} / ${totalPages}`),
9686
- React__default['default'].createElement(react.DefaultButton, { className: nextButtonsStyles, onClick: onNextButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.next,
9687
- /* @conditional-compile-remove(vertical-gallery) */
9688
- ariaLabel: strings.rightNavButtonAriaLabel, "data-ui-id": ids.overflowGalleryRightNavButton },
9689
- React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryRightButton", styles: navIconStyles }))));
9690
- };
9691
-
9692
9485
  // Copyright (c) Microsoft Corporation.
9693
9486
  /**
9694
9487
  * @private
@@ -9807,26 +9600,28 @@ const VERTICAL_GALLERY_TILE_SIZE_REM = { minHeight: 6.75, maxHeight: 11, width:
9807
9600
  *
9808
9601
  * width is being increased by 1rem to account for the gap width desired for the VerticalGallery.
9809
9602
  *
9603
+ * Add 1.5 rem on width to account for horizontal padding
9604
+ *
9810
9605
  * @param shouldFloatLocalVideo whether rendered in floating layout or not
9811
9606
  * @returns Style set for VerticalGallery container.
9812
9607
  */
9813
9608
  const verticalGalleryContainerStyle = (shouldFloatLocalVideo, isNarrow, isShort) => {
9814
9609
  return isNarrow && isShort
9815
9610
  ? {
9816
- width: `${SHORT_VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`,
9611
+ width: `${SHORT_VERTICAL_GALLERY_TILE_SIZE_REM.width + 1.5}rem`,
9817
9612
  height: shouldFloatLocalVideo ? `calc(100% - ${_pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.height)})` : '100%',
9818
9613
  paddingBottom: '0.5rem'
9819
9614
  }
9820
9615
  : !isNarrow && isShort
9821
9616
  ? {
9822
- width: `${SHORT_VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`,
9617
+ width: `${SHORT_VERTICAL_GALLERY_TILE_SIZE_REM.width + 1.5}rem`,
9823
9618
  height: shouldFloatLocalVideo
9824
9619
  ? `calc(100% - ${_pxToRem(SHORT_VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX.height)})`
9825
9620
  : '100%',
9826
9621
  paddingBottom: '0.5rem'
9827
9622
  }
9828
9623
  : {
9829
- width: `${VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`,
9624
+ width: `${VERTICAL_GALLERY_TILE_SIZE_REM.width + 1.5}rem`,
9830
9625
  height: shouldFloatLocalVideo
9831
9626
  ? `calc(100% - ${_pxToRem(VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX.height)})`
9832
9627
  : '100%',
@@ -9864,32 +9659,49 @@ const verticalGalleryStyle = (isShort) => {
9864
9659
 
9865
9660
  // Copyright (c) Microsoft Corporation.
9866
9661
  /**
9867
- * Responsive container for the VerticalGallery Component. Performs calculations for number of children
9868
- * for the VerticalGallery
9869
- * @param props
9662
+ * Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
9663
+ * gaps in between
9870
9664
  *
9871
- * @beta
9665
+ * @private
9872
9666
  */
9873
- const ResponsiveVerticalGallery = (props) => {
9874
- const { children, containerStyles, verticalGalleryStyles, gapHeightRem, controlBarHeightRem, isShort } = props;
9875
- const containerRef = React.useRef(null);
9876
- const containerHeight = _useContainerHeight(containerRef);
9877
- const topPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingTop) : 0;
9878
- const bottomPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingBottom) : 0;
9879
- const childrenPerPage = calculateChildrenPerPage({
9880
- numberOfChildren: React__default['default'].Children.count(children),
9881
- containerHeight: (containerHeight !== null && containerHeight !== void 0 ? containerHeight : 0) - topPadding - bottomPadding,
9882
- gapHeightRem,
9883
- controlBarHeight: controlBarHeightRem !== null && controlBarHeightRem !== void 0 ? controlBarHeightRem : 2,
9884
- isShort: isShort !== null && isShort !== void 0 ? isShort : false
9885
- });
9886
- return (React__default['default'].createElement("div", { "data-ui-id": "responsive-vertical-gallery", ref: containerRef, className: react.mergeStyles(containerStyles) },
9887
- React__default['default'].createElement(VerticalGallery, { childrenPerPage: childrenPerPage, styles: verticalGalleryStyles }, children)));
9667
+ const calculateHorizontalChildrenPerPage = (args) => {
9668
+ const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
9669
+ const childWidth = _convertRemToPx(childWidthRem);
9670
+ const gapWidth = _convertRemToPx(gapWidthRem);
9671
+ /** First check how many children can fit in containerWidth.
9672
+ * __________________________________
9673
+ * | || |
9674
+ * | || |
9675
+ * |________________||________________|
9676
+ * <-----------containerWidth--------->
9677
+ * containerWidth = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
9678
+ */
9679
+ const numberOfChildrenInContainer = Math.floor((containerWidth + gapWidth) / (childWidth + gapWidth));
9680
+ // If all children fit then return numberOfChildrenInContainer
9681
+ if (numberOfChildren <= numberOfChildrenInContainer) {
9682
+ return numberOfChildrenInContainer;
9683
+ }
9684
+ const buttonWidth = _convertRemToPx(buttonWidthRem);
9685
+ /** We know we need to paginate. So we need to subtract the buttonWidth twice and gapWidth twice from
9686
+ * containerWidth to compute childrenSpace
9687
+ * <-----------containerWidth--------->
9688
+ * __________________________________
9689
+ * | || || || |
9690
+ * |<|| || ||>|
9691
+ * |_||_____________||_____________||_|
9692
+ * <-------childrenSpace------>
9693
+ */
9694
+ const childrenSpace = containerWidth - 2 * buttonWidth - 2 * gapWidth;
9695
+ // Now that we have childrenSpace width we can figure out how many children can fit in childrenSpace.
9696
+ // childrenSpace = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
9697
+ return Math.max(Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth)), 1);
9888
9698
  };
9889
9699
  /**
9890
9700
  * Helper function to find the number of children for the VerticalGallery on each page.
9701
+ *
9702
+ * @private
9891
9703
  */
9892
- const calculateChildrenPerPage = (args) => {
9704
+ const calculateVerticalChildrenPerPage = (args) => {
9893
9705
  const { numberOfChildren, containerHeight, gapHeightRem, controlBarHeight, isShort } = args;
9894
9706
  const childMinHeightPx = _convertRemToPx(isShort ? SHORT_VERTICAL_GALLERY_TILE_SIZE_REM.minHeight : VERTICAL_GALLERY_TILE_SIZE_REM.minHeight);
9895
9707
  const gapHeightPx = _convertRemToPx(gapHeightRem);
@@ -9935,6 +9747,222 @@ const calculateChildrenPerPage = (args) => {
9935
9747
  return Math.max(Math.floor((childSpace + gapHeightPx) / (childMinHeightPx + gapHeightPx)), 1);
9936
9748
  };
9937
9749
 
9750
+ // Copyright (c) Microsoft Corporation.
9751
+ /**
9752
+ * Wrapped HorizontalGallery that adjusts the number of items per page based on the
9753
+ * available width obtained from a ResizeObserver, width per child, gap width, and button width
9754
+ */
9755
+ const ResponsiveHorizontalGallery = (props) => {
9756
+ const { childWidthRem, gapWidthRem, buttonWidthRem = 0, onFetchTilesToRender } = props;
9757
+ const containerRef = React.useRef(null);
9758
+ const containerWidth = _useContainerWidth(containerRef);
9759
+ const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
9760
+ const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
9761
+ const childrenPerPage = calculateHorizontalChildrenPerPage({
9762
+ numberOfChildren: React__default['default'].Children.count(props.children),
9763
+ containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
9764
+ childWidthRem,
9765
+ gapWidthRem,
9766
+ buttonWidthRem
9767
+ });
9768
+ return (React__default['default'].createElement("div", { "data-ui-id": "responsive-horizontal-gallery", ref: containerRef, className: react.mergeStyles(props.containerStyles) },
9769
+ React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles, onFetchTilesToRender: onFetchTilesToRender }, props.children)));
9770
+ };
9771
+
9772
+ // Copyright (c) Microsoft Corporation.
9773
+ // Licensed under the MIT license.
9774
+ /**
9775
+ * Vertical Gallery gap size in rem between tiles and buttons
9776
+ *
9777
+ * @private
9778
+ */
9779
+ const VERTICAL_GALLERY_GAP = 0.5;
9780
+ /**
9781
+ * @private
9782
+ */
9783
+ const childrenContainerStyle = (pageControlBarHeight) => {
9784
+ return {
9785
+ width: '100%',
9786
+ height: `calc(100% - ${pageControlBarHeight + VERTICAL_GALLERY_GAP}rem)`,
9787
+ gap: `${VERTICAL_GALLERY_GAP}rem`
9788
+ };
9789
+ };
9790
+ /**
9791
+ * @private
9792
+ */
9793
+ const rootStyle = {
9794
+ height: '100%',
9795
+ width: '100%',
9796
+ gap: `${VERTICAL_GALLERY_GAP}rem`,
9797
+ position: 'relative'
9798
+ };
9799
+ /**
9800
+ * @private
9801
+ */
9802
+ const pageNavigationControlBarContainerStyle = {
9803
+ height: '2rem',
9804
+ width: '100%',
9805
+ position: 'absolute',
9806
+ bottom: '0'
9807
+ };
9808
+ /**
9809
+ * @private
9810
+ */
9811
+ const leftRightButtonStyles = (theme) => {
9812
+ return {
9813
+ background: 'none',
9814
+ padding: 0,
9815
+ height: 'auto',
9816
+ borderRadius: theme.effects.roundedCorner4,
9817
+ border: 'none',
9818
+ minWidth: '2rem'
9819
+ };
9820
+ };
9821
+ /**
9822
+ * @private
9823
+ */
9824
+ const participantPageCounter = {
9825
+ lineHeight: '2rem',
9826
+ width: '100%',
9827
+ textAlign: 'center'
9828
+ };
9829
+ /**
9830
+ * @private
9831
+ */
9832
+ const navIconStyles = {
9833
+ root: {
9834
+ lineHeight: '0'
9835
+ }
9836
+ };
9837
+
9838
+ // Copyright (c) Microsoft Corporation.
9839
+ /**
9840
+ * VerticalGallery is a overflow gallery for participants in the {@link VideoGallery} component. Stacks
9841
+ * participants on the Y-axis of the VideoGallery for better use of horizontal space.
9842
+ *
9843
+ * @beta
9844
+ */
9845
+ const VerticalGallery = (props) => {
9846
+ const { children, styles, childrenPerPage, onFetchTilesToRender } = props;
9847
+ const [page, setPage] = React.useState(1);
9848
+ const [buttonState, setButtonState] = React.useState({ previous: true, next: true });
9849
+ /* @conditional-compile-remove(vertical-gallery) */
9850
+ const ids = useIdentifiers();
9851
+ const numberOfChildren = React__default['default'].Children.count(children);
9852
+ const lastPage = Math.ceil(numberOfChildren / childrenPerPage);
9853
+ const indexesArray = React.useMemo(() => {
9854
+ return bucketize([...Array(numberOfChildren).keys()], childrenPerPage);
9855
+ }, [numberOfChildren, childrenPerPage]);
9856
+ React.useEffect(() => {
9857
+ if (onFetchTilesToRender && indexesArray) {
9858
+ onFetchTilesToRender(indexesArray[page - 1]);
9859
+ }
9860
+ }, [indexesArray, onFetchTilesToRender, page]);
9861
+ const firstIndexOfCurrentPage = (page - 1) * childrenPerPage;
9862
+ const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
9863
+ const childrenOnCurrentPage = React.useMemo(() => {
9864
+ return indexesArray[clippedPage - 1].map((index) => {
9865
+ return React__default['default'].Children.toArray(children)[index];
9866
+ });
9867
+ }, [indexesArray, clippedPage, children]);
9868
+ const showButtons = numberOfChildren > childrenPerPage;
9869
+ const onPreviousButtonClick = () => {
9870
+ setPage(page - 1);
9871
+ };
9872
+ const onNextButtonClick = () => {
9873
+ setPage(page + 1);
9874
+ };
9875
+ if (page > lastPage && lastPage > 0) {
9876
+ setPage(lastPage);
9877
+ }
9878
+ React.useEffect(() => {
9879
+ if (page > 1 && page < lastPage && showButtons) {
9880
+ // we are somewhere in between first and last pages.
9881
+ setButtonState({ previous: false, next: false });
9882
+ }
9883
+ else if (page === 1 && showButtons) {
9884
+ // we are on the first page.
9885
+ setButtonState({ previous: true, next: false });
9886
+ }
9887
+ else if (page === lastPage && showButtons) {
9888
+ // we are on the last page.
9889
+ setButtonState({ previous: false, next: true });
9890
+ }
9891
+ }, [page, numberOfChildren, lastPage, showButtons]);
9892
+ const childContainerStyle = React.useMemo(() => {
9893
+ return { root: childrenContainerStyle(2) };
9894
+ }, []);
9895
+ const childrenStyles = React.useMemo(() => {
9896
+ return { root: styles === null || styles === void 0 ? void 0 : styles.children };
9897
+ }, [styles === null || styles === void 0 ? void 0 : styles.children]);
9898
+ if (childrenPerPage <= 0) {
9899
+ return React__default['default'].createElement(React__default['default'].Fragment, null);
9900
+ }
9901
+ return (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(rootStyle, styles === null || styles === void 0 ? void 0 : styles.root) },
9902
+ React__default['default'].createElement(react.Stack, { styles: childContainerStyle }, childrenOnCurrentPage === null || childrenOnCurrentPage === void 0 ? void 0 : childrenOnCurrentPage.map((child, i) => {
9903
+ return (React__default['default'].createElement(react.Stack.Item, { key: i, styles: childrenStyles, "data-ui-id": ids.verticalGalleryVideoTile }, child));
9904
+ })),
9905
+ showButtons && (React__default['default'].createElement(VerticalGalleryControlBar, { buttonsDisabled: buttonState, onPreviousButtonClick: onPreviousButtonClick, onNextButtonClick: onNextButtonClick, totalPages: lastPage, currentPage: page }))));
9906
+ };
9907
+ const VerticalGalleryControlBar = (props) => {
9908
+ const { onNextButtonClick, onPreviousButtonClick, buttonsDisabled, currentPage, totalPages, styles } = props;
9909
+ const theme = useTheme();
9910
+ /* @conditional-compile-remove(vertical-gallery) */
9911
+ const ids = useIdentifiers();
9912
+ /* @conditional-compile-remove(vertical-gallery) */
9913
+ const strings = useLocale$1().strings.VerticalGallery;
9914
+ const pageCounterContainerStyles = React.useMemo(() => {
9915
+ return react.mergeStyles(pageNavigationControlBarContainerStyle, styles === null || styles === void 0 ? void 0 : styles.root);
9916
+ }, [styles === null || styles === void 0 ? void 0 : styles.root]);
9917
+ const previousButtonSyles = React.useMemo(() => {
9918
+ return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.previousButton);
9919
+ }, [styles === null || styles === void 0 ? void 0 : styles.previousButton, theme]);
9920
+ const pageCounterStyles = React.useMemo(() => {
9921
+ return react.mergeStyles(participantPageCounter, styles === null || styles === void 0 ? void 0 : styles.counter);
9922
+ }, [styles === null || styles === void 0 ? void 0 : styles.counter]);
9923
+ const nextButtonsStyles = React.useMemo(() => {
9924
+ return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.nextButton);
9925
+ }, [styles === null || styles === void 0 ? void 0 : styles.nextButton, theme]);
9926
+ const controlBarSpacing = { childrenGap: '0.5rem' };
9927
+ return (React__default['default'].createElement(react.Stack, { horizontalAlign: "center", tokens: controlBarSpacing, horizontal: true, className: pageCounterContainerStyles },
9928
+ React__default['default'].createElement(react.DefaultButton, { className: previousButtonSyles, onClick: onPreviousButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.previous,
9929
+ /* @conditional-compile-remove(vertical-gallery) */
9930
+ ariaLabel: strings.leftNavButtonAriaLabel, "data-ui-id": ids.overflowGalleryLeftNavButton },
9931
+ React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryLeftButton", styles: navIconStyles })),
9932
+ React__default['default'].createElement(react.Text
9933
+ /* @conditional-compile-remove(vertical-gallery) */
9934
+ , { "data-ui-id": ids.verticalGalleryPageCounter, className: pageCounterStyles }, `${currentPage} / ${totalPages}`),
9935
+ React__default['default'].createElement(react.DefaultButton, { className: nextButtonsStyles, onClick: onNextButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.next,
9936
+ /* @conditional-compile-remove(vertical-gallery) */
9937
+ ariaLabel: strings.rightNavButtonAriaLabel, "data-ui-id": ids.overflowGalleryRightNavButton },
9938
+ React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryRightButton", styles: navIconStyles }))));
9939
+ };
9940
+
9941
+ // Copyright (c) Microsoft Corporation.
9942
+ /**
9943
+ * Responsive container for the VerticalGallery Component. Performs calculations for number of children
9944
+ * for the VerticalGallery
9945
+ * @param props
9946
+ *
9947
+ * @beta
9948
+ */
9949
+ const ResponsiveVerticalGallery = (props) => {
9950
+ const { children, containerStyles, verticalGalleryStyles, gapHeightRem, controlBarHeightRem, isShort, onFetchTilesToRender } = props;
9951
+ const containerRef = React.useRef(null);
9952
+ const containerHeight = _useContainerHeight(containerRef);
9953
+ const topPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingTop) : 0;
9954
+ const bottomPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingBottom) : 0;
9955
+ const childrenPerPage = calculateVerticalChildrenPerPage({
9956
+ numberOfChildren: React__default['default'].Children.count(children),
9957
+ containerHeight: (containerHeight !== null && containerHeight !== void 0 ? containerHeight : 0) - topPadding - bottomPadding,
9958
+ gapHeightRem,
9959
+ controlBarHeight: controlBarHeightRem !== null && controlBarHeightRem !== void 0 ? controlBarHeightRem : 2,
9960
+ isShort: isShort !== null && isShort !== void 0 ? isShort : false
9961
+ });
9962
+ return (React__default['default'].createElement("div", { "data-ui-id": "responsive-vertical-gallery", ref: containerRef, className: react.mergeStyles(containerStyles) },
9963
+ React__default['default'].createElement(VerticalGallery, { childrenPerPage: childrenPerPage, styles: verticalGalleryStyles, onFetchTilesToRender: onFetchTilesToRender }, children)));
9964
+ };
9965
+
9938
9966
  // Copyright (c) Microsoft Corporation.
9939
9967
  /**
9940
9968
  * @private
@@ -10020,7 +10048,13 @@ const scrollableHorizontalGalleryContainerStyles = react.mergeStyles({
10020
10048
  * @private
10021
10049
  */
10022
10050
  const ScrollableHorizontalGallery = (props) => {
10023
- const { horizontalGalleryElements } = props;
10051
+ const { horizontalGalleryElements, onFetchTilesToRender } = props;
10052
+ React.useEffect(() => {
10053
+ const indexesArray = [...Array(horizontalGalleryElements === null || horizontalGalleryElements === void 0 ? void 0 : horizontalGalleryElements.length).keys()];
10054
+ if (onFetchTilesToRender && indexesArray) {
10055
+ onFetchTilesToRender(indexesArray);
10056
+ }
10057
+ }, [onFetchTilesToRender, horizontalGalleryElements === null || horizontalGalleryElements === void 0 ? void 0 : horizontalGalleryElements.length]);
10024
10058
  const ref = React.useRef();
10025
10059
  const { events: dragabbleEvents } = reactUseDraggableScroll.useDraggable(ref);
10026
10060
  return (React__default['default'].createElement("div", Object.assign({ ref: ref }, dragabbleEvents, { className: scrollableHorizontalGalleryContainerStyles }),
@@ -10034,7 +10068,7 @@ const ScrollableHorizontalGallery = (props) => {
10034
10068
  * @private
10035
10069
  */
10036
10070
  const OverflowGallery = (props) => {
10037
- const { shouldFloatLocalVideo = false, isNarrow = false,
10071
+ const { shouldFloatLocalVideo = false, onFetchTilesToRender, isNarrow = false,
10038
10072
  /* @conditional-compile-remove(vertical-gallery) */
10039
10073
  isShort = false, overflowGalleryElements, horizontalGalleryStyles,
10040
10074
  /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout = 'HorizontalBottom',
@@ -10066,13 +10100,13 @@ const OverflowGallery = (props) => {
10066
10100
  ]);
10067
10101
  /* @conditional-compile-remove(vertical-gallery) */
10068
10102
  if (overflowGalleryLayout === 'VerticalRight') {
10069
- return (React__default['default'].createElement(ResponsiveVerticalGallery, { key: "responsive-vertical-gallery", containerStyles: containerStyles, verticalGalleryStyles: galleryStyles, controlBarHeightRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapHeightRem: HORIZONTAL_GALLERY_GAP, isShort: isShort }, overflowGalleryElements));
10103
+ return (React__default['default'].createElement(ResponsiveVerticalGallery, { key: "responsive-vertical-gallery", containerStyles: containerStyles, verticalGalleryStyles: galleryStyles, controlBarHeightRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapHeightRem: HORIZONTAL_GALLERY_GAP, isShort: isShort, onFetchTilesToRender: onFetchTilesToRender }, overflowGalleryElements));
10070
10104
  }
10071
10105
  /* @conditional-compile-remove(pinned-participants) */
10072
10106
  if (isNarrow) {
10073
- return (React__default['default'].createElement(ScrollableHorizontalGallery, { key: "scrollable-horizontal-gallery", horizontalGalleryElements: overflowGalleryElements }));
10107
+ return (React__default['default'].createElement(ScrollableHorizontalGallery, { horizontalGalleryElements: overflowGalleryElements, onFetchTilesToRender: onFetchTilesToRender, key: "scrollable-horizontal-gallery" }));
10074
10108
  }
10075
- return (React__default['default'].createElement(ResponsiveHorizontalGallery, { key: "responsive-horizontal-gallery", containerStyles: containerStyles, horizontalGalleryStyles: galleryStyles, childWidthRem: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width : LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width, buttonWidthRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapWidthRem: HORIZONTAL_GALLERY_GAP }, overflowGalleryElements));
10109
+ return (React__default['default'].createElement(ResponsiveHorizontalGallery, { key: "responsive-horizontal-gallery", containerStyles: containerStyles, onFetchTilesToRender: onFetchTilesToRender, horizontalGalleryStyles: galleryStyles, childWidthRem: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width : LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width, buttonWidthRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapWidthRem: HORIZONTAL_GALLERY_GAP }, overflowGalleryElements));
10076
10110
  };
10077
10111
 
10078
10112
  // Copyright (c) Microsoft Corporation.
@@ -10105,10 +10139,20 @@ const DefaultLayout = (props) => {
10105
10139
  ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && activeVideoStreams++ < maxRemoteVideoStreams
10106
10140
  : (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
10107
10141
  });
10108
- const horizontalGalleryTiles = horizontalGalleryParticipants.map((p) => {
10142
+ /**
10143
+ * instantiate indexes available to render with indexes available that would be on first page
10144
+ *
10145
+ * For some components which do not strictly follow the order of the array, we might
10146
+ * re-render the initial tiles -> dispose them -> create new tiles, we need to take care of
10147
+ * this case when those components are here
10148
+ */
10149
+ const [indexesToRender, setIndexesToRender] = React.useState([
10150
+ ...Array(maxRemoteVideoStreams - activeVideoStreams).keys()
10151
+ ]);
10152
+ const horizontalGalleryTiles = horizontalGalleryParticipants.map((p, i) => {
10109
10153
  var _a, _b;
10110
10154
  return onRenderRemoteParticipant(p, maxRemoteVideoStreams && maxRemoteVideoStreams >= 0
10111
- ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && activeVideoStreams++ < maxRemoteVideoStreams
10155
+ ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && indexesToRender.includes(i) && activeVideoStreams++ < maxRemoteVideoStreams
10112
10156
  : (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
10113
10157
  });
10114
10158
  if (localVideoComponent) {
@@ -10124,12 +10168,13 @@ const DefaultLayout = (props) => {
10124
10168
  /* @conditional-compile-remove(vertical-gallery) */
10125
10169
  veritcalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.verticalGallery,
10126
10170
  /* @conditional-compile-remove(pinned-participants) */
10127
- overflowGalleryLayout: overflowGalleryLayout }));
10171
+ overflowGalleryLayout: overflowGalleryLayout, onFetchTilesToRender: setIndexesToRender }));
10128
10172
  }, [
10129
10173
  isNarrow,
10130
10174
  /* @conditional-compile-remove(vertical-gallery) */ isShort,
10131
10175
  horizontalGalleryTiles,
10132
10176
  styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
10177
+ setIndexesToRender,
10133
10178
  /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout,
10134
10179
  /* @conditional-compile-remove(vertical-gallery) */ styles === null || styles === void 0 ? void 0 : styles.verticalGallery
10135
10180
  ]);
@@ -10904,14 +10949,24 @@ const FloatingLocalVideoLayout = (props) => {
10904
10949
  ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && activeVideoStreams++ < maxRemoteVideoStreams
10905
10950
  : (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
10906
10951
  });
10907
- const shouldFloatLocalVideo = remoteParticipants.length > 0;
10952
+ const shouldFloatLocalVideo = remoteParticipants.length > 0 || !!screenShareComponent;
10908
10953
  if (!shouldFloatLocalVideo && localVideoComponent) {
10909
10954
  gridTiles.push(localVideoComponent);
10910
10955
  }
10911
- const horizontalGalleryTiles = horizontalGalleryParticipants.map((p) => {
10956
+ /**
10957
+ * instantiate indexes available to render with indexes available that would be on first page
10958
+ *
10959
+ * For some components which do not strictly follow the order of the array, we might
10960
+ * re-render the initial tiles -> dispose them -> create new tiles, we need to take care of
10961
+ * this case when those components are here
10962
+ */
10963
+ const [indexesToRender, setIndexesToRender] = React.useState([
10964
+ ...Array(maxRemoteVideoStreams - activeVideoStreams).keys()
10965
+ ]);
10966
+ const horizontalGalleryTiles = horizontalGalleryParticipants.map((p, i) => {
10912
10967
  var _a, _b;
10913
10968
  return onRenderRemoteParticipant(p, maxRemoteVideoStreams && maxRemoteVideoStreams >= 0
10914
- ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && activeVideoStreams++ < maxRemoteVideoStreams
10969
+ ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && indexesToRender.includes(i) && activeVideoStreams++ < maxRemoteVideoStreams
10915
10970
  : (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
10916
10971
  });
10917
10972
  const layerHostId = reactHooks.useId('layerhost');
@@ -10920,7 +10975,7 @@ const FloatingLocalVideoLayout = (props) => {
10920
10975
  return SMALL_FLOATING_MODAL_SIZE_PX;
10921
10976
  }
10922
10977
  /* @conditional-compile-remove(vertical-gallery) */
10923
- if (horizontalGalleryTiles.length > 0 && overflowGalleryLayout === 'VerticalRight') {
10978
+ if ((horizontalGalleryTiles.length > 0 || !!screenShareComponent) && overflowGalleryLayout === 'VerticalRight') {
10924
10979
  return isNarrow
10925
10980
  ? SMALL_FLOATING_MODAL_SIZE_PX
10926
10981
  : isShort
@@ -10932,23 +10987,24 @@ const FloatingLocalVideoLayout = (props) => {
10932
10987
  horizontalGalleryTiles.length,
10933
10988
  isNarrow,
10934
10989
  /* @conditional-compile-remove(vertical-gallery) */ isShort,
10935
- /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
10990
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout,
10991
+ /* @conditional-compile-remove(vertical-gallery) */ screenShareComponent
10936
10992
  ]);
10937
10993
  const wrappedLocalVideoComponent = localVideoComponent && shouldFloatLocalVideo ? (
10938
10994
  // When we use showCameraSwitcherInLocalPreview it disables dragging to allow keyboard navigation.
10939
10995
  showCameraSwitcherInLocalPreview ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme, localVideoSize), {
10940
10996
  boxShadow: theme.effects.elevation8,
10941
10997
  zIndex: LOCAL_VIDEO_TILE_ZINDEX
10942
- }) }, localVideoComponent)) : horizontalGalleryTiles.length > 0 ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, localVideoSize)) }, localVideoComponent)) : (React__default['default'].createElement(FloatingLocalVideo, { localVideoComponent: localVideoComponent, layerHostId: layerHostId, localVideoSize: localVideoSize, parentWidth: parentWidth, parentHeight: parentHeight }))) : undefined;
10998
+ }) }, localVideoComponent)) : horizontalGalleryTiles.length > 0 || !!screenShareComponent ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, localVideoSize)) }, localVideoComponent)) : (React__default['default'].createElement(FloatingLocalVideo, { localVideoComponent: localVideoComponent, layerHostId: layerHostId, localVideoSize: localVideoSize, parentWidth: parentWidth, parentHeight: parentHeight }))) : undefined;
10943
10999
  const overflowGallery = React.useMemo(() => {
10944
- if (horizontalGalleryTiles.length === 0) {
11000
+ if (horizontalGalleryTiles.length === 0 && !screenShareComponent) {
10945
11001
  return null;
10946
11002
  }
10947
11003
  return (React__default['default'].createElement(OverflowGallery
10948
11004
  /* @conditional-compile-remove(vertical-gallery) */
10949
11005
  , {
10950
11006
  /* @conditional-compile-remove(vertical-gallery) */
10951
- isShort: isShort, isNarrow: isNarrow, shouldFloatLocalVideo: true, overflowGalleryElements: horizontalGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
11007
+ isShort: isShort, onFetchTilesToRender: setIndexesToRender, isNarrow: isNarrow, shouldFloatLocalVideo: true, overflowGalleryElements: horizontalGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
10952
11008
  /* @conditional-compile-remove(vertical-gallery) */
10953
11009
  veritcalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.verticalGallery,
10954
11010
  /* @conditional-compile-remove(vertical-gallery) */
@@ -10958,6 +11014,8 @@ const FloatingLocalVideoLayout = (props) => {
10958
11014
  /* @conditional-compile-remove(vertical-gallery) */ isShort,
10959
11015
  horizontalGalleryTiles,
10960
11016
  styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
11017
+ setIndexesToRender,
11018
+ screenShareComponent,
10961
11019
  /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout,
10962
11020
  /* @conditional-compile-remove(vertical-gallery) */ styles === null || styles === void 0 ? void 0 : styles.verticalGallery
10963
11021
  ]);
@@ -11030,7 +11088,8 @@ const VideoGallery = (props) => {
11030
11088
  : undefined;
11031
11089
  /* @conditional-compile-remove(pinned-participants) */
11032
11090
  const drawerMenuHostId = reactHooks.useId('drawerMenuHost', drawerMenuHostIdFromProp);
11033
- const shouldFloatLocalVideo = !!(layout === 'floatingLocalVideo' && remoteParticipants.length > 0);
11091
+ const shouldFloatLocalVideo = !!((layout === 'floatingLocalVideo' && remoteParticipants.length > 0) ||
11092
+ localParticipant.isScreenSharingOn);
11034
11093
  const containerRef = React.useRef(null);
11035
11094
  const containerWidth = _useContainerWidth(containerRef);
11036
11095
  const containerHeight = _useContainerHeight(containerRef);
@@ -11670,6 +11729,18 @@ const CameraButton = (props) => {
11670
11729
  iconName: props.checked ? 'SplitButtonPrimaryActionCameraOn' : 'SplitButtonPrimaryActionCameraOff',
11671
11730
  styles: { root: { lineHeight: 0 } }
11672
11731
  }
11732
+ },
11733
+ /* @conditional-compile-remove(video-background-effects) */
11734
+ {
11735
+ key: 'effects',
11736
+ text: 'Effects',
11737
+ title: 'Video Effects',
11738
+ iconProps: { iconName: 'OptionsVideoBackgroundEffect', styles: { root: { lineHeight: 0 } } },
11739
+ onClick: () => {
11740
+ if (props.onShowVideoEffectsPicker) {
11741
+ props.onShowVideoEffectsPicker(true);
11742
+ }
11743
+ }
11673
11744
  }
11674
11745
  ]
11675
11746
  }
@@ -17823,7 +17894,9 @@ const concatButtonBaseStyles = (...styles) => {
17823
17894
  const Camera = (props) => {
17824
17895
  const cameraButtonProps = usePropsFor$1(CameraButton);
17825
17896
  const styles = React.useMemo(() => { var _a; return concatButtonBaseStyles((_a = props.styles) !== null && _a !== void 0 ? _a : {}); }, [props.styles]);
17826
- return (React__default['default'].createElement(CameraButton, Object.assign({ "data-ui-id": "call-composite-camera-button" }, cameraButtonProps, { showLabel: props.displayType !== 'compact', styles: styles, enableDeviceSelectionMenu: props.splitButtonsForDeviceSelection, disabled: cameraButtonProps.disabled || props.disabled })));
17897
+ return (React__default['default'].createElement(CameraButton, Object.assign({ "data-ui-id": "call-composite-camera-button" }, cameraButtonProps, { showLabel: props.displayType !== 'compact', styles: styles, enableDeviceSelectionMenu: props.splitButtonsForDeviceSelection, disabled: cameraButtonProps.disabled || props.disabled,
17898
+ /* @conditional-compile-remove(video-background-effects) */
17899
+ onShowVideoEffectsPicker: props.onShowVideoEffectsPicker })));
17827
17900
  };
17828
17901
 
17829
17902
  // Copyright (c) Microsoft Corporation.
@@ -18301,7 +18374,7 @@ const CallControls = (props) => {
18301
18374
  /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
18302
18375
  !props.isMobile && (React__default['default'].createElement(Participants, { option: options === null || options === void 0 ? void 0 : options.participantsButton, callInvitationURL: props.callInvitationURL, onFetchParticipantMenuItems: props.onFetchParticipantMenuItems, displayType: options === null || options === void 0 ? void 0 : options.displayType, increaseFlyoutItemSize: props.increaseFlyoutItemSize, isMobile: props.isMobile, disabled: isDisabled$2(options === null || options === void 0 ? void 0 : options.participantsButton) })) && (
18303
18376
  /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
18304
- React__default['default'].createElement(People, { checked: props.peopleButtonChecked, showLabel: (options === null || options === void 0 ? void 0 : options.displayType) !== 'compact', onClick: props.onPeopleButtonClicked, "data-ui-id": "call-composite-people-button", strings: peopleButtonStrings, disabled: isDisabled$2(options === null || options === void 0 ? void 0 : options.participantsButton) })),
18377
+ React__default['default'].createElement(People, { checked: props.peopleButtonChecked, ariaLabel: peopleButtonStrings === null || peopleButtonStrings === void 0 ? void 0 : peopleButtonStrings.label, showLabel: (options === null || options === void 0 ? void 0 : options.displayType) !== 'compact', onClick: props.onPeopleButtonClicked, "data-ui-id": "call-composite-people-button", strings: peopleButtonStrings, disabled: isDisabled$2(options === null || options === void 0 ? void 0 : options.participantsButton) })),
18305
18378
  isEnabled$2(options === null || options === void 0 ? void 0 : options.devicesButton) && (React__default['default'].createElement(Devices, { displayType: options === null || options === void 0 ? void 0 : options.displayType, increaseFlyoutItemSize: props.increaseFlyoutItemSize, disabled: isDisabled$2(options === null || options === void 0 ? void 0 : options.devicesButton) })),
18306
18379
  /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(PSTN-calls) */
18307
18380
  isEnabled$2(options === null || options === void 0 ? void 0 : options.moreButton) && moreButtonContextualMenuItems().length > 0 && (React__default['default'].createElement(MoreButton, { strings: moreButtonStrings, menuIconProps: { hidden: true }, menuProps: { items: moreButtonContextualMenuItems() }, showLabel: (options === null || options === void 0 ? void 0 : options.displayType) !== 'compact' })),
@@ -22753,7 +22826,9 @@ const CallWithChatControlBar = (props) => {
22753
22826
  disabled: props.disableButtonsForHoldScreen || isDisabled$2(options.microphoneButton) })),
22754
22827
  isEnabled$1(options.cameraButton) && (React__default['default'].createElement(Camera, { displayType: options.displayType, styles: commonButtonStyles, splitButtonsForDeviceSelection: !props.mobileView,
22755
22828
  /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
22756
- disabled: props.disableButtonsForHoldScreen || isDisabled$2(options.cameraButton) })),
22829
+ disabled: props.disableButtonsForHoldScreen || isDisabled$2(options.cameraButton),
22830
+ /* @conditional-compile-remove(video-background-effects) */
22831
+ onShowVideoEffectsPicker: props.onShowVideoEffectsPicker })),
22757
22832
  props.mobileView && isEnabled$1(options === null || options === void 0 ? void 0 : options.chatButton) && chatButton,
22758
22833
  isEnabled$1(options.screenShareButton) && (React__default['default'].createElement(ScreenShare, { option: options.screenShareButton, displayType: options.displayType, styles: screenShareButtonStyles,
22759
22834
  /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
@@ -22778,7 +22853,7 @@ const CallWithChatControlBar = (props) => {
22778
22853
  _b.slice(0, CUSTOM_BUTTON_OPTIONS.MAX_SECONDARY_DESKTOP_CUSTOM_BUTTONS).map((CustomButton, i) => {
22779
22854
  return (React__default['default'].createElement(CustomButton, { key: `secondary-custom-button-${i}`, styles: commonButtonStyles, showLabel: options.displayType !== 'compact' }));
22780
22855
  }),
22781
- 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 || isDisabled$2(options.peopleButton), strings: peopleButtonStrings, styles: commonButtonStyles })),
22856
+ isEnabled$1(options === null || options === void 0 ? void 0 : options.peopleButton) && (React__default['default'].createElement(PeopleButton, { checked: props.peopleButtonChecked, ariaLabel: peopleButtonStrings === null || peopleButtonStrings === void 0 ? void 0 : peopleButtonStrings.label, showLabel: options.displayType !== 'compact', onClick: props.onPeopleButtonClicked, "data-ui-id": "call-with-chat-composite-people-button", disabled: props.disableButtonsForLobbyPage || isDisabled$2(options.peopleButton), strings: peopleButtonStrings, styles: commonButtonStyles })),
22782
22857
  isEnabled$1(options === null || options === void 0 ? void 0 : options.chatButton) && chatButton))));
22783
22858
  };
22784
22859
  const desktopButtonContainerStyle = {
@@ -23378,10 +23453,30 @@ const CallWithChatPane = (props) => {
23378
23453
  React__default['default'].createElement(_DrawerMenu, { onLightDismiss: () => setDrawerMenuItems([]), items: drawerMenuItems })))));
23379
23454
  };
23380
23455
 
23456
+ // Copyright (c) Microsoft Corporation.
23457
+ /**
23458
+ * Pane that is used to show video effects button
23459
+ * @private
23460
+ */
23461
+ /** @beta */
23462
+ const VideoEffectsPane = (props) => {
23463
+ return VideoEffectsPaneTrampoline(props.showVideoEffectsOptions, props.setshowVideoEffectsOptions);
23464
+ };
23465
+ const VideoEffectsPaneTrampoline = (showVideoEffectsOptions, setshowVideoEffectsOptions) => {
23466
+ /* @conditional-compile-remove(video-background-effects) */
23467
+ return (React__default['default'].createElement(react.Panel, { headerText: "Effects", isOpen: showVideoEffectsOptions, onDismiss: () => setshowVideoEffectsOptions(false), hasCloseButton: true, closeButtonAriaLabel: "Close", isLightDismiss: true }));
23468
+ };
23469
+
23381
23470
  // Copyright (c) Microsoft Corporation.
23382
23471
  const CallWithChatScreen = (props) => {
23383
23472
  const { callWithChatAdapter, fluentTheme, formFactor = 'desktop' } = props;
23384
23473
  const mobileView = formFactor === 'mobile';
23474
+ /* @conditional-compile-remove(video-background-effects) */
23475
+ const [showVideoEffectsPane, setVideoEffectsPane] = React.useState(false);
23476
+ /* @conditional-compile-remove(video-background-effects) */
23477
+ const setShowVideoEffectsPane = React.useCallback((showVideoEffectsOptions) => {
23478
+ setVideoEffectsPane(showVideoEffectsOptions);
23479
+ }, [setVideoEffectsPane]);
23385
23480
  if (!callWithChatAdapter) {
23386
23481
  throw new Error('CallWithChatAdapter is undefined');
23387
23482
  }
@@ -23526,6 +23621,8 @@ const CallWithChatScreen = (props) => {
23526
23621
  // Perf: Instead of removing the video gallery from DOM, we hide it to prevent re-renders.
23527
23622
  style: callCompositeContainerCSS },
23528
23623
  React__default['default'].createElement(CallComposite, Object.assign({}, props, { formFactor: formFactor, options: callCompositeOptions, adapter: callAdapter, fluentTheme: fluentTheme }))),
23624
+ /* @conditional-compile-remove(video-background-effects) */
23625
+ React__default['default'].createElement(VideoEffectsPane, { showVideoEffectsOptions: showVideoEffectsPane, setshowVideoEffectsOptions: setShowVideoEffectsPane }),
23529
23626
  chatProps.adapter && callAdapter && hasJoinedCall && (React__default['default'].createElement(CallWithChatPane, { chatCompositeProps: chatProps, inviteLink: props.joinInvitationURL, onClose: closePane, chatAdapter: chatProps.adapter, callAdapter: callAdapter, onFetchAvatarPersonaData: props.onFetchAvatarPersonaData, onFetchParticipantMenuItems: props.onFetchParticipantMenuItems, onChatButtonClicked: showShowChatTabHeaderButton(props.callControls) ? selectChat : undefined, onPeopleButtonClicked: showShowPeopleTabHeaderButton(props.callControls) ? selectPeople : undefined, modalLayerHostId: modalLayerHostId, mobileView: mobileView, activePane: activePane,
23530
23627
  /* @conditional-compile-remove(file-sharing) */
23531
23628
  fileSharing: props.fileSharing, rtl: props.rtl, callControls: typeof props.callControls !== 'boolean' ? props.callControls : undefined }))),
@@ -23535,7 +23632,9 @@ const CallWithChatScreen = (props) => {
23535
23632
  /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
23536
23633
  disableButtonsForHoldScreen: isInLocalHold, callControls: props.callControls, containerHeight: containerHeight, containerWidth: containerWidth,
23537
23634
  /* @conditional-compile-remove(PSTN-calls) */
23538
- onClickShowDialpad: alternateCallerId ? onClickShowDialpad : undefined })))),
23635
+ onClickShowDialpad: alternateCallerId ? onClickShowDialpad : undefined,
23636
+ /* @conditional-compile-remove(video-background-effects) */
23637
+ onShowVideoEffectsPicker: setShowVideoEffectsPane })))),
23539
23638
  showControlBar && showDrawer && (React__default['default'].createElement(ChatAdapterProvider, { adapter: chatProps.adapter },
23540
23639
  React__default['default'].createElement(CallAdapterProvider, { adapter: callAdapter },
23541
23640
  React__default['default'].createElement(react.Stack, { styles: drawerContainerStyles() },