communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
89 lines • 4.96 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { concatStyleSets, ContextualMenu, Stack } from '@fluentui/react';
import React, { useCallback, useMemo, useState } from 'react';
import { LocalAndRemotePIP } from '../CallComposite/components/LocalAndRemotePIP';
import { useHandlers } from '../CallComposite/hooks/useHandlers';
import { useSelector } from '../CallComposite/hooks/useSelector';
import { localAndRemotePIPSelector } from '../CallComposite/selectors/localAndRemotePIPSelector';
import { _ModalClone } from "../../../../react-components/src";
import { _RemoteVideoTile } from "../../../../react-components/src";
import { hiddenStyle, modalStyle, PIPContainerStyle } from './styles/ModalLocalAndRemotePIP.styles';
import { useLocale } from '../localization';
import { getRole } from '../CallComposite/selectors/baseSelectors';
/**
* Drag options for Modal in {@link ModalLocalAndRemotePIP} component
*/
const DRAG_OPTIONS = {
moveMenuItemText: 'Move',
closeMenuItemText: 'Close',
menu: ContextualMenu,
keepInBounds: true
};
/**
* A wrapping component with a draggable {@link LocalAndRemotePIP} component that is bound to a LayerHost component with id
* specified by `modalLayerHostId` prop
* @private
*/
export const ModalLocalAndRemotePIP = (props) => {
var _a;
const rootStyles = props.hidden ? hiddenStyle : PIPContainerStyle;
const role = useSelector(getRole);
const locale = useLocale();
const pictureInPictureProps = useSelector(localAndRemotePIPSelector);
const [touchStartTouches, setTouchStartTouches] = useState(null);
const onTouchEnd = useCallback((event) => {
var _a;
if (touchStartTouches &&
touchStartTouches[0] &&
touchStartTouches.length === 1 &&
event.changedTouches[0] &&
event.changedTouches.length === 1) {
const touchStartTouch = touchStartTouches[0];
const touchEndTouch = event.changedTouches[0];
if (Math.abs(touchStartTouch.clientX - touchEndTouch.clientX) < 10 &&
Math.abs(touchStartTouch.clientY - touchEndTouch.clientY) < 10) {
(_a = props.onDismissSidePane) === null || _a === void 0 ? void 0 : _a.call(props);
}
}
}, [props, touchStartTouches]);
const onTouchStart = useCallback((event) => {
setTouchStartTouches(event.touches);
}, []);
const onKeyDown = useCallback((event) => {
var _a;
if (event.key === 'Enter' || event.key === ' ') {
(_a = props.onDismissSidePane) === null || _a === void 0 ? void 0 : _a.call(props);
}
}, [props]);
const pictureInPictureHandlers = useHandlers(LocalAndRemotePIP);
const remoteParticipant = pictureInPictureProps.remoteParticipant;
const localAndRemotePIP = useMemo(() => {
var _a, _b, _c, _d;
if (role === 'Consumer' && (remoteParticipant === null || remoteParticipant === void 0 ? void 0 : remoteParticipant.userId)) {
return (React.createElement(Stack, { tabIndex: 0, "aria-label": (_b = (_a = props.strings) === null || _a === void 0 ? void 0 : _a.dismissModalAriaLabel) !== null && _b !== void 0 ? _b : '', onKeyDown: onKeyDown },
React.createElement(_RemoteVideoTile, Object.assign({ strings: locale.component.strings.videoGallery }, remoteParticipant, { remoteParticipant: remoteParticipant }))));
}
return (React.createElement(Stack, { tabIndex: 0, "aria-label": (_d = (_c = props.strings) === null || _c === void 0 ? void 0 : _c.dismissModalAriaLabel) !== null && _d !== void 0 ? _d : '', onKeyDown: onKeyDown },
React.createElement(LocalAndRemotePIP, Object.assign({}, pictureInPictureProps, pictureInPictureHandlers, { remoteParticipant: remoteParticipant }))));
}, [
role,
onKeyDown,
pictureInPictureProps,
props,
pictureInPictureHandlers,
locale.component.strings.videoGallery,
remoteParticipant
]);
if (role === 'Consumer' && !remoteParticipant) {
return null;
}
const modalStylesThemed = concatStyleSets(modalStyle, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.modal);
return (React.createElement(Stack, { styles: rootStyles },
React.createElement(Stack, { onTouchStart: onTouchStart, onTouchEnd: onTouchEnd },
React.createElement(_ModalClone, { isOpen: true, isModeless: true, dragOptions: DRAG_OPTIONS, styles: modalStylesThemed, layerProps: { hostId: props.modalLayerHostId }, minDragPosition: props.minDragPosition, maxDragPosition: props.maxDragPosition },
// Only render LocalAndRemotePIP when this component is NOT hidden because VideoGallery needs to have
// possession of the dominant remote participant video stream
!props.hidden && localAndRemotePIP))));
};
//# sourceMappingURL=ModalLocalAndRemotePIP.js.map