@azure/communication-react 1.5.1-alpha-202306180015 → 1.5.1-alpha-202306210014
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/README.md +2 -3
- package/dist/communication-react.d.ts +4 -0
- package/dist/dist-cjs/communication-react/index.js +833 -767
- package/dist/dist-cjs/communication-react/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/identifier.d.ts +6 -0
- package/dist/dist-esm/acs-ui-common/src/identifier.js +12 -1
- package/dist/dist-esm/acs-ui-common/src/identifier.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/index.d.ts +1 -1
- package/dist/dist-esm/acs-ui-common/src/index.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/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/react-components/src/components/HorizontalGallery.js +6 -3
- package/dist/dist-esm/react-components/src/components/HorizontalGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js +6 -1
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.d.ts +2 -2
- package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js +2 -1
- package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +25 -39
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/mentionTagUtils.d.ts +0 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/mentionTagUtils.js +50 -21
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/mentionTagUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VerticalGallery.js +6 -3
- package/dist/dist-esm/react-components/src/components/VerticalGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js +4 -2
- package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js +11 -6
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.d.ts +3 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js +3 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.js +6 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.d.ts +1 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.js +11 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery.js +12 -7
- package/dist/dist-esm/react-components/src/components/VideoGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoTile.js +1 -1
- package/dist/dist-esm/react-components/src/components/VideoTile.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.js +1 -1
- package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/VideoGallery.styles.d.ts +4 -0
- package/dist/dist-esm/react-components/src/components/styles/VideoGallery.styles.js +6 -0
- package/dist/dist-esm/react-components/src/components/styles/VideoGallery.styles.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts +4 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +3 -3
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/TransferPage.js +24 -11
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/TransferPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/TransferPage.styles.d.ts +7 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/TransferPage.styles.js +4 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/TransferPage.styles.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.d.ts +0 -9
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js +1 -14
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js +2 -2
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/localization/locales/en-US/strings.json +2 -1
- package/package.json +8 -8
@@ -163,11 +163,22 @@ const _toCommunicationIdentifier = (id) => {
|
|
163
163
|
}
|
164
164
|
return id;
|
165
165
|
};
|
166
|
+
/**
|
167
|
+
* Check if an object is identifier.
|
168
|
+
*
|
169
|
+
* @internal
|
170
|
+
*/
|
171
|
+
const _isValidIdentifier = (identifier) => {
|
172
|
+
return (communicationCommon.isCommunicationUserIdentifier(identifier) ||
|
173
|
+
communicationCommon.isPhoneNumberIdentifier(identifier) ||
|
174
|
+
communicationCommon.isMicrosoftTeamsUserIdentifier(identifier) ||
|
175
|
+
communicationCommon.isUnknownIdentifier(identifier));
|
176
|
+
};
|
166
177
|
|
167
178
|
// Copyright (c) Microsoft Corporation.
|
168
179
|
// Licensed under the MIT license.
|
169
180
|
// GENERATED FILE. DO NOT EDIT MANUALLY.
|
170
|
-
var telemetryVersion = '1.5.1-alpha-
|
181
|
+
var telemetryVersion = '1.5.1-alpha-202306210014';
|
171
182
|
|
172
183
|
// Copyright (c) Microsoft Corporation.
|
173
184
|
/**
|
@@ -6304,10 +6315,14 @@ const getTagClosingTagInfo = (tag) => {
|
|
6304
6315
|
* @returns Updated HTML and selection index if the selection index should be set.
|
6305
6316
|
*/
|
6306
6317
|
const updateHTML = (props) => {
|
6307
|
-
const { htmlText, oldPlainText,
|
6318
|
+
const { htmlText, oldPlainText, tags, startIndex, oldPlainTextEndIndex, change, mentionTrigger } = props;
|
6308
6319
|
if (tags.length === 0 || (startIndex === 0 && oldPlainTextEndIndex === oldPlainText.length - 1)) {
|
6309
6320
|
// no tags added yet or the whole text is changed
|
6310
|
-
|
6321
|
+
const changeWithSkippedChars = escapeHTMLChars(change);
|
6322
|
+
const updatedHTML = escapeHTMLChars(oldPlainText.substring(0, startIndex)) +
|
6323
|
+
changeWithSkippedChars +
|
6324
|
+
escapeHTMLChars(oldPlainText.substring(oldPlainTextEndIndex));
|
6325
|
+
return { updatedHTML, updatedSelectionIndex: undefined };
|
6311
6326
|
}
|
6312
6327
|
let result = '';
|
6313
6328
|
let lastProcessedHTMLIndex = 0;
|
@@ -6317,7 +6332,7 @@ const updateHTML = (props) => {
|
|
6317
6332
|
// e.g.: change is after and partially in tag => change will be added after the tag and outdated text in the tag will be removed
|
6318
6333
|
// e.g.: change is on the beginning of the tag => change will be added before the tag
|
6319
6334
|
// e.g.: change is on the end of the tag => change will be added to the tag if it's not mention and after the tag if it's mention
|
6320
|
-
let processedChange = change;
|
6335
|
+
let processedChange = escapeHTMLChars(change);
|
6321
6336
|
// end tag plain text index of the last processed tag
|
6322
6337
|
let lastProcessedPlainTextTagEndIndex = 0;
|
6323
6338
|
// as some tags/text can be removed fully, selection should be updated correctly
|
@@ -6339,13 +6354,13 @@ const updateHTML = (props) => {
|
|
6339
6354
|
if (startIndex <= tag.plainTextBeginIndex) {
|
6340
6355
|
// change start is before the open tag
|
6341
6356
|
// Math.max(lastProcessedPlainTextTagEndIndex, startIndex) is used as startIndex may not be in [[previous tag].plainTextEndIndex - tag.plainTextBeginIndex] range
|
6342
|
-
const startChangeDiff =
|
6357
|
+
const startChangeDiff = getChangeDiff(oldPlainText, Math.max(lastProcessedPlainTextTagEndIndex, startIndex), tag.plainTextBeginIndex);
|
6343
6358
|
result += htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex - startChangeDiff) + processedChange;
|
6344
6359
|
processedChange = '';
|
6345
6360
|
if (oldPlainTextEndIndex <= tag.plainTextBeginIndex) {
|
6346
6361
|
// the whole change is before tag start
|
6347
6362
|
// mentionTag length can be ignored here as the change is before the tag
|
6348
|
-
const endChangeDiff = tag.plainTextBeginIndex
|
6363
|
+
const endChangeDiff = getChangeDiff(oldPlainText, oldPlainTextEndIndex, tag.plainTextBeginIndex);
|
6349
6364
|
lastProcessedHTMLIndex = tag.openTagIndex - endChangeDiff;
|
6350
6365
|
// the change is handled; exit
|
6351
6366
|
break;
|
@@ -6375,13 +6390,13 @@ const updateHTML = (props) => {
|
|
6375
6390
|
if (startIndex !== tag.plainTextBeginIndex && startIndex !== closingTagInfo.plainTextEndIndex) {
|
6376
6391
|
// mention tag should be deleted when user tries to edit it in the middle
|
6377
6392
|
result += htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex) + processedChange;
|
6378
|
-
changeNewEndIndex = tag.plainTextBeginIndex + processedChange.length;
|
6393
|
+
changeNewEndIndex = tag.plainTextBeginIndex + unEscapeHtmlCharacters(processedChange).length;
|
6379
6394
|
lastProcessedHTMLIndex = closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength;
|
6380
6395
|
}
|
6381
6396
|
else if (startIndex === tag.plainTextBeginIndex) {
|
6382
6397
|
// non empty change at the beginning of the mention tag to be added before the mention tag
|
6383
6398
|
result += htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex) + processedChange;
|
6384
|
-
changeNewEndIndex = tag.plainTextBeginIndex + processedChange.length;
|
6399
|
+
changeNewEndIndex = tag.plainTextBeginIndex + unEscapeHtmlCharacters(processedChange).length;
|
6385
6400
|
lastProcessedHTMLIndex = tag.openTagIndex;
|
6386
6401
|
}
|
6387
6402
|
else if (startIndex === closingTagInfo.plainTextEndIndex) {
|
@@ -6389,12 +6404,13 @@ const updateHTML = (props) => {
|
|
6389
6404
|
result +=
|
6390
6405
|
htmlText.substring(lastProcessedHTMLIndex, closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength) +
|
6391
6406
|
processedChange;
|
6392
|
-
changeNewEndIndex = closingTagInfo.plainTextEndIndex + processedChange.length;
|
6407
|
+
changeNewEndIndex = closingTagInfo.plainTextEndIndex + unEscapeHtmlCharacters(processedChange).length;
|
6393
6408
|
lastProcessedHTMLIndex = closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength;
|
6394
6409
|
}
|
6395
6410
|
processedChange = '';
|
6396
6411
|
}
|
6397
6412
|
else {
|
6413
|
+
// When change is empty, it means that this change is a deletion
|
6398
6414
|
const updateMentionTagResult = handleMentionTagUpdate({
|
6399
6415
|
htmlText,
|
6400
6416
|
oldPlainText,
|
@@ -6422,7 +6438,6 @@ const updateHTML = (props) => {
|
|
6422
6438
|
const updatedContent = updateHTML({
|
6423
6439
|
htmlText: tag.content,
|
6424
6440
|
oldPlainText,
|
6425
|
-
newPlainText,
|
6426
6441
|
tags: tag.subTags,
|
6427
6442
|
startIndex,
|
6428
6443
|
oldPlainTextEndIndex,
|
@@ -6434,13 +6449,13 @@ const updateHTML = (props) => {
|
|
6434
6449
|
}
|
6435
6450
|
else {
|
6436
6451
|
// no subtags
|
6437
|
-
const startChangeDiff =
|
6452
|
+
const startChangeDiff = getChangeDiff(oldPlainText, tag.plainTextBeginIndex, startIndex);
|
6438
6453
|
result +=
|
6439
6454
|
htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex + tag.openTagBody.length + startChangeDiff) +
|
6440
6455
|
processedChange;
|
6441
6456
|
processedChange = '';
|
6442
6457
|
if (oldPlainTextEndIndex < closingTagInfo.plainTextEndIndex) {
|
6443
|
-
const endChangeDiff =
|
6458
|
+
const endChangeDiff = getChangeDiff(oldPlainText, tag.plainTextBeginIndex, oldPlainTextEndIndex);
|
6444
6459
|
lastProcessedHTMLIndex = tag.openTagIndex + tag.openTagBody.length + endChangeDiff;
|
6445
6460
|
}
|
6446
6461
|
else if (oldPlainTextEndIndex === closingTagInfo.plainTextEndIndex) {
|
@@ -6479,7 +6494,6 @@ const updateHTML = (props) => {
|
|
6479
6494
|
const updatedContent = updateHTML({
|
6480
6495
|
htmlText: tag.content,
|
6481
6496
|
oldPlainText,
|
6482
|
-
newPlainText,
|
6483
6497
|
tags: tag.subTags,
|
6484
6498
|
startIndex,
|
6485
6499
|
oldPlainTextEndIndex,
|
@@ -6539,7 +6553,6 @@ const updateHTML = (props) => {
|
|
6539
6553
|
const updatedContent = updateHTML({
|
6540
6554
|
htmlText: tag.content,
|
6541
6555
|
oldPlainText,
|
6542
|
-
newPlainText,
|
6543
6556
|
tags: tag.subTags,
|
6544
6557
|
startIndex,
|
6545
6558
|
oldPlainTextEndIndex,
|
@@ -6555,7 +6568,7 @@ const updateHTML = (props) => {
|
|
6555
6568
|
htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex + tag.openTagBody.length) + processedChange;
|
6556
6569
|
processedChange = '';
|
6557
6570
|
// oldPlainTextEndIndex already includes mentionTag length
|
6558
|
-
const endChangeDiff = closingTagInfo.plainTextEndIndex
|
6571
|
+
const endChangeDiff = getChangeDiff(oldPlainText, oldPlainTextEndIndex, closingTagInfo.plainTextEndIndex);
|
6559
6572
|
// as change may be before the end of the tag, we need to add the rest of the tag
|
6560
6573
|
lastProcessedHTMLIndex = closingTagInfo.closeTagIdx - endChangeDiff;
|
6561
6574
|
}
|
@@ -6567,9 +6580,9 @@ const updateHTML = (props) => {
|
|
6567
6580
|
if (i === tags.length - 1 && oldPlainTextEndIndex >= closingTagInfo.plainTextEndIndex) {
|
6568
6581
|
// the last tag should handle the end of the change if needed
|
6569
6582
|
// oldPlainTextEndIndex already includes mentionTag length
|
6570
|
-
const endChangeDiff =
|
6583
|
+
const endChangeDiff = getChangeDiff(oldPlainText, closingTagInfo.plainTextEndIndex, oldPlainTextEndIndex);
|
6571
6584
|
if (startIndex >= closingTagInfo.plainTextEndIndex) {
|
6572
|
-
const startChangeDiff =
|
6585
|
+
const startChangeDiff = getChangeDiff(oldPlainText, closingTagInfo.plainTextEndIndex, startIndex);
|
6573
6586
|
result +=
|
6574
6587
|
htmlText.substring(lastProcessedHTMLIndex, closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength + startChangeDiff) + processedChange;
|
6575
6588
|
}
|
@@ -6719,17 +6732,18 @@ const textToTagParser = (text, trigger) => {
|
|
6719
6732
|
if (!foundHtmlTag) {
|
6720
6733
|
if (parseIndex !== 0) {
|
6721
6734
|
// Add the remaining text to the plain text representation
|
6722
|
-
|
6735
|
+
const newText = text.substring(parseIndex);
|
6736
|
+
plainTextRepresentation += unEscapeHtmlCharacters(newText);
|
6723
6737
|
}
|
6724
6738
|
else {
|
6725
|
-
plainTextRepresentation = text;
|
6739
|
+
plainTextRepresentation = unEscapeHtmlCharacters(text);
|
6726
6740
|
}
|
6727
6741
|
break;
|
6728
6742
|
}
|
6729
6743
|
if (foundHtmlTag.type === 'open' || foundHtmlTag.type === 'self-closing') {
|
6730
6744
|
const nextTag = parseOpenTag(foundHtmlTag.content, foundHtmlTag.startIdx);
|
6731
6745
|
// Add the plain text between the last tag and this one found
|
6732
|
-
plainTextRepresentation += text.substring(parseIndex, foundHtmlTag.startIdx);
|
6746
|
+
plainTextRepresentation += unEscapeHtmlCharacters(text.substring(parseIndex, foundHtmlTag.startIdx));
|
6733
6747
|
nextTag.plainTextBeginIndex = plainTextRepresentation.length;
|
6734
6748
|
if (foundHtmlTag.type === 'open') {
|
6735
6749
|
tagParseStack.push(nextTag);
|
@@ -6755,14 +6769,14 @@ const textToTagParser = (text, trigger) => {
|
|
6755
6769
|
plainTextRepresentation.slice(currentOpenTag.plainTextBeginIndex);
|
6756
6770
|
}
|
6757
6771
|
if (!currentOpenTag.subTags) {
|
6758
|
-
plainTextRepresentation += currentOpenTag.content;
|
6772
|
+
plainTextRepresentation += unEscapeHtmlCharacters(currentOpenTag.content);
|
6759
6773
|
}
|
6760
6774
|
else if (currentOpenTag.subTags.length > 0) {
|
6761
6775
|
// Add text after the last tag
|
6762
6776
|
const lastSubTag = currentOpenTag.subTags[currentOpenTag.subTags.length - 1];
|
6763
6777
|
const startOfRemainingText = ((_a = lastSubTag.closingTagIndex) !== null && _a !== void 0 ? _a : lastSubTag.openTagIndex) + lastSubTag.tagType.length + 3;
|
6764
6778
|
const trailingText = currentOpenTag.content.substring(startOfRemainingText);
|
6765
|
-
plainTextRepresentation += trailingText;
|
6779
|
+
plainTextRepresentation += unEscapeHtmlCharacters(trailingText);
|
6766
6780
|
}
|
6767
6781
|
currentOpenTag.plainTextEndIndex = plainTextRepresentation.length;
|
6768
6782
|
addTag(currentOpenTag, tagParseStack, tags);
|
@@ -6850,6 +6864,32 @@ const addTag = (tag, parseStack, tags) => {
|
|
6850
6864
|
}
|
6851
6865
|
}
|
6852
6866
|
};
|
6867
|
+
// We should revisit this in the future when we support other text such as rich text editing.
|
6868
|
+
const escapeHTMLChars = (text) => {
|
6869
|
+
const mentionRegex = new RegExp(`<${MSFT_MENTION_TAG}(.*?)>(.*?)</${MSFT_MENTION_TAG}>`, 'i');
|
6870
|
+
if (!text.match(mentionRegex)) {
|
6871
|
+
return text
|
6872
|
+
.replace(/&(?![A-Z]+;)/gi, '&')
|
6873
|
+
.replace(/</g, '<')
|
6874
|
+
.replace(/>/g, '>');
|
6875
|
+
}
|
6876
|
+
return text;
|
6877
|
+
};
|
6878
|
+
const getChangeDiff = (plainText, startIndex, endIndex) => {
|
6879
|
+
return endIndex - startIndex + getLengthDiffForEscapedHtmlChars(plainText, startIndex, endIndex);
|
6880
|
+
};
|
6881
|
+
const getLengthDiffForEscapedHtmlChars = (text, startIndex, endIndex) => {
|
6882
|
+
var _a, _b;
|
6883
|
+
const subText = text.substring(startIndex, endIndex);
|
6884
|
+
const escapedAngleBracketCount = ((_a = subText.match(/(<)|(>)/g)) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
6885
|
+
let escapedCharLength = escapedAngleBracketCount * ('<'.length - '<'.length);
|
6886
|
+
const escapedAmpersandCount = ((_b = subText.match(/&/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
6887
|
+
escapedCharLength += escapedAmpersandCount * ('&'.length - '&'.length);
|
6888
|
+
return escapedCharLength;
|
6889
|
+
};
|
6890
|
+
const unEscapeHtmlCharacters = (text) => {
|
6891
|
+
return text.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');
|
6892
|
+
};
|
6853
6893
|
|
6854
6894
|
// Copyright (c) Microsoft Corporation.
|
6855
6895
|
/**
|
@@ -7117,13 +7157,11 @@ const TextFieldWithMention = (props) => {
|
|
7117
7157
|
const oldPlainText = inputTextValue;
|
7118
7158
|
const mention = htmlStringForMentionSuggestion(suggestion, localeStrings);
|
7119
7159
|
// update plain text with the mention html text
|
7120
|
-
const newPlainText = inputTextValue.substring(0, currentTriggerStartIndex) + mention + inputTextValue.substring(selectionEnd);
|
7121
7160
|
const triggerText = (_b = mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger) !== null && _b !== void 0 ? _b : DEFAULT_MENTION_TRIGGER;
|
7122
7161
|
// update html text with updated plain text
|
7123
7162
|
const updatedContent = updateHTML({
|
7124
7163
|
htmlText: textValue,
|
7125
7164
|
oldPlainText,
|
7126
|
-
newPlainText,
|
7127
7165
|
tags: tagsValue,
|
7128
7166
|
startIndex: currentTriggerStartIndex,
|
7129
7167
|
oldPlainTextEndIndex: selectionEnd,
|
@@ -7438,44 +7476,32 @@ const TextFieldWithMention = (props) => {
|
|
7438
7476
|
}
|
7439
7477
|
}
|
7440
7478
|
}
|
7441
|
-
|
7442
|
-
|
7443
|
-
|
7444
|
-
|
7445
|
-
|
7446
|
-
|
7447
|
-
|
7448
|
-
|
7449
|
-
|
7450
|
-
|
7451
|
-
|
7452
|
-
|
7453
|
-
|
7454
|
-
|
7455
|
-
|
7456
|
-
|
7457
|
-
|
7458
|
-
|
7459
|
-
|
7460
|
-
|
7461
|
-
|
7462
|
-
|
7463
|
-
|
7464
|
-
|
7465
|
-
|
7466
|
-
|
7467
|
-
mentionTrigger: triggerText
|
7468
|
-
});
|
7469
|
-
result = updatedContent.updatedHTML;
|
7470
|
-
// update caret index if needed
|
7471
|
-
if (updatedContent.updatedSelectionIndex !== undefined) {
|
7472
|
-
setCaretIndex(updatedContent.updatedSelectionIndex);
|
7473
|
-
setSelectionEndValue(updatedContent.updatedSelectionIndex);
|
7474
|
-
setSelectionStartValue(updatedContent.updatedSelectionIndex);
|
7475
|
-
}
|
7476
|
-
}
|
7477
|
-
onChange && onChange(event, result);
|
7478
|
-
}), [onChange, mentionLookupOptions, setCaretIndex, setCaretPosition, updateMentionSuggestions, debouncedQueryUpdate]);
|
7479
|
+
const { changeStart, oldChangeEnd, newChangeEnd } = findStringsDiffIndexes({
|
7480
|
+
oldText: inputTextValue,
|
7481
|
+
newText: newValue,
|
7482
|
+
previousSelectionStart: previousSelectionStartValue,
|
7483
|
+
previousSelectionEnd: previousSelectionEndValue,
|
7484
|
+
currentSelectionStart: currentSelectionStartValue,
|
7485
|
+
currentSelectionEnd: currentSelectionEndValue
|
7486
|
+
});
|
7487
|
+
const change = newValue.substring(changeStart, newChangeEnd);
|
7488
|
+
const updatedContent = updateHTML({
|
7489
|
+
htmlText: htmlTextValue,
|
7490
|
+
oldPlainText: inputTextValue,
|
7491
|
+
tags: tagsValue,
|
7492
|
+
startIndex: changeStart,
|
7493
|
+
oldPlainTextEndIndex: oldChangeEnd,
|
7494
|
+
change,
|
7495
|
+
mentionTrigger: triggerText
|
7496
|
+
});
|
7497
|
+
// update caret index if needed
|
7498
|
+
if (updatedContent.updatedSelectionIndex !== undefined) {
|
7499
|
+
setCaretIndex(updatedContent.updatedSelectionIndex);
|
7500
|
+
setSelectionEndValue(updatedContent.updatedSelectionIndex);
|
7501
|
+
setSelectionStartValue(updatedContent.updatedSelectionIndex);
|
7502
|
+
}
|
7503
|
+
onChange && onChange(event, updatedContent.updatedHTML);
|
7504
|
+
}), [debouncedQueryUpdate, mentionLookupOptions, onChange, updateMentionSuggestions]);
|
7479
7505
|
// Adjust the selection range based on a mouse / touch interaction
|
7480
7506
|
const handleOnMove = React.useCallback(({ event, selectionStartValue, selectionEndValue, interactionStartSelection, shouldHandleMoveEvent }) => {
|
7481
7507
|
if (shouldHandleMoveEvent &&
|
@@ -7640,7 +7666,12 @@ const InputBoxComponent = (props) => {
|
|
7640
7666
|
if (props.mentionLookupOptions) {
|
7641
7667
|
return React__default['default'].createElement(TextFieldWithMention, Object.assign({}, textFieldWithMentionProps));
|
7642
7668
|
}
|
7643
|
-
return (React__default['default'].createElement(react.TextField, Object.assign({}, textFieldProps, { "data-ui-id": dataUiId, value: textValue, onChange: onChange, onKeyDown: onTextFieldKeyDown
|
7669
|
+
return (React__default['default'].createElement(react.TextField, Object.assign({}, textFieldProps, { "data-ui-id": dataUiId, value: textValue, onChange: onChange, onKeyDown: onTextFieldKeyDown, onFocus: (e) => {
|
7670
|
+
// Fix for setting the cursor to the correct position when multiline is true
|
7671
|
+
// This approach should be reviewed during migration to FluentUI v9
|
7672
|
+
e.currentTarget.value = '';
|
7673
|
+
e.currentTarget.value = textValue;
|
7674
|
+
} })));
|
7644
7675
|
};
|
7645
7676
|
return (React__default['default'].createElement(react.Stack, { className: mergedRootStyle },
|
7646
7677
|
React__default['default'].createElement("div", { className: mergedTextContainerStyle }, renderTextField())));
|
@@ -11271,7 +11302,7 @@ const VideoTile = (props) => {
|
|
11271
11302
|
}
|
11272
11303
|
const currentObserver = observer.current;
|
11273
11304
|
return () => currentObserver.disconnect();
|
11274
|
-
}, [
|
11305
|
+
}, [videoTileRef]);
|
11275
11306
|
/* @conditional-compile-remove(pinned-participants) */
|
11276
11307
|
const useLongPressProps = React.useMemo(() => {
|
11277
11308
|
return {
|
@@ -11630,6 +11661,12 @@ const localVideoCameraCycleButtonStyles = (theme) => {
|
|
11630
11661
|
}
|
11631
11662
|
};
|
11632
11663
|
};
|
11664
|
+
/**
|
11665
|
+
* @private
|
11666
|
+
*/
|
11667
|
+
const localVideoTileContainerStyles = {
|
11668
|
+
root: { width: '100%', height: '100%' }
|
11669
|
+
};
|
11633
11670
|
|
11634
11671
|
// Copyright (c) Microsoft Corporation.
|
11635
11672
|
/**
|
@@ -11772,7 +11809,7 @@ const DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS = 6;
|
|
11772
11809
|
const _useOrganizedParticipants = (props) => {
|
11773
11810
|
const visibleGridParticipants = React.useRef([]);
|
11774
11811
|
const visibleOverflowGalleryParticipants = React.useRef([]);
|
11775
|
-
const { remoteParticipants = [], dominantSpeakers = [], maxRemoteVideoStreams, maxOverflowGalleryDominantSpeakers = DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS, isScreenShareActive = false, pinnedParticipantUserIds = [] } = props;
|
11812
|
+
const { remoteParticipants = [], localParticipant, dominantSpeakers = [], maxRemoteVideoStreams, maxOverflowGalleryDominantSpeakers = DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS, isScreenShareActive = false, pinnedParticipantUserIds = [] } = props;
|
11776
11813
|
const videoParticipants = remoteParticipants.filter((p) => { var _a; return (_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable; });
|
11777
11814
|
visibleGridParticipants.current =
|
11778
11815
|
pinnedParticipantUserIds.length > 0 || isScreenShareActive
|
@@ -11810,7 +11847,13 @@ const _useOrganizedParticipants = (props) => {
|
|
11810
11847
|
]);
|
11811
11848
|
const gridParticipants = getGridParticipants();
|
11812
11849
|
const getOverflowGalleryRemoteParticipants = React.useCallback(() => {
|
11813
|
-
if (isScreenShareActive) {
|
11850
|
+
if (isScreenShareActive && localParticipant) {
|
11851
|
+
const localParticipantPlusOverflow = [localParticipant].concat(visibleGridParticipants.current.concat(visibleOverflowGalleryParticipants.current));
|
11852
|
+
// If screen sharing is active, assign video and audio participants as overflow gallery participants
|
11853
|
+
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
|
11854
|
+
return localParticipantPlusOverflow.concat(callingParticipants);
|
11855
|
+
}
|
11856
|
+
else if (isScreenShareActive) {
|
11814
11857
|
// If screen sharing is active, assign video and audio participants as overflow gallery participants
|
11815
11858
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
|
11816
11859
|
return visibleGridParticipants.current.concat(visibleOverflowGalleryParticipants.current.concat(callingParticipants));
|
@@ -11825,7 +11868,8 @@ const _useOrganizedParticipants = (props) => {
|
|
11825
11868
|
}
|
11826
11869
|
}, [
|
11827
11870
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ callingParticipants,
|
11828
|
-
isScreenShareActive
|
11871
|
+
isScreenShareActive,
|
11872
|
+
localParticipant
|
11829
11873
|
]);
|
11830
11874
|
const overflowGalleryParticipants = getOverflowGalleryRemoteParticipants();
|
11831
11875
|
return { gridParticipants, overflowGalleryParticipants: overflowGalleryParticipants };
|
@@ -11978,9 +12022,12 @@ const HorizontalGallery = (props) => {
|
|
11978
12022
|
const firstIndexOfCurrentPage = page * childrenPerPage;
|
11979
12023
|
const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
|
11980
12024
|
const childrenOnCurrentPage = React.useMemo(() => {
|
11981
|
-
|
11982
|
-
return
|
11983
|
-
|
12025
|
+
if (indexesArray[0] !== undefined) {
|
12026
|
+
return indexesArray[clippedPage].map((index) => {
|
12027
|
+
return React__default['default'].Children.toArray(children)[index];
|
12028
|
+
});
|
12029
|
+
}
|
12030
|
+
return [];
|
11984
12031
|
}, [indexesArray, clippedPage, children]);
|
11985
12032
|
const showButtons = numberOfChildren > childrenPerPage;
|
11986
12033
|
const disablePreviousButton = page === 0;
|
@@ -12036,10 +12083,13 @@ const LOCAL_VIDEO_TILE_ZINDEX = 2;
|
|
12036
12083
|
/**
|
12037
12084
|
* @private
|
12038
12085
|
*/
|
12039
|
-
const localVideoTileContainerStyle = (theme, localVideoTileSizeRem) => {
|
12086
|
+
const localVideoTileContainerStyle = (theme, localVideoTileSizeRem, screenSharePresent) => {
|
12087
|
+
console.log(screenSharePresent);
|
12040
12088
|
return {
|
12041
|
-
|
12042
|
-
|
12089
|
+
width: screenSharePresent ? `${localVideoTileSizeRem.width}rem` : '',
|
12090
|
+
height: screenSharePresent ? `${localVideoTileSizeRem.height}rem` : '',
|
12091
|
+
minWidth: screenSharePresent ? '' : `${localVideoTileSizeRem.width}rem`,
|
12092
|
+
minHeight: screenSharePresent ? '' : `${localVideoTileSizeRem.height}rem`,
|
12043
12093
|
position: 'absolute',
|
12044
12094
|
bottom: `${localVideoTileOuterPaddingRem}rem`,
|
12045
12095
|
borderRadius: theme.effects.roundedCorner4,
|
@@ -12366,7 +12416,7 @@ const childrenContainerStyle = (pageControlBarHeight) => {
|
|
12366
12416
|
*/
|
12367
12417
|
const rootStyle = {
|
12368
12418
|
height: '100%',
|
12369
|
-
width: '
|
12419
|
+
width: 'inherit',
|
12370
12420
|
gap: `${VERTICAL_GALLERY_GAP}rem`,
|
12371
12421
|
position: 'relative'
|
12372
12422
|
};
|
@@ -12435,9 +12485,12 @@ const VerticalGallery = (props) => {
|
|
12435
12485
|
const firstIndexOfCurrentPage = (page - 1) * childrenPerPage;
|
12436
12486
|
const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
|
12437
12487
|
const childrenOnCurrentPage = React.useMemo(() => {
|
12438
|
-
|
12439
|
-
return
|
12440
|
-
|
12488
|
+
if (indexesArray[0] !== undefined) {
|
12489
|
+
return indexesArray[clippedPage - 1].map((index) => {
|
12490
|
+
return React__default['default'].Children.toArray(children)[index];
|
12491
|
+
});
|
12492
|
+
}
|
12493
|
+
return;
|
12441
12494
|
}, [indexesArray, clippedPage, children]);
|
12442
12495
|
const showButtons = numberOfChildren > childrenPerPage;
|
12443
12496
|
const onPreviousButtonClick = () => {
|
@@ -12521,13 +12574,14 @@ const VerticalGalleryControlBar = (props) => {
|
|
12521
12574
|
* @beta
|
12522
12575
|
*/
|
12523
12576
|
const ResponsiveVerticalGallery = (props) => {
|
12577
|
+
var _a;
|
12524
12578
|
const { children, containerStyles, verticalGalleryStyles, gapHeightRem, controlBarHeightRem, isShort, onFetchTilesToRender, onChildrenPerPageChange } = props;
|
12525
12579
|
const containerRef = React.useRef(null);
|
12526
12580
|
const containerHeight = _useContainerHeight(containerRef);
|
12527
12581
|
const topPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingTop) : 0;
|
12528
12582
|
const bottomPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingBottom) : 0;
|
12529
12583
|
const childrenPerPage = calculateVerticalChildrenPerPage({
|
12530
|
-
numberOfChildren: React__default['default'].Children.count(children),
|
12584
|
+
numberOfChildren: (_a = React__default['default'].Children.count(children)) !== null && _a !== void 0 ? _a : 0,
|
12531
12585
|
containerHeight: (containerHeight !== null && containerHeight !== void 0 ? containerHeight : 0) - topPadding - bottomPadding,
|
12532
12586
|
gapHeightRem,
|
12533
12587
|
controlBarHeight: controlBarHeightRem !== null && controlBarHeightRem !== void 0 ? controlBarHeightRem : 2,
|
@@ -12621,16 +12675,16 @@ const OverflowGallery = (props) => {
|
|
12621
12675
|
]);
|
12622
12676
|
/* @conditional-compile-remove(vertical-gallery) */
|
12623
12677
|
if (overflowGalleryPosition === 'VerticalRight') {
|
12624
|
-
return (React__default['default'].createElement(ResponsiveVerticalGallery, { key: "responsive-vertical-gallery", containerStyles: containerStyles, verticalGalleryStyles: galleryStyles, controlBarHeightRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapHeightRem: HORIZONTAL_GALLERY_GAP, isShort: isShort, onFetchTilesToRender: onFetchTilesToRender, onChildrenPerPageChange: onChildrenPerPageChange }, overflowGalleryElements));
|
12678
|
+
return (React__default['default'].createElement(ResponsiveVerticalGallery, { key: "responsive-vertical-gallery", containerStyles: containerStyles, verticalGalleryStyles: galleryStyles, controlBarHeightRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapHeightRem: HORIZONTAL_GALLERY_GAP, isShort: isShort, onFetchTilesToRender: onFetchTilesToRender, onChildrenPerPageChange: onChildrenPerPageChange }, overflowGalleryElements ? overflowGalleryElements : [React__default['default'].createElement(React__default['default'].Fragment, null)]));
|
12625
12679
|
}
|
12626
12680
|
/* @conditional-compile-remove(pinned-participants) */
|
12627
12681
|
if (isNarrow) {
|
12628
12682
|
// There are no pages for ScrollableHorizontalGallery so we will approximate the first 3 remote
|
12629
12683
|
// participant tiles are visible
|
12630
12684
|
onChildrenPerPageChange === null || onChildrenPerPageChange === void 0 ? void 0 : onChildrenPerPageChange(3);
|
12631
|
-
return (React__default['default'].createElement(ScrollableHorizontalGallery, { horizontalGalleryElements: overflowGalleryElements, onFetchTilesToRender: onFetchTilesToRender, key: "scrollable-horizontal-gallery" }));
|
12685
|
+
return (React__default['default'].createElement(ScrollableHorizontalGallery, { horizontalGalleryElements: overflowGalleryElements ? overflowGalleryElements : [React__default['default'].createElement(React__default['default'].Fragment, null)], onFetchTilesToRender: onFetchTilesToRender, key: "scrollable-horizontal-gallery" }));
|
12632
12686
|
}
|
12633
|
-
return (React__default['default'].createElement(ResponsiveHorizontalGallery, { key: "responsive-horizontal-gallery", containerStyles: containerStyles, onFetchTilesToRender: onFetchTilesToRender, horizontalGalleryStyles: galleryStyles, buttonWidthRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapWidthRem: HORIZONTAL_GALLERY_GAP, onChildrenPerPageChange: onChildrenPerPageChange }, overflowGalleryElements));
|
12687
|
+
return (React__default['default'].createElement(ResponsiveHorizontalGallery, { key: "responsive-horizontal-gallery", containerStyles: containerStyles, onFetchTilesToRender: onFetchTilesToRender, horizontalGalleryStyles: galleryStyles, buttonWidthRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapWidthRem: HORIZONTAL_GALLERY_GAP, onChildrenPerPageChange: onChildrenPerPageChange }, overflowGalleryElements ? overflowGalleryElements : [React__default['default'].createElement(React__default['default'].Fragment, null)]));
|
12634
12688
|
};
|
12635
12689
|
|
12636
12690
|
// Copyright (c) Microsoft Corporation.
|
@@ -12641,7 +12695,7 @@ const OverflowGallery = (props) => {
|
|
12641
12695
|
* @private
|
12642
12696
|
*/
|
12643
12697
|
const DefaultLayout = (props) => {
|
12644
|
-
const { remoteParticipants = [], dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, parentWidth,
|
12698
|
+
const { remoteParticipants = [], localParticipant, dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, parentWidth,
|
12645
12699
|
/* @conditional-compile-remove(vertical-gallery) */
|
12646
12700
|
parentHeight, pinnedParticipantUserIds = [],
|
12647
12701
|
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryPosition = 'HorizontalBottom' } = props;
|
@@ -12650,14 +12704,16 @@ const DefaultLayout = (props) => {
|
|
12650
12704
|
const isShort = parentHeight ? isShortHeight(parentHeight) : false;
|
12651
12705
|
// This is for tracking the number of children in the first page of overflow gallery.
|
12652
12706
|
// This number will be used for the maxOverflowGalleryDominantSpeakers when organizing the remote participants.
|
12707
|
+
// We need to add the local participant to the pinned participant count so we are placing the speakers correctly.
|
12653
12708
|
const childrenPerPage = React.useRef(4);
|
12654
12709
|
const { gridParticipants, overflowGalleryParticipants } = useOrganizedParticipants({
|
12655
12710
|
remoteParticipants,
|
12711
|
+
localParticipant,
|
12656
12712
|
dominantSpeakers,
|
12657
12713
|
maxRemoteVideoStreams,
|
12658
12714
|
isScreenShareActive: !!screenShareComponent,
|
12659
12715
|
maxOverflowGalleryDominantSpeakers: screenShareComponent
|
12660
|
-
? childrenPerPage.current - (pinnedParticipantUserIds.length % childrenPerPage.current)
|
12716
|
+
? childrenPerPage.current - ((pinnedParticipantUserIds.length + 1) % childrenPerPage.current)
|
12661
12717
|
: childrenPerPage.current,
|
12662
12718
|
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds
|
12663
12719
|
});
|
@@ -13502,7 +13558,10 @@ const FloatingLocalVideoLayout = (props) => {
|
|
13502
13558
|
const overflowGalleryTiles = overflowGalleryParticipants.map((p, i) => {
|
13503
13559
|
var _a, _b;
|
13504
13560
|
return onRenderRemoteParticipant(p, maxRemoteVideoStreams && maxRemoteVideoStreams >= 0
|
13505
|
-
? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) &&
|
13561
|
+
? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) &&
|
13562
|
+
indexesToRender &&
|
13563
|
+
indexesToRender.includes(i) &&
|
13564
|
+
activeVideoStreams++ < maxRemoteVideoStreams
|
13506
13565
|
: (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
|
13507
13566
|
});
|
13508
13567
|
const layerHostId = reactHooks.useId('layerhost');
|
@@ -13511,7 +13570,7 @@ const FloatingLocalVideoLayout = (props) => {
|
|
13511
13570
|
return SMALL_FLOATING_MODAL_SIZE_REM;
|
13512
13571
|
}
|
13513
13572
|
/* @conditional-compile-remove(vertical-gallery) */
|
13514
|
-
if (overflowGalleryTiles.length > 0 && overflowGalleryPosition === 'VerticalRight') {
|
13573
|
+
if ((overflowGalleryTiles.length > 0 || screenShareComponent) && overflowGalleryPosition === 'VerticalRight') {
|
13515
13574
|
return isNarrow
|
13516
13575
|
? SMALL_FLOATING_MODAL_SIZE_REM
|
13517
13576
|
: isShort
|
@@ -13519,25 +13578,26 @@ const FloatingLocalVideoLayout = (props) => {
|
|
13519
13578
|
: VERTICAL_GALLERY_FLOATING_MODAL_SIZE_REM;
|
13520
13579
|
}
|
13521
13580
|
/*@conditional-compile-remove(click-to-call) */
|
13522
|
-
if (overflowGalleryTiles.length > 0 && overflowGalleryPosition === 'HorizontalBottom') {
|
13581
|
+
if ((overflowGalleryTiles.length > 0 || screenShareComponent) && overflowGalleryPosition === 'HorizontalBottom') {
|
13523
13582
|
return localVideoTileSize === '16:9' || !isNarrow ? LARGE_FLOATING_MODAL_SIZE_REM : SMALL_FLOATING_MODAL_SIZE_REM;
|
13524
13583
|
}
|
13525
13584
|
return LARGE_FLOATING_MODAL_SIZE_REM;
|
13526
13585
|
}, [
|
13527
13586
|
overflowGalleryTiles.length,
|
13528
13587
|
isNarrow,
|
13588
|
+
screenShareComponent,
|
13529
13589
|
/* @conditional-compile-remove(vertical-gallery) */ isShort,
|
13530
13590
|
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryPosition,
|
13531
13591
|
/* @conditional-compile-remove(click-to-call) */ localVideoTileSize
|
13532
13592
|
]);
|
13533
|
-
const wrappedLocalVideoComponent = localVideoComponent && shouldFloatLocalVideo ? (
|
13593
|
+
const wrappedLocalVideoComponent = (localVideoComponent && shouldFloatLocalVideo) || (screenShareComponent && localVideoComponent) ? (
|
13534
13594
|
// When we use showCameraSwitcherInLocalPreview it disables dragging to allow keyboard navigation.
|
13535
13595
|
showCameraSwitcherInLocalPreview ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme, localVideoSizeRem), {
|
13536
13596
|
boxShadow: theme.effects.elevation8,
|
13537
13597
|
zIndex: LOCAL_VIDEO_TILE_ZINDEX
|
13538
|
-
}) }, localVideoComponent)) : overflowGalleryTiles.length > 0 ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, localVideoSizeRem)) }, localVideoComponent)) : (React__default['default'].createElement(FloatingLocalVideo, { localVideoComponent: localVideoComponent, layerHostId: layerHostId, localVideoSizeRem: localVideoSizeRem, parentWidth: parentWidth, parentHeight: parentHeight }))) : undefined;
|
13598
|
+
}) }, localVideoComponent)) : overflowGalleryTiles.length > 0 || screenShareComponent ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, localVideoSizeRem, !!screenShareComponent)) }, localVideoComponent)) : (React__default['default'].createElement(FloatingLocalVideo, { localVideoComponent: localVideoComponent, layerHostId: layerHostId, localVideoSizeRem: localVideoSizeRem, parentWidth: parentWidth, parentHeight: parentHeight }))) : undefined;
|
13539
13599
|
const overflowGallery = React.useMemo(() => {
|
13540
|
-
if (overflowGalleryTiles.length === 0) {
|
13600
|
+
if (overflowGalleryTiles.length === 0 && !screenShareComponent) {
|
13541
13601
|
return null;
|
13542
13602
|
}
|
13543
13603
|
return (React__default['default'].createElement(OverflowGallery
|
@@ -13554,6 +13614,7 @@ const FloatingLocalVideoLayout = (props) => {
|
|
13554
13614
|
}, [
|
13555
13615
|
isNarrow,
|
13556
13616
|
/* @conditional-compile-remove(vertical-gallery) */ isShort,
|
13617
|
+
screenShareComponent,
|
13557
13618
|
overflowGalleryTiles,
|
13558
13619
|
styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
|
13559
13620
|
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryPosition,
|
@@ -13670,7 +13731,7 @@ const VideoGallery = (props) => {
|
|
13670
13731
|
root: { borderRadius: theme.effects.roundedCorner4 }
|
13671
13732
|
}, styles === null || styles === void 0 ? void 0 : styles.localVideo);
|
13672
13733
|
const initialsName = !localParticipant.displayName ? '' : localParticipant.displayName;
|
13673
|
-
return (React__default['default'].createElement(react.Stack, { key: "local-video-tile-key", tabIndex: 0, "aria-label": strings.localVideoMovementLabel, role: 'dialog' },
|
13734
|
+
return (React__default['default'].createElement(react.Stack, { styles: localVideoTileContainerStyles, key: "local-video-tile-key", tabIndex: 0, "aria-label": strings.localVideoMovementLabel, role: 'dialog' },
|
13674
13735
|
React__default['default'].createElement(_LocalVideoTile, { userId: localParticipant.userId, onCreateLocalStreamView: onCreateLocalStreamView, onDisposeLocalStreamView: onDisposeLocalStreamView, isAvailable: (_a = localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable, isMuted: localParticipant.isMuted, renderElement: (_b = localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.videoStream) === null || _b === void 0 ? void 0 : _b.renderElement, displayName: isNarrow ? '' : strings.localVideoLabel, initialsName: initialsName, localVideoViewOptions: localVideoViewOptions, onRenderAvatar: onRenderAvatar, showLabel: !((shouldFloatLocalVideo && isNarrow) ||
|
13675
13736
|
/*@conditional-compile-remove(click-to-call) */ localVideoTileSize === '9:16'), showMuteIndicator: showMuteIndicator, showCameraSwitcherInLocalPreview: showCameraSwitcherInLocalPreview, localVideoCameraCycleButtonProps: localVideoCameraCycleButtonProps, localVideoCameraSwitcherLabel: strings.localVideoCameraSwitcherLabel, localVideoSelectedDescription: strings.localVideoSelectedDescription, styles: localVideoTileStyles })));
|
13676
13737
|
}, [
|
@@ -13732,11 +13793,13 @@ const VideoGallery = (props) => {
|
|
13732
13793
|
/* @conditional-compile-remove(PSTN-calls) */
|
13733
13794
|
participantState: participant.state,
|
13734
13795
|
/* @conditional-compile-remove(pinned-participants) */
|
13735
|
-
menuKind:
|
13736
|
-
?
|
13737
|
-
|
13738
|
-
|
13739
|
-
|
13796
|
+
menuKind: participant.userId === localParticipant.userId
|
13797
|
+
? undefined
|
13798
|
+
: remoteVideoTileMenuOptions
|
13799
|
+
? remoteVideoTileMenuOptions.kind === 'drawer'
|
13800
|
+
? 'drawer'
|
13801
|
+
: 'contextual'
|
13802
|
+
: undefined,
|
13740
13803
|
/* @conditional-compile-remove(pinned-participants) */
|
13741
13804
|
drawerMenuHostId: drawerMenuHostId,
|
13742
13805
|
/* @conditional-compile-remove(pinned-participants) */
|
@@ -13753,6 +13816,7 @@ const VideoGallery = (props) => {
|
|
13753
13816
|
onCreateRemoteStreamView,
|
13754
13817
|
onDisposeRemoteVideoStreamView,
|
13755
13818
|
remoteVideoViewOptions,
|
13819
|
+
localParticipant,
|
13756
13820
|
onRenderAvatar,
|
13757
13821
|
showMuteIndicator,
|
13758
13822
|
strings,
|
@@ -13773,6 +13837,7 @@ const VideoGallery = (props) => {
|
|
13773
13837
|
: undefined;
|
13774
13838
|
const layoutProps = React.useMemo(() => ({
|
13775
13839
|
remoteParticipants,
|
13840
|
+
localParticipant,
|
13776
13841
|
screenShareComponent,
|
13777
13842
|
showCameraSwitcherInLocalPreview,
|
13778
13843
|
maxRemoteVideoStreams,
|
@@ -13787,6 +13852,7 @@ const VideoGallery = (props) => {
|
|
13787
13852
|
/* @conditional-compile-remove(click-to-call) */ localVideoTileSize
|
13788
13853
|
}), [
|
13789
13854
|
remoteParticipants,
|
13855
|
+
localParticipant,
|
13790
13856
|
screenShareComponent,
|
13791
13857
|
showCameraSwitcherInLocalPreview,
|
13792
13858
|
maxRemoteVideoStreams,
|
@@ -18786,7 +18852,7 @@ const CallCompositeIcon = (props) => (React__default['default'].createElement(re
|
|
18786
18852
|
*/
|
18787
18853
|
const CallWithChatCompositeIcon = (props) => (React__default['default'].createElement(react.FontIcon, Object.assign({}, props)));
|
18788
18854
|
|
18789
|
-
var call$j={cameraLabel:"Camera",noCamerasLabel:"No cameras found",cameraPermissionDenied:"Your browser is blocking access to your camera",cameraTurnedOff:"Your camera is turned off",chatButtonLabel:"Chat",close:"Close",complianceBannerNowOnlyRecording:"You are now only recording this meeting.",complianceBannerNowOnlyTranscription:"You are now only transcribing this meeting.",complianceBannerRecordingAndTranscriptionSaved:"Recording and transcription are being saved.",complianceBannerRecordingAndTranscriptionStarted:"Recording and transcription have started.",complianceBannerRecordingAndTranscriptionStopped:"Recording and transcription have stopped.",complianceBannerRecordingSaving:"Recording is being saved.",complianceBannerRecordingStarted:"Recording has started.",complianceBannerRecordingStopped:"Recording has stopped.",complianceBannerTranscriptionStarted:"Transcription has started.",complianceBannerTranscriptionConsent:"By joining, you are giving consent for this meeting to be transcribed.",complianceBannerTranscriptionSaving:"Transcription is being saved.",complianceBannerTranscriptionStopped:"Transcription has stopped.",configurationPageTitle:"Start a call",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",defaultPlaceHolder:"Select an option",dismissSidePaneButtonLabel:"Close",videoEffectsPaneTitle:"Effects",videoEffectsPaneBackgroundSelectionTitle:"Background",configurationPageVideoEffectsButtonLabel:"Effects",unableToStartVideoEffect:"Unable to apply video effect.",blurBackgroundEffectButtonLabel:"Blur",blurBackgroundTooltip:"Blur Background",removeBackgroundEffectButtonLabel:"None",removeBackgroundTooltip:"Remove Background",cameraOffBackgroundEffectWarningText:"Your camera is off. Turn on camera to see video effect.",failedToJoinCallDueToNoNetworkMoreDetails:"Call was disconnected due to a network issue. Check your connection and join again.",failedToJoinCallDueToNoNetworkTitle:"Call disconnected",failedToJoinTeamsMeetingReasonAccessDeniedMoreDetails:"You were not granted entry in the call. If this was a mistake, re-join the call.",failedToJoinTeamsMeetingReasonAccessDeniedTitle:"Dismissed from lobby",learnMore:"Learn more",leavingCallTitle:"Leaving...",leftCallMoreDetails:"If this was a mistake, re-join the call.",leftCallTitle:"You left the call",lobbyScreenConnectingToCallTitle:"Joining call",lobbyScreenWaitingToBeAdmittedTitle:"Waiting to be admitted",microphonePermissionDenied:"Your browser is blocking access to your microphone",microphoneToggleInLobbyNotAllowed:"Cannot mute or unmute while in lobby.",mutedMessage:"You're muted",networkReconnectMoreDetails:"Looks like something went wrong. We're trying to get back into the call.",networkReconnectTitle:"Hold on",deniedPermissionToRoomDetails:"You do not have permission to join this room.",deniedPermissionToRoomTitle:"Permission denied to room",peopleButtonLabel:"People",peoplePaneTitle:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",privacyPolicy:"Privacy policy",rejoinCallButtonLabel:"Re-join call",removedFromCallMoreDetails:"Another participant removed you from the call.",removedFromCallTitle:"You were removed",removeMenuLabel:"Remove",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",roomNotFoundDetails:"Room ID provided is not valid.",roomNotFoundTitle:"Room not found",soundLabel:"Sound",noMicrophonesLabel:"No microphones found",noSpeakersLabel:"No speakers found",startCallButtonLabel:"Start call",openDialpadButtonLabel:"Dial phone number",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",moreButtonCallingLabel:"More",resumeCallButtonLabel:"Resume",resumingCallButtonLabel:"Resuming...",resumeCallButtonAriaLabel:"Resume call",resumingCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number",outboundCallingNoticeString:"Calling...",participantJoinedNoticeString:"{displayName} joined",twoParticipantJoinedNoticeString:"{displayName1} and {displayName2} have joined",threeParticipantJoinedNoticeString:"{displayName1}, {displayName2} and {displayName3} have joined",participantLeftNoticeString:"{displayName} left",twoParticipantLeftNoticeString:"{displayName1} and {displayName2} have left",threeParticipantLeftNoticeString:"{displayName1}, {displayName2} and {displayName3} have left",unnamedParticipantString:"unnamed participant",manyUnnamedParticipantsJoined:"unnamed participant and {numOfParticipants} other participants joined",manyUnnamedParticipantsLeft:"unnamed participant and {numOfParticipants} other participants left",manyParticipantsJoined:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants joined",manyParticipantsLeft:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants left",liveCaptionsLabel:"Live captions",captionsSettingsLabel:"Caption settings",startCaptionsButtonOnLabel:"Turn on captions",startCaptionsButtonOffLabel:"Turn off captions",startCaptionsButtonTooltipOnContent:"Turn off captions",startCaptionsButtonTooltipOffContent:"Turn on captions",captionsSettingsModalTitle:"What language is being spoken?",captionsSettingsDropdownLabel:"Spoken language",captionsSettingsDropdownInfoText:"Language that everyone on this call is speaking.",captionsSettingsConfirmButtonLabel:"Confirm",captionsSettingsCancelButtonLabel:"Cancel",captionsSettingsModalAriaLabel:"Captions Setting Modal",captionsSettingsCloseModalButtonAriaLabel:"Close Captions Setting",captionsBannerMoreButtonCallingLabel:"More",captionsBannerMoreButtonTooltip:"More options",captionsAvailableLanguageStrings:{"ar-ae":"Arabic - U.A.E.","ar-sa":"Arabic - Saudi Arabia","da-dk":"Danish","de-de":"German - Germany","en-au":"English - Australia","en-ca":"English - Canada","en-gb":"English - United Kingdom","en-in":"English - India","en-nz":"English - New Zealand","en-us":"English - United States","es-es":"Spanish - Spain (Modern Sort)","es-mx":"Spanish - Mexico","fi-fi":"Finnish","fr-ca":"French - Canada","fr-fr":"French - France","hi-in":"Hindi","it-it":"Italian - Italy","ja-jp":"Japanese","ko-kr":"Korean","nb-no":"Norwegian (Bokmål)","nl-be":"Dutch - Belgium","nl-nl":"Dutch - Netherlands","pl-pl":"Polish","pt-br":"Portuguese - Brazil","ru-ru":"Russian","sv-se":"Swedish","zh-cn":"Chinese - People's Republic of China","zh-hk":"Chinese - Hong Kong SAR","cs-cz":"Czech","pt-pt":"Portuguese - Portugal","tr-tr":"Turkish","vi-vn":"Vietnamese","th-th":"Thai","he-il":"Hebrew","cy-gb":"Welsh","uk-ua":"Ukrainian","el-gr":"Greek","hu-hu":"Hungarian","ro-ro":"Romanian","sk-sk":"Slovak","zh-tw":"Chinese - Taiwan"},captionsBannerSpinnerText:"Starting captions...",transferPageTransferorText:"Transferring...",transferPageTransferTargetText:"Connecting...",transferPageUnknownTransferorDisplayName:"Unknown",transferPageUnknownTransferTargetDisplayName:"Unknown"};var chat$j={chatListHeader:"In this chat",uploadFile:"Upload File"};var callWithChat$j={chatButtonLabel:"Chat",chatButtonNewMessageNotificationLabel:"New Message",chatButtonTooltipClosedWithMessageCount:"Show chat ({unreadMessagesCount} unread)",chatButtonTooltipClose:"Hide chat",chatButtonTooltipOpen:"Show chat",chatPaneTitle:"Chat",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",dismissSidePaneButtonLabel:"Close",moreDrawerAudioDeviceMenuTitle:"Audio Device",moreDrawerButtonLabel:"More options",moreDrawerButtonTooltip:"More options",moreDrawerMicrophoneMenuTitle:"Microphone",moreDrawerSpeakerMenuTitle:"Speaker",moreDrawerCaptionsMenuTitle:"Live captions",moreDrawerSpokenLanguageMenuTitle:"Spoken language",peopleButtonLabel:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",peoplePaneTitle:"People",pictureInPictureTileAriaLabel:"Video Feeds. Click to return to call screen.",removeMenuLabel:"Remove",openDialpadButtonLabel:"Dial phone number",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number"};var en_US = {call:call$j,chat:chat$j,callWithChat:callWithChat$j};
|
18855
|
+
var call$j={cameraLabel:"Camera",noCamerasLabel:"No cameras found",cameraPermissionDenied:"Your browser is blocking access to your camera",cameraTurnedOff:"Your camera is turned off",chatButtonLabel:"Chat",close:"Close",complianceBannerNowOnlyRecording:"You are now only recording this meeting.",complianceBannerNowOnlyTranscription:"You are now only transcribing this meeting.",complianceBannerRecordingAndTranscriptionSaved:"Recording and transcription are being saved.",complianceBannerRecordingAndTranscriptionStarted:"Recording and transcription have started.",complianceBannerRecordingAndTranscriptionStopped:"Recording and transcription have stopped.",complianceBannerRecordingSaving:"Recording is being saved.",complianceBannerRecordingStarted:"Recording has started.",complianceBannerRecordingStopped:"Recording has stopped.",complianceBannerTranscriptionStarted:"Transcription has started.",complianceBannerTranscriptionConsent:"By joining, you are giving consent for this meeting to be transcribed.",complianceBannerTranscriptionSaving:"Transcription is being saved.",complianceBannerTranscriptionStopped:"Transcription has stopped.",configurationPageTitle:"Start a call",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",defaultPlaceHolder:"Select an option",dismissSidePaneButtonLabel:"Close",videoEffectsPaneTitle:"Effects",videoEffectsPaneBackgroundSelectionTitle:"Background",configurationPageVideoEffectsButtonLabel:"Effects",unableToStartVideoEffect:"Unable to apply video effect.",blurBackgroundEffectButtonLabel:"Blur",blurBackgroundTooltip:"Blur Background",removeBackgroundEffectButtonLabel:"None",removeBackgroundTooltip:"Remove Background",cameraOffBackgroundEffectWarningText:"Your camera is off. Turn on camera to see video effect.",failedToJoinCallDueToNoNetworkMoreDetails:"Call was disconnected due to a network issue. Check your connection and join again.",failedToJoinCallDueToNoNetworkTitle:"Call disconnected",failedToJoinTeamsMeetingReasonAccessDeniedMoreDetails:"You were not granted entry in the call. If this was a mistake, re-join the call.",failedToJoinTeamsMeetingReasonAccessDeniedTitle:"Dismissed from lobby",learnMore:"Learn more",leavingCallTitle:"Leaving...",leftCallMoreDetails:"If this was a mistake, re-join the call.",leftCallTitle:"You left the call",lobbyScreenConnectingToCallTitle:"Joining call",lobbyScreenWaitingToBeAdmittedTitle:"Waiting to be admitted",microphonePermissionDenied:"Your browser is blocking access to your microphone",microphoneToggleInLobbyNotAllowed:"Cannot mute or unmute while in lobby.",mutedMessage:"You're muted",networkReconnectMoreDetails:"Looks like something went wrong. We're trying to get back into the call.",networkReconnectTitle:"Hold on",deniedPermissionToRoomDetails:"You do not have permission to join this room.",deniedPermissionToRoomTitle:"Permission denied to room",peopleButtonLabel:"People",peoplePaneTitle:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",privacyPolicy:"Privacy policy",rejoinCallButtonLabel:"Re-join call",removedFromCallMoreDetails:"Another participant removed you from the call.",removedFromCallTitle:"You were removed",removeMenuLabel:"Remove",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",roomNotFoundDetails:"Room ID provided is not valid.",roomNotFoundTitle:"Room not found",soundLabel:"Sound",noMicrophonesLabel:"No microphones found",noSpeakersLabel:"No speakers found",startCallButtonLabel:"Start call",openDialpadButtonLabel:"Dial phone number",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",moreButtonCallingLabel:"More",resumeCallButtonLabel:"Resume",resumingCallButtonLabel:"Resuming...",resumeCallButtonAriaLabel:"Resume call",resumingCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number",outboundCallingNoticeString:"Calling...",participantJoinedNoticeString:"{displayName} joined",twoParticipantJoinedNoticeString:"{displayName1} and {displayName2} have joined",threeParticipantJoinedNoticeString:"{displayName1}, {displayName2} and {displayName3} have joined",participantLeftNoticeString:"{displayName} left",twoParticipantLeftNoticeString:"{displayName1} and {displayName2} have left",threeParticipantLeftNoticeString:"{displayName1}, {displayName2} and {displayName3} have left",unnamedParticipantString:"unnamed participant",manyUnnamedParticipantsJoined:"unnamed participant and {numOfParticipants} other participants joined",manyUnnamedParticipantsLeft:"unnamed participant and {numOfParticipants} other participants left",manyParticipantsJoined:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants joined",manyParticipantsLeft:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants left",liveCaptionsLabel:"Live captions",captionsSettingsLabel:"Caption settings",startCaptionsButtonOnLabel:"Turn on captions",startCaptionsButtonOffLabel:"Turn off captions",startCaptionsButtonTooltipOnContent:"Turn off captions",startCaptionsButtonTooltipOffContent:"Turn on captions",captionsSettingsModalTitle:"What language is being spoken?",captionsSettingsDropdownLabel:"Spoken language",captionsSettingsDropdownInfoText:"Language that everyone on this call is speaking.",captionsSettingsConfirmButtonLabel:"Confirm",captionsSettingsCancelButtonLabel:"Cancel",captionsSettingsModalAriaLabel:"Captions Setting Modal",captionsSettingsCloseModalButtonAriaLabel:"Close Captions Setting",captionsBannerMoreButtonCallingLabel:"More",captionsBannerMoreButtonTooltip:"More options",captionsAvailableLanguageStrings:{"ar-ae":"Arabic - U.A.E.","ar-sa":"Arabic - Saudi Arabia","da-dk":"Danish","de-de":"German - Germany","en-au":"English - Australia","en-ca":"English - Canada","en-gb":"English - United Kingdom","en-in":"English - India","en-nz":"English - New Zealand","en-us":"English - United States","es-es":"Spanish - Spain (Modern Sort)","es-mx":"Spanish - Mexico","fi-fi":"Finnish","fr-ca":"French - Canada","fr-fr":"French - France","hi-in":"Hindi","it-it":"Italian - Italy","ja-jp":"Japanese","ko-kr":"Korean","nb-no":"Norwegian (Bokmål)","nl-be":"Dutch - Belgium","nl-nl":"Dutch - Netherlands","pl-pl":"Polish","pt-br":"Portuguese - Brazil","ru-ru":"Russian","sv-se":"Swedish","zh-cn":"Chinese - People's Republic of China","zh-hk":"Chinese - Hong Kong SAR","cs-cz":"Czech","pt-pt":"Portuguese - Portugal","tr-tr":"Turkish","vi-vn":"Vietnamese","th-th":"Thai","he-il":"Hebrew","cy-gb":"Welsh","uk-ua":"Ukrainian","el-gr":"Greek","hu-hu":"Hungarian","ro-ro":"Romanian","sk-sk":"Slovak","zh-tw":"Chinese - Taiwan"},captionsBannerSpinnerText:"Starting captions...",transferPageTransferorText:"Transferring...",transferPageTransferTargetText:"Connecting...",transferPageUnknownTransferorDisplayName:"Unknown",transferPageUnknownTransferTargetDisplayName:"Unknown",transferPageNoticeString:"You are being transferred"};var chat$j={chatListHeader:"In this chat",uploadFile:"Upload File"};var callWithChat$j={chatButtonLabel:"Chat",chatButtonNewMessageNotificationLabel:"New Message",chatButtonTooltipClosedWithMessageCount:"Show chat ({unreadMessagesCount} unread)",chatButtonTooltipClose:"Hide chat",chatButtonTooltipOpen:"Show chat",chatPaneTitle:"Chat",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",dismissSidePaneButtonLabel:"Close",moreDrawerAudioDeviceMenuTitle:"Audio Device",moreDrawerButtonLabel:"More options",moreDrawerButtonTooltip:"More options",moreDrawerMicrophoneMenuTitle:"Microphone",moreDrawerSpeakerMenuTitle:"Speaker",moreDrawerCaptionsMenuTitle:"Live captions",moreDrawerSpokenLanguageMenuTitle:"Spoken language",peopleButtonLabel:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",peoplePaneTitle:"People",pictureInPictureTileAriaLabel:"Video Feeds. Click to return to call screen.",removeMenuLabel:"Remove",openDialpadButtonLabel:"Dial phone number",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number"};var en_US = {call:call$j,chat:chat$j,callWithChat:callWithChat$j};
|
18790
18856
|
|
18791
18857
|
var call$i={cameraLabel:"Camera",noCamerasLabel:"No cameras found",cameraPermissionDenied:"Your browser is blocking access to your camera",cameraTurnedOff:"Your camera is turned off",chatButtonLabel:"Chat",close:"Close",complianceBannerNowOnlyRecording:"You are now only recording this meeting.",complianceBannerNowOnlyTranscription:"You are now only transcribing this meeting.",complianceBannerRecordingAndTranscriptionSaved:"Recording and transcription are being saved.",complianceBannerRecordingAndTranscriptionStarted:"Recording and transcription have started.",complianceBannerRecordingAndTranscriptionStopped:"Recording and transcription have stopped.",complianceBannerRecordingSaving:"Recording is being saved.",complianceBannerRecordingStarted:"Recording has started.",complianceBannerRecordingStopped:"Recording has stopped.",complianceBannerTranscriptionStarted:"Transcription has started.",complianceBannerTranscriptionConsent:"By joining, you are giving consent for this meeting to be transcribed.",complianceBannerTranscriptionSaving:"Transcription is being saved.",complianceBannerTranscriptionStopped:"Transcription has stopped.",configurationPageTitle:"Start a call",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",defaultPlaceHolder:"Select an option",dismissSidePaneButtonLabel:"Close",videoEffectsPaneTitle:"Effects",videoEffectsPaneBackgroundSelectionTitle:"Background",configurationPageVideoEffectsButtonLabel:"Effects",unableToStartVideoEffect:"Unable to apply video effect.",blurBackgroundEffectButtonLabel:"Blur",blurBackgroundTooltip:"Blur Background",removeBackgroundEffectButtonLabel:"None",removeBackgroundTooltip:"Remove Background",cameraOffBackgroundEffectWarningText:"Your camera is off. Turn on camera to see video effect.",failedToJoinCallDueToNoNetworkMoreDetails:"Call was disconnected due to a network issue. Check your connection and join again.",failedToJoinCallDueToNoNetworkTitle:"Call disconnected",failedToJoinTeamsMeetingReasonAccessDeniedMoreDetails:"You were not granted entry in the call. If this was a mistake, re-join the call.",failedToJoinTeamsMeetingReasonAccessDeniedTitle:"Dismissed from lobby",learnMore:"Learn more",leavingCallTitle:"Leaving...",leftCallMoreDetails:"If this was a mistake, re-join the call.",leftCallTitle:"You left the call",lobbyScreenConnectingToCallTitle:"Joining call",lobbyScreenWaitingToBeAdmittedTitle:"Waiting to be admitted",microphonePermissionDenied:"Your browser is blocking access to your microphone",microphoneToggleInLobbyNotAllowed:"Cannot mute or unmute while in lobby.",mutedMessage:"You're muted",networkReconnectMoreDetails:"Looks like something went wrong. We're trying to get back into the call.",networkReconnectTitle:"Hold on",deniedPermissionToRoomDetails:"You do not have permission to join this room.",deniedPermissionToRoomTitle:"Permission denied to room",peopleButtonLabel:"People",peoplePaneTitle:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",privacyPolicy:"Privacy policy",rejoinCallButtonLabel:"Re-join call",removedFromCallMoreDetails:"Another participant removed you from the call.",removedFromCallTitle:"You were removed",removeMenuLabel:"Remove",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",roomNotFoundDetails:"Room ID provided is not valid.",roomNotFoundTitle:"Room not found",soundLabel:"Sound",noMicrophonesLabel:"No microphones found",noSpeakersLabel:"No speakers found",startCallButtonLabel:"Start call",openDialpadButtonLabel:"Dial phone number",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",moreButtonCallingLabel:"More",resumeCallButtonLabel:"Resume",resumingCallButtonLabel:"Resuming...",resumeCallButtonAriaLabel:"Resume call",resumingCallButtonAriaLabel:"Resume call",holdScreenLabel:"You're on hold",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number",outboundCallingNoticeString:"Calling...",participantJoinedNoticeString:"{displayName} joined",twoParticipantJoinedNoticeString:"{displayName1} and {displayName2} have joined",threeParticipantJoinedNoticeString:"{displayName1}, {displayName2} and {displayName3} have joined",participantLeftNoticeString:"{displayName} left",twoParticipantLeftNoticeString:"{displayName1} and {displayName2} have left",threeParticipantLeftNoticeString:"{displayName1}, {displayName2} and {displayName3} have left",unnamedParticipantString:"unnamed participant",manyUnnamedParticipantsJoined:"unnamed participant and {numOfParticipants} other participants joined",manyUnnamedParticipantsLeft:"unnamed participant and {numOfParticipants} other participants left",manyParticipantsJoined:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants joined",manyParticipantsLeft:"{displayName1}, {displayName2}, {displayName3} and {numOfParticipants} other participants left",liveCaptionsLabel:"Live captions",captionsSettingsLabel:"Caption settings",startCaptionsButtonOnLabel:"Turn on captions",startCaptionsButtonOffLabel:"Turn off captions",startCaptionsButtonTooltipOnContent:"Turn off captions",startCaptionsButtonTooltipOffContent:"Turn on captions",captionsSettingsModalTitle:"What language is being spoken?",captionsSettingsDropdownLabel:"Spoken language",captionsSettingsDropdownInfoText:"Language that everyone on this call is speaking.",captionsSettingsConfirmButtonLabel:"Confirm",captionsSettingsCancelButtonLabel:"Cancel",captionsSettingsModalAriaLabel:"Captions Setting Modal",captionsSettingsCloseModalButtonAriaLabel:"Close Captions Setting",captionsBannerMoreButtonCallingLabel:"More",captionsBannerMoreButtonTooltip:"More options",captionsAvailableLanguageStrings:{"ar-ae":"Arabic - U.A.E.","ar-sa":"Arabic - Saudi Arabia","da-dk":"Danish","de-de":"German - Germany","en-au":"English - Australia","en-ca":"English - Canada","en-gb":"English - United Kingdom","en-in":"English - India","en-nz":"English - New Zealand","en-us":"English - United States","es-es":"Spanish - Spain (Modern Sort)","es-mx":"Spanish - Mexico","fi-fi":"Finnish","fr-ca":"French - Canada","fr-fr":"French - France","hi-in":"Hindi","it-it":"Italian - Italy","ja-jp":"Japanese","ko-kr":"Korean","nb-no":"Norwegian (Bokmål)","nl-be":"Dutch - Belgium","nl-nl":"Dutch - Netherlands","pl-pl":"Polish","pt-br":"Portuguese - Brazil","ru-ru":"Russian","sv-se":"Swedish","zh-cn":"Chinese - People's Republic of China","zh-hk":"Chinese - Hong Kong SAR","cs-cz":"Czech","pt-pt":"Portuguese - Portugal","tr-tr":"Turkish","vi-vn":"Vietnamese","th-th":"Thai","he-il":"Hebrew","cy-gb":"Welsh","uk-ua":"Ukrainian","el-gr":"Greek","hu-hu":"Hungarian","ro-ro":"Romanian","sk-sk":"Slovak","zh-tw":"Chinese - Taiwan"},captionsBannerSpinnerText:"Starting captions...",transferPageTransferorText:"Transferring...",transferPageTransferTargetText:"Connecting...",transferPageUnknownTransferorDisplayName:"Unknown",transferPageUnknownTransferTargetDisplayName:"Unknown"};var chat$i={chatListHeader:"In this chat",uploadFile:"Upload File"};var callWithChat$i={chatButtonLabel:"Chat",chatButtonNewMessageNotificationLabel:"New Message",chatButtonTooltipClosedWithMessageCount:"Show chat ({unreadMessagesCount} unread)",chatButtonTooltipClose:"Hide chat",chatButtonTooltipOpen:"Show chat",chatPaneTitle:"Chat",copyInviteLinkButtonLabel:"Copy invite link",copyInviteLinkActionedAriaLabel:"Invite link copied",dismissSidePaneButtonLabel:"Close",moreDrawerAudioDeviceMenuTitle:"Audio Device",moreDrawerButtonLabel:"More options",moreDrawerButtonTooltip:"More options",moreDrawerMicrophoneMenuTitle:"Microphone",moreDrawerSpeakerMenuTitle:"Speaker",moreDrawerCaptionsMenuTitle:"Live captions",moreDrawerSpokenLanguageMenuTitle:"Spoken language",peopleButtonLabel:"People",peopleButtonTooltipOpen:"Show participants",peopleButtonTooltipClose:"Hide participants",peoplePaneSubTitle:"In this call",peoplePaneTitle:"People",pictureInPictureTileAriaLabel:"Video Feeds. Click to return to call screen.",removeMenuLabel:"Remove",openDialpadButtonLabel:"Dial phone number",returnToCallButtonAriaDescription:"Return to Call",returnToCallButtonAriaLabel:"Back",peoplePaneAddPeopleButtonLabel:"Add People",dialpadStartCallButtonLabel:"Call",dialpadModalTitle:"Dial Phone Number",dialpadModalAriaLabel:"Dialpad",dialpadCloseModalButtonAriaLabel:"Close dialpad",openDtmfDialpadLabel:"Show dialpad",dtmfDialpadPlaceholderText:"Enter number"};var en_GB = {call:call$i,chat:chat$i,callWithChat:callWithChat$i};
|
18792
18858
|
|
@@ -19252,22 +19318,6 @@ const convertObservableFileUploadToFileUploadsUiState = (fileUploads) => {
|
|
19252
19318
|
}, {});
|
19253
19319
|
};
|
19254
19320
|
|
19255
|
-
// Copyright (c) Microsoft Corporation.
|
19256
|
-
// Licensed under the MIT license.
|
19257
|
-
/**
|
19258
|
-
* Subset of CallCompositePages that represent an end call state.
|
19259
|
-
* @private
|
19260
|
-
*/
|
19261
|
-
const END_CALL_PAGES = [
|
19262
|
-
'accessDeniedTeamsMeeting',
|
19263
|
-
'joinCallFailedDueToNoNetwork',
|
19264
|
-
'leftCall',
|
19265
|
-
/* @conditional-compile-remove(rooms) */ 'deniedPermissionToRoom',
|
19266
|
-
'removedFromCall',
|
19267
|
-
/* @conditional-compile-remove(rooms) */ 'roomNotFound',
|
19268
|
-
/* @conditional-compile-remove(unsupported-browser) */ 'unsupportedEnvironment'
|
19269
|
-
];
|
19270
|
-
|
19271
19321
|
// Copyright (c) Microsoft Corporation.
|
19272
19322
|
// Licensed under the MIT license.
|
19273
19323
|
var __awaiter$i = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
@@ -19279,443 +19329,80 @@ var __awaiter$i = (window && window.__awaiter) || function (thisArg, _arguments,
|
|
19279
19329
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
19280
19330
|
});
|
19281
19331
|
};
|
19282
|
-
|
19283
|
-
|
19284
|
-
|
19285
|
-
|
19286
|
-
|
19287
|
-
|
19288
|
-
const DENIED_PERMISSION_TO_ROOM_SUB_CODE = 5828;
|
19289
|
-
/**
|
19290
|
-
* @private
|
19291
|
-
*/
|
19292
|
-
const isCameraOn = (state) => {
|
19293
|
-
if (state.call) {
|
19294
|
-
const stream = state.call.localVideoStreams.find((stream) => stream.mediaStreamType === 'Video');
|
19295
|
-
return !!stream;
|
19296
|
-
}
|
19297
|
-
else {
|
19298
|
-
if (state.devices.selectedCamera) {
|
19299
|
-
const previewOn = _isPreviewOn(state.devices);
|
19300
|
-
return previewOn;
|
19301
|
-
}
|
19302
|
-
}
|
19303
|
-
return false;
|
19332
|
+
var __asyncValues = (window && window.__asyncValues) || function (o) {
|
19333
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
19334
|
+
var m = o[Symbol.asyncIterator], i;
|
19335
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
19336
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
19337
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
19304
19338
|
};
|
19305
19339
|
/**
|
19306
|
-
*
|
19307
|
-
* For example do not show screenshare button.
|
19308
|
-
*
|
19340
|
+
* Context of Chat, which is a centralized context for all state updates
|
19309
19341
|
* @private
|
19310
19342
|
*/
|
19311
|
-
|
19312
|
-
|
19313
|
-
|
19314
|
-
|
19315
|
-
|
19316
|
-
|
19317
|
-
|
19318
|
-
|
19319
|
-
|
19320
|
-
|
19321
|
-
|
19322
|
-
|
19343
|
+
class ChatContext {
|
19344
|
+
constructor(clientState, threadId) {
|
19345
|
+
this.emitter = new EventEmitter__default['default']();
|
19346
|
+
const thread = clientState.threads[threadId];
|
19347
|
+
this.threadId = threadId;
|
19348
|
+
if (!thread) {
|
19349
|
+
throw 'Cannot find threadId, please initialize thread before use!';
|
19350
|
+
}
|
19351
|
+
this.state = {
|
19352
|
+
userId: clientState.userId,
|
19353
|
+
displayName: clientState.displayName,
|
19354
|
+
thread,
|
19355
|
+
latestErrors: clientState.latestErrors
|
19356
|
+
};
|
19323
19357
|
}
|
19324
|
-
|
19325
|
-
|
19326
|
-
var CallEndReasons;
|
19327
|
-
(function (CallEndReasons) {
|
19328
|
-
CallEndReasons[CallEndReasons["LEFT_CALL"] = 0] = "LEFT_CALL";
|
19329
|
-
CallEndReasons[CallEndReasons["ACCESS_DENIED"] = 1] = "ACCESS_DENIED";
|
19330
|
-
CallEndReasons[CallEndReasons["REMOVED_FROM_CALL"] = 2] = "REMOVED_FROM_CALL";
|
19331
|
-
CallEndReasons[CallEndReasons["ROOM_NOT_FOUND"] = 3] = "ROOM_NOT_FOUND";
|
19332
|
-
CallEndReasons[CallEndReasons["DENIED_PERMISSION_TO_ROOM"] = 4] = "DENIED_PERMISSION_TO_ROOM";
|
19333
|
-
})(CallEndReasons || (CallEndReasons = {}));
|
19334
|
-
const getCallEndReason = (call) => {
|
19335
|
-
var _a, _b, _c, _d, _e;
|
19336
|
-
const remoteParticipantsEndedArray = Array.from(Object.values(call.remoteParticipantsEnded));
|
19337
|
-
/**
|
19338
|
-
* Handle the special case in a PSTN call where removing the last user kicks the caller out of the call.
|
19339
|
-
* The code and subcode is the same as when a user is removed from a teams interop call.
|
19340
|
-
* Hence, we look at the last remote participant removed to determine if the last participant removed was a phone number.
|
19341
|
-
* If yes, the caller was kicked out of the call, but we need to show them that they left the call.
|
19342
|
-
* Note: This check will only work for 1:1 PSTN Calls. The subcode is different for 1:N PSTN calls, and we do not need to handle that case.
|
19343
|
-
*/
|
19344
|
-
if (remoteParticipantsEndedArray.length === 1 &&
|
19345
|
-
communicationCommon.isPhoneNumberIdentifier(remoteParticipantsEndedArray[0].identifier) &&
|
19346
|
-
((_a = call.callEndReason) === null || _a === void 0 ? void 0 : _a.subCode) !== REMOTE_PSTN_USER_HUNG_UP) {
|
19347
|
-
return CallEndReasons.LEFT_CALL;
|
19358
|
+
onStateChange(handler) {
|
19359
|
+
this.emitter.on('stateChanged', handler);
|
19348
19360
|
}
|
19349
|
-
|
19350
|
-
|
19361
|
+
offStateChange(handler) {
|
19362
|
+
this.emitter.off('stateChanged', handler);
|
19351
19363
|
}
|
19352
|
-
|
19353
|
-
|
19364
|
+
setState(state) {
|
19365
|
+
this.state = state;
|
19366
|
+
this.emitter.emit('stateChanged', this.state);
|
19354
19367
|
}
|
19355
|
-
|
19356
|
-
|
19357
|
-
return CallEndReasons.ROOM_NOT_FOUND;
|
19368
|
+
getState() {
|
19369
|
+
return this.state;
|
19358
19370
|
}
|
19359
|
-
|
19360
|
-
|
19361
|
-
return CallEndReasons.DENIED_PERMISSION_TO_ROOM;
|
19371
|
+
setError(error) {
|
19372
|
+
this.setState(Object.assign(Object.assign({}, this.state), { error }));
|
19362
19373
|
}
|
19363
|
-
|
19364
|
-
|
19365
|
-
|
19374
|
+
updateClientState(clientState) {
|
19375
|
+
const thread = clientState.threads[this.threadId];
|
19376
|
+
if (!thread) {
|
19377
|
+
throw 'Cannot find threadId, please make sure thread state is still in Stateful ChatClient.';
|
19378
|
+
}
|
19379
|
+
let updatedState = {
|
19380
|
+
userId: clientState.userId,
|
19381
|
+
displayName: clientState.displayName,
|
19382
|
+
thread,
|
19383
|
+
latestErrors: clientState.latestErrors
|
19384
|
+
};
|
19385
|
+
/* @conditional-compile-remove(file-sharing) */
|
19386
|
+
updatedState = Object.assign(Object.assign({}, updatedState), { fileUploads: this.state.fileUploads });
|
19387
|
+
this.setState(updatedState);
|
19366
19388
|
}
|
19367
|
-
|
19368
|
-
};
|
19389
|
+
}
|
19369
19390
|
/**
|
19370
|
-
* Get the current call composite page based on the current call composite state
|
19371
|
-
*
|
19372
|
-
* @param Call - The current call state
|
19373
|
-
* @param previousCall - The state of the most recent previous call that has ended.
|
19374
|
-
*
|
19375
|
-
* @remarks - The previousCall state is needed to determine if the call has ended.
|
19376
|
-
* When the call ends a new call object is created, and so we must lookback at the
|
19377
|
-
* previous call state to understand how the call has ended. If there is no previous
|
19378
|
-
* call we know that this is a fresh call and can display the configuration page.
|
19379
|
-
*
|
19380
19391
|
* @private
|
19381
19392
|
*/
|
19382
|
-
|
19383
|
-
|
19384
|
-
|
19385
|
-
|
19386
|
-
|
19387
|
-
|
19388
|
-
|
19389
|
-
|
19390
|
-
|
19391
|
-
|
19392
|
-
|
19393
|
-
|
19394
|
-
|
19395
|
-
// `_isInLobbyOrConnecting` needs to be checked first because `_isInCall` also returns true when call is in lobby.
|
19396
|
-
if (_isInLobbyOrConnecting(call === null || call === void 0 ? void 0 : call.state)) {
|
19397
|
-
return 'lobby';
|
19398
|
-
// `LocalHold` needs to be checked before `isInCall` since it is also a state that's considered in call.
|
19399
|
-
}
|
19400
|
-
else if ((call === null || call === void 0 ? void 0 : call.state) === 'LocalHold') {
|
19401
|
-
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
|
19402
|
-
return 'hold';
|
19403
|
-
}
|
19404
|
-
else if ((call === null || call === void 0 ? void 0 : call.state) === 'Disconnecting') {
|
19405
|
-
return 'leaving';
|
19406
|
-
}
|
19407
|
-
else if (_isInCall(call === null || call === void 0 ? void 0 : call.state)) {
|
19408
|
-
return 'call';
|
19409
|
-
}
|
19410
|
-
else {
|
19411
|
-
// When the call object has been constructed after clicking , but before 'connecting' has been
|
19412
|
-
// set on the call object, we continue to show the configuration screen.
|
19413
|
-
// The call object does not correctly reflect local device state until `call.state` moves to `connecting`.
|
19414
|
-
// Moving to the 'lobby' page too soon leads to components that depend on the `call` object to show incorrect
|
19415
|
-
// transitional state.
|
19416
|
-
return 'configuration';
|
19417
|
-
}
|
19418
|
-
}
|
19419
|
-
if (previousCall) {
|
19420
|
-
const reason = getCallEndReason(previousCall);
|
19421
|
-
/* @conditional-compile-remove(rooms) */
|
19422
|
-
switch (reason) {
|
19423
|
-
case CallEndReasons.ROOM_NOT_FOUND:
|
19424
|
-
return 'roomNotFound';
|
19425
|
-
case CallEndReasons.DENIED_PERMISSION_TO_ROOM:
|
19426
|
-
return 'deniedPermissionToRoom';
|
19427
|
-
}
|
19428
|
-
switch (reason) {
|
19429
|
-
case CallEndReasons.ACCESS_DENIED:
|
19430
|
-
return 'accessDeniedTeamsMeeting';
|
19431
|
-
case CallEndReasons.REMOVED_FROM_CALL:
|
19432
|
-
return 'removedFromCall';
|
19433
|
-
case CallEndReasons.LEFT_CALL:
|
19434
|
-
if (previousCall.diagnostics.network.latest.noNetwork) {
|
19435
|
-
return 'joinCallFailedDueToNoNetwork';
|
19436
|
-
}
|
19437
|
-
return 'leftCall';
|
19438
|
-
}
|
19439
|
-
}
|
19440
|
-
// No call state - show starting page (configuration)
|
19441
|
-
return 'configuration';
|
19442
|
-
};
|
19443
|
-
/** @private */
|
19444
|
-
const IsCallEndedPage = (
|
19445
|
-
/**
|
19446
|
-
* Explicitly listing the pages of this function intentionally.
|
19447
|
-
* This protects against adding a new composite page that should be marked as an callEndedPage.
|
19448
|
-
* EndCallPages are used to trigger onCallEnded events so this could easily be missed.
|
19449
|
-
* When you add a new composite page this will throw a compiler error. If this new page is an
|
19450
|
-
* EndCallPage ensure you update the END_CALL_PAGES. Afterwards update the `page` parameter
|
19451
|
-
* type below to allow your new page, i.e. add `| <your new page>
|
19452
|
-
*/
|
19453
|
-
page) => END_CALL_PAGES.includes(page);
|
19454
|
-
/**
|
19455
|
-
* Creates a new call control options object and sets the correct values for disabling
|
19456
|
-
* the buttons provided in the `disabledControls` array.
|
19457
|
-
* Returns a new object without changing the original object.
|
19458
|
-
* @param callControlOptions options for the call control component that need to be modified.
|
19459
|
-
* @param disabledControls An array of controls to disable.
|
19460
|
-
* @returns a copy of callControlOptions with disabledControls disabled
|
19461
|
-
* @private
|
19462
|
-
*/
|
19463
|
-
const disableCallControls = (callControlOptions, disabledControls) => {
|
19464
|
-
var _a;
|
19465
|
-
if (callControlOptions === false) {
|
19466
|
-
return false;
|
19467
|
-
}
|
19468
|
-
// Ensure we clone the prop if it is an object to ensure we do not mutate the original prop.
|
19469
|
-
let newOptions = (_a = (callControlOptions instanceof Object ? Object.assign({}, callControlOptions) : callControlOptions)) !== null && _a !== void 0 ? _a : {};
|
19470
|
-
if (newOptions === true || newOptions === undefined) {
|
19471
|
-
newOptions = disabledControls.reduce((acc, key) => {
|
19472
|
-
acc[key] = { disabled: true };
|
19473
|
-
return acc;
|
19474
|
-
}, {});
|
19475
|
-
}
|
19476
|
-
else {
|
19477
|
-
disabledControls.forEach((key) => {
|
19478
|
-
if (newOptions[key] !== false) {
|
19479
|
-
newOptions[key] = { disabled: true };
|
19480
|
-
}
|
19481
|
-
});
|
19482
|
-
}
|
19483
|
-
return newOptions;
|
19484
|
-
};
|
19485
|
-
/**
|
19486
|
-
* Check if a disabled object is provided for a button and returns if the button is disabled.
|
19487
|
-
* A button is only disabled if is explicitly set to disabled.
|
19488
|
-
*
|
19489
|
-
* @param option
|
19490
|
-
* @returns whether a button is disabled
|
19491
|
-
* @private
|
19492
|
-
*/
|
19493
|
-
const isDisabled$2 = (option) => {
|
19494
|
-
if (option === undefined || typeof option === 'boolean') {
|
19495
|
-
return false;
|
19496
|
-
}
|
19497
|
-
return option.disabled;
|
19498
|
-
};
|
19499
|
-
/* @conditional-compile-remove(call-readiness) */
|
19500
|
-
/**
|
19501
|
-
* @returns Permissions state for the camera.
|
19502
|
-
*/
|
19503
|
-
const queryCameraPermissionFromPermissionsAPI = () => __awaiter$i(void 0, void 0, void 0, function* () {
|
19504
|
-
try {
|
19505
|
-
return (yield navigator.permissions.query({ name: 'camera' })).state;
|
19506
|
-
}
|
19507
|
-
catch (e) {
|
19508
|
-
console.info('permissions API is not supported by browser', e);
|
19509
|
-
return 'unsupported';
|
19510
|
-
}
|
19511
|
-
});
|
19512
|
-
/* @conditional-compile-remove(call-readiness) */
|
19513
|
-
/**
|
19514
|
-
* @returns Permissions state for the microphone.
|
19515
|
-
*/
|
19516
|
-
const queryMicrophonePermissionFromPermissionsAPI = () => __awaiter$i(void 0, void 0, void 0, function* () {
|
19517
|
-
try {
|
19518
|
-
return (yield navigator.permissions.query({ name: 'microphone' })).state;
|
19519
|
-
}
|
19520
|
-
catch (e) {
|
19521
|
-
console.info('permissions API is not supported by browser', e);
|
19522
|
-
return 'unsupported';
|
19523
|
-
}
|
19524
|
-
});
|
19525
|
-
/* @conditional-compile-remove(call-readiness) */
|
19526
|
-
/**
|
19527
|
-
*
|
19528
|
-
* This function uses permission API to determine if device permission state is granted, prompt or denied
|
19529
|
-
* @returns whether device permission state is granted, prompt or denied
|
19530
|
-
* If permission API is not supported on this browser, permission state is set to unsupported.
|
19531
|
-
* @private
|
19532
|
-
*/
|
19533
|
-
const getDevicePermissionState = (setVideoState, setAudioState) => __awaiter$i(void 0, void 0, void 0, function* () {
|
19534
|
-
const [cameraResult, microphoneResult] = yield Promise.all([
|
19535
|
-
queryCameraPermissionFromPermissionsAPI(),
|
19536
|
-
queryMicrophonePermissionFromPermissionsAPI()
|
19537
|
-
]);
|
19538
|
-
setVideoState(cameraResult);
|
19539
|
-
setAudioState(microphoneResult);
|
19540
|
-
});
|
19541
|
-
/* @conditional-compile-remove(unsupported-browser) */
|
19542
|
-
const isUnsupportedEnvironment = (environmentInfo, unsupportedBrowserVersionOptedIn) => {
|
19543
|
-
return !!((environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.isSupportedBrowser) === false ||
|
19544
|
-
((environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.isSupportedBrowserVersion) === false && !unsupportedBrowserVersionOptedIn) ||
|
19545
|
-
(environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.isSupportedPlatform) === false);
|
19546
|
-
};
|
19547
|
-
/**
|
19548
|
-
* Check if an object is identifier.
|
19549
|
-
*
|
19550
|
-
* @param identifier
|
19551
|
-
* @returns whether an identifier is one of identifier types (for runtime validation)
|
19552
|
-
* @private
|
19553
|
-
*/
|
19554
|
-
const isValidIdentifier = (identifier) => {
|
19555
|
-
return (communicationCommon.isCommunicationUserIdentifier(identifier) ||
|
19556
|
-
communicationCommon.isPhoneNumberIdentifier(identifier) ||
|
19557
|
-
communicationCommon.isMicrosoftTeamsUserIdentifier(identifier) ||
|
19558
|
-
communicationCommon.isUnknownIdentifier(identifier));
|
19559
|
-
};
|
19560
|
-
/**
|
19561
|
-
* Check if we are using safari browser
|
19562
|
-
* @private
|
19563
|
-
*/
|
19564
|
-
const _isSafari = (environmentInfo) => {
|
19565
|
-
/* @conditional-compile-remove(unsupported-browser) */
|
19566
|
-
return (environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.environment.browser) === 'safari';
|
19567
|
-
};
|
19568
|
-
/**
|
19569
|
-
* @private
|
19570
|
-
* This is the util function to create a participant modifier for remote participantList
|
19571
|
-
* It memoize previous original participant items and only update the changed participant
|
19572
|
-
* It takes in one modifier function to generate one single participant object, it returns undefined if the object keeps unmodified
|
19573
|
-
*/
|
19574
|
-
const createParticipantModifier = (createModifiedParticipant) => {
|
19575
|
-
let previousParticipantState = undefined;
|
19576
|
-
let modifiedParticipants = {};
|
19577
|
-
const memoizedParticipants = {};
|
19578
|
-
return (state) => {
|
19579
|
-
var _a, _b, _c, _d;
|
19580
|
-
// if root state is the same, we don't need to update the participants
|
19581
|
-
if (((_a = state.call) === null || _a === void 0 ? void 0 : _a.remoteParticipants) !== previousParticipantState) {
|
19582
|
-
modifiedParticipants = {};
|
19583
|
-
const originalParticipants = (_b = state.call) === null || _b === void 0 ? void 0 : _b.remoteParticipants;
|
19584
|
-
for (const key in originalParticipants) {
|
19585
|
-
const modifiedParticipant = createModifiedParticipant(key, originalParticipants[key]);
|
19586
|
-
if (modifiedParticipant === undefined) {
|
19587
|
-
modifiedParticipants[key] = originalParticipants[key];
|
19588
|
-
continue;
|
19589
|
-
}
|
19590
|
-
// Generate the new item if original cached item has been changed
|
19591
|
-
if (((_c = memoizedParticipants[key]) === null || _c === void 0 ? void 0 : _c.originalRef) !== originalParticipants[key]) {
|
19592
|
-
memoizedParticipants[key] = {
|
19593
|
-
newParticipant: modifiedParticipant,
|
19594
|
-
originalRef: originalParticipants[key]
|
19595
|
-
};
|
19596
|
-
}
|
19597
|
-
// the modified participant is always coming from the memoized cache, whether is was refreshed
|
19598
|
-
// from the previous closure or not
|
19599
|
-
modifiedParticipants[key] = memoizedParticipants[key].newParticipant;
|
19600
|
-
}
|
19601
|
-
previousParticipantState = (_d = state.call) === null || _d === void 0 ? void 0 : _d.remoteParticipants;
|
19602
|
-
}
|
19603
|
-
return Object.assign(Object.assign({}, state), { call: state.call
|
19604
|
-
? Object.assign(Object.assign({}, state.call), { remoteParticipants: modifiedParticipants }) : undefined });
|
19605
|
-
};
|
19606
|
-
};
|
19607
|
-
/**
|
19608
|
-
* @private
|
19609
|
-
*/
|
19610
|
-
const dismissVideoEffectsError = (toDismiss) => {
|
19611
|
-
var _a;
|
19612
|
-
const now = new Date(Date.now());
|
19613
|
-
const toDismissTimestamp = (_a = toDismiss.timestamp) !== null && _a !== void 0 ? _a : now;
|
19614
|
-
// Record that this error was dismissed for the first time right now.
|
19615
|
-
return {
|
19616
|
-
dismissedAt: now > toDismissTimestamp ? now : toDismissTimestamp,
|
19617
|
-
activeSince: toDismiss.timestamp
|
19618
|
-
};
|
19619
|
-
};
|
19620
|
-
/* @conditional-compile-remove(video-background-effects) */
|
19621
|
-
/** @private */
|
19622
|
-
const getBackgroundEffectFromSelectedEffect = (selectedEffect) => (selectedEffect === null || selectedEffect === void 0 ? void 0 : selectedEffect.effectName) === 'blur'
|
19623
|
-
? new communicationCallingEffects.BackgroundBlurEffect()
|
19624
|
-
: (selectedEffect === null || selectedEffect === void 0 ? void 0 : selectedEffect.effectName) === 'replacement'
|
19625
|
-
? new communicationCallingEffects.BackgroundReplacementEffect({ backgroundImageUrl: selectedEffect.backgroundImageUrl })
|
19626
|
-
: undefined;
|
19627
|
-
/* @conditional-compile-remove(video-background-effects) */
|
19628
|
-
/**
|
19629
|
-
* @remarks this logic should mimic the onToggleCamera in the common call handlers.
|
19630
|
-
* @private
|
19631
|
-
*/
|
19632
|
-
const getSelectedCameraFromAdapterState = (state) => state.devices.selectedCamera || state.devices.cameras[0];
|
19633
|
-
|
19634
|
-
// Copyright (c) Microsoft Corporation.
|
19635
|
-
// Licensed under the MIT license.
|
19636
|
-
var __awaiter$h = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
19637
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
19638
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
19639
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
19640
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
19641
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
19642
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
19643
|
-
});
|
19644
|
-
};
|
19645
|
-
var __asyncValues = (window && window.__asyncValues) || function (o) {
|
19646
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
19647
|
-
var m = o[Symbol.asyncIterator], i;
|
19648
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
19649
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
19650
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
19651
|
-
};
|
19652
|
-
/**
|
19653
|
-
* Context of Chat, which is a centralized context for all state updates
|
19654
|
-
* @private
|
19655
|
-
*/
|
19656
|
-
class ChatContext {
|
19657
|
-
constructor(clientState, threadId) {
|
19658
|
-
this.emitter = new EventEmitter__default['default']();
|
19659
|
-
const thread = clientState.threads[threadId];
|
19660
|
-
this.threadId = threadId;
|
19661
|
-
if (!thread) {
|
19662
|
-
throw 'Cannot find threadId, please initialize thread before use!';
|
19663
|
-
}
|
19664
|
-
this.state = {
|
19665
|
-
userId: clientState.userId,
|
19666
|
-
displayName: clientState.displayName,
|
19667
|
-
thread,
|
19668
|
-
latestErrors: clientState.latestErrors
|
19669
|
-
};
|
19670
|
-
}
|
19671
|
-
onStateChange(handler) {
|
19672
|
-
this.emitter.on('stateChanged', handler);
|
19673
|
-
}
|
19674
|
-
offStateChange(handler) {
|
19675
|
-
this.emitter.off('stateChanged', handler);
|
19676
|
-
}
|
19677
|
-
setState(state) {
|
19678
|
-
this.state = state;
|
19679
|
-
this.emitter.emit('stateChanged', this.state);
|
19680
|
-
}
|
19681
|
-
getState() {
|
19682
|
-
return this.state;
|
19683
|
-
}
|
19684
|
-
setError(error) {
|
19685
|
-
this.setState(Object.assign(Object.assign({}, this.state), { error }));
|
19686
|
-
}
|
19687
|
-
updateClientState(clientState) {
|
19688
|
-
const thread = clientState.threads[this.threadId];
|
19689
|
-
if (!thread) {
|
19690
|
-
throw 'Cannot find threadId, please make sure thread state is still in Stateful ChatClient.';
|
19691
|
-
}
|
19692
|
-
let updatedState = {
|
19693
|
-
userId: clientState.userId,
|
19694
|
-
displayName: clientState.displayName,
|
19695
|
-
thread,
|
19696
|
-
latestErrors: clientState.latestErrors
|
19697
|
-
};
|
19698
|
-
/* @conditional-compile-remove(file-sharing) */
|
19699
|
-
updatedState = Object.assign(Object.assign({}, updatedState), { fileUploads: this.state.fileUploads });
|
19700
|
-
this.setState(updatedState);
|
19701
|
-
}
|
19702
|
-
}
|
19703
|
-
/**
|
19704
|
-
* @private
|
19705
|
-
*/
|
19706
|
-
class AzureCommunicationChatAdapter {
|
19707
|
-
constructor(chatClient, chatThreadClient,
|
19708
|
-
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ options) {
|
19709
|
-
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
19710
|
-
this.credential = undefined;
|
19711
|
-
this.emitter = new EventEmitter__default['default']();
|
19712
|
-
this.bindAllPublicMethods();
|
19713
|
-
this.chatClient = chatClient;
|
19714
|
-
this.chatThreadClient = chatThreadClient;
|
19715
|
-
this.context = new ChatContext(chatClient.getState(), chatThreadClient.threadId);
|
19716
|
-
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
19717
|
-
if (options && options.credential) {
|
19718
|
-
this.credential = options.credential;
|
19393
|
+
class AzureCommunicationChatAdapter {
|
19394
|
+
constructor(chatClient, chatThreadClient,
|
19395
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ options) {
|
19396
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
19397
|
+
this.credential = undefined;
|
19398
|
+
this.emitter = new EventEmitter__default['default']();
|
19399
|
+
this.bindAllPublicMethods();
|
19400
|
+
this.chatClient = chatClient;
|
19401
|
+
this.chatThreadClient = chatThreadClient;
|
19402
|
+
this.context = new ChatContext(chatClient.getState(), chatThreadClient.threadId);
|
19403
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
19404
|
+
if (options && options.credential) {
|
19405
|
+
this.credential = options.credential;
|
19719
19406
|
}
|
19720
19407
|
/* @conditional-compile-remove(file-sharing) */ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
19721
19408
|
this.fileUploadAdapter = new AzureCommunicationFileUploadAdapter(this.context);
|
@@ -19768,9 +19455,9 @@ class AzureCommunicationChatAdapter {
|
|
19768
19455
|
this.unsubscribeAllEvents();
|
19769
19456
|
}
|
19770
19457
|
fetchInitialData() {
|
19771
|
-
return __awaiter$
|
19458
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19772
19459
|
// If get properties fails we dont want to try to get the participants after.
|
19773
|
-
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19460
|
+
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19774
19461
|
var e_1, _a;
|
19775
19462
|
yield this.chatThreadClient.getProperties();
|
19776
19463
|
try {
|
@@ -19804,8 +19491,8 @@ class AzureCommunicationChatAdapter {
|
|
19804
19491
|
this.context.offStateChange(handler);
|
19805
19492
|
}
|
19806
19493
|
sendMessage(content, options = {}) {
|
19807
|
-
return __awaiter$
|
19808
|
-
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19494
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19495
|
+
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19809
19496
|
/* @conditional-compile-remove(file-sharing) */
|
19810
19497
|
options.metadata = Object.assign(Object.assign({}, options.metadata), convertFileUploadsUiStateToMessageMetadata(this.context.getState().fileUploads));
|
19811
19498
|
/* @conditional-compile-remove(file-sharing) */
|
@@ -19822,51 +19509,51 @@ class AzureCommunicationChatAdapter {
|
|
19822
19509
|
});
|
19823
19510
|
}
|
19824
19511
|
sendReadReceipt(chatMessageId) {
|
19825
|
-
return __awaiter$
|
19826
|
-
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19512
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19513
|
+
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19827
19514
|
yield this.handlers.onMessageSeen(chatMessageId);
|
19828
19515
|
}));
|
19829
19516
|
});
|
19830
19517
|
}
|
19831
19518
|
sendTypingIndicator() {
|
19832
|
-
return __awaiter$
|
19833
|
-
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19519
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19520
|
+
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19834
19521
|
yield this.handlers.onTyping();
|
19835
19522
|
}));
|
19836
19523
|
});
|
19837
19524
|
}
|
19838
19525
|
removeParticipant(userId) {
|
19839
|
-
return __awaiter$
|
19840
|
-
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19526
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19527
|
+
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19841
19528
|
yield this.handlers.onRemoveParticipant(userId);
|
19842
19529
|
}));
|
19843
19530
|
});
|
19844
19531
|
}
|
19845
19532
|
setTopic(topicName) {
|
19846
|
-
return __awaiter$
|
19847
|
-
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19533
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19534
|
+
yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19848
19535
|
yield this.handlers.updateThreadTopicName(topicName);
|
19849
19536
|
}));
|
19850
19537
|
});
|
19851
19538
|
}
|
19852
19539
|
loadPreviousChatMessages(messagesToLoad) {
|
19853
|
-
return __awaiter$
|
19854
|
-
return yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19540
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19541
|
+
return yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19855
19542
|
return yield this.handlers.onLoadPreviousChatMessages(messagesToLoad);
|
19856
19543
|
}));
|
19857
19544
|
});
|
19858
19545
|
}
|
19859
19546
|
updateMessage(messageId, content, metadata, options) {
|
19860
|
-
return __awaiter$
|
19861
|
-
return yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19547
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19548
|
+
return yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19862
19549
|
/* @conditional-compile-remove(file-sharing) */
|
19863
19550
|
return yield this.handlers.onUpdateMessage(messageId, content, metadata, options);
|
19864
19551
|
}));
|
19865
19552
|
});
|
19866
19553
|
}
|
19867
19554
|
deleteMessage(messageId) {
|
19868
|
-
return __awaiter$
|
19869
|
-
return yield this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19555
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19556
|
+
return yield this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19870
19557
|
return yield this.handlers.onDeleteMessage(messageId);
|
19871
19558
|
}));
|
19872
19559
|
});
|
@@ -19901,8 +19588,8 @@ class AzureCommunicationChatAdapter {
|
|
19901
19588
|
}
|
19902
19589
|
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
19903
19590
|
downloadAttachments(options) {
|
19904
|
-
return __awaiter$
|
19905
|
-
return this.asyncTeeErrorToEventEmitter(() => __awaiter$
|
19591
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19592
|
+
return this.asyncTeeErrorToEventEmitter(() => __awaiter$i(this, void 0, void 0, function* () {
|
19906
19593
|
if (this.credential === undefined) {
|
19907
19594
|
const e = new Error();
|
19908
19595
|
e['target'] = 'ChatThreadClient.getMessage';
|
@@ -19922,9 +19609,9 @@ class AzureCommunicationChatAdapter {
|
|
19922
19609
|
}
|
19923
19610
|
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
19924
19611
|
downloadAuthenticatedFile(accessToken, options) {
|
19925
|
-
return __awaiter$
|
19612
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19926
19613
|
function fetchWithAuthentication(url, token) {
|
19927
|
-
return __awaiter$
|
19614
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
19928
19615
|
const headers = new Headers();
|
19929
19616
|
headers.append('Authorization', `Bearer ${token}`);
|
19930
19617
|
try {
|
@@ -19996,7 +19683,7 @@ class AzureCommunicationChatAdapter {
|
|
19996
19683
|
this.emitter.off(event, listener);
|
19997
19684
|
}
|
19998
19685
|
asyncTeeErrorToEventEmitter(f) {
|
19999
|
-
return __awaiter$
|
19686
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
20000
19687
|
try {
|
20001
19688
|
return yield f();
|
20002
19689
|
}
|
@@ -20038,8 +19725,8 @@ const convertEventType = (type) => {
|
|
20038
19725
|
*
|
20039
19726
|
* @public
|
20040
19727
|
*/
|
20041
|
-
const createAzureCommunicationChatAdapter = ({ endpoint: endpointUrl, userId, displayName, credential, threadId }) => __awaiter$
|
20042
|
-
if (!
|
19728
|
+
const createAzureCommunicationChatAdapter = ({ endpoint: endpointUrl, userId, displayName, credential, threadId }) => __awaiter$i(void 0, void 0, void 0, function* () {
|
19729
|
+
if (!_isValidIdentifier(userId)) {
|
20043
19730
|
throw new Error('Provided userId is invalid. Please provide valid identifier object.');
|
20044
19731
|
}
|
20045
19732
|
const chatClient = createStatefulChatClient({
|
@@ -20107,7 +19794,7 @@ beforeDispose) => {
|
|
20107
19794
|
if (!credential || !displayName || !endpoint || !threadId || !userId) {
|
20108
19795
|
return;
|
20109
19796
|
}
|
20110
|
-
(() => __awaiter$
|
19797
|
+
(() => __awaiter$i(void 0, void 0, void 0, function* () {
|
20111
19798
|
if (adapterRef.current) {
|
20112
19799
|
// Dispose the old adapter when a new one is created.
|
20113
19800
|
//
|
@@ -20139,7 +19826,7 @@ beforeDispose) => {
|
|
20139
19826
|
// Dispose any existing adapter when the component unmounts.
|
20140
19827
|
React.useEffect(() => {
|
20141
19828
|
return () => {
|
20142
|
-
(() => __awaiter$
|
19829
|
+
(() => __awaiter$i(void 0, void 0, void 0, function* () {
|
20143
19830
|
if (adapterRef.current) {
|
20144
19831
|
if (beforeDisposeRef.current) {
|
20145
19832
|
yield beforeDisposeRef.current(adapterRef.current);
|
@@ -20163,7 +19850,7 @@ beforeDispose) => {
|
|
20163
19850
|
function createAzureCommunicationChatAdapterFromClient(chatClient, chatThreadClient,
|
20164
19851
|
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
20165
19852
|
options) {
|
20166
|
-
return __awaiter$
|
19853
|
+
return __awaiter$i(this, void 0, void 0, function* () {
|
20167
19854
|
return new AzureCommunicationChatAdapter(chatClient, chatThreadClient,
|
20168
19855
|
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ options);
|
20169
19856
|
});
|
@@ -20376,7 +20063,7 @@ const sendboxContainerStyles = {
|
|
20376
20063
|
|
20377
20064
|
// Copyright (c) Microsoft Corporation.
|
20378
20065
|
// Licensed under the MIT license.
|
20379
|
-
var __awaiter$
|
20066
|
+
var __awaiter$h = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
20380
20067
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
20381
20068
|
return new (P || (P = Promise))(function (resolve, reject) {
|
20382
20069
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
@@ -20397,7 +20084,7 @@ const AvatarPersona = (props) => {
|
|
20397
20084
|
const { userId, dataProvider, text, imageUrl, imageInitials, initialsColor, initialsTextColor, showOverflowTooltip } = props;
|
20398
20085
|
const [data, setData] = React.useState();
|
20399
20086
|
React.useEffect(() => {
|
20400
|
-
(() => __awaiter$
|
20087
|
+
(() => __awaiter$h(void 0, void 0, void 0, function* () {
|
20401
20088
|
if (dataProvider && userId) {
|
20402
20089
|
const newData = yield dataProvider(userId);
|
20403
20090
|
if (avatarDeepDifferenceCheck(data, newData)) {
|
@@ -20764,6 +20451,253 @@ const FileDownloadErrorBar = (props) => {
|
|
20764
20451
|
}
|
20765
20452
|
};
|
20766
20453
|
|
20454
|
+
// Copyright (c) Microsoft Corporation.
|
20455
|
+
// Licensed under the MIT license.
|
20456
|
+
var __awaiter$g = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
20457
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
20458
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
20459
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
20460
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
20461
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
20462
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
20463
|
+
});
|
20464
|
+
};
|
20465
|
+
/**
|
20466
|
+
* @private
|
20467
|
+
*/
|
20468
|
+
const ChatScreen = (props) => {
|
20469
|
+
const { onFetchAvatarPersonaData, onRenderMessage, onRenderTypingIndicator, options, styles, fileSharing, formFactor } = props;
|
20470
|
+
const defaultNumberOfChatMessagesToReload = 5;
|
20471
|
+
/* @conditional-compile-remove(file-sharing) */
|
20472
|
+
const [downloadErrorMessage, setDownloadErrorMessage] = React__default['default'].useState('');
|
20473
|
+
const adapter = useAdapter$1();
|
20474
|
+
const theme = useTheme();
|
20475
|
+
React.useEffect(() => {
|
20476
|
+
// Initial data should be always fetched by the composite(or external caller) instead of the adapter
|
20477
|
+
const fetchData = () => __awaiter$g(void 0, void 0, void 0, function* () {
|
20478
|
+
// Fetch initial data for adapter
|
20479
|
+
yield adapter.fetchInitialData();
|
20480
|
+
// Fetch initial set of messages. Without fetching messages here, if the Composite's adapter is changed the message thread does not load new messages.
|
20481
|
+
yield adapter.loadPreviousChatMessages(defaultNumberOfChatMessagesToReload);
|
20482
|
+
});
|
20483
|
+
fetchData();
|
20484
|
+
}, [adapter]);
|
20485
|
+
const messageThreadProps = usePropsFor$2(MessageThread);
|
20486
|
+
const sendBoxProps = usePropsFor$2(SendBox);
|
20487
|
+
const typingIndicatorProps = usePropsFor$2(TypingIndicator);
|
20488
|
+
const headerProps = useAdaptedSelector$1(getHeaderProps);
|
20489
|
+
const errorBarProps = usePropsFor$2(ErrorBar);
|
20490
|
+
const onRenderAvatarCallback = React.useCallback((userId, defaultOptions) => {
|
20491
|
+
return (React__default['default'].createElement(AvatarPersona, Object.assign({ userId: userId, hidePersonaDetails: true }, defaultOptions, { dataProvider: onFetchAvatarPersonaData })));
|
20492
|
+
}, [onFetchAvatarPersonaData]);
|
20493
|
+
const messageThreadStyles = Object.assign({}, messageThreadChatCompositeStyles(theme.semanticColors.bodyBackground), styles === null || styles === void 0 ? void 0 : styles.messageThread);
|
20494
|
+
const typingIndicatorStyles = Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.typingIndicator);
|
20495
|
+
const sendBoxStyles = Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.sendBox);
|
20496
|
+
const userId = toFlatCommunicationIdentifier(adapter.getState().userId);
|
20497
|
+
const fileUploadButtonOnChange = React.useCallback((files) => {
|
20498
|
+
if (!files) {
|
20499
|
+
return;
|
20500
|
+
}
|
20501
|
+
/* @conditional-compile-remove(file-sharing) */
|
20502
|
+
const fileUploads = adapter.registerActiveFileUploads(Array.from(files));
|
20503
|
+
/* @conditional-compile-remove(file-sharing) */
|
20504
|
+
fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.uploadHandler(userId, fileUploads);
|
20505
|
+
}, [adapter, fileSharing, userId]);
|
20506
|
+
/* @conditional-compile-remove(file-sharing) */
|
20507
|
+
const onRenderFileDownloads = React.useCallback((userId, message) => (React__default['default'].createElement(_FileDownloadCards, { userId: userId, fileMetadata: message.attachedFilesMetadata || [], downloadHandler: fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.downloadHandler, onDownloadErrorMessage: (errorMessage) => {
|
20508
|
+
setDownloadErrorMessage(errorMessage);
|
20509
|
+
} })), [fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.downloadHandler]);
|
20510
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
20511
|
+
const onRenderInlineAttachment = React.useCallback((attachment) => __awaiter$g(void 0, void 0, void 0, function* () {
|
20512
|
+
if (attachment.previewUrl) {
|
20513
|
+
const blob = yield adapter.downloadAttachments({ attachmentUrls: [attachment.previewUrl] });
|
20514
|
+
return blob;
|
20515
|
+
}
|
20516
|
+
return [{ blobUrl: '' }];
|
20517
|
+
}), [adapter]);
|
20518
|
+
const AttachFileButton = React.useCallback(() => {
|
20519
|
+
if (!(fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.uploadHandler)) {
|
20520
|
+
return null;
|
20521
|
+
}
|
20522
|
+
return (React__default['default'].createElement(FileUploadButtonWrapper, { accept: fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.accept, multiple: fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.multiple, onChange: fileUploadButtonOnChange }));
|
20523
|
+
}, [fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.accept, fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.multiple, fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.uploadHandler, fileUploadButtonOnChange]);
|
20524
|
+
return (React__default['default'].createElement(react.Stack, { className: chatContainer, grow: true },
|
20525
|
+
(options === null || options === void 0 ? void 0 : options.topic) !== false && React__default['default'].createElement(ChatHeader, Object.assign({}, headerProps)),
|
20526
|
+
React__default['default'].createElement(react.Stack, { className: chatArea, tokens: participantListContainerPadding, horizontal: true, grow: true },
|
20527
|
+
React__default['default'].createElement(react.Stack, { className: chatWrapper, grow: true },
|
20528
|
+
(options === null || options === void 0 ? void 0 : options.errorBar) !== false && React__default['default'].createElement(ErrorBar, Object.assign({}, errorBarProps)),
|
20529
|
+
/* @conditional-compile-remove(file-sharing) */
|
20530
|
+
React__default['default'].createElement(FileDownloadErrorBar, { onDismissDownloadErrorMessage: React.useCallback(() => {
|
20531
|
+
setDownloadErrorMessage('');
|
20532
|
+
}, []), fileDownloadErrorMessage: downloadErrorMessage || '' }),
|
20533
|
+
React__default['default'].createElement(MessageThread, Object.assign({}, messageThreadProps, { onRenderAvatar: onRenderAvatarCallback, onRenderMessage: onRenderMessage,
|
20534
|
+
/* @conditional-compile-remove(file-sharing) */
|
20535
|
+
onRenderFileDownloads: onRenderFileDownloads,
|
20536
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
20537
|
+
onFetchAttachments: onRenderInlineAttachment, numberOfChatMessagesToReload: defaultNumberOfChatMessagesToReload, styles: messageThreadStyles })),
|
20538
|
+
React__default['default'].createElement(react.Stack, { className: react.mergeStyles(sendboxContainerStyles) },
|
20539
|
+
React__default['default'].createElement("div", { className: react.mergeStyles(typingIndicatorContainerStyles) }, onRenderTypingIndicator ? (onRenderTypingIndicator(typingIndicatorProps.typingUsers)) : (React__default['default'].createElement(TypingIndicator, Object.assign({}, typingIndicatorProps, { styles: typingIndicatorStyles })))),
|
20540
|
+
React__default['default'].createElement(react.Stack, { horizontal: formFactor === 'mobile' },
|
20541
|
+
formFactor === 'mobile' && (React__default['default'].createElement(react.Stack, { verticalAlign: "center" },
|
20542
|
+
React__default['default'].createElement(AttachFileButton, null))),
|
20543
|
+
React__default['default'].createElement(react.Stack, { grow: true },
|
20544
|
+
React__default['default'].createElement(SendBox, Object.assign({}, sendBoxProps, { autoFocus: options === null || options === void 0 ? void 0 : options.autoFocus, styles: sendBoxStyles,
|
20545
|
+
/* @conditional-compile-remove(file-sharing) */
|
20546
|
+
activeFileUploads: useSelector$2(fileUploadsSelector).files,
|
20547
|
+
/* @conditional-compile-remove(file-sharing) */
|
20548
|
+
onCancelFileUpload: adapter.cancelFileUpload }))),
|
20549
|
+
formFactor !== 'mobile' && React__default['default'].createElement(AttachFileButton, null)))),
|
20550
|
+
/* @conditional-compile-remove(chat-composite-participant-pane) */
|
20551
|
+
(options === null || options === void 0 ? void 0 : options.participantPane) === true && (React__default['default'].createElement(ChatScreenPeoplePane, { onFetchAvatarPersonaData: onFetchAvatarPersonaData, onFetchParticipantMenuItems: props.onFetchParticipantMenuItems, isMobile: formFactor === 'mobile' })))));
|
20552
|
+
};
|
20553
|
+
|
20554
|
+
// Copyright (c) Microsoft Corporation.
|
20555
|
+
/**
|
20556
|
+
* A customizable UI composite for the chat experience.
|
20557
|
+
*
|
20558
|
+
* @remarks Chat composite min width and height are respectively 17.5rem and 20rem (280px and 320px, with default rem at 16px)
|
20559
|
+
*
|
20560
|
+
* @public
|
20561
|
+
*/
|
20562
|
+
const ChatComposite = (props) => {
|
20563
|
+
const { adapter, options, onFetchAvatarPersonaData, onRenderTypingIndicator, onRenderMessage, onFetchParticipantMenuItems } = props;
|
20564
|
+
const formFactor = props['formFactor'] || 'desktop';
|
20565
|
+
/**
|
20566
|
+
* @TODO Remove this function and pass the props directly when file-sharing is promoted to stable.
|
20567
|
+
* @private
|
20568
|
+
*/
|
20569
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
20570
|
+
const fileSharingOptions = () => {
|
20571
|
+
/* @conditional-compile-remove(file-sharing) */
|
20572
|
+
return {
|
20573
|
+
fileSharing: options === null || options === void 0 ? void 0 : options.fileSharing
|
20574
|
+
};
|
20575
|
+
};
|
20576
|
+
return (React__default['default'].createElement("div", { className: chatScreenContainerStyle },
|
20577
|
+
React__default['default'].createElement(BaseProvider, Object.assign({}, props),
|
20578
|
+
React__default['default'].createElement(ChatAdapterProvider, { adapter: adapter },
|
20579
|
+
React__default['default'].createElement(ChatScreen, Object.assign({ formFactor: formFactor, options: options, onFetchAvatarPersonaData: onFetchAvatarPersonaData, onRenderTypingIndicator: onRenderTypingIndicator, onRenderMessage: onRenderMessage, onFetchParticipantMenuItems: onFetchParticipantMenuItems }, fileSharingOptions()))))));
|
20580
|
+
};
|
20581
|
+
|
20582
|
+
// Copyright (c) Microsoft Corporation.
|
20583
|
+
const CallAdapterContext = React.createContext(undefined);
|
20584
|
+
/**
|
20585
|
+
* @private
|
20586
|
+
*/
|
20587
|
+
const CallAdapterProvider = (props) => {
|
20588
|
+
const { adapter } = props;
|
20589
|
+
return React__default['default'].createElement(CallAdapterContext.Provider, { value: adapter }, props.children);
|
20590
|
+
};
|
20591
|
+
/**
|
20592
|
+
* @private
|
20593
|
+
*/
|
20594
|
+
const useAdapter = () => {
|
20595
|
+
const adapter = React.useContext(CallAdapterContext);
|
20596
|
+
if (!adapter) {
|
20597
|
+
throw 'Cannot find adapter please initialize before usage.';
|
20598
|
+
}
|
20599
|
+
return adapter;
|
20600
|
+
};
|
20601
|
+
|
20602
|
+
// Copyright (c) Microsoft Corporation.
|
20603
|
+
/**
|
20604
|
+
* @private
|
20605
|
+
*/
|
20606
|
+
const useAdaptedSelector = (selector, selectorProps) => {
|
20607
|
+
return useSelectorWithAdaptation(selector, adaptCompositeState, selectorProps);
|
20608
|
+
};
|
20609
|
+
/**
|
20610
|
+
* @private
|
20611
|
+
*/
|
20612
|
+
const useSelectorWithAdaptation = (selector, adaptState, selectorProps) => {
|
20613
|
+
var _a;
|
20614
|
+
const adapter = useAdapter();
|
20615
|
+
// Keeps track of whether the current component is mounted or not. If it has unmounted, make sure we do not modify the
|
20616
|
+
// state or it will cause React warnings in the console. https://skype.visualstudio.com/SPOOL/_workitems/edit/2453212
|
20617
|
+
const mounted = React.useRef(false);
|
20618
|
+
React.useEffect(() => {
|
20619
|
+
mounted.current = true;
|
20620
|
+
return () => {
|
20621
|
+
mounted.current = false;
|
20622
|
+
};
|
20623
|
+
});
|
20624
|
+
const callId = (_a = adapter.getState().call) === null || _a === void 0 ? void 0 : _a.id;
|
20625
|
+
const callConfigProps = React.useMemo(() => ({
|
20626
|
+
callId
|
20627
|
+
}), [callId]);
|
20628
|
+
const [props, setProps] = React.useState(selector(adaptState(adapter.getState()), selectorProps !== null && selectorProps !== void 0 ? selectorProps : callConfigProps));
|
20629
|
+
const propRef = React.useRef(props);
|
20630
|
+
propRef.current = props;
|
20631
|
+
React.useEffect(() => {
|
20632
|
+
const onStateChange = (state) => {
|
20633
|
+
if (!mounted.current) {
|
20634
|
+
return;
|
20635
|
+
}
|
20636
|
+
const newProps = selector(adaptState(state), selectorProps !== null && selectorProps !== void 0 ? selectorProps : callConfigProps);
|
20637
|
+
if (propRef.current !== newProps) {
|
20638
|
+
setProps(newProps);
|
20639
|
+
}
|
20640
|
+
};
|
20641
|
+
adapter.onStateChange(onStateChange);
|
20642
|
+
return () => {
|
20643
|
+
adapter.offStateChange(onStateChange);
|
20644
|
+
};
|
20645
|
+
}, [adaptState, adapter, selector, selectorProps, callConfigProps]);
|
20646
|
+
return props;
|
20647
|
+
};
|
20648
|
+
const memoizeState = memoizeOne__default['default']((userId, deviceManager, calls, latestErrors, displayName, alternateCallerId, environmentInfo) => ({
|
20649
|
+
userId,
|
20650
|
+
incomingCalls: {},
|
20651
|
+
incomingCallsEnded: {},
|
20652
|
+
callsEnded: {},
|
20653
|
+
deviceManager,
|
20654
|
+
callAgent: { displayName },
|
20655
|
+
calls,
|
20656
|
+
latestErrors,
|
20657
|
+
/* @conditional-compile-remove(PSTN-calls) */
|
20658
|
+
alternateCallerId,
|
20659
|
+
/* @conditional-compile-remove(unsupported-browser) */
|
20660
|
+
environmentInfo
|
20661
|
+
}));
|
20662
|
+
const memoizeCalls = memoizeOne__default['default']((call) => (call ? { [call.id]: call } : {}));
|
20663
|
+
const adaptCompositeState = (compositeState) => {
|
20664
|
+
return memoizeState(compositeState.userId, compositeState.devices, memoizeCalls(compositeState.call),
|
20665
|
+
// This is an unsafe type expansion.
|
20666
|
+
// compositeState.latestErrors can contain properties that are not valid in CallErrors.
|
20667
|
+
//
|
20668
|
+
// But there is no way to check for valid property names at runtime:
|
20669
|
+
// - The set of valid property names is built from types in the @azure/communication-calling.
|
20670
|
+
// Thus we don't have a literal array of allowed strings at runtime.
|
20671
|
+
// - Due to minification / uglification, the property names from the objects at runtime can't be used
|
20672
|
+
// to compare against permissible values inferred from the types.
|
20673
|
+
//
|
20674
|
+
// This is not a huge problem -- it simply means that our adapted selector will include some extra operations
|
20675
|
+
// that are unknown to the UI component and data binding libraries. Generic handling of the errors (e.g.,
|
20676
|
+
// just displaying them in some UI surface) will continue to work for these operations. Handling of
|
20677
|
+
// specific operations (e.g., acting on errors related to permission issues) will ignore these operations.
|
20678
|
+
compositeState.latestErrors, compositeState.displayName,
|
20679
|
+
/* @conditional-compile-remove(PSTN-calls) */
|
20680
|
+
compositeState.alternateCallerId,
|
20681
|
+
/* @conditional-compile-remove(unsupported-browser) */
|
20682
|
+
compositeState.environmentInfo);
|
20683
|
+
};
|
20684
|
+
|
20685
|
+
// Copyright (c) Microsoft Corporation.
|
20686
|
+
// Licensed under the MIT license.
|
20687
|
+
/**
|
20688
|
+
* Subset of CallCompositePages that represent an end call state.
|
20689
|
+
* @private
|
20690
|
+
*/
|
20691
|
+
const END_CALL_PAGES = [
|
20692
|
+
'accessDeniedTeamsMeeting',
|
20693
|
+
'joinCallFailedDueToNoNetwork',
|
20694
|
+
'leftCall',
|
20695
|
+
/* @conditional-compile-remove(rooms) */ 'deniedPermissionToRoom',
|
20696
|
+
'removedFromCall',
|
20697
|
+
/* @conditional-compile-remove(rooms) */ 'roomNotFound',
|
20698
|
+
/* @conditional-compile-remove(unsupported-browser) */ 'unsupportedEnvironment'
|
20699
|
+
];
|
20700
|
+
|
20767
20701
|
// Copyright (c) Microsoft Corporation.
|
20768
20702
|
// Licensed under the MIT license.
|
20769
20703
|
var __awaiter$f = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
@@ -20775,225 +20709,344 @@ var __awaiter$f = (window && window.__awaiter) || function (thisArg, _arguments,
|
|
20775
20709
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
20776
20710
|
});
|
20777
20711
|
};
|
20712
|
+
const ACCESS_DENIED_TEAMS_MEETING_SUB_CODE = 5854;
|
20713
|
+
const REMOTE_PSTN_USER_HUNG_UP = 560000;
|
20714
|
+
const REMOVED_FROM_CALL_SUB_CODES = [5000, 5300, REMOTE_PSTN_USER_HUNG_UP];
|
20715
|
+
/* @conditional-compile-remove(rooms) */
|
20716
|
+
const ROOM_NOT_FOUND_SUB_CODE = 5751;
|
20717
|
+
/* @conditional-compile-remove(rooms) */
|
20718
|
+
const DENIED_PERMISSION_TO_ROOM_SUB_CODE = 5828;
|
20778
20719
|
/**
|
20779
20720
|
* @private
|
20780
20721
|
*/
|
20781
|
-
const
|
20782
|
-
|
20783
|
-
|
20784
|
-
|
20785
|
-
|
20786
|
-
|
20787
|
-
|
20788
|
-
|
20789
|
-
|
20790
|
-
const fetchData = () => __awaiter$f(void 0, void 0, void 0, function* () {
|
20791
|
-
// Fetch initial data for adapter
|
20792
|
-
yield adapter.fetchInitialData();
|
20793
|
-
// Fetch initial set of messages. Without fetching messages here, if the Composite's adapter is changed the message thread does not load new messages.
|
20794
|
-
yield adapter.loadPreviousChatMessages(defaultNumberOfChatMessagesToReload);
|
20795
|
-
});
|
20796
|
-
fetchData();
|
20797
|
-
}, [adapter]);
|
20798
|
-
const messageThreadProps = usePropsFor$2(MessageThread);
|
20799
|
-
const sendBoxProps = usePropsFor$2(SendBox);
|
20800
|
-
const typingIndicatorProps = usePropsFor$2(TypingIndicator);
|
20801
|
-
const headerProps = useAdaptedSelector$1(getHeaderProps);
|
20802
|
-
const errorBarProps = usePropsFor$2(ErrorBar);
|
20803
|
-
const onRenderAvatarCallback = React.useCallback((userId, defaultOptions) => {
|
20804
|
-
return (React__default['default'].createElement(AvatarPersona, Object.assign({ userId: userId, hidePersonaDetails: true }, defaultOptions, { dataProvider: onFetchAvatarPersonaData })));
|
20805
|
-
}, [onFetchAvatarPersonaData]);
|
20806
|
-
const messageThreadStyles = Object.assign({}, messageThreadChatCompositeStyles(theme.semanticColors.bodyBackground), styles === null || styles === void 0 ? void 0 : styles.messageThread);
|
20807
|
-
const typingIndicatorStyles = Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.typingIndicator);
|
20808
|
-
const sendBoxStyles = Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.sendBox);
|
20809
|
-
const userId = toFlatCommunicationIdentifier(adapter.getState().userId);
|
20810
|
-
const fileUploadButtonOnChange = React.useCallback((files) => {
|
20811
|
-
if (!files) {
|
20812
|
-
return;
|
20722
|
+
const isCameraOn = (state) => {
|
20723
|
+
if (state.call) {
|
20724
|
+
const stream = state.call.localVideoStreams.find((stream) => stream.mediaStreamType === 'Video');
|
20725
|
+
return !!stream;
|
20726
|
+
}
|
20727
|
+
else {
|
20728
|
+
if (state.devices.selectedCamera) {
|
20729
|
+
const previewOn = _isPreviewOn(state.devices);
|
20730
|
+
return previewOn;
|
20813
20731
|
}
|
20814
|
-
|
20815
|
-
|
20816
|
-
|
20817
|
-
|
20818
|
-
|
20819
|
-
|
20820
|
-
|
20821
|
-
|
20822
|
-
|
20823
|
-
|
20824
|
-
|
20825
|
-
|
20826
|
-
|
20827
|
-
|
20732
|
+
}
|
20733
|
+
return false;
|
20734
|
+
};
|
20735
|
+
/**
|
20736
|
+
* Reduce the set of call controls visible on mobile.
|
20737
|
+
* For example do not show screenshare button.
|
20738
|
+
*
|
20739
|
+
* @private
|
20740
|
+
*/
|
20741
|
+
const reduceCallControlsForMobile = (callControlOptions) => {
|
20742
|
+
if (callControlOptions === false) {
|
20743
|
+
return false;
|
20744
|
+
}
|
20745
|
+
// Ensure call controls a valid object.
|
20746
|
+
const reduceCallControlOptions = callControlOptions === true ? {} : callControlOptions || {};
|
20747
|
+
// Set to compressed mode when composite is optimized for mobile
|
20748
|
+
reduceCallControlOptions.displayType = 'compact';
|
20749
|
+
// Do not show screen share button when composite is optimized for mobile unless the developer
|
20750
|
+
// has explicitly opted in.
|
20751
|
+
if (reduceCallControlOptions.screenShareButton !== true) {
|
20752
|
+
reduceCallControlOptions.screenShareButton = false;
|
20753
|
+
}
|
20754
|
+
return reduceCallControlOptions;
|
20755
|
+
};
|
20756
|
+
var CallEndReasons;
|
20757
|
+
(function (CallEndReasons) {
|
20758
|
+
CallEndReasons[CallEndReasons["LEFT_CALL"] = 0] = "LEFT_CALL";
|
20759
|
+
CallEndReasons[CallEndReasons["ACCESS_DENIED"] = 1] = "ACCESS_DENIED";
|
20760
|
+
CallEndReasons[CallEndReasons["REMOVED_FROM_CALL"] = 2] = "REMOVED_FROM_CALL";
|
20761
|
+
CallEndReasons[CallEndReasons["ROOM_NOT_FOUND"] = 3] = "ROOM_NOT_FOUND";
|
20762
|
+
CallEndReasons[CallEndReasons["DENIED_PERMISSION_TO_ROOM"] = 4] = "DENIED_PERMISSION_TO_ROOM";
|
20763
|
+
})(CallEndReasons || (CallEndReasons = {}));
|
20764
|
+
const getCallEndReason = (call) => {
|
20765
|
+
var _a, _b, _c, _d, _e;
|
20766
|
+
const remoteParticipantsEndedArray = Array.from(Object.values(call.remoteParticipantsEnded));
|
20767
|
+
/**
|
20768
|
+
* Handle the special case in a PSTN call where removing the last user kicks the caller out of the call.
|
20769
|
+
* The code and subcode is the same as when a user is removed from a teams interop call.
|
20770
|
+
* Hence, we look at the last remote participant removed to determine if the last participant removed was a phone number.
|
20771
|
+
* If yes, the caller was kicked out of the call, but we need to show them that they left the call.
|
20772
|
+
* Note: This check will only work for 1:1 PSTN Calls. The subcode is different for 1:N PSTN calls, and we do not need to handle that case.
|
20773
|
+
*/
|
20774
|
+
if (remoteParticipantsEndedArray.length === 1 &&
|
20775
|
+
communicationCommon.isPhoneNumberIdentifier(remoteParticipantsEndedArray[0].identifier) &&
|
20776
|
+
((_a = call.callEndReason) === null || _a === void 0 ? void 0 : _a.subCode) !== REMOTE_PSTN_USER_HUNG_UP) {
|
20777
|
+
return CallEndReasons.LEFT_CALL;
|
20778
|
+
}
|
20779
|
+
if (((_b = call.callEndReason) === null || _b === void 0 ? void 0 : _b.subCode) && call.callEndReason.subCode === ACCESS_DENIED_TEAMS_MEETING_SUB_CODE) {
|
20780
|
+
return CallEndReasons.ACCESS_DENIED;
|
20781
|
+
}
|
20782
|
+
if (((_c = call.callEndReason) === null || _c === void 0 ? void 0 : _c.subCode) && REMOVED_FROM_CALL_SUB_CODES.includes(call.callEndReason.subCode)) {
|
20783
|
+
return CallEndReasons.REMOVED_FROM_CALL;
|
20784
|
+
}
|
20785
|
+
/* @conditional-compile-remove(rooms) */
|
20786
|
+
if (((_d = call.callEndReason) === null || _d === void 0 ? void 0 : _d.subCode) && call.callEndReason.subCode === ROOM_NOT_FOUND_SUB_CODE) {
|
20787
|
+
return CallEndReasons.ROOM_NOT_FOUND;
|
20788
|
+
}
|
20789
|
+
/* @conditional-compile-remove(rooms) */
|
20790
|
+
if (((_e = call.callEndReason) === null || _e === void 0 ? void 0 : _e.subCode) && call.callEndReason.subCode === DENIED_PERMISSION_TO_ROOM_SUB_CODE) {
|
20791
|
+
return CallEndReasons.DENIED_PERMISSION_TO_ROOM;
|
20792
|
+
}
|
20793
|
+
if (call.callEndReason) {
|
20794
|
+
// No error codes match, assume the user simply left the call regularly
|
20795
|
+
return CallEndReasons.LEFT_CALL;
|
20796
|
+
}
|
20797
|
+
throw new Error('No matching call end reason');
|
20798
|
+
};
|
20799
|
+
/**
|
20800
|
+
* Get the current call composite page based on the current call composite state
|
20801
|
+
*
|
20802
|
+
* @param Call - The current call state
|
20803
|
+
* @param previousCall - The state of the most recent previous call that has ended.
|
20804
|
+
*
|
20805
|
+
* @remarks - The previousCall state is needed to determine if the call has ended.
|
20806
|
+
* When the call ends a new call object is created, and so we must lookback at the
|
20807
|
+
* previous call state to understand how the call has ended. If there is no previous
|
20808
|
+
* call we know that this is a fresh call and can display the configuration page.
|
20809
|
+
*
|
20810
|
+
* @private
|
20811
|
+
*/
|
20812
|
+
const getCallCompositePage = (call, previousCall, unsupportedBrowserInfo, transferCall) => {
|
20813
|
+
/* @conditional-compile-remove(unsupported-browser) */
|
20814
|
+
if (isUnsupportedEnvironment(unsupportedBrowserInfo.environmentInfo, unsupportedBrowserInfo.unsupportedBrowserVersionOptedIn)) {
|
20815
|
+
return 'unsupportedEnvironment';
|
20816
|
+
}
|
20817
|
+
/* @conditional-compile-remove(call-transfer) */
|
20818
|
+
if (transferCall !== undefined) {
|
20819
|
+
return 'transferring';
|
20820
|
+
}
|
20821
|
+
if (call) {
|
20822
|
+
// Must check for ongoing call *before* looking at any previous calls.
|
20823
|
+
// If the composite completes one call and joins another, the previous calls
|
20824
|
+
// will be populated, but not relevant for determining the page.
|
20825
|
+
// `_isInLobbyOrConnecting` needs to be checked first because `_isInCall` also returns true when call is in lobby.
|
20826
|
+
if (_isInLobbyOrConnecting(call === null || call === void 0 ? void 0 : call.state)) {
|
20827
|
+
return 'lobby';
|
20828
|
+
// `LocalHold` needs to be checked before `isInCall` since it is also a state that's considered in call.
|
20828
20829
|
}
|
20829
|
-
|
20830
|
-
|
20831
|
-
|
20832
|
-
if (!(fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.uploadHandler)) {
|
20833
|
-
return null;
|
20830
|
+
else if ((call === null || call === void 0 ? void 0 : call.state) === 'LocalHold') {
|
20831
|
+
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
|
20832
|
+
return 'hold';
|
20834
20833
|
}
|
20835
|
-
|
20836
|
-
|
20837
|
-
|
20838
|
-
(
|
20839
|
-
|
20840
|
-
|
20841
|
-
|
20842
|
-
|
20843
|
-
|
20844
|
-
|
20845
|
-
|
20846
|
-
|
20847
|
-
|
20848
|
-
|
20849
|
-
|
20850
|
-
|
20851
|
-
|
20852
|
-
|
20853
|
-
|
20854
|
-
|
20855
|
-
|
20856
|
-
|
20857
|
-
|
20858
|
-
|
20859
|
-
|
20860
|
-
|
20861
|
-
|
20862
|
-
|
20863
|
-
|
20864
|
-
|
20834
|
+
else if ((call === null || call === void 0 ? void 0 : call.state) === 'Disconnecting') {
|
20835
|
+
return 'leaving';
|
20836
|
+
}
|
20837
|
+
else if (_isInCall(call === null || call === void 0 ? void 0 : call.state)) {
|
20838
|
+
return 'call';
|
20839
|
+
}
|
20840
|
+
else {
|
20841
|
+
// When the call object has been constructed after clicking , but before 'connecting' has been
|
20842
|
+
// set on the call object, we continue to show the configuration screen.
|
20843
|
+
// The call object does not correctly reflect local device state until `call.state` moves to `connecting`.
|
20844
|
+
// Moving to the 'lobby' page too soon leads to components that depend on the `call` object to show incorrect
|
20845
|
+
// transitional state.
|
20846
|
+
return 'configuration';
|
20847
|
+
}
|
20848
|
+
}
|
20849
|
+
if (previousCall) {
|
20850
|
+
const reason = getCallEndReason(previousCall);
|
20851
|
+
/* @conditional-compile-remove(rooms) */
|
20852
|
+
switch (reason) {
|
20853
|
+
case CallEndReasons.ROOM_NOT_FOUND:
|
20854
|
+
return 'roomNotFound';
|
20855
|
+
case CallEndReasons.DENIED_PERMISSION_TO_ROOM:
|
20856
|
+
return 'deniedPermissionToRoom';
|
20857
|
+
}
|
20858
|
+
switch (reason) {
|
20859
|
+
case CallEndReasons.ACCESS_DENIED:
|
20860
|
+
return 'accessDeniedTeamsMeeting';
|
20861
|
+
case CallEndReasons.REMOVED_FROM_CALL:
|
20862
|
+
return 'removedFromCall';
|
20863
|
+
case CallEndReasons.LEFT_CALL:
|
20864
|
+
if (previousCall.diagnostics.network.latest.noNetwork) {
|
20865
|
+
return 'joinCallFailedDueToNoNetwork';
|
20866
|
+
}
|
20867
|
+
return 'leftCall';
|
20868
|
+
}
|
20869
|
+
}
|
20870
|
+
// No call state - show starting page (configuration)
|
20871
|
+
return 'configuration';
|
20872
|
+
};
|
20873
|
+
/** @private */
|
20874
|
+
const IsCallEndedPage = (
|
20875
|
+
/**
|
20876
|
+
* Explicitly listing the pages of this function intentionally.
|
20877
|
+
* This protects against adding a new composite page that should be marked as an callEndedPage.
|
20878
|
+
* EndCallPages are used to trigger onCallEnded events so this could easily be missed.
|
20879
|
+
* When you add a new composite page this will throw a compiler error. If this new page is an
|
20880
|
+
* EndCallPage ensure you update the END_CALL_PAGES. Afterwards update the `page` parameter
|
20881
|
+
* type below to allow your new page, i.e. add `| <your new page>
|
20882
|
+
*/
|
20883
|
+
page) => END_CALL_PAGES.includes(page);
|
20884
|
+
/**
|
20885
|
+
* Creates a new call control options object and sets the correct values for disabling
|
20886
|
+
* the buttons provided in the `disabledControls` array.
|
20887
|
+
* Returns a new object without changing the original object.
|
20888
|
+
* @param callControlOptions options for the call control component that need to be modified.
|
20889
|
+
* @param disabledControls An array of controls to disable.
|
20890
|
+
* @returns a copy of callControlOptions with disabledControls disabled
|
20891
|
+
* @private
|
20892
|
+
*/
|
20893
|
+
const disableCallControls = (callControlOptions, disabledControls) => {
|
20894
|
+
var _a;
|
20895
|
+
if (callControlOptions === false) {
|
20896
|
+
return false;
|
20897
|
+
}
|
20898
|
+
// Ensure we clone the prop if it is an object to ensure we do not mutate the original prop.
|
20899
|
+
let newOptions = (_a = (callControlOptions instanceof Object ? Object.assign({}, callControlOptions) : callControlOptions)) !== null && _a !== void 0 ? _a : {};
|
20900
|
+
if (newOptions === true || newOptions === undefined) {
|
20901
|
+
newOptions = disabledControls.reduce((acc, key) => {
|
20902
|
+
acc[key] = { disabled: true };
|
20903
|
+
return acc;
|
20904
|
+
}, {});
|
20905
|
+
}
|
20906
|
+
else {
|
20907
|
+
disabledControls.forEach((key) => {
|
20908
|
+
if (newOptions[key] !== false) {
|
20909
|
+
newOptions[key] = { disabled: true };
|
20910
|
+
}
|
20911
|
+
});
|
20912
|
+
}
|
20913
|
+
return newOptions;
|
20865
20914
|
};
|
20866
|
-
|
20867
|
-
// Copyright (c) Microsoft Corporation.
|
20868
20915
|
/**
|
20869
|
-
*
|
20870
|
-
*
|
20871
|
-
* @remarks Chat composite min width and height are respectively 17.5rem and 20rem (280px and 320px, with default rem at 16px)
|
20916
|
+
* Check if a disabled object is provided for a button and returns if the button is disabled.
|
20917
|
+
* A button is only disabled if is explicitly set to disabled.
|
20872
20918
|
*
|
20873
|
-
* @
|
20919
|
+
* @param option
|
20920
|
+
* @returns whether a button is disabled
|
20921
|
+
* @private
|
20874
20922
|
*/
|
20875
|
-
const
|
20876
|
-
|
20877
|
-
|
20878
|
-
|
20879
|
-
|
20880
|
-
* @private
|
20881
|
-
*/
|
20882
|
-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
20883
|
-
const fileSharingOptions = () => {
|
20884
|
-
/* @conditional-compile-remove(file-sharing) */
|
20885
|
-
return {
|
20886
|
-
fileSharing: options === null || options === void 0 ? void 0 : options.fileSharing
|
20887
|
-
};
|
20888
|
-
};
|
20889
|
-
return (React__default['default'].createElement("div", { className: chatScreenContainerStyle },
|
20890
|
-
React__default['default'].createElement(BaseProvider, Object.assign({}, props),
|
20891
|
-
React__default['default'].createElement(ChatAdapterProvider, { adapter: adapter },
|
20892
|
-
React__default['default'].createElement(ChatScreen, Object.assign({ formFactor: formFactor, options: options, onFetchAvatarPersonaData: onFetchAvatarPersonaData, onRenderTypingIndicator: onRenderTypingIndicator, onRenderMessage: onRenderMessage, onFetchParticipantMenuItems: onFetchParticipantMenuItems }, fileSharingOptions()))))));
|
20923
|
+
const isDisabled$2 = (option) => {
|
20924
|
+
if (option === undefined || typeof option === 'boolean') {
|
20925
|
+
return false;
|
20926
|
+
}
|
20927
|
+
return option.disabled;
|
20893
20928
|
};
|
20894
|
-
|
20895
|
-
|
20896
|
-
|
20929
|
+
/* @conditional-compile-remove(call-readiness) */
|
20930
|
+
/**
|
20931
|
+
* @returns Permissions state for the camera.
|
20932
|
+
*/
|
20933
|
+
const queryCameraPermissionFromPermissionsAPI = () => __awaiter$f(void 0, void 0, void 0, function* () {
|
20934
|
+
try {
|
20935
|
+
return (yield navigator.permissions.query({ name: 'camera' })).state;
|
20936
|
+
}
|
20937
|
+
catch (e) {
|
20938
|
+
console.info('permissions API is not supported by browser', e);
|
20939
|
+
return 'unsupported';
|
20940
|
+
}
|
20941
|
+
});
|
20942
|
+
/* @conditional-compile-remove(call-readiness) */
|
20943
|
+
/**
|
20944
|
+
* @returns Permissions state for the microphone.
|
20945
|
+
*/
|
20946
|
+
const queryMicrophonePermissionFromPermissionsAPI = () => __awaiter$f(void 0, void 0, void 0, function* () {
|
20947
|
+
try {
|
20948
|
+
return (yield navigator.permissions.query({ name: 'microphone' })).state;
|
20949
|
+
}
|
20950
|
+
catch (e) {
|
20951
|
+
console.info('permissions API is not supported by browser', e);
|
20952
|
+
return 'unsupported';
|
20953
|
+
}
|
20954
|
+
});
|
20955
|
+
/* @conditional-compile-remove(call-readiness) */
|
20897
20956
|
/**
|
20957
|
+
*
|
20958
|
+
* This function uses permission API to determine if device permission state is granted, prompt or denied
|
20959
|
+
* @returns whether device permission state is granted, prompt or denied
|
20960
|
+
* If permission API is not supported on this browser, permission state is set to unsupported.
|
20898
20961
|
* @private
|
20899
20962
|
*/
|
20900
|
-
const
|
20901
|
-
const
|
20902
|
-
|
20963
|
+
const getDevicePermissionState = (setVideoState, setAudioState) => __awaiter$f(void 0, void 0, void 0, function* () {
|
20964
|
+
const [cameraResult, microphoneResult] = yield Promise.all([
|
20965
|
+
queryCameraPermissionFromPermissionsAPI(),
|
20966
|
+
queryMicrophonePermissionFromPermissionsAPI()
|
20967
|
+
]);
|
20968
|
+
setVideoState(cameraResult);
|
20969
|
+
setAudioState(microphoneResult);
|
20970
|
+
});
|
20971
|
+
/* @conditional-compile-remove(unsupported-browser) */
|
20972
|
+
const isUnsupportedEnvironment = (environmentInfo, unsupportedBrowserVersionOptedIn) => {
|
20973
|
+
return !!((environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.isSupportedBrowser) === false ||
|
20974
|
+
((environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.isSupportedBrowserVersion) === false && !unsupportedBrowserVersionOptedIn) ||
|
20975
|
+
(environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.isSupportedPlatform) === false);
|
20903
20976
|
};
|
20904
20977
|
/**
|
20978
|
+
* Check if we are using safari browser
|
20905
20979
|
* @private
|
20906
20980
|
*/
|
20907
|
-
const
|
20908
|
-
|
20909
|
-
|
20910
|
-
throw 'Cannot find adapter please initialize before usage.';
|
20911
|
-
}
|
20912
|
-
return adapter;
|
20981
|
+
const _isSafari = (environmentInfo) => {
|
20982
|
+
/* @conditional-compile-remove(unsupported-browser) */
|
20983
|
+
return (environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.environment.browser) === 'safari';
|
20913
20984
|
};
|
20914
|
-
|
20915
|
-
// Copyright (c) Microsoft Corporation.
|
20916
20985
|
/**
|
20917
20986
|
* @private
|
20987
|
+
* This is the util function to create a participant modifier for remote participantList
|
20988
|
+
* It memoize previous original participant items and only update the changed participant
|
20989
|
+
* It takes in one modifier function to generate one single participant object, it returns undefined if the object keeps unmodified
|
20918
20990
|
*/
|
20919
|
-
const
|
20920
|
-
|
20991
|
+
const createParticipantModifier = (createModifiedParticipant) => {
|
20992
|
+
let previousParticipantState = undefined;
|
20993
|
+
let modifiedParticipants = {};
|
20994
|
+
const memoizedParticipants = {};
|
20995
|
+
return (state) => {
|
20996
|
+
var _a, _b, _c, _d;
|
20997
|
+
// if root state is the same, we don't need to update the participants
|
20998
|
+
if (((_a = state.call) === null || _a === void 0 ? void 0 : _a.remoteParticipants) !== previousParticipantState) {
|
20999
|
+
modifiedParticipants = {};
|
21000
|
+
const originalParticipants = (_b = state.call) === null || _b === void 0 ? void 0 : _b.remoteParticipants;
|
21001
|
+
for (const key in originalParticipants) {
|
21002
|
+
const modifiedParticipant = createModifiedParticipant(key, originalParticipants[key]);
|
21003
|
+
if (modifiedParticipant === undefined) {
|
21004
|
+
modifiedParticipants[key] = originalParticipants[key];
|
21005
|
+
continue;
|
21006
|
+
}
|
21007
|
+
// Generate the new item if original cached item has been changed
|
21008
|
+
if (((_c = memoizedParticipants[key]) === null || _c === void 0 ? void 0 : _c.originalRef) !== originalParticipants[key]) {
|
21009
|
+
memoizedParticipants[key] = {
|
21010
|
+
newParticipant: modifiedParticipant,
|
21011
|
+
originalRef: originalParticipants[key]
|
21012
|
+
};
|
21013
|
+
}
|
21014
|
+
// the modified participant is always coming from the memoized cache, whether is was refreshed
|
21015
|
+
// from the previous closure or not
|
21016
|
+
modifiedParticipants[key] = memoizedParticipants[key].newParticipant;
|
21017
|
+
}
|
21018
|
+
previousParticipantState = (_d = state.call) === null || _d === void 0 ? void 0 : _d.remoteParticipants;
|
21019
|
+
}
|
21020
|
+
return Object.assign(Object.assign({}, state), { call: state.call
|
21021
|
+
? Object.assign(Object.assign({}, state.call), { remoteParticipants: modifiedParticipants }) : undefined });
|
21022
|
+
};
|
20921
21023
|
};
|
20922
21024
|
/**
|
20923
21025
|
* @private
|
20924
21026
|
*/
|
20925
|
-
const
|
21027
|
+
const dismissVideoEffectsError = (toDismiss) => {
|
20926
21028
|
var _a;
|
20927
|
-
const
|
20928
|
-
|
20929
|
-
//
|
20930
|
-
|
20931
|
-
|
20932
|
-
|
20933
|
-
|
20934
|
-
mounted.current = false;
|
20935
|
-
};
|
20936
|
-
});
|
20937
|
-
const callId = (_a = adapter.getState().call) === null || _a === void 0 ? void 0 : _a.id;
|
20938
|
-
const callConfigProps = React.useMemo(() => ({
|
20939
|
-
callId
|
20940
|
-
}), [callId]);
|
20941
|
-
const [props, setProps] = React.useState(selector(adaptState(adapter.getState()), selectorProps !== null && selectorProps !== void 0 ? selectorProps : callConfigProps));
|
20942
|
-
const propRef = React.useRef(props);
|
20943
|
-
propRef.current = props;
|
20944
|
-
React.useEffect(() => {
|
20945
|
-
const onStateChange = (state) => {
|
20946
|
-
if (!mounted.current) {
|
20947
|
-
return;
|
20948
|
-
}
|
20949
|
-
const newProps = selector(adaptState(state), selectorProps !== null && selectorProps !== void 0 ? selectorProps : callConfigProps);
|
20950
|
-
if (propRef.current !== newProps) {
|
20951
|
-
setProps(newProps);
|
20952
|
-
}
|
20953
|
-
};
|
20954
|
-
adapter.onStateChange(onStateChange);
|
20955
|
-
return () => {
|
20956
|
-
adapter.offStateChange(onStateChange);
|
20957
|
-
};
|
20958
|
-
}, [adaptState, adapter, selector, selectorProps, callConfigProps]);
|
20959
|
-
return props;
|
20960
|
-
};
|
20961
|
-
const memoizeState = memoizeOne__default['default']((userId, deviceManager, calls, latestErrors, displayName, alternateCallerId, environmentInfo) => ({
|
20962
|
-
userId,
|
20963
|
-
incomingCalls: {},
|
20964
|
-
incomingCallsEnded: {},
|
20965
|
-
callsEnded: {},
|
20966
|
-
deviceManager,
|
20967
|
-
callAgent: { displayName },
|
20968
|
-
calls,
|
20969
|
-
latestErrors,
|
20970
|
-
/* @conditional-compile-remove(PSTN-calls) */
|
20971
|
-
alternateCallerId,
|
20972
|
-
/* @conditional-compile-remove(unsupported-browser) */
|
20973
|
-
environmentInfo
|
20974
|
-
}));
|
20975
|
-
const memoizeCalls = memoizeOne__default['default']((call) => (call ? { [call.id]: call } : {}));
|
20976
|
-
const adaptCompositeState = (compositeState) => {
|
20977
|
-
return memoizeState(compositeState.userId, compositeState.devices, memoizeCalls(compositeState.call),
|
20978
|
-
// This is an unsafe type expansion.
|
20979
|
-
// compositeState.latestErrors can contain properties that are not valid in CallErrors.
|
20980
|
-
//
|
20981
|
-
// But there is no way to check for valid property names at runtime:
|
20982
|
-
// - The set of valid property names is built from types in the @azure/communication-calling.
|
20983
|
-
// Thus we don't have a literal array of allowed strings at runtime.
|
20984
|
-
// - Due to minification / uglification, the property names from the objects at runtime can't be used
|
20985
|
-
// to compare against permissible values inferred from the types.
|
20986
|
-
//
|
20987
|
-
// This is not a huge problem -- it simply means that our adapted selector will include some extra operations
|
20988
|
-
// that are unknown to the UI component and data binding libraries. Generic handling of the errors (e.g.,
|
20989
|
-
// just displaying them in some UI surface) will continue to work for these operations. Handling of
|
20990
|
-
// specific operations (e.g., acting on errors related to permission issues) will ignore these operations.
|
20991
|
-
compositeState.latestErrors, compositeState.displayName,
|
20992
|
-
/* @conditional-compile-remove(PSTN-calls) */
|
20993
|
-
compositeState.alternateCallerId,
|
20994
|
-
/* @conditional-compile-remove(unsupported-browser) */
|
20995
|
-
compositeState.environmentInfo);
|
21029
|
+
const now = new Date(Date.now());
|
21030
|
+
const toDismissTimestamp = (_a = toDismiss.timestamp) !== null && _a !== void 0 ? _a : now;
|
21031
|
+
// Record that this error was dismissed for the first time right now.
|
21032
|
+
return {
|
21033
|
+
dismissedAt: now > toDismissTimestamp ? now : toDismissTimestamp,
|
21034
|
+
activeSince: toDismiss.timestamp
|
21035
|
+
};
|
20996
21036
|
};
|
21037
|
+
/* @conditional-compile-remove(video-background-effects) */
|
21038
|
+
/** @private */
|
21039
|
+
const getBackgroundEffectFromSelectedEffect = (selectedEffect) => (selectedEffect === null || selectedEffect === void 0 ? void 0 : selectedEffect.effectName) === 'blur'
|
21040
|
+
? new communicationCallingEffects.BackgroundBlurEffect()
|
21041
|
+
: (selectedEffect === null || selectedEffect === void 0 ? void 0 : selectedEffect.effectName) === 'replacement'
|
21042
|
+
? new communicationCallingEffects.BackgroundReplacementEffect({ backgroundImageUrl: selectedEffect.backgroundImageUrl })
|
21043
|
+
: undefined;
|
21044
|
+
/* @conditional-compile-remove(video-background-effects) */
|
21045
|
+
/**
|
21046
|
+
* @remarks this logic should mimic the onToggleCamera in the common call handlers.
|
21047
|
+
* @private
|
21048
|
+
*/
|
21049
|
+
const getSelectedCameraFromAdapterState = (state) => state.devices.selectedCamera || state.devices.cameras[0];
|
20997
21050
|
|
20998
21051
|
// Copyright (c) Microsoft Corporation.
|
20999
21052
|
// Licensed under the MIT license.
|
@@ -26021,6 +26074,10 @@ const outboundCallStringsTrampoline = (strings) => {
|
|
26021
26074
|
|
26022
26075
|
// Copyright (c) Microsoft Corporation.
|
26023
26076
|
// Licensed under the MIT license.
|
26077
|
+
/**
|
26078
|
+
* @private
|
26079
|
+
*/
|
26080
|
+
const pageContainer = { width: '100%', height: '100%' };
|
26024
26081
|
/**
|
26025
26082
|
* @private
|
26026
26083
|
*/
|
@@ -26081,6 +26138,8 @@ const TransferPage = (props) => {
|
|
26081
26138
|
const remoteParticipants = useSelector$1(getRemoteParticipants);
|
26082
26139
|
/* @conditional-compile-remove(call-transfer) */
|
26083
26140
|
const transferCall = useSelector$1(getTransferCall);
|
26141
|
+
/* @conditional-compile-remove(call-transfer) */
|
26142
|
+
const [announcerString, setAnnouncerString] = React.useState(undefined);
|
26084
26143
|
// Reduce the controls shown when mobile view is enabled.
|
26085
26144
|
const callControlOptions = props.mobileView
|
26086
26145
|
? reduceCallControlsForMobile((_a = props.options) === null || _a === void 0 ? void 0 : _a.callControls)
|
@@ -26095,6 +26154,10 @@ const TransferPage = (props) => {
|
|
26095
26154
|
}
|
26096
26155
|
return 'transferor';
|
26097
26156
|
}, [transferCall, transferTarget === null || transferTarget === void 0 ? void 0 : transferTarget.displayName]);
|
26157
|
+
/* @conditional-compile-remove(call-transfer) */
|
26158
|
+
React.useEffect(() => {
|
26159
|
+
setAnnouncerString(strings.transferPageNoticeString);
|
26160
|
+
}, [strings.transferPageNoticeString]);
|
26098
26161
|
let transferTileParticipant = transferor;
|
26099
26162
|
/* @conditional-compile-remove(call-transfer) */
|
26100
26163
|
if (pageSubject === 'transferTarget') {
|
@@ -26107,16 +26170,19 @@ const TransferPage = (props) => {
|
|
26107
26170
|
transferParticipantDisplayName =
|
26108
26171
|
(_d = transferTarget === null || transferTarget === void 0 ? void 0 : transferTarget.displayName) !== null && _d !== void 0 ? _d : strings.transferPageUnknownTransferTargetDisplayName;
|
26109
26172
|
}
|
26110
|
-
return (React__default['default'].createElement(
|
26111
|
-
|
26112
|
-
|
26113
|
-
|
26114
|
-
|
26115
|
-
|
26116
|
-
|
26117
|
-
|
26118
|
-
|
26119
|
-
|
26173
|
+
return (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(pageContainer) },
|
26174
|
+
/* @conditional-compile-remove(call-transfer) */
|
26175
|
+
React__default['default'].createElement(Announcer$1, { announcementString: announcerString, ariaLive: "polite" }),
|
26176
|
+
React__default['default'].createElement(CallArrangement, { complianceBannerProps: { strings },
|
26177
|
+
// Ignore errors from before current call. This avoids old errors from showing up when a user re-joins a call.
|
26178
|
+
errorBarProps: ((_e = props.options) === null || _e === void 0 ? void 0 : _e.errorBar) !== false && Object.assign(Object.assign({}, errorBarProps), { ignorePremountErrors: true }), callControlProps: {
|
26179
|
+
options: callControlOptions,
|
26180
|
+
increaseFlyoutItemSize: props.mobileView
|
26181
|
+
}, mobileView: props.mobileView, modalLayerHostId: props.modalLayerHostId, onRenderGalleryContent: () => (React__default['default'].createElement(TransferTile, { userId: transferTileParticipant ? toFlatCommunicationIdentifier(transferTileParticipant === null || transferTileParticipant === void 0 ? void 0 : transferTileParticipant.identifier) : undefined, displayName: transferParticipantDisplayName, initialsName: transferParticipantDisplayName,
|
26182
|
+
/* @conditional-compile-remove(call-transfer) */
|
26183
|
+
statusText: pageSubject === 'transferTarget'
|
26184
|
+
? strings.transferPageTransferTargetText
|
26185
|
+
: strings.transferPageTransferorText, onRenderAvatar: props.onRenderAvatar, onFetchAvatarPersonaData: props.onFetchAvatarPersonaData })), dataUiId: 'transfer-page', updateSidePaneRenderer: props.updateSidePaneRenderer, mobileChatTabHeader: props.mobileChatTabHeader })));
|
26120
26186
|
};
|
26121
26187
|
const TransferTile = (props) => {
|
26122
26188
|
const { displayName, initialsName, userId, onRenderAvatar, onFetchAvatarPersonaData, statusText } = props;
|
@@ -27551,7 +27617,7 @@ class AzureCommunicationCallAdapter {
|
|
27551
27617
|
const createAzureCommunicationCallAdapter = ({ userId, displayName, credential, locator,
|
27552
27618
|
/* @conditional-compile-remove(PSTN-calls) */ alternateCallerId,
|
27553
27619
|
/* @conditional-compile-remove(video-background-effects) */ options }) => __awaiter$3(void 0, void 0, void 0, function* () {
|
27554
|
-
if (!
|
27620
|
+
if (!_isValidIdentifier(userId)) {
|
27555
27621
|
throw new Error('Invalid identifier. Please provide valid identifier object.');
|
27556
27622
|
}
|
27557
27623
|
const callClient = createStatefulCallClient({
|