UNPKG

communication-react-19

Version:

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

132 lines 7.94 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import React, { useCallback, useState, useMemo } from 'react'; import { useLocale } from '../localization'; import { ControlBarButton } from './ControlBarButton'; import { _HighContrastAwareIcon } from './HighContrastAwareIcon'; import { ContextualMenuItemType } from '@fluentui/react'; import { generateDefaultDeviceMenuProps } from './DevicesButton'; import { Announcer } from './Announcer'; const defaultLocalVideoViewOptions = { scalingMode: 'Crop', isMirrored: true }; /** * A button to turn camera on / off. * * Can be used with {@link ControlBar}. * * @public */ export const CameraButton = (props) => { var _a, _b, _c, _d, _e, _f, _g, _h; const { localVideoViewOptions, onToggleCamera, onSelectCamera } = props; const [waitForCamera, setWaitForCamera] = useState(false); const localeStrings = useLocale().strings.cameraButton; const strings = Object.assign(Object.assign({}, localeStrings), props.strings); const [announcerString, setAnnouncerString] = useState(undefined); const [announcerPresent, setAnnouncerPresent] = useState(false); const disabled = props.disabled || waitForCamera; const onRenderCameraOnIcon = () => (React.createElement(_HighContrastAwareIcon, { disabled: disabled, iconName: "ControlButtonCameraOn" })); const onRenderCameraOffIcon = () => (React.createElement(_HighContrastAwareIcon, { disabled: disabled, iconName: "ControlButtonCameraOff" })); if (waitForCamera && strings.tooltipVideoLoadingContent) { strings.tooltipDisabledContent = strings.tooltipVideoLoadingContent; } const cameraOn = props.checked; const cameraTurningOn = waitForCamera && !cameraOn; // Ensure Aria-label by default reflects the loading state of the camera const ariaLabel = ((_a = props.ariaLabel) !== null && _a !== void 0 ? _a : cameraTurningOn) ? strings.tooltipVideoLoadingContent : undefined; const splitButtonAriaString = cameraTurningOn ? strings.tooltipVideoLoadingContent : cameraOn ? strings.onSplitButtonAriaLabel : strings.offSplitButtonAriaLabel; const toggleAnnouncerString = useCallback((isCameraOn) => { setAnnouncerString(!isCameraOn ? strings.cameraActionTurnedOffAnnouncement : strings.cameraActionTurnedOnAnnouncement); }, [strings.cameraActionTurnedOffAnnouncement, strings.cameraActionTurnedOnAnnouncement]); const onVideoIsLoadingAnnouncementCallback = useCallback(() => { if (!cameraOn) { setAnnouncerString(strings.tooltipVideoLoadingContent); } }, [setAnnouncerString, cameraOn, strings.tooltipVideoLoadingContent]); const onToggleClick = useCallback(() => __awaiter(void 0, void 0, void 0, function* () { // Throttle click on camera, need to await onToggleCamera then allow another click if (onToggleCamera) { setWaitForCamera(true); try { yield onToggleCamera(localVideoViewOptions !== null && localVideoViewOptions !== void 0 ? localVideoViewOptions : defaultLocalVideoViewOptions); // allows for the setting of narrator strings triggering the announcer when camera is turned on or off. toggleAnnouncerString(!cameraOn); } finally { setWaitForCamera(false); } } }), [cameraOn, localVideoViewOptions, onToggleCamera, toggleAnnouncerString]); const onToggleClickCallback = useCallback(() => { onVideoIsLoadingAnnouncementCallback(); onToggleClick(); }, [onVideoIsLoadingAnnouncementCallback, onToggleClick]); const onChangeCameraClick = useCallback((device) => __awaiter(void 0, void 0, void 0, function* () { // Throttle changing camera to prevent too many callbacks if (onSelectCamera) { setWaitForCamera(true); try { yield onSelectCamera(device); } finally { setWaitForCamera(false); } } }), [onSelectCamera]); const splitButtonMenuItems = []; if (props.onClickVideoEffects) { splitButtonMenuItems.push({ key: 'effects', 'data-ui-id': 'camera-split-button-video-effects', text: strings.videoEffectsMenuItemTitle, iconProps: { iconName: 'ControlButtonVideoEffectsOption', styles: { root: { lineHeight: 0 } } }, onClick: () => { if (props.onClickVideoEffects) { props.onClickVideoEffects(true); } } }); } splitButtonMenuItems.push({ key: 'cameraPrimaryAction', text: props.checked ? strings.onSplitButtonPrimaryActionCamera : strings.offSplitButtonPrimaryActionCamera, onClick: () => { onToggleClick(); }, iconProps: { iconName: props.checked ? 'SplitButtonPrimaryActionCameraOn' : 'SplitButtonPrimaryActionCameraOff', styles: { root: { lineHeight: 0 } } } }); const splitButtonPrimaryAction = { key: 'primaryAction', title: 'toggle camera', itemType: ContextualMenuItemType.Section, sectionProps: { topDivider: true, items: splitButtonMenuItems } }; const splitButtonMenuProps = useMemo(() => (Object.assign(Object.assign({}, props.splitButtonMenuProps), { className: 'camera-split-button' })), [props.splitButtonMenuProps]); return (React.createElement(React.Fragment, null, announcerPresent && React.createElement(Announcer, { announcementString: announcerString, ariaLive: 'polite' }), React.createElement(ControlBarButton, Object.assign({}, props, { disabled: disabled, onClick: onToggleCamera ? onToggleClickCallback : props.onClick, onRenderOnIcon: (_b = props.onRenderOnIcon) !== null && _b !== void 0 ? _b : onRenderCameraOnIcon, onRenderOffIcon: (_c = props.onRenderOffIcon) !== null && _c !== void 0 ? _c : onRenderCameraOffIcon, strings: strings, labelKey: (_d = props.labelKey) !== null && _d !== void 0 ? _d : 'cameraButtonLabel', menuProps: (_e = props.menuProps) !== null && _e !== void 0 ? _e : (props.enableDeviceSelectionMenu ? generateDefaultDeviceMenuProps(Object.assign(Object.assign({}, props), { onSelectCamera: onChangeCameraClick, styles: (_f = props.styles) === null || _f === void 0 ? void 0 : _f.menuStyles }), strings, splitButtonPrimaryAction) : undefined), menuIconProps: ((_g = props.menuIconProps) !== null && _g !== void 0 ? _g : !props.enableDeviceSelectionMenu) ? { hidden: true } : undefined, split: (_h = props.split) !== null && _h !== void 0 ? _h : props.enableDeviceSelectionMenu, "aria-description": strings.cameraButtonAriaDescription, "aria-roledescription": props.enableDeviceSelectionMenu ? strings.cameraButtonSplitRoleDescription : undefined, ariaLabel: ariaLabel, splitButtonAriaLabel: props.enableDeviceSelectionMenu ? splitButtonAriaString : undefined, splitButtonMenuProps: splitButtonMenuProps, onFocus: () => setAnnouncerPresent(true), onBlur: () => setAnnouncerPresent(false) })))); }; //# sourceMappingURL=CameraButton.js.map