UNPKG

communication-react-19

Version:

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

201 lines 10.3 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { ContextualMenuItemType, merge } from '@fluentui/react'; import { _preventDismissOnEvent as preventDismissOnEvent } from "../../../acs-ui-common/src"; import React from 'react'; import { useLocale } from '../localization'; import { ControlBarButton } from './ControlBarButton'; import { _HighContrastAwareIcon } from './HighContrastAwareIcon'; import { buttonFlyoutItemStyles } from './styles/ControlBar.styles'; const defaultLocalVideoViewOptions = { scalingMode: 'Crop', isMirrored: true }; /** * Generates default {@link IContextualMenuProps} for buttons that * show a drop-down to select devices to use. * * @internal */ export const generateDefaultDeviceMenuProps = (props, strings, primaryActionItem, isSelectCamAllowed = true, isSelectMicAllowed = true) => { var _a, _b, _c, _d; const { microphones, speakers, cameras, selectedMicrophone, selectedSpeaker, selectedCamera, onSelectCamera, onSelectMicrophone, onSelectSpeaker } = props; const defaultMenuProps = { items: [], styles: props.styles, calloutProps: { styles: { root: { // Confine the menu to the parents bounds. // More info: https://github.com/microsoft/fluentui/issues/18835 // NB: 95% to keep some space for margin, drop shadow etc around the Callout. maxWidth: '95%' } }, preventDismissOnEvent } }; const menuItemStyles = merge(buttonFlyoutItemStyles, (_b = (_a = props.styles) === null || _a === void 0 ? void 0 : _a.menuItemStyles) !== null && _b !== void 0 ? _b : {}); if (cameras && selectedCamera && onSelectCamera && isSelectCamAllowed) { defaultMenuProps.items.push({ key: 'cameras', itemType: ContextualMenuItemType.Section, sectionProps: { title: strings.cameraMenuTitle, items: [ { key: 'sectionCamera', title: strings.cameraMenuTooltip, subMenuProps: { calloutProps: { preventDismissOnEvent }, items: cameras.map((camera) => ({ key: camera.id, text: camera.name, title: camera.name, iconProps: { iconName: 'ContextMenuCameraIcon', styles: { root: { lineHeight: 0 } } }, itemProps: { styles: menuItemStyles }, canCheck: true, isChecked: camera.id === (selectedCamera === null || selectedCamera === void 0 ? void 0 : selectedCamera.id), onClick: () => { if (camera.id !== (selectedCamera === null || selectedCamera === void 0 ? void 0 : selectedCamera.id)) { onSelectCamera(camera, defaultLocalVideoViewOptions); } } })) }, text: selectedCamera.name } ] } }); if (primaryActionItem) { defaultMenuProps.items.push(primaryActionItem); } } if (microphones && selectedMicrophone && onSelectMicrophone && isSelectMicAllowed) { // Set props as Microphone if speakers can be enumerated else set as Audio Device const speakersAvailable = speakers && speakers.length > 0; const key = speakersAvailable ? 'sectionMicrophone' : 'sectionAudioDevice'; const title = speakersAvailable ? strings.microphoneMenuTooltip : strings.audioDeviceMenuTooltip; const defaultMicrophoneLabelFallback = (_c = strings.defaultMicrophoneLabelFallback) !== null && _c !== void 0 ? _c : 'Default'; // If the default microphone has no name, use the default fallback label. This occurs on Android WebViews. const selectedMicIsDefault = selectedMicrophone.id === ((_d = microphones[0]) === null || _d === void 0 ? void 0 : _d.id); const selectedMicrophoneName = selectedMicIsDefault && !selectedMicrophone.name ? defaultMicrophoneLabelFallback : selectedMicrophone.name; defaultMenuProps.items.push({ key: 'microphones', itemType: ContextualMenuItemType.Section, sectionProps: { title: strings.microphoneMenuTitle, items: [ { key: key, title: title, subMenuProps: { calloutProps: { preventDismissOnEvent }, items: microphones.map((microphone, i) => { const microphoneIsDefault = i === 0; // If the default microphone has no name, use the default fallback label. This occurs on Android WebViews. const micLabel = microphoneIsDefault && !microphone.name ? defaultMicrophoneLabelFallback : microphone.name; return { key: microphone.id, text: micLabel, title: micLabel, itemProps: { styles: menuItemStyles }, iconProps: { iconName: 'ContextMenuMicIcon', styles: { root: { lineHeight: 0 } } }, canCheck: true, isChecked: microphone.id === (selectedMicrophone === null || selectedMicrophone === void 0 ? void 0 : selectedMicrophone.id), onClick: () => { if (microphone.id !== (selectedMicrophone === null || selectedMicrophone === void 0 ? void 0 : selectedMicrophone.id)) { onSelectMicrophone(microphone); } } }; }) }, text: selectedMicrophoneName } ] } }); } if (speakers && selectedSpeaker && onSelectSpeaker) { defaultMenuProps.items.push({ key: 'speakers', itemType: ContextualMenuItemType.Section, sectionProps: { title: strings.speakerMenuTitle, items: [ { key: 'sectionSpeaker', subMenuProps: { calloutProps: { preventDismissOnEvent }, items: speakers.map((speaker) => ({ key: speaker.id, text: speaker.name, title: speaker.name, itemProps: { styles: menuItemStyles }, iconProps: { iconName: 'ContextMenuSpeakerIcon', styles: { root: { lineHeight: 0 } } }, canCheck: true, isChecked: speaker.id === (selectedSpeaker === null || selectedSpeaker === void 0 ? void 0 : selectedSpeaker.id), onClick: () => { if (speaker.id !== (selectedSpeaker === null || selectedSpeaker === void 0 ? void 0 : selectedSpeaker.id)) { onSelectSpeaker(speaker); } } })) }, text: selectedSpeaker.name } ] } }); } if (microphones && selectedMicrophone && onSelectMicrophone && isSelectMicAllowed && primaryActionItem) { defaultMenuProps.items.push(primaryActionItem); } if (defaultMenuProps.items.length === 0) { // Avoids creating an empty context menu. return undefined; } return defaultMenuProps; }; /** * A button to open a menu that controls device options. * * Can be used with {@link ControlBar}. * * @public */ export const DevicesButton = (props) => { var _a, _b, _c; const { onRenderIcon } = props; const localeStrings = useLocale().strings.devicesButton; const strings = Object.assign(Object.assign({}, localeStrings), props.strings); const devicesButtonMenu = (_a = props.menuProps) !== null && _a !== void 0 ? _a : generateDefaultDeviceMenuProps(Object.assign(Object.assign({}, props), { styles: (_b = props.styles) === null || _b === void 0 ? void 0 : _b.menuStyles }), strings); const onRenderOptionsIcon = () => { return React.createElement(_HighContrastAwareIcon, { disabled: props.disabled, iconName: "ControlButtonOptions" }); }; return (React.createElement(ControlBarButton, Object.assign({}, props, { menuProps: devicesButtonMenu, menuIconProps: { hidden: true }, onRenderIcon: onRenderIcon !== null && onRenderIcon !== void 0 ? onRenderIcon : onRenderOptionsIcon, strings: strings, labelKey: (_c = props.labelKey) !== null && _c !== void 0 ? _c : 'devicesButtonLabel' }))); }; //# sourceMappingURL=DevicesButton.js.map