@azure/communication-react 1.12.1-alpha-202401240013 → 1.12.1-alpha-202401250013
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/communication-react.d.ts +10 -5
- package/dist/dist-cjs/communication-react/index.js +330 -254
- package/dist/dist-cjs/communication-react/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.d.ts +1 -1
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsEditBox.js +2 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsEditBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.d.ts +9 -5
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js +5 -9
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/FileUploadCards.d.ts +32 -1
- package/dist/dist-esm/react-components/src/components/FileUploadCards.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/InputBoxButton.d.ts +19 -0
- package/dist/dist-esm/react-components/src/components/InputBoxButton.js +32 -0
- package/dist/dist-esm/react-components/src/components/InputBoxButton.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.d.ts +0 -17
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js +3 -29
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.d.ts +19 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.js +13 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.d.ts +34 -1
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js +45 -3
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.d.ts +15 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.js +18 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.d.ts +18 -0
- package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.js +40 -0
- package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/SendBox.d.ts +1 -32
- package/dist/dist-esm/react-components/src/components/SendBox.js +33 -30
- package/dist/dist-esm/react-components/src/components/SendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.d.ts +0 -17
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +1 -28
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/index.d.ts +2 -1
- package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.d.ts +13 -0
- package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.js +30 -0
- package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.d.ts +0 -16
- package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.js +0 -32
- package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.d.ts +5 -0
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js +16 -0
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.d.ts +8 -2
- package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.js +13 -7
- package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.d.ts +10 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +18 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js +30 -3
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js +11 -4
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.d.ts +5 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js +4 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.d.ts +7 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js +13 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js +11 -16
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +5 -1
@@ -14,6 +14,9 @@ var textareaCaretTs = require('textarea-caret-ts');
|
|
14
14
|
var reactComponents = require('@fluentui/react-components');
|
15
15
|
var useDebounce = require('use-debounce');
|
16
16
|
var reactFileTypeIcons = require('@fluentui/react-file-type-icons');
|
17
|
+
require('roosterjs-editor-plugins');
|
18
|
+
require('roosterjs-editor-core');
|
19
|
+
require('roosterjs-react');
|
17
20
|
var uuid = require('uuid');
|
18
21
|
var reactChat = require('@fluentui-contrib/react-chat');
|
19
22
|
var react$1 = require('@griffel/react');
|
@@ -170,7 +173,7 @@ function getDefaultExportFromCjs (x) {
|
|
170
173
|
// Copyright (c) Microsoft Corporation.
|
171
174
|
// Licensed under the MIT License.
|
172
175
|
// GENERATED FILE. DO NOT EDIT MANUALLY.
|
173
|
-
var telemetryVersion = '1.12.1-alpha-
|
176
|
+
var telemetryVersion = '1.12.1-alpha-202401250013';
|
174
177
|
|
175
178
|
|
176
179
|
var telemetryVersion$1 = /*@__PURE__*/getDefaultExportFromCjs(telemetryVersion);
|
@@ -6029,11 +6032,17 @@ const sendButtonStyle = react.mergeStyles({
|
|
6029
6032
|
/**
|
6030
6033
|
* @private
|
6031
6034
|
*/
|
6032
|
-
const sendIconStyle =
|
6033
|
-
|
6034
|
-
|
6035
|
-
|
6036
|
-
|
6035
|
+
const sendIconStyle = (props) => {
|
6036
|
+
const { theme, hasText,
|
6037
|
+
/* @conditional-compile-remove(file-sharing) */ hasFile, hasErrorMessage, customSendIconStyle } = props;
|
6038
|
+
const hasNoContent = !hasText && /* @conditional-compile-remove(file-sharing) */ !hasFile;
|
6039
|
+
return react.mergeStyles({
|
6040
|
+
width: '1.25rem',
|
6041
|
+
height: '1.25rem',
|
6042
|
+
margin: 'auto',
|
6043
|
+
color: hasErrorMessage || hasNoContent ? theme.palette.neutralTertiary : theme.palette.themePrimary
|
6044
|
+
}, customSendIconStyle);
|
6045
|
+
};
|
6037
6046
|
/**
|
6038
6047
|
* @private
|
6039
6048
|
*/
|
@@ -6066,7 +6075,7 @@ const borderAndBoxShadowStyle = (props) => {
|
|
6066
6075
|
const borderColorActive = hasErrorMessage ? theme.semanticColors.errorText : theme.palette.themePrimary;
|
6067
6076
|
const borderThickness = disabled ? 0 : defaultSendBoxInactiveBorderThicknessREM;
|
6068
6077
|
const borderActiveThickness = disabled ? 0 : defaultSendBoxActiveBorderThicknessREM;
|
6069
|
-
return {
|
6078
|
+
return react.mergeStyles({
|
6070
6079
|
borderRadius: theme.effects.roundedCorner4,
|
6071
6080
|
border: `${borderThickness}rem solid ${borderColor}`,
|
6072
6081
|
// The border thickness of the sendbox wrapper changes on hover, to prevent the border thickness change causing the
|
@@ -6076,7 +6085,7 @@ const borderAndBoxShadowStyle = (props) => {
|
|
6076
6085
|
border: `${borderActiveThickness}rem solid ${borderColorActive}`,
|
6077
6086
|
margin: `${defaultSendBoxActiveBorderThicknessREM - borderActiveThickness}rem`
|
6078
6087
|
}
|
6079
|
-
};
|
6088
|
+
});
|
6080
6089
|
};
|
6081
6090
|
|
6082
6091
|
// Copyright (c) Microsoft Corporation.
|
@@ -6544,57 +6553,6 @@ const textFieldStyle = {
|
|
6544
6553
|
borderRadius: '0.25rem'
|
6545
6554
|
}
|
6546
6555
|
};
|
6547
|
-
/**
|
6548
|
-
* @private
|
6549
|
-
*/
|
6550
|
-
const inputButtonStyle = react.mergeStyles({
|
6551
|
-
color: 'grey',
|
6552
|
-
margin: 'auto',
|
6553
|
-
width: '1.0625rem',
|
6554
|
-
height: '1.0625rem',
|
6555
|
-
backgroundColor: 'transparent',
|
6556
|
-
'&:hover': {
|
6557
|
-
backgroundColor: 'transparent'
|
6558
|
-
}
|
6559
|
-
});
|
6560
|
-
/**
|
6561
|
-
* @private
|
6562
|
-
*/
|
6563
|
-
const inputButtonTooltipStyle = react.mergeStyles({
|
6564
|
-
// The toolTip host container show be a flex box, so that alignItems: 'center' works for inside buttons
|
6565
|
-
display: 'flex'
|
6566
|
-
});
|
6567
|
-
/**
|
6568
|
-
* @private
|
6569
|
-
*/
|
6570
|
-
const iconWrapperStyle$1 = react.mergeStyles({
|
6571
|
-
pointerEvents: 'none'
|
6572
|
-
});
|
6573
|
-
|
6574
|
-
// Copyright (c) Microsoft Corporation.
|
6575
|
-
// Licensed under the MIT License.
|
6576
|
-
/**
|
6577
|
-
* @private
|
6578
|
-
*/
|
6579
|
-
const isDarkThemed = (theme) => {
|
6580
|
-
const themeBlackBrightness = getPerceptualBrightnessOfHexColor(theme.palette.black);
|
6581
|
-
const themeWhiteBrightness = getPerceptualBrightnessOfHexColor(theme.palette.white);
|
6582
|
-
if (Number.isNaN(themeBlackBrightness) || Number.isNaN(themeWhiteBrightness)) {
|
6583
|
-
return false;
|
6584
|
-
}
|
6585
|
-
return themeBlackBrightness > themeWhiteBrightness;
|
6586
|
-
};
|
6587
|
-
const getPerceptualBrightnessOfHexColor = (hexColor) => {
|
6588
|
-
// return NaN if hexColor is not a hex code
|
6589
|
-
if (!/^#[0-9A-Fa-f]{6}$/i.test(hexColor)) {
|
6590
|
-
return NaN;
|
6591
|
-
}
|
6592
|
-
const r = parseInt(hexColor.substring(1, 3), 16);
|
6593
|
-
const g = parseInt(hexColor.substring(3, 5), 16);
|
6594
|
-
const b = parseInt(hexColor.substring(5, 7), 16);
|
6595
|
-
// arithmetic mean μ of the red, green, and blue color coordinates. Source: https://en.wikipedia.org/wiki/Brightness
|
6596
|
-
return (r + g + b) / 3;
|
6597
|
-
};
|
6598
6556
|
|
6599
6557
|
// Copyright (c) Microsoft Corporation.
|
6600
6558
|
// Licensed under the MIT License.
|
@@ -8317,14 +8275,71 @@ const InputBoxComponent = (props) => {
|
|
8317
8275
|
return (React.createElement(react.Stack, { className: mergedRootStyle },
|
8318
8276
|
React.createElement("div", { className: mergedTextContainerStyle }, renderTextField())));
|
8319
8277
|
};
|
8278
|
+
|
8279
|
+
// Copyright (c) Microsoft Corporation.
|
8280
|
+
// Licensed under the MIT License.
|
8281
|
+
/**
|
8282
|
+
* @private
|
8283
|
+
*/
|
8284
|
+
const isDarkThemed = (theme) => {
|
8285
|
+
const themeBlackBrightness = getPerceptualBrightnessOfHexColor(theme.palette.black);
|
8286
|
+
const themeWhiteBrightness = getPerceptualBrightnessOfHexColor(theme.palette.white);
|
8287
|
+
if (Number.isNaN(themeBlackBrightness) || Number.isNaN(themeWhiteBrightness)) {
|
8288
|
+
return false;
|
8289
|
+
}
|
8290
|
+
return themeBlackBrightness > themeWhiteBrightness;
|
8291
|
+
};
|
8292
|
+
const getPerceptualBrightnessOfHexColor = (hexColor) => {
|
8293
|
+
// return NaN if hexColor is not a hex code
|
8294
|
+
if (!/^#[0-9A-Fa-f]{6}$/i.test(hexColor)) {
|
8295
|
+
return NaN;
|
8296
|
+
}
|
8297
|
+
const r = parseInt(hexColor.substring(1, 3), 16);
|
8298
|
+
const g = parseInt(hexColor.substring(3, 5), 16);
|
8299
|
+
const b = parseInt(hexColor.substring(5, 7), 16);
|
8300
|
+
// arithmetic mean μ of the red, green, and blue color coordinates. Source: https://en.wikipedia.org/wiki/Brightness
|
8301
|
+
return (r + g + b) / 3;
|
8302
|
+
};
|
8303
|
+
|
8304
|
+
// Copyright (c) Microsoft Corporation.
|
8305
|
+
// Licensed under the MIT License.
|
8306
|
+
/**
|
8307
|
+
* @private
|
8308
|
+
*/
|
8309
|
+
const inputBoxButtonStyle = react.mergeStyles({
|
8310
|
+
color: 'grey',
|
8311
|
+
margin: 'auto',
|
8312
|
+
width: '1.0625rem',
|
8313
|
+
height: '1.0625rem',
|
8314
|
+
backgroundColor: 'transparent',
|
8315
|
+
'&:hover': {
|
8316
|
+
backgroundColor: 'transparent'
|
8317
|
+
}
|
8318
|
+
});
|
8319
|
+
/**
|
8320
|
+
* @private
|
8321
|
+
*/
|
8322
|
+
const inputBoxButtonTooltipStyle = react.mergeStyles({
|
8323
|
+
// The toolTip host container show be a flex box, so that alignItems: 'center' works for inside buttons
|
8324
|
+
display: 'flex'
|
8325
|
+
});
|
8326
|
+
/**
|
8327
|
+
* @private
|
8328
|
+
*/
|
8329
|
+
const iconWrapperStyle$1 = react.mergeStyles({
|
8330
|
+
pointerEvents: 'none'
|
8331
|
+
});
|
8332
|
+
|
8333
|
+
// Copyright (c) Microsoft Corporation.
|
8334
|
+
// Licensed under the MIT License.
|
8320
8335
|
/**
|
8321
8336
|
* @private
|
8322
8337
|
*/
|
8323
8338
|
const InputBoxButton = (props) => {
|
8324
8339
|
const { onRenderIcon, onClick, ariaLabel, className, id, tooltipContent } = props;
|
8325
8340
|
const [isHover, setIsHover] = React.useState(false);
|
8326
|
-
const mergedButtonStyle = react.mergeStyles(
|
8327
|
-
const theme = useTheme();
|
8341
|
+
const mergedButtonStyle = react.mergeStyles(inputBoxButtonStyle, className);
|
8342
|
+
const theme = react.useTheme();
|
8328
8343
|
const calloutStyle = { root: { padding: 0 }, calloutMain: { padding: '0.5rem' } };
|
8329
8344
|
// Place callout with no gap between it and the button.
|
8330
8345
|
const calloutProps = {
|
@@ -8332,7 +8347,7 @@ const InputBoxButton = (props) => {
|
|
8332
8347
|
styles: calloutStyle,
|
8333
8348
|
backgroundColor: isDarkThemed(theme) ? theme.palette.neutralLighter : ''
|
8334
8349
|
};
|
8335
|
-
return (React.createElement(react.TooltipHost, { hostClassName:
|
8350
|
+
return (React.createElement(react.TooltipHost, { hostClassName: inputBoxButtonTooltipStyle, content: tooltipContent, calloutProps: Object.assign({}, calloutProps) },
|
8336
8351
|
React.createElement(react.IconButton, { className: mergedButtonStyle, ariaLabel: ariaLabel, onClick: onClick, id: id, onMouseEnter: () => {
|
8337
8352
|
setIsHover(true);
|
8338
8353
|
}, onMouseLeave: () => {
|
@@ -8568,8 +8583,26 @@ const _FileUploadCards = (props) => {
|
|
8568
8583
|
|
8569
8584
|
// Copyright (c) Microsoft Corporation.
|
8570
8585
|
// Licensed under the MIT License.
|
8571
|
-
|
8586
|
+
/* @conditional-compile-remove(file-sharing) */
|
8587
|
+
/**
|
8588
|
+
* @private
|
8589
|
+
*/
|
8590
|
+
const hasIncompleteFileUploads = (activeFileUploads) => {
|
8591
|
+
return !!((activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.length) &&
|
8592
|
+
!activeFileUploads.filter((fileUpload) => !fileUpload.error).every((fileUpload) => fileUpload.uploadComplete));
|
8593
|
+
};
|
8594
|
+
/* @conditional-compile-remove(file-sharing) */
|
8595
|
+
/**
|
8596
|
+
* @private
|
8597
|
+
*/
|
8598
|
+
const hasCompletedFileUploads = (activeFileUploads) => {
|
8599
|
+
return !!(activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.find((file) => !file.error));
|
8600
|
+
};
|
8601
|
+
|
8602
|
+
// Copyright (c) Microsoft Corporation.
|
8603
|
+
// Licensed under the MIT License.
|
8572
8604
|
const MAXIMUM_LENGTH_OF_MESSAGE$1 = 8000;
|
8605
|
+
const EMPTY_MESSAGE_REGEX = /^\s*$/;
|
8573
8606
|
/**
|
8574
8607
|
* Component for typing and sending messages.
|
8575
8608
|
*
|
@@ -8581,15 +8614,17 @@ const MAXIMUM_LENGTH_OF_MESSAGE$1 = 8000;
|
|
8581
8614
|
const SendBox = (props) => {
|
8582
8615
|
const { disabled, systemMessage, supportNewline, onSendMessage, onTyping, onRenderIcon, onRenderSystemMessage, styles, autoFocus,
|
8583
8616
|
/* @conditional-compile-remove(mention) */
|
8584
|
-
mentionLookupOptions
|
8617
|
+
mentionLookupOptions,
|
8618
|
+
/* @conditional-compile-remove(file-sharing) */
|
8619
|
+
activeFileUploads } = props;
|
8585
8620
|
const theme = useTheme();
|
8586
8621
|
const localeStrings = useLocale$1().strings.sendBox;
|
8587
8622
|
const strings = Object.assign(Object.assign({}, localeStrings), props.strings);
|
8588
8623
|
const ids = useIdentifiers();
|
8589
|
-
const activeFileUploads = activeFileUploadsTrampoline(props);
|
8590
8624
|
const [textValue, setTextValue] = React.useState('');
|
8591
8625
|
const [textValueOverflow, setTextValueOverflow] = React.useState(false);
|
8592
8626
|
const sendTextFieldRef = React.useRef(null);
|
8627
|
+
/* @conditional-compile-remove(file-sharing) */
|
8593
8628
|
const [fileUploadsPendingError, setFileUploadsPendingError] = React.useState(undefined);
|
8594
8629
|
const sendMessageOnClick = () => {
|
8595
8630
|
var _a;
|
@@ -8598,16 +8633,18 @@ const SendBox = (props) => {
|
|
8598
8633
|
return;
|
8599
8634
|
}
|
8600
8635
|
// Don't send message until all files have been uploaded successfully
|
8636
|
+
/* @conditional-compile-remove(file-sharing) */
|
8601
8637
|
setFileUploadsPendingError(undefined);
|
8602
|
-
|
8603
|
-
|
8638
|
+
/* @conditional-compile-remove(file-sharing) */
|
8639
|
+
if (hasIncompleteFileUploads(activeFileUploads)) {
|
8604
8640
|
setFileUploadsPendingError({ message: strings.fileUploadsPendingError, timestamp: Date.now() });
|
8605
8641
|
return;
|
8606
8642
|
}
|
8607
8643
|
const message = textValue;
|
8608
8644
|
// we don't want to send empty messages including spaces, newlines, tabs
|
8609
8645
|
// Message can be empty if there is a valid file upload
|
8610
|
-
if (!EMPTY_MESSAGE_REGEX.test(message) ||
|
8646
|
+
if (!EMPTY_MESSAGE_REGEX.test(message) ||
|
8647
|
+
/* @conditional-compile-remove(file-sharing) */ hasCompletedFileUploads(activeFileUploads)) {
|
8611
8648
|
onSendMessage && onSendMessage(sanitizeText(message));
|
8612
8649
|
setTextValue('');
|
8613
8650
|
}
|
@@ -8629,18 +8666,28 @@ const SendBox = (props) => {
|
|
8629
8666
|
const errorMessage = systemMessage !== null && systemMessage !== void 0 ? systemMessage : textTooLongMessage;
|
8630
8667
|
const mergedSendButtonStyle = React.useMemo(() => react.mergeStyles(sendButtonStyle, styles === null || styles === void 0 ? void 0 : styles.sendMessageIconContainer), [styles === null || styles === void 0 ? void 0 : styles.sendMessageIconContainer]);
|
8631
8668
|
const mergedStyles = React.useMemo(() => react.concatStyleSets(styles), [styles]);
|
8632
|
-
const
|
8633
|
-
|
8634
|
-
|
8635
|
-
|
8636
|
-
|
8669
|
+
const mergedSendIconStyle = React.useMemo(() => sendIconStyle({
|
8670
|
+
theme,
|
8671
|
+
hasText: !!textValue,
|
8672
|
+
/* @conditional-compile-remove(file-sharing) */ hasFile: hasCompletedFileUploads(activeFileUploads),
|
8673
|
+
hasErrorMessage: !!errorMessage,
|
8674
|
+
customSendIconStyle: styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon
|
8675
|
+
}), [
|
8676
|
+
theme,
|
8677
|
+
textValue,
|
8678
|
+
/* @conditional-compile-remove(file-sharing) */ activeFileUploads,
|
8679
|
+
errorMessage,
|
8680
|
+
styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon
|
8681
|
+
]);
|
8637
8682
|
const onRenderSendIcon = React.useCallback((isHover) => onRenderIcon ? (onRenderIcon(isHover)) : (React.createElement(react.Icon, { iconName: isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend', className: mergedSendIconStyle })), [mergedSendIconStyle, onRenderIcon, textValue]);
|
8638
8683
|
// Ensure that errors are cleared when there are no files in sendBox
|
8684
|
+
/* @conditional-compile-remove(file-sharing) */
|
8639
8685
|
React.useEffect(() => {
|
8640
8686
|
if (!(activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.filter((upload) => !upload.error).length)) {
|
8641
8687
|
setFileUploadsPendingError(undefined);
|
8642
8688
|
}
|
8643
8689
|
}, [activeFileUploads]);
|
8690
|
+
/* @conditional-compile-remove(file-sharing) */
|
8644
8691
|
const sendBoxErrorsProps = React.useMemo(() => {
|
8645
8692
|
var _a;
|
8646
8693
|
return {
|
@@ -8662,13 +8709,13 @@ const SendBox = (props) => {
|
|
8662
8709
|
} })));
|
8663
8710
|
}, [activeFileUploads, props, localeStrings]);
|
8664
8711
|
return (React.createElement(react.Stack, { className: react.mergeStyles(sendBoxWrapperStyles, { overflow: 'visible' } // This is needed for the mention popup to be visible
|
8665
|
-
) },
|
8712
|
+
) }, /* @conditional-compile-remove(file-sharing) */
|
8666
8713
|
React.createElement(SendBoxErrors, Object.assign({}, sendBoxErrorsProps)),
|
8667
|
-
React.createElement(react.Stack, { className:
|
8714
|
+
React.createElement(react.Stack, { className: borderAndBoxShadowStyle({
|
8668
8715
|
theme,
|
8669
8716
|
hasErrorMessage: !!errorMessage,
|
8670
8717
|
disabled: !!disabled
|
8671
|
-
})
|
8718
|
+
}) },
|
8672
8719
|
React.createElement(InputBoxComponent, { autoFocus: autoFocus, "data-ui-id": ids.sendboxTextField, disabled: disabled, errorMessage: onRenderSystemMessage ? onRenderSystemMessage(errorMessage) : errorMessage, textFieldRef: sendTextFieldRef, id: "sendbox", placeholderText: strings.placeholderText, textValue: textValue, onChange: (_, newValue) => setText(newValue), onKeyDown: (ev) => {
|
8673
8720
|
const keyWasSendingMessage = ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline);
|
8674
8721
|
if (!keyWasSendingMessage) {
|
@@ -8691,15 +8738,6 @@ const SendBox = (props) => {
|
|
8691
8738
|
/**
|
8692
8739
|
* @private
|
8693
8740
|
*/
|
8694
|
-
const hasIncompleteFileUploads = (props) => {
|
8695
|
-
const activeFileUploads = activeFileUploadsTrampoline(props);
|
8696
|
-
return !!((activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.length) &&
|
8697
|
-
!activeFileUploads.filter((fileUpload) => !fileUpload.error).every((fileUpload) => fileUpload.uploadComplete));
|
8698
|
-
};
|
8699
|
-
const hasFile = (props) => {
|
8700
|
-
const activeFileUploads = activeFileUploadsTrampoline(props);
|
8701
|
-
return !!(activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.find((file) => !file.error));
|
8702
|
-
};
|
8703
8741
|
const sanitizeText = (message) => {
|
8704
8742
|
if (EMPTY_MESSAGE_REGEX.test(message)) {
|
8705
8743
|
return '';
|
@@ -8708,10 +8746,6 @@ const sanitizeText = (message) => {
|
|
8708
8746
|
return message;
|
8709
8747
|
}
|
8710
8748
|
};
|
8711
|
-
const activeFileUploadsTrampoline = (props) => {
|
8712
|
-
/* @conditional-compile-remove(file-sharing) */
|
8713
|
-
return props.activeFileUploads;
|
8714
|
-
};
|
8715
8749
|
|
8716
8750
|
// Copyright (c) Microsoft Corporation.
|
8717
8751
|
// Licensed under the MIT License.
|
@@ -8959,6 +8993,21 @@ const ImageGallery = (props) => {
|
|
8959
8993
|
renderBodyWithLightDismiss()));
|
8960
8994
|
};
|
8961
8995
|
|
8996
|
+
// Copyright (c) Microsoft Corporation.
|
8997
|
+
// Licensed under the MIT License.
|
8998
|
+
/**
|
8999
|
+
* @private
|
9000
|
+
*/
|
9001
|
+
react.mergeStyles({
|
9002
|
+
border: 'none',
|
9003
|
+
overflow: 'auto',
|
9004
|
+
padding: '10px',
|
9005
|
+
outline: 'none',
|
9006
|
+
bottom: '0',
|
9007
|
+
minHeight: '2.25rem',
|
9008
|
+
maxHeight: '8.25rem'
|
9009
|
+
});
|
9010
|
+
|
8962
9011
|
// Copyright (c) Microsoft Corporation.
|
8963
9012
|
// Licensed under the MIT License.
|
8964
9013
|
/** @private */
|
@@ -18403,7 +18452,7 @@ const DialpadButton = (props) => {
|
|
18403
18452
|
const DialpadContainer = (props) => {
|
18404
18453
|
var _a, _b;
|
18405
18454
|
const theme = react.useTheme();
|
18406
|
-
const { onSendDtmfTone, onClickDialpadButton, textFieldValue, onChange, showDeleteButton = true, isMobile = false, disableDtmfPlayback,
|
18455
|
+
const { onSendDtmfTone, onClickDialpadButton, textFieldValue, onChange, showDeleteButton = true, isMobile = false, disableDtmfPlayback, dialpadMode = 'dialer' } = props;
|
18407
18456
|
const dtmfToneAudioContext = React.useRef(new AudioContext());
|
18408
18457
|
const [plainTextValue, setPlainTextValue] = React.useState(textFieldValue !== null && textFieldValue !== void 0 ? textFieldValue : '');
|
18409
18458
|
const plainTextValuePreviousRenderValue = React.useRef(plainTextValue);
|
@@ -18450,20 +18499,16 @@ const DialpadContainer = (props) => {
|
|
18450
18499
|
setText(modifiedInput);
|
18451
18500
|
};
|
18452
18501
|
return (React.createElement(react.Stack, { className: react.mergeStyles(containerStyles$3(theme), (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root), "data-test-id": "dialpadContainer", "data-ui-id": "dialpadContainer", horizontalAlign: 'center' },
|
18453
|
-
React.createElement(react.TextField, { styles: react.concatStyleSets(textFieldStyles(theme), (_b = props.styles) === null || _b === void 0 ? void 0 : _b.textField), value: textFieldValue ? textFieldValue :
|
18502
|
+
dialpadMode === 'dialer' && (React.createElement(react.TextField, { styles: react.concatStyleSets(textFieldStyles(theme), (_b = props.styles) === null || _b === void 0 ? void 0 : _b.textField), value: textFieldValue ? textFieldValue : formatPhoneNumber(plainTextValue),
|
18454
18503
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
18455
18504
|
onChange: (e) => {
|
18456
|
-
|
18457
|
-
setText(e.target.value);
|
18458
|
-
}
|
18505
|
+
setText(e.target.value);
|
18459
18506
|
}, onClick: (e) => {
|
18460
|
-
|
18461
|
-
e.preventDefault();
|
18462
|
-
}
|
18507
|
+
e.preventDefault();
|
18463
18508
|
}, placeholder: props.strings.placeholderText, "data-test-id": "dialpad-input", onRenderSuffix: () => {
|
18464
18509
|
var _a;
|
18465
18510
|
return (React.createElement(React.Fragment, null, showDeleteButton && plainTextValue.length !== 0 && (React.createElement(react.IconButton, { ariaLabel: props.strings.deleteButtonAriaLabel, onClick: deleteNumbers, styles: react.concatStyleSets(iconButtonStyles(theme), (_a = props.styles) === null || _a === void 0 ? void 0 : _a.deleteIcon), iconProps: { iconName: 'DialpadBackspace' } }))));
|
18466
|
-
} }),
|
18511
|
+
} })),
|
18467
18512
|
React.createElement(react.FocusZone, null, dialPadButtonsDefault.map((rows, rowIndex) => {
|
18468
18513
|
return (React.createElement(react.Stack, { horizontal: true, key: `row_${rowIndex}`, horizontalAlign: "stretch", tokens: { childrenGap: '1rem' } }, rows.map((button, columnIndex) => (React.createElement(DialpadButton, { key: `button_${columnIndex}`,
|
18469
18514
|
/* row index = 0
|
@@ -25714,6 +25759,10 @@ const getLatestCapabilitiesChangedInfo = (state) => {
|
|
25714
25759
|
var _a, _b;
|
25715
25760
|
return (_b = (_a = state.call) === null || _a === void 0 ? void 0 : _a.capabilitiesFeature) === null || _b === void 0 ? void 0 : _b.latestCapabilitiesChangeInfo;
|
25716
25761
|
};
|
25762
|
+
/**
|
25763
|
+
* @private
|
25764
|
+
*/
|
25765
|
+
const getTargetCallees = (state) => state.targetCallees;
|
25717
25766
|
|
25718
25767
|
// Copyright (c) Microsoft Corporation.
|
25719
25768
|
// Licensed under the MIT License.
|
@@ -26472,6 +26521,151 @@ const useCallWithChatCompositeStrings = () => {
|
|
26472
26521
|
return locale.strings.callWithChat;
|
26473
26522
|
};
|
26474
26523
|
|
26524
|
+
// Copyright (c) Microsoft Corporation.
|
26525
|
+
// Licensed under the MIT License.
|
26526
|
+
/**
|
26527
|
+
* @private
|
26528
|
+
*/
|
26529
|
+
const mediaGallerySelector = reselect__namespace.createSelector([getLocalVideoStreams], (localVideoStreams) => {
|
26530
|
+
var _a, _b;
|
26531
|
+
return {
|
26532
|
+
isVideoStreamOn: !!((_b = (_a = localVideoStreams === null || localVideoStreams === void 0 ? void 0 : localVideoStreams.find((stream) => stream.mediaStreamType === 'Video')) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.target)
|
26533
|
+
};
|
26534
|
+
});
|
26535
|
+
/**
|
26536
|
+
* Custom selector for this hook to retrieve all the participants that are currently
|
26537
|
+
* connected to the call.
|
26538
|
+
*/
|
26539
|
+
const getRemoteParticipantsConnectedSelector = reselect__namespace.createSelector([getRemoteParticipants], (remoteParticipants) => {
|
26540
|
+
const participants = Object.values(remoteParticipants !== null && remoteParticipants !== void 0 ? remoteParticipants : {});
|
26541
|
+
return participants.filter((p) => p.state === 'Connected');
|
26542
|
+
});
|
26543
|
+
|
26544
|
+
// Copyright (c) Microsoft Corporation.
|
26545
|
+
// Licensed under the MIT License.
|
26546
|
+
/**
|
26547
|
+
* sets the announcement string whenever a Participant comes or goes from a call to be
|
26548
|
+
* used by the system narrator.
|
26549
|
+
*
|
26550
|
+
* @returns string to be used by the narrator and Announcer component
|
26551
|
+
*
|
26552
|
+
* @internal
|
26553
|
+
*/
|
26554
|
+
const useParticipantChangedAnnouncement = () => {
|
26555
|
+
const locale = useLocale().strings.call;
|
26556
|
+
const strings = React.useMemo(() => {
|
26557
|
+
return {
|
26558
|
+
participantJoinedNoticeString: locale.participantJoinedNoticeString,
|
26559
|
+
twoParticipantJoinedNoticeString: locale.twoParticipantJoinedNoticeString,
|
26560
|
+
threeParticipantJoinedNoticeString: locale.threeParticipantJoinedNoticeString,
|
26561
|
+
participantLeftNoticeString: locale.participantLeftNoticeString,
|
26562
|
+
twoParticipantLeftNoticeString: locale.twoParticipantLeftNoticeString,
|
26563
|
+
threeParticipantLeftNoticeString: locale.threeParticipantLeftNoticeString,
|
26564
|
+
unnamedParticipantString: locale.unnamedParticipantString,
|
26565
|
+
manyParticipantsJoined: locale.manyParticipantsJoined,
|
26566
|
+
manyParticipantsLeft: locale.manyParticipantsLeft,
|
26567
|
+
manyUnnamedParticipantsJoined: locale.manyUnnamedParticipantsJoined,
|
26568
|
+
manyUnnamedParticipantsLeft: locale.manyUnnamedParticipantsLeft
|
26569
|
+
};
|
26570
|
+
}, [locale]);
|
26571
|
+
const [announcerString, setAnnouncerString] = React.useState('');
|
26572
|
+
const currentParticipants = useSelector$1(getRemoteParticipantsConnectedSelector);
|
26573
|
+
/**
|
26574
|
+
* We want to use a useRef here since we want to not fire this hook based on the previous participants
|
26575
|
+
* this allows this value to be used in the hook without being in the dependency array.
|
26576
|
+
*
|
26577
|
+
* Note: By definition if this hook is used in another component it is not pure anymore.
|
26578
|
+
*/
|
26579
|
+
const previousParticipants = React.useRef(currentParticipants);
|
26580
|
+
const resetAnnoucement = (string) => {
|
26581
|
+
setAnnouncerString(string);
|
26582
|
+
};
|
26583
|
+
React.useMemo(() => {
|
26584
|
+
const currentIds = currentParticipants.map((p) => toFlatCommunicationIdentifier(p.identifier));
|
26585
|
+
const previousIds = previousParticipants.current.map((p) => toFlatCommunicationIdentifier(p.identifier));
|
26586
|
+
const whoJoined = currentParticipants.filter((p) => !previousIds.includes(toFlatCommunicationIdentifier(p.identifier)));
|
26587
|
+
const whoLeft = previousParticipants.current.filter((p) => !currentIds.includes(toFlatCommunicationIdentifier(p.identifier)));
|
26588
|
+
if (whoJoined.length > 0) {
|
26589
|
+
resetAnnoucement(createAnnouncementString('joined', whoJoined, strings));
|
26590
|
+
}
|
26591
|
+
if (whoLeft.length > 0) {
|
26592
|
+
resetAnnoucement(createAnnouncementString('left', whoLeft, strings));
|
26593
|
+
}
|
26594
|
+
// Update cached value at the end.
|
26595
|
+
previousParticipants.current = currentParticipants;
|
26596
|
+
}, [currentParticipants, strings]);
|
26597
|
+
return announcerString;
|
26598
|
+
};
|
26599
|
+
/**
|
26600
|
+
* Generates the announcement string for when a participant joins or leaves a call.
|
26601
|
+
*/
|
26602
|
+
const createAnnouncementString = (direction, participants, strings) => {
|
26603
|
+
var _a, _b, _c;
|
26604
|
+
/**
|
26605
|
+
* If there are no participants return empty string.
|
26606
|
+
*/
|
26607
|
+
if (participants.length === 0) {
|
26608
|
+
return '';
|
26609
|
+
}
|
26610
|
+
/**
|
26611
|
+
* Filter participants into two arrays to put all the unnamed participants at the back of the
|
26612
|
+
* names being announced.
|
26613
|
+
*/
|
26614
|
+
const unnamedParticipants = participants.filter((p) => !p.displayName);
|
26615
|
+
const namedParicipants = participants.filter((p) => p.displayName);
|
26616
|
+
const sortedParticipants = namedParicipants.concat(unnamedParticipants);
|
26617
|
+
/**
|
26618
|
+
* if there are only unnamed participants present in the array announce a special unnamed participants
|
26619
|
+
* only string.
|
26620
|
+
*/
|
26621
|
+
if (sortedParticipants.filter((p) => p.displayName).length === 0 && sortedParticipants.length > 1) {
|
26622
|
+
return _formatString(direction === 'joined' ? strings.manyUnnamedParticipantsJoined : strings.manyUnnamedParticipantsLeft, {
|
26623
|
+
numOfParticipants: (sortedParticipants.length - 1).toString()
|
26624
|
+
});
|
26625
|
+
}
|
26626
|
+
const participantNames = sortedParticipants.map((p) => { var _a; return (_a = p.displayName) !== null && _a !== void 0 ? _a : strings.unnamedParticipantString; });
|
26627
|
+
switch (sortedParticipants.length) {
|
26628
|
+
case 1:
|
26629
|
+
return _formatString(direction === 'joined' ? strings.participantJoinedNoticeString : strings.participantLeftNoticeString, { displayName: participantNames[0] });
|
26630
|
+
case 2:
|
26631
|
+
return _formatString(direction === 'joined' ? strings.twoParticipantJoinedNoticeString : strings.twoParticipantLeftNoticeString, {
|
26632
|
+
displayName1: participantNames[0],
|
26633
|
+
displayName2: participantNames[1]
|
26634
|
+
});
|
26635
|
+
case 3:
|
26636
|
+
return _formatString(direction === 'joined' ? strings.threeParticipantJoinedNoticeString : strings.threeParticipantLeftNoticeString, {
|
26637
|
+
displayName1: participantNames[0],
|
26638
|
+
displayName2: participantNames[1],
|
26639
|
+
displayName3: participantNames[2]
|
26640
|
+
});
|
26641
|
+
}
|
26642
|
+
/**
|
26643
|
+
* If we have more than 3 participants joining we need to do something more to announce them
|
26644
|
+
* appropriately.
|
26645
|
+
*
|
26646
|
+
* We don't want to announce every name when more than 3 participants join at once so
|
26647
|
+
* we parse out the first 3 names we have and announce those with the number of others.
|
26648
|
+
*/
|
26649
|
+
const numberOfExtraParticipants = sortedParticipants.length - 3;
|
26650
|
+
return _formatString(direction === 'joined' ? strings.manyParticipantsJoined : strings.manyParticipantsLeft, {
|
26651
|
+
displayName1: (_a = sortedParticipants[0].displayName) !== null && _a !== void 0 ? _a : strings.unnamedParticipantString,
|
26652
|
+
displayName2: (_b = sortedParticipants[1].displayName) !== null && _b !== void 0 ? _b : strings.unnamedParticipantString,
|
26653
|
+
displayName3: (_c = sortedParticipants[2].displayName) !== null && _c !== void 0 ? _c : strings.unnamedParticipantString,
|
26654
|
+
numOfParticipants: numberOfExtraParticipants.toString()
|
26655
|
+
});
|
26656
|
+
};
|
26657
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
26658
|
+
/**
|
26659
|
+
* determines if the media gallery should be replaced by the dtmf dialer
|
26660
|
+
* @param callees Target callees to determine if the dtmf dialer should be shown
|
26661
|
+
* @returns whether the dialer should be the gallery content or not
|
26662
|
+
*/
|
26663
|
+
const showDtmfDialer = (callees) => {
|
26664
|
+
return !!((callees === null || callees === void 0 ? void 0 : callees.filter((callee) => {
|
26665
|
+
return communicationCommon.isPhoneNumberIdentifier(callee) || communicationCommon.isMicrosoftTeamsAppIdentifier(callee);
|
26666
|
+
})) && callees.length > 0);
|
26667
|
+
};
|
26668
|
+
|
26475
26669
|
// Copyright (c) Microsoft Corporation.
|
26476
26670
|
// Licensed under the MIT License.
|
26477
26671
|
var __awaiter$f = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
@@ -26510,6 +26704,10 @@ const DesktopMoreButton = (props) => {
|
|
26510
26704
|
/* @conditional-compile-remove(gallery-layouts) */
|
26511
26705
|
const [previousLayout, setPreviousLayout] = React.useState((_a = props.userSetGalleryLayout) !== null && _a !== void 0 ? _a : 'floatingLocalVideo');
|
26512
26706
|
/* @conditional-compile-remove(dtmf-dialer) */
|
26707
|
+
const callees = useSelector$1(getTargetCallees);
|
26708
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
26709
|
+
const allowDtmfDialer = showDtmfDialer(callees);
|
26710
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
26513
26711
|
const [dtmfDialerChecked, setDtmfDialerChecked] = React.useState((_b = props.dtmfDialerPresent) !== null && _b !== void 0 ? _b : false);
|
26514
26712
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ /* @conditional-compile-remove(close-captions) */
|
26515
26713
|
const moreButtonStrings = React.useMemo(() => ({
|
@@ -26624,24 +26822,9 @@ const DesktopMoreButton = (props) => {
|
|
26624
26822
|
/**
|
26625
26823
|
* Only render the dtmf dialer if the dialpad for PSTN calls is not present
|
26626
26824
|
*/
|
26627
|
-
if (props.onSetDialpadPage &&
|
26825
|
+
if (props.onSetDialpadPage && allowDtmfDialer) {
|
26628
26826
|
moreButtonContextualMenuItems.push(dtmfDialerScreenOption);
|
26629
26827
|
}
|
26630
|
-
/*@conditional-compile-remove(PSTN-calls) */
|
26631
|
-
if (props.onClickShowDialpad) {
|
26632
|
-
moreButtonContextualMenuItems.push({
|
26633
|
-
key: 'showDialpadKey',
|
26634
|
-
text: localeStrings.strings.callWithChat.openDtmfDialpadLabel,
|
26635
|
-
onClick: () => {
|
26636
|
-
props.onClickShowDialpad && props.onClickShowDialpad();
|
26637
|
-
},
|
26638
|
-
iconProps: { iconName: 'Dialpad', styles: { root: { lineHeight: 0 } } },
|
26639
|
-
itemProps: {
|
26640
|
-
styles: buttonFlyoutIncreasedSizeStyles
|
26641
|
-
},
|
26642
|
-
disabled: props.disableButtonsForHoldScreen
|
26643
|
-
});
|
26644
|
-
}
|
26645
26828
|
/* @conditional-compile-remove(gallery-layouts) */
|
26646
26829
|
if (props.onUserSetOverflowGalleryPositionChange) {
|
26647
26830
|
const galleryOptions = {
|
@@ -29385,140 +29568,6 @@ const localVideoCameraCycleButtonSelector = reselect.createSelector([getDeviceMa
|
|
29385
29568
|
};
|
29386
29569
|
});
|
29387
29570
|
|
29388
|
-
// Copyright (c) Microsoft Corporation.
|
29389
|
-
// Licensed under the MIT License.
|
29390
|
-
/**
|
29391
|
-
* @private
|
29392
|
-
*/
|
29393
|
-
const mediaGallerySelector = reselect__namespace.createSelector([getLocalVideoStreams], (localVideoStreams) => {
|
29394
|
-
var _a, _b;
|
29395
|
-
return {
|
29396
|
-
isVideoStreamOn: !!((_b = (_a = localVideoStreams === null || localVideoStreams === void 0 ? void 0 : localVideoStreams.find((stream) => stream.mediaStreamType === 'Video')) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.target)
|
29397
|
-
};
|
29398
|
-
});
|
29399
|
-
/**
|
29400
|
-
* Custom selector for this hook to retrieve all the participants that are currently
|
29401
|
-
* connected to the call.
|
29402
|
-
*/
|
29403
|
-
const getRemoteParticipantsConnectedSelector = reselect__namespace.createSelector([getRemoteParticipants], (remoteParticipants) => {
|
29404
|
-
const participants = Object.values(remoteParticipants !== null && remoteParticipants !== void 0 ? remoteParticipants : {});
|
29405
|
-
return participants.filter((p) => p.state === 'Connected');
|
29406
|
-
});
|
29407
|
-
|
29408
|
-
// Copyright (c) Microsoft Corporation.
|
29409
|
-
// Licensed under the MIT License.
|
29410
|
-
/**
|
29411
|
-
* sets the announcement string whenever a Participant comes or goes from a call to be
|
29412
|
-
* used by the system narrator.
|
29413
|
-
*
|
29414
|
-
* @returns string to be used by the narrator and Announcer component
|
29415
|
-
*
|
29416
|
-
* @internal
|
29417
|
-
*/
|
29418
|
-
const useParticipantChangedAnnouncement = () => {
|
29419
|
-
const locale = useLocale().strings.call;
|
29420
|
-
const strings = React.useMemo(() => {
|
29421
|
-
return {
|
29422
|
-
participantJoinedNoticeString: locale.participantJoinedNoticeString,
|
29423
|
-
twoParticipantJoinedNoticeString: locale.twoParticipantJoinedNoticeString,
|
29424
|
-
threeParticipantJoinedNoticeString: locale.threeParticipantJoinedNoticeString,
|
29425
|
-
participantLeftNoticeString: locale.participantLeftNoticeString,
|
29426
|
-
twoParticipantLeftNoticeString: locale.twoParticipantLeftNoticeString,
|
29427
|
-
threeParticipantLeftNoticeString: locale.threeParticipantLeftNoticeString,
|
29428
|
-
unnamedParticipantString: locale.unnamedParticipantString,
|
29429
|
-
manyParticipantsJoined: locale.manyParticipantsJoined,
|
29430
|
-
manyParticipantsLeft: locale.manyParticipantsLeft,
|
29431
|
-
manyUnnamedParticipantsJoined: locale.manyUnnamedParticipantsJoined,
|
29432
|
-
manyUnnamedParticipantsLeft: locale.manyUnnamedParticipantsLeft
|
29433
|
-
};
|
29434
|
-
}, [locale]);
|
29435
|
-
const [announcerString, setAnnouncerString] = React.useState('');
|
29436
|
-
const currentParticipants = useSelector$1(getRemoteParticipantsConnectedSelector);
|
29437
|
-
/**
|
29438
|
-
* We want to use a useRef here since we want to not fire this hook based on the previous participants
|
29439
|
-
* this allows this value to be used in the hook without being in the dependency array.
|
29440
|
-
*
|
29441
|
-
* Note: By definition if this hook is used in another component it is not pure anymore.
|
29442
|
-
*/
|
29443
|
-
const previousParticipants = React.useRef(currentParticipants);
|
29444
|
-
const resetAnnoucement = (string) => {
|
29445
|
-
setAnnouncerString(string);
|
29446
|
-
};
|
29447
|
-
React.useMemo(() => {
|
29448
|
-
const currentIds = currentParticipants.map((p) => toFlatCommunicationIdentifier(p.identifier));
|
29449
|
-
const previousIds = previousParticipants.current.map((p) => toFlatCommunicationIdentifier(p.identifier));
|
29450
|
-
const whoJoined = currentParticipants.filter((p) => !previousIds.includes(toFlatCommunicationIdentifier(p.identifier)));
|
29451
|
-
const whoLeft = previousParticipants.current.filter((p) => !currentIds.includes(toFlatCommunicationIdentifier(p.identifier)));
|
29452
|
-
if (whoJoined.length > 0) {
|
29453
|
-
resetAnnoucement(createAnnouncementString('joined', whoJoined, strings));
|
29454
|
-
}
|
29455
|
-
if (whoLeft.length > 0) {
|
29456
|
-
resetAnnoucement(createAnnouncementString('left', whoLeft, strings));
|
29457
|
-
}
|
29458
|
-
// Update cached value at the end.
|
29459
|
-
previousParticipants.current = currentParticipants;
|
29460
|
-
}, [currentParticipants, strings]);
|
29461
|
-
return announcerString;
|
29462
|
-
};
|
29463
|
-
/**
|
29464
|
-
* Generates the announcement string for when a participant joins or leaves a call.
|
29465
|
-
*/
|
29466
|
-
const createAnnouncementString = (direction, participants, strings) => {
|
29467
|
-
var _a, _b, _c;
|
29468
|
-
/**
|
29469
|
-
* If there are no participants return empty string.
|
29470
|
-
*/
|
29471
|
-
if (participants.length === 0) {
|
29472
|
-
return '';
|
29473
|
-
}
|
29474
|
-
/**
|
29475
|
-
* Filter participants into two arrays to put all the unnamed participants at the back of the
|
29476
|
-
* names being announced.
|
29477
|
-
*/
|
29478
|
-
const unnamedParticipants = participants.filter((p) => !p.displayName);
|
29479
|
-
const namedParicipants = participants.filter((p) => p.displayName);
|
29480
|
-
const sortedParticipants = namedParicipants.concat(unnamedParticipants);
|
29481
|
-
/**
|
29482
|
-
* if there are only unnamed participants present in the array announce a special unnamed participants
|
29483
|
-
* only string.
|
29484
|
-
*/
|
29485
|
-
if (sortedParticipants.filter((p) => p.displayName).length === 0 && sortedParticipants.length > 1) {
|
29486
|
-
return _formatString(direction === 'joined' ? strings.manyUnnamedParticipantsJoined : strings.manyUnnamedParticipantsLeft, {
|
29487
|
-
numOfParticipants: (sortedParticipants.length - 1).toString()
|
29488
|
-
});
|
29489
|
-
}
|
29490
|
-
const participantNames = sortedParticipants.map((p) => { var _a; return (_a = p.displayName) !== null && _a !== void 0 ? _a : strings.unnamedParticipantString; });
|
29491
|
-
switch (sortedParticipants.length) {
|
29492
|
-
case 1:
|
29493
|
-
return _formatString(direction === 'joined' ? strings.participantJoinedNoticeString : strings.participantLeftNoticeString, { displayName: participantNames[0] });
|
29494
|
-
case 2:
|
29495
|
-
return _formatString(direction === 'joined' ? strings.twoParticipantJoinedNoticeString : strings.twoParticipantLeftNoticeString, {
|
29496
|
-
displayName1: participantNames[0],
|
29497
|
-
displayName2: participantNames[1]
|
29498
|
-
});
|
29499
|
-
case 3:
|
29500
|
-
return _formatString(direction === 'joined' ? strings.threeParticipantJoinedNoticeString : strings.threeParticipantLeftNoticeString, {
|
29501
|
-
displayName1: participantNames[0],
|
29502
|
-
displayName2: participantNames[1],
|
29503
|
-
displayName3: participantNames[2]
|
29504
|
-
});
|
29505
|
-
}
|
29506
|
-
/**
|
29507
|
-
* If we have more than 3 participants joining we need to do something more to announce them
|
29508
|
-
* appropriately.
|
29509
|
-
*
|
29510
|
-
* We don't want to announce every name when more than 3 participants join at once so
|
29511
|
-
* we parse out the first 3 names we have and announce those with the number of others.
|
29512
|
-
*/
|
29513
|
-
const numberOfExtraParticipants = sortedParticipants.length - 3;
|
29514
|
-
return _formatString(direction === 'joined' ? strings.manyParticipantsJoined : strings.manyParticipantsLeft, {
|
29515
|
-
displayName1: (_a = sortedParticipants[0].displayName) !== null && _a !== void 0 ? _a : strings.unnamedParticipantString,
|
29516
|
-
displayName2: (_b = sortedParticipants[1].displayName) !== null && _b !== void 0 ? _b : strings.unnamedParticipantString,
|
29517
|
-
displayName3: (_c = sortedParticipants[2].displayName) !== null && _c !== void 0 ? _c : strings.unnamedParticipantString,
|
29518
|
-
numOfParticipants: numberOfExtraParticipants.toString()
|
29519
|
-
});
|
29520
|
-
};
|
29521
|
-
|
29522
29571
|
// Copyright (c) Microsoft Corporation.
|
29523
29572
|
// Licensed under the MIT License.
|
29524
29573
|
const VideoGalleryStyles = {
|
@@ -29878,16 +29927,22 @@ const DtmfDialpadPageContent = (props) => {
|
|
29878
29927
|
const remoteParticipants = (_b = adapterState.call) === null || _b === void 0 ? void 0 : _b.remoteParticipants;
|
29879
29928
|
let calleeName;
|
29880
29929
|
if (remoteParticipants) {
|
29881
|
-
|
29930
|
+
const remoteParticipantValues = Object.values(remoteParticipants);
|
29931
|
+
if (calleeId && communicationCommon.isPhoneNumberIdentifier(calleeId)) {
|
29932
|
+
calleeName = calleeId.phoneNumber;
|
29933
|
+
}
|
29934
|
+
else {
|
29935
|
+
calleeName = remoteParticipantValues.find((p) => p.identifier === calleeId);
|
29936
|
+
}
|
29882
29937
|
}
|
29883
29938
|
return (React.createElement(react.Stack, { style: { height: '100%', width: '100%', background: theme.palette.white } },
|
29884
|
-
React.createElement(react.Stack, { style: { margin: 'auto' } },
|
29939
|
+
React.createElement(react.Stack, { verticalAlign: 'center', style: { margin: 'auto' } },
|
29885
29940
|
React.createElement(DtmfDialerContentTimer, null),
|
29886
|
-
React.createElement(react.Text,
|
29941
|
+
React.createElement(react.Text, { style: { margin: 'auto' } }, calleeName !== 'Unnamed participant' ? calleeName : ''),
|
29887
29942
|
React.createElement(Dialpad, { onSendDtmfTone: (tone) => __awaiter$b(void 0, void 0, void 0, function* () {
|
29888
29943
|
/* @conditional-compile-remove(dtmf-dialer) */
|
29889
29944
|
yield adapter.sendDtmfTone(tone);
|
29890
|
-
}),
|
29945
|
+
}), dialpadMode: 'dtmf' }))));
|
29891
29946
|
};
|
29892
29947
|
const DtmfDialerContentTimer = () => {
|
29893
29948
|
const [time, setTime] = React.useState(0);
|
@@ -29936,7 +29991,26 @@ const CallPage = (props) => {
|
|
29936
29991
|
const mutedNotificationProps = useSelector$1(mutedNotificationSelector);
|
29937
29992
|
const networkReconnectTileProps = useSelector$1(networkReconnectTileSelector);
|
29938
29993
|
/* @conditional-compile-remove(dtmf-dialer) */
|
29939
|
-
const
|
29994
|
+
const remoteParticipantsConnected = useSelector$1(getRemoteParticipantsConnectedSelector);
|
29995
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
29996
|
+
const callees = useSelector$1(getTargetCallees);
|
29997
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
29998
|
+
const renderDtmfDialerFromStart = showDtmfDialer(callees);
|
29999
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
30000
|
+
const [dtmfDialerPresent, setDtmfDialerPresent] = React.useState(renderDtmfDialerFromStart);
|
30001
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
30002
|
+
const dialerShouldAutoDismiss = React.useRef(renderDtmfDialerFromStart);
|
30003
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
30004
|
+
/**
|
30005
|
+
* This useEffect is about clearing the dtmf dialer should there be a new participant that joins the call.
|
30006
|
+
* This will only happen the first time should the dialer be present when the call starts.
|
30007
|
+
*/
|
30008
|
+
React.useEffect(() => {
|
30009
|
+
if (remoteParticipantsConnected.length > 1 && dtmfDialerPresent && dialerShouldAutoDismiss.current) {
|
30010
|
+
setDtmfDialerPresent(false);
|
30011
|
+
dialerShouldAutoDismiss.current = false;
|
30012
|
+
}
|
30013
|
+
}, [dtmfDialerPresent, remoteParticipantsConnected, setDtmfDialerPresent]);
|
29940
30014
|
const strings = useLocale().strings.call;
|
29941
30015
|
// Reduce the controls shown when mobile view is enabled.
|
29942
30016
|
const callControlOptions = mobileView ? reduceCallControlsForMobile(options === null || options === void 0 ? void 0 : options.callControls) : options === null || options === void 0 ? void 0 : options.callControls;
|
@@ -29977,7 +30051,9 @@ const CallPage = (props) => {
|
|
29977
30051
|
/* @conditional-compile-remove(capabilities) */
|
29978
30052
|
capabilitiesChangedNotificationBarProps: props.capabilitiesChangedNotificationBarProps,
|
29979
30053
|
/* @conditional-compile-remove(dtmf-dialer) */
|
29980
|
-
onSetDialpadPage: () => setDtmfDialerPresent(!dtmfDialerPresent)
|
30054
|
+
onSetDialpadPage: () => setDtmfDialerPresent(!dtmfDialerPresent),
|
30055
|
+
/* @conditional-compile-remove(dtmf-dialer) */
|
30056
|
+
dtmfDialerPresent: dtmfDialerPresent }));
|
29981
30057
|
};
|
29982
30058
|
/**
|
29983
30059
|
* @private
|