communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
449 lines • 21.9 kB
JavaScript
// 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 { CaptionsBanner } from "../../../../../react-components/src";
import { HoldButton } from "../../../../../react-components/src";
import { StartCaptionsButton } from "../../../../../react-components/src";
import React from 'react';
import { useState } from 'react';
import { useMemo, useCallback } from 'react';
import { usePropsFor } from '../../CallComposite/hooks/usePropsFor';
import { buttonFlyoutIncreasedSizeStyles } from '../../CallComposite/styles/Buttons.styles';
import { MoreButton } from '../MoreButton';
import { useLocale } from '../../localization';
import { CUSTOM_BUTTON_OPTIONS, generateCustomCallDesktopOverflowButtons, onFetchCustomButtonPropsTrampoline } from './CustomButton';
import { _preventDismissOnEvent } from "../../../../../acs-ui-common/src";
import { showDtmfDialer } from '../../CallComposite/utils/MediaGalleryUtils';
import { useSelector } from '../../CallComposite/hooks/useSelector';
import { getTargetCallees } from '../../CallComposite/selectors/baseSelectors';
import { getIsTogetherModeActive, getCapabilites, getLocalUserId, getIsTeamsCall } from '../../CallComposite/selectors/baseSelectors';
import { getTeamsMeetingCoordinates, getIsTeamsMeeting } from '../../CallComposite/selectors/baseSelectors';
/**
*
* @private
*/
export const DesktopMoreButton = (props) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
const localeStrings = useLocale();
const holdButtonProps = usePropsFor(HoldButton);
const startCaptionsButtonProps = usePropsFor(StartCaptionsButton);
const realTimeTextProps = usePropsFor(CaptionsBanner);
const startCaptions = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
yield startCaptionsButtonProps.onStartCaptions({
spokenLanguage: startCaptionsButtonProps.currentSpokenLanguage
});
}), [startCaptionsButtonProps]);
/* @conditional-compile-remove(overflow-top-composite) */
const [galleryPositionTop, setGalleryPositionTop] = useState(false);
const [focusedContentOn, setFocusedContentOn] = useState(false);
const [previousLayout, setPreviousLayout] = useState((_a = props.userSetGalleryLayout) !== null && _a !== void 0 ? _a : 'floatingLocalVideo');
const callees = useSelector(getTargetCallees);
const allowDtmfDialer = showDtmfDialer(callees);
const isTeamsMeeting = useSelector(getIsTeamsMeeting);
const teamsMeetingCoordinates = useSelector(getTeamsMeetingCoordinates);
const isTogetherModeActive = useSelector(getIsTogetherModeActive);
const participantCapability = useSelector(getCapabilites);
const participantId = useSelector(getLocalUserId);
const isTeamsCall = useSelector(getIsTeamsCall);
const [dtmfDialerChecked, setDtmfDialerChecked] = useState((_b = props.dtmfDialerPresent) !== null && _b !== void 0 ? _b : false);
const moreButtonStrings = useMemo(() => ({
label: localeStrings.strings.call.moreButtonCallingLabel,
tooltipOffContent: localeStrings.strings.callWithChat.moreDrawerButtonTooltip
}), [localeStrings]);
const moreButtonContextualMenuItems = [];
const menuSubIconStyleSet = {
root: {
height: 'unset',
lineHeight: '100%',
width: '1.25rem'
}
};
if (props.callControls === true || ((_c = props.callControls) === null || _c === void 0 ? void 0 : _c.holdButton) !== false) {
moreButtonContextualMenuItems.push({
key: 'holdButtonKey',
text: localeStrings.component.strings.holdButton.tooltipOffContent,
onClick: () => {
holdButtonProps.onToggleHold();
},
iconProps: { iconName: 'HoldCallContextualMenuItem', styles: { root: { lineHeight: 0 } } },
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
disabled: props.disableButtonsForHoldScreen
});
}
// is captions feature is active
if (props.isCaptionsSupported) {
const captionsContextualMenuItems = [];
moreButtonContextualMenuItems.push({
key: 'liveCaptionsKey',
id: 'common-call-composite-captions-button',
text: localeStrings.strings.call.liveCaptionsLabel,
iconProps: { iconName: 'CaptionsIcon', styles: { root: { lineHeight: 0 } } },
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
disabled: props.disableButtonsForHoldScreen,
subMenuProps: {
id: 'captions-contextual-menu',
items: captionsContextualMenuItems,
calloutProps: {
preventDismissOnEvent: _preventDismissOnEvent
}
},
submenuIconProps: {
iconName: 'HorizontalGalleryRightButton',
styles: menuSubIconStyleSet
}
});
captionsContextualMenuItems.push({
key: 'ToggleCaptionsKey',
id: 'common-call-composite-captions-toggle-button',
text: startCaptionsButtonProps.checked
? localeStrings.strings.call.startCaptionsButtonTooltipOnContent
: localeStrings.strings.call.startCaptionsButtonTooltipOffContent,
onClick: () => {
if (startCaptionsButtonProps.checked) {
startCaptionsButtonProps.onStopCaptions();
}
else {
if (startCaptionsButtonProps.currentSpokenLanguage !== '') {
startCaptions();
}
else if (props.onCaptionsSettingsClick) {
props.onCaptionsSettingsClick();
}
}
},
iconProps: {
iconName: startCaptionsButtonProps.checked ? 'CaptionsOffIcon' : 'CaptionsIcon',
styles: { root: { lineHeight: 0 } }
},
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
disabled: props.disableButtonsForHoldScreen
});
if (props.onCaptionsSettingsClick) {
captionsContextualMenuItems.push({
key: 'openCaptionsSettingsKey',
id: 'common-call-composite-captions-settings-button',
text: localeStrings.strings.call.captionsSettingsLabel,
onClick: props.onCaptionsSettingsClick,
iconProps: {
iconName: 'CaptionsSettingsIcon',
styles: { root: { lineHeight: 0 } }
},
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
disabled: props.disableButtonsForHoldScreen || !startCaptionsButtonProps.checked
});
}
}
//RTT
if (props.isRealTimeTextSupported) {
const realTimeTextContextualMenuItems = [];
const rttDisabled = props.disableButtonsForHoldScreen || realTimeTextProps.isRealTimeTextOn || props.startRealTimeTextButtonChecked;
moreButtonContextualMenuItems.push({
key: 'realTimeTextKey',
id: 'common-call-composite-rtt-button',
text: localeStrings.strings.call.realTimeTextLabel,
iconProps: { iconName: 'RealTimeTextIcon', styles: { root: { lineHeight: 0 } } },
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
disabled: props.disableButtonsForHoldScreen,
subMenuProps: {
id: 'rtt-contextual-menu',
items: realTimeTextContextualMenuItems,
calloutProps: {
preventDismissOnEvent: _preventDismissOnEvent
}
},
submenuIconProps: {
iconName: 'HorizontalGalleryRightButton',
styles: menuSubIconStyleSet
}
});
realTimeTextContextualMenuItems.push({
key: 'StartRealTimeTextKey',
id: 'common-call-composite-rtt-start-button',
text: localeStrings.strings.call.startRealTimeTextLabel,
ariaLabel: rttDisabled
? localeStrings.strings.call.disabledStartRealTimeTextLabel
: localeStrings.strings.call.startRealTimeTextLabel,
onClick: props.onStartRealTimeTextClick,
iconProps: {
iconName: 'RealTimeTextIcon',
styles: { root: { lineHeight: 0 } }
},
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
disabled: rttDisabled
});
}
const dtmfDialerScreenOption = {
key: 'dtmfDialerScreenKey',
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
text: !dtmfDialerChecked
? localeStrings.strings.call.dtmfDialerMoreButtonLabelOn
: localeStrings.strings.call.dtmfDialerMoreButtonLabelOff,
onClick: () => {
var _a;
(_a = props.onSetDialpadPage) === null || _a === void 0 ? void 0 : _a.call(props);
setDtmfDialerChecked(!dtmfDialerChecked);
},
iconProps: {
iconName: 'DtmfDialpadButton',
styles: { root: { lineHeight: 0 } }
}
};
/**
* Only render the dtmf dialer if the dialpad for PSTN calls is not present
*/
if (props.onSetDialpadPage && allowDtmfDialer) {
if (props.callControls === true || ((_d = props.callControls) === null || _d === void 0 ? void 0 : _d.dtmfDialerButton) !== false) {
moreButtonContextualMenuItems.push(dtmfDialerScreenOption);
}
}
const joinByPhoneOption = {
key: 'phoneCallKey',
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
text: localeStrings.strings.call.phoneCallMoreButtonLabel,
onClick: () => {
var _a;
(_a = props.onMeetingPhoneInfoClick) === null || _a === void 0 ? void 0 : _a.call(props);
},
iconProps: {
iconName: 'PhoneNumberButton',
styles: { root: { lineHeight: 0 } }
}
};
/**
* Only render the phone call button if meeting conordinates are present
*/
if (props.teamsMeetingPhoneCallEnable && isTeamsMeeting && teamsMeetingCoordinates) {
moreButtonContextualMenuItems.push(joinByPhoneOption);
}
if (props.onUserSetOverflowGalleryPositionChange) {
const galleryOptions = {
key: 'overflowGalleryPositionKey',
iconProps: {
iconName: 'GalleryOptions',
styles: { root: { lineHeight: 0 } }
},
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
submenuIconProps: {
styles: menuSubIconStyleSet
},
text: localeStrings.strings.call.moreButtonGalleryControlLabel,
disabled: props.disableButtonsForHoldScreen,
subMenuProps: {
items: [
{
key: 'dynamicSelectionKey',
text: localeStrings.strings.call.moreButtonGalleryFloatingLocalLayoutLabel,
canCheck: true,
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
isChecked: props.userSetGalleryLayout === 'floatingLocalVideo',
onClick: () => {
var _a;
(_a = props.onUserSetGalleryLayout) === null || _a === void 0 ? void 0 : _a.call(props, 'floatingLocalVideo');
setFocusedContentOn(false);
},
iconProps: {
iconName: 'FloatingLocalVideoGalleryLayout',
styles: { root: { lineHeight: 0 } }
}
},
{
key: 'speakerSelectionKey',
text: localeStrings.strings.call.moreButtonGallerySpeakerLayoutLabel,
canCheck: true,
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
isChecked: props.userSetGalleryLayout === 'speaker',
onClick: () => {
var _a;
(_a = props.onUserSetGalleryLayout) === null || _a === void 0 ? void 0 : _a.call(props, 'speaker');
setFocusedContentOn(false);
},
iconProps: {
iconName: 'SpeakerGalleryLayout',
styles: { root: { lineHeight: 0 } }
}
},
{
key: 'focusedContentSelectionKey',
text: localeStrings.strings.call.moreButtonGalleryFocusedContentLayoutLabel,
canCheck: true,
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
isChecked: focusedContentOn,
onClick: () => {
var _a, _b, _c;
if (focusedContentOn === false) {
setPreviousLayout((_a = props.userSetGalleryLayout) !== null && _a !== void 0 ? _a : 'floatingLocalVideo');
(_b = props.onUserSetGalleryLayout) === null || _b === void 0 ? void 0 : _b.call(props, 'focusedContent');
setFocusedContentOn(true);
}
else {
(_c = props.onUserSetGalleryLayout) === null || _c === void 0 ? void 0 : _c.call(props, previousLayout);
setFocusedContentOn(false);
}
},
iconProps: {
iconName: 'FocusedContentGalleryLayout',
styles: { root: { lineHeight: 0 } }
}
}
],
calloutProps: {
preventDismissOnEvent: _preventDismissOnEvent
}
}
};
/* @conditional-compile-remove(gallery-layout-composite) */
const galleryOption = {
key: 'defaultSelectionKey',
text: localeStrings.strings.call.moreButtonGalleryDefaultLayoutLabel,
canCheck: true,
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
isChecked: props.userSetGalleryLayout === 'default',
onClick: () => {
var _a;
(_a = props.onUserSetGalleryLayout) === null || _a === void 0 ? void 0 : _a.call(props, 'default');
setFocusedContentOn(false);
},
iconProps: {
iconName: 'DefaultGalleryLayout',
styles: { root: { lineHeight: 0 } }
}
};
/* @conditional-compile-remove(large-gallery) */
const largeGalleryOption = {
key: 'largeGallerySelectionKey',
text: localeStrings.strings.call.moreButtonLargeGalleryDefaultLayoutLabel,
canCheck: true,
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
isChecked: props.userSetGalleryLayout === 'largeGallery',
onClick: () => {
var _a;
(_a = props.onUserSetGalleryLayout) === null || _a === void 0 ? void 0 : _a.call(props, 'largeGallery');
setFocusedContentOn(false);
},
iconProps: {
iconName: 'LargeGalleryLayout',
styles: { root: { lineHeight: 0 } }
}
};
const togetherModeOption = {
key: 'togetherModeSelectionKey',
text: localeStrings.strings.call.moreButtonTogetherModeLayoutLabel,
canCheck: true,
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
isChecked: props.userSetGalleryLayout === 'togetherMode',
onClick: () => {
var _a;
(_a = props.onUserSetGalleryLayout) === null || _a === void 0 ? void 0 : _a.call(props, 'togetherMode');
setFocusedContentOn(false);
},
disabled: !(((participantId === null || participantId === void 0 ? void 0 : participantId.kind) === 'microsoftTeamsUser' && ((_e = participantCapability === null || participantCapability === void 0 ? void 0 : participantCapability.startTogetherMode) === null || _e === void 0 ? void 0 : _e.isPresent)) ||
isTogetherModeActive),
iconProps: {
iconName: 'TogetherModeLayout',
styles: { root: { lineHeight: 0 } }
}
};
/* @conditional-compile-remove(overflow-top-composite) */
const overflowGalleryOption = {
key: 'topKey',
text: localeStrings.strings.call.moreButtonGalleryPositionToggleLabel,
canCheck: true,
topDivider: true,
itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
},
iconProps: {
iconName: 'OverflowGalleryTop',
styles: { root: { lineHeight: 0 } }
},
isChecked: galleryPositionTop,
onClick: () => {
var _a, _b;
if (galleryPositionTop === false) {
(_a = props.onUserSetOverflowGalleryPositionChange) === null || _a === void 0 ? void 0 : _a.call(props, 'horizontalTop');
setGalleryPositionTop(true);
}
else {
(_b = props.onUserSetOverflowGalleryPositionChange) === null || _b === void 0 ? void 0 : _b.call(props, 'Responsive');
setGalleryPositionTop(false);
}
}
};
/* @conditional-compile-remove(large-gallery) */
(_g = (_f = galleryOptions.subMenuProps) === null || _f === void 0 ? void 0 : _f.items) === null || _g === void 0 ? void 0 : _g.push(largeGalleryOption);
/* @conditional-compile-remove(gallery-layout-composite) */
(_j = (_h = galleryOptions.subMenuProps) === null || _h === void 0 ? void 0 : _h.items) === null || _j === void 0 ? void 0 : _j.push(galleryOption);
/* @conditional-compile-remove(overflow-top-composite) */
(_l = (_k = galleryOptions.subMenuProps) === null || _k === void 0 ? void 0 : _k.items) === null || _l === void 0 ? void 0 : _l.push(overflowGalleryOption);
if (isTeamsCall || isTeamsMeeting) {
(_o = (_m = galleryOptions.subMenuProps) === null || _m === void 0 ? void 0 : _m.items) === null || _o === void 0 ? void 0 : _o.push(togetherModeOption);
}
if (props.callControls === true || ((_p = props.callControls) === null || _p === void 0 ? void 0 : _p.galleryControlsButton) !== false) {
moreButtonContextualMenuItems.push(galleryOptions);
}
}
const customDrawerButtons = useMemo(() => generateCustomCallDesktopOverflowButtons(onFetchCustomButtonPropsTrampoline(typeof props.callControls === 'object' ? props.callControls : undefined), typeof props.callControls === 'object' ? props.callControls.displayType : undefined), [props.callControls]);
customDrawerButtons['primary'].slice(CUSTOM_BUTTON_OPTIONS.MAX_PRIMARY_DESKTOP_CUSTOM_BUTTONS).forEach((element) => {
moreButtonContextualMenuItems.push(Object.assign({ itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
} }, element));
});
customDrawerButtons['secondary']
.slice(CUSTOM_BUTTON_OPTIONS.MAX_SECONDARY_DESKTOP_CUSTOM_BUTTONS)
.forEach((element) => {
moreButtonContextualMenuItems.push(Object.assign({ itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
} }, element));
});
customDrawerButtons['overflow'].forEach((element) => {
moreButtonContextualMenuItems.push(Object.assign({ itemProps: {
styles: buttonFlyoutIncreasedSizeStyles
} }, element));
});
return (React.createElement(MoreButton, Object.assign({}, props, { "data-ui-id": "common-call-composite-more-button", strings: moreButtonStrings, menuIconProps: { hidden: true }, menuProps: {
shouldFocusOnContainer: false,
items: moreButtonContextualMenuItems,
calloutProps: {
preventDismissOnEvent: _preventDismissOnEvent
}
} })));
};
//# sourceMappingURL=DesktopMoreButton.js.map