communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
59 lines • 3.24 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { mergeStyles, Spinner } from '@fluentui/react';
/* @conditional-compile-remove(remote-ufd) */
import { Stack } from '@fluentui/react';
import React, { useEffect, useRef, useState } from 'react';
import { invertedVideoInPipStyle, mediaContainer, container, loadingSpinnerContainer, loadSpinnerStyles } from './styles/StreamMedia.styles';
/* @conditional-compile-remove(remote-ufd) */
import { reconnectingContainer, reconnectSpinnerStyles } from './styles/StreamMedia.styles';
/* @conditional-compile-remove(remote-ufd) */
import { useLocale } from '../localization';
import { useTheme } from '../theming';
/**
* Utility component to convert an HTMLElement with a video stream into a JSX element.
*
* Use to convert an HTMLElement returned by headless calling API into a component that can be rendered as a {@link VideoTile}.
*
* @public
*/
export const StreamMedia = (props) => {
const containerEl = useRef(null);
const theme = useTheme();
/* @conditional-compile-remove(remote-ufd) */
const reconnectingText = useLocale().strings.videoTile.participantReconnecting || 'Reconnecting...';
const { isMirrored, videoStreamElement, styles, loadingState = 'none' } = props;
const [pipEnabled, setPipEnabled] = useState(false);
useEffect(() => {
const container = containerEl.current;
if (!container) {
return;
}
// If videoStreamElement changes, we clear the container to make sure we don't have duplicate, and replace it with
// the new videoStreamElement. If videoStreamElement is undefined nothing is appended and container should be empty
// and we don't render anyting.
container.innerHTML = '';
setPipEnabled(false);
if (videoStreamElement) {
videoStreamElement.addEventListener('enterpictureinpicture', () => {
setPipEnabled(true);
});
videoStreamElement.addEventListener('leavepictureinpicture', () => {
setPipEnabled(false);
});
container.appendChild(videoStreamElement);
}
return () => {
container.innerHTML = '';
setPipEnabled(false);
};
}, [videoStreamElement]);
return (React.createElement("div", { className: container() },
React.createElement("div", { "data-ui-id": "stream-media-container", className: mergeStyles(isMirrored && pipEnabled ? invertedVideoInPipStyle(theme) : mediaContainer(theme), styles === null || styles === void 0 ? void 0 : styles.root), ref: containerEl }),
loadingState === 'loading' && (React.createElement("div", { className: loadingSpinnerContainer() },
React.createElement(Spinner, { "data-ui-id": "stream-media-loading-spinner", styles: loadSpinnerStyles }))),
/* @conditional-compile-remove(remote-ufd) */
loadingState === 'reconnecting' && (React.createElement(Stack, { className: reconnectingContainer() },
React.createElement(Spinner, { "data-ui-id": "stream-media-loading-spinner", styles: reconnectSpinnerStyles(), label: reconnectingText })))));
};
//# sourceMappingURL=StreamMedia.js.map