UNPKG

communication-react-19

Version:

React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)

82 lines 5.2 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Stack } from '@fluentui/react'; import React, { useMemo, useState, useRef } from 'react'; import { GridLayout } from '../GridLayout'; import { isNarrowWidth } from '../utils/responsive'; import { isShortHeight } from '../utils/responsive'; import { rootLayoutStyle } from './styles/DefaultLayout.styles'; import { videoGalleryLayoutGap } from './styles/Layout.styles'; import { MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY, renderTiles, useOrganizedParticipants } from './utils/videoGalleryLayoutUtils'; import { OverflowGallery } from './OverflowGallery'; /** * DefaultLayout displays remote participants, local video component, and screen sharing component in * a grid an overflow gallery. * * @private */ export const DefaultLayout = (props) => { const { remoteParticipants = [], localParticipant, dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, parentWidth, parentHeight, pinnedParticipantUserIds = [], overflowGalleryPosition = 'horizontalBottom', spotlightedParticipantUserIds = [] } = props; const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false; const isShort = parentHeight ? isShortHeight(parentHeight) : false; // This is for tracking the number of children in the first page of overflow gallery. // This number will be used for the maxOverflowGalleryDominantSpeakers when organizing the remote participants. // We need to add the local participant to the pinned participant count so we are placing the speakers correctly. const childrenPerPage = useRef(4); const remoteVideosOn = remoteParticipants.filter((p) => { var _a; return (_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable; }).length > 0; const { gridParticipants, overflowGalleryParticipants } = useOrganizedParticipants({ remoteParticipants, localParticipant, dominantSpeakers, maxGridParticipants: remoteVideosOn ? maxRemoteVideoStreams : MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY, isScreenShareActive: !!screenShareComponent, maxOverflowGalleryDominantSpeakers: screenShareComponent ? childrenPerPage.current - ((pinnedParticipantUserIds.length + 1) % childrenPerPage.current) : childrenPerPage.current, pinnedParticipantUserIds, layout: 'default', spotlightedParticipantUserIds }); /** * instantiate indexes available to render with indexes available that would be on first page * * For some components which do not strictly follow the order of the array, we might * re-render the initial tiles -> dispose them -> create new tiles, we need to take care of * this case when those components are here */ const [indexesToRender, setIndexesToRender] = useState([]); let { gridTiles, overflowGalleryTiles } = renderTiles(gridParticipants, onRenderRemoteParticipant, maxRemoteVideoStreams, indexesToRender, overflowGalleryParticipants, dominantSpeakers); if (localVideoComponent) { if (screenShareComponent || spotlightedParticipantUserIds.length > 0) { overflowGalleryTiles = [localVideoComponent].concat(overflowGalleryTiles); } else { gridTiles = [localVideoComponent].concat(gridTiles); } } const overflowGallery = useMemo(() => { if (overflowGalleryTiles.length === 0) { return null; } return (React.createElement(OverflowGallery, { isNarrow: isNarrow, isShort: isShort, shouldFloatLocalVideo: false, overflowGalleryElements: overflowGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery, verticalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.verticalGallery, overflowGalleryPosition: overflowGalleryPosition, onFetchTilesToRender: setIndexesToRender, onChildrenPerPageChange: (n) => { childrenPerPage.current = n; }, parentWidth: parentWidth })); }, [ isNarrow, isShort, overflowGalleryTiles, styles === null || styles === void 0 ? void 0 : styles.horizontalGallery, overflowGalleryPosition, setIndexesToRender, styles === null || styles === void 0 ? void 0 : styles.verticalGallery, parentWidth ]); return (React.createElement(Stack, { horizontal: overflowGalleryPosition === 'verticalRight', styles: rootLayoutStyle, tokens: videoGalleryLayoutGap }, props.overflowGalleryPosition === 'horizontalTop' ? overflowGallery : React.createElement(React.Fragment, null), screenShareComponent ? (screenShareComponent) : (React.createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)), overflowGalleryTrampoline(overflowGallery, props.overflowGalleryPosition))); }; const overflowGalleryTrampoline = (gallery, galleryPosition) => { return galleryPosition !== 'horizontalTop' ? gallery : React.createElement(React.Fragment, null); }; //# sourceMappingURL=DefaultLayout.js.map