@azure/communication-react 1.16.0-alpha-202404160012 → 1.16.0-alpha-202404180013
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/communication-react.d.ts +1 -1
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-CmrzlNzS.js → ChatMessageComponentAsRichTextEditBox-C3t87AZz.js} +3 -3
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-CmrzlNzS.js.map → ChatMessageComponentAsRichTextEditBox-C3t87AZz.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index-CC43HCUd.js → index-BP7335hI.js} +207 -71
- package/dist/dist-cjs/communication-react/index-BP7335hI.js.map +1 -0
- package/dist/dist-cjs/communication-react/index.js +2 -2
- 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/calling-stateful-client/src/DeviceManagerDeclarative.js +68 -4
- package/dist/dist-esm/calling-stateful-client/src/DeviceManagerDeclarative.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.js +8 -4
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts +9 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js +44 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.d.ts +14 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +5 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +49 -13
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js +3 -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 +3 -2
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/LargeGalleryLayout.js +1 -2
- package/dist/dist-esm/react-components/src/components/VideoGallery/LargeGalleryLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/SpeakerVideoLayout.js +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/SpeakerVideoLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.d.ts +5 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.js +17 -17
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js +10 -21
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.js +2 -6
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/SidePaneHeader.js +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/SidePaneHeader.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-cjs/communication-react/index-CC43HCUd.js.map +0 -1
@@ -17,9 +17,9 @@ var reactFileTypeIcons = require('@fluentui/react-file-type-icons');
|
|
17
17
|
var react$1 = require('@griffel/react');
|
18
18
|
var roosterjsEditorPlugins = require('roosterjs-editor-plugins');
|
19
19
|
var roosterjsEditorCore = require('roosterjs-editor-core');
|
20
|
+
var roosterjsEditorTypesCompatible = require('roosterjs-editor-types-compatible');
|
20
21
|
var roosterjsReact = require('roosterjs-react');
|
21
22
|
var roosterjsEditorDom = require('roosterjs-editor-dom');
|
22
|
-
var roosterjsEditorTypesCompatible = require('roosterjs-editor-types-compatible');
|
23
23
|
var roosterjsEditorApi = require('roosterjs-editor-api');
|
24
24
|
var reactChat = require('@fluentui-contrib/react-chat');
|
25
25
|
var uuid = require('uuid');
|
@@ -176,7 +176,7 @@ function getDefaultExportFromCjs (x) {
|
|
176
176
|
// Copyright (c) Microsoft Corporation.
|
177
177
|
// Licensed under the MIT License.
|
178
178
|
// GENERATED FILE. DO NOT EDIT MANUALLY.
|
179
|
-
var telemetryVersion = '1.16.0-alpha-
|
179
|
+
var telemetryVersion = '1.16.0-alpha-202404180013';
|
180
180
|
|
181
181
|
|
182
182
|
var telemetryVersion$1 = /*@__PURE__*/getDefaultExportFromCjs(telemetryVersion);
|
@@ -1451,6 +1451,24 @@ class ProxyDeviceManager {
|
|
1451
1451
|
this._deviceManager.on('audioDevicesUpdated', this.audioDevicesUpdated);
|
1452
1452
|
this._deviceManager.on('selectedMicrophoneChanged', this.selectedMicrophoneChanged);
|
1453
1453
|
this._deviceManager.on('selectedSpeakerChanged', this.selectedSpeakerChanged);
|
1454
|
+
// Subscribe to browser camera permissions changes
|
1455
|
+
try {
|
1456
|
+
navigator.permissions.query({ name: 'camera' }).then((cameraPermissions) => {
|
1457
|
+
cameraPermissions.addEventListener('change', this.permissionsApiStateChangeHandler);
|
1458
|
+
});
|
1459
|
+
}
|
1460
|
+
catch (e) {
|
1461
|
+
console.info('Could not subscribe to Permissions API Camera changed events, API is not supported by browser', e);
|
1462
|
+
}
|
1463
|
+
// Subscribe to browser microphone permissions changes
|
1464
|
+
try {
|
1465
|
+
navigator.permissions.query({ name: 'microphone' }).then((micPermissions) => {
|
1466
|
+
micPermissions.addEventListener('change', this.permissionsApiStateChangeHandler);
|
1467
|
+
});
|
1468
|
+
}
|
1469
|
+
catch (e) {
|
1470
|
+
console.info('Could not subscribe to Permissions API Microphone changed events, API is not supported by browser', e);
|
1471
|
+
}
|
1454
1472
|
};
|
1455
1473
|
/**
|
1456
1474
|
* This is used to unsubscribe DeclarativeDeviceManager from the DeviceManager events.
|
@@ -1460,7 +1478,28 @@ class ProxyDeviceManager {
|
|
1460
1478
|
this._deviceManager.off('audioDevicesUpdated', this.audioDevicesUpdated);
|
1461
1479
|
this._deviceManager.off('selectedMicrophoneChanged', this.selectedMicrophoneChanged);
|
1462
1480
|
this._deviceManager.off('selectedSpeakerChanged', this.selectedSpeakerChanged);
|
1481
|
+
// Unsubscribe from browser camera permissions changes
|
1482
|
+
try {
|
1483
|
+
navigator.permissions.query({ name: 'camera' }).then((cameraPermissions) => {
|
1484
|
+
cameraPermissions.removeEventListener('change', this.permissionsApiStateChangeHandler);
|
1485
|
+
});
|
1486
|
+
}
|
1487
|
+
catch (e) {
|
1488
|
+
console.info('Could not Unsubscribe to Permissions API Camera changed events, API is not supported by browser', e);
|
1489
|
+
}
|
1490
|
+
// Unsubscribe from browser microphone permissions changes
|
1491
|
+
try {
|
1492
|
+
navigator.permissions.query({ name: 'microphone' }).then((micPermissions) => {
|
1493
|
+
micPermissions.removeEventListener('change', this.permissionsApiStateChangeHandler);
|
1494
|
+
});
|
1495
|
+
}
|
1496
|
+
catch (e) {
|
1497
|
+
console.info('Could not Unsubscribe to Permissions API Camera changed events, API is not supported by browser', e);
|
1498
|
+
}
|
1463
1499
|
};
|
1500
|
+
this.permissionsApiStateChangeHandler = () => __awaiter$O(this, void 0, void 0, function* () {
|
1501
|
+
yield this.updateDevicePermissionState();
|
1502
|
+
});
|
1464
1503
|
/**
|
1465
1504
|
* Used to set a camera inside the proxy device manager.
|
1466
1505
|
*
|
@@ -1485,6 +1524,32 @@ class ProxyDeviceManager {
|
|
1485
1524
|
this.selectedSpeakerChanged = () => {
|
1486
1525
|
this._context.setDeviceManagerSelectedSpeaker(this._deviceManager.selectedSpeaker);
|
1487
1526
|
};
|
1527
|
+
this.updateDevicePermissionState = (sdkDeviceAccessState) => __awaiter$O(this, void 0, void 0, function* () {
|
1528
|
+
let hasCameraPermission = !!(sdkDeviceAccessState === null || sdkDeviceAccessState === void 0 ? void 0 : sdkDeviceAccessState.video);
|
1529
|
+
let hasMicPermission = !!(sdkDeviceAccessState === null || sdkDeviceAccessState === void 0 ? void 0 : sdkDeviceAccessState.audio);
|
1530
|
+
// Supplement the SDK values with values from the Permissions API to get a better understanding of the device
|
1531
|
+
// permission state. The SDK only uses the getUserMedia API to determine the device permission state. However,
|
1532
|
+
// this returns false if the camera is in use by another application. The Permissions API can provide more
|
1533
|
+
// information about the device permission state, but is not supported yet in Firefox or Android WebView.
|
1534
|
+
// Note: It also has the limitation where it cannot detect if the device is blocked by the Operating System
|
1535
|
+
// permissions.
|
1536
|
+
try {
|
1537
|
+
const [cameraPermissions, micPermissions] = yield Promise.all([
|
1538
|
+
navigator.permissions.query({ name: 'camera' }),
|
1539
|
+
navigator.permissions.query({ name: 'microphone' })
|
1540
|
+
]);
|
1541
|
+
hasCameraPermission = cameraPermissions.state === 'granted';
|
1542
|
+
hasMicPermission = micPermissions.state === 'granted';
|
1543
|
+
}
|
1544
|
+
catch (e) {
|
1545
|
+
console.info('Permissions API is not supported by browser', e);
|
1546
|
+
}
|
1547
|
+
this._context.setDeviceManagerDeviceAccess({
|
1548
|
+
video: hasCameraPermission,
|
1549
|
+
audio: hasMicPermission
|
1550
|
+
});
|
1551
|
+
this.setDeviceManager();
|
1552
|
+
});
|
1488
1553
|
this._deviceManager = deviceManager;
|
1489
1554
|
this._context = context;
|
1490
1555
|
this.setDeviceManager();
|
@@ -1535,11 +1600,10 @@ class ProxyDeviceManager {
|
|
1535
1600
|
}
|
1536
1601
|
case 'askDevicePermission': {
|
1537
1602
|
return this._context.withAsyncErrorTeedToState((...args) => {
|
1538
|
-
return target.askDevicePermission(...args).then((deviceAccess) => {
|
1539
|
-
this.
|
1540
|
-
this.setDeviceManager();
|
1603
|
+
return target.askDevicePermission(...args).then((deviceAccess) => __awaiter$O(this, void 0, void 0, function* () {
|
1604
|
+
yield this.updateDevicePermissionState(deviceAccess);
|
1541
1605
|
return deviceAccess;
|
1542
|
-
});
|
1606
|
+
}));
|
1543
1607
|
}, 'DeviceManager.askDevicePermission');
|
1544
1608
|
}
|
1545
1609
|
default:
|
@@ -9915,14 +9979,14 @@ const ribbonTableButtonRootStyles = (theme, isSelected) => {
|
|
9915
9979
|
'.ribbon-table-button-regular-icon': {
|
9916
9980
|
width: '1.25rem',
|
9917
9981
|
height: '1.25rem',
|
9918
|
-
|
9982
|
+
margin: '-0.25rem 0.25rem 0 0.25rem',
|
9919
9983
|
color: theme.palette.neutralPrimary,
|
9920
9984
|
display: isSelected ? 'none' : 'inline-block'
|
9921
9985
|
},
|
9922
9986
|
'.ribbon-table-button-filled-icon': {
|
9923
9987
|
width: '1.25rem',
|
9924
9988
|
height: '1.25rem',
|
9925
|
-
|
9989
|
+
margin: '-0.25rem 0.25rem 0 0.25rem',
|
9926
9990
|
color: theme.palette.themePrimary,
|
9927
9991
|
display: isSelected ? 'inline-block' : 'none'
|
9928
9992
|
}
|
@@ -9933,22 +9997,11 @@ const ribbonTableButtonRootStyles = (theme, isSelected) => {
|
|
9933
9997
|
* @private
|
9934
9998
|
*/
|
9935
9999
|
const ribbonDividerStyle = (theme) => {
|
9936
|
-
return {
|
9937
|
-
|
9938
|
-
|
9939
|
-
|
9940
|
-
|
9941
|
-
selectors: {
|
9942
|
-
// Icon's color doesn't work here because of the specificity
|
9943
|
-
'.ms-Button-icon': {
|
9944
|
-
color: theme.palette.neutralQuaternaryAlt
|
9945
|
-
},
|
9946
|
-
'.ms-Button-menuIcon': {
|
9947
|
-
color: theme.palette.neutralQuaternaryAlt
|
9948
|
-
}
|
9949
|
-
}
|
9950
|
-
}
|
9951
|
-
};
|
10000
|
+
return react.mergeStyles({
|
10001
|
+
color: theme.palette.neutralQuaternaryAlt,
|
10002
|
+
margin: '0 -0.5rem',
|
10003
|
+
paddingTop: '0.5rem'
|
10004
|
+
});
|
9952
10005
|
};
|
9953
10006
|
/**
|
9954
10007
|
* @private
|
@@ -9971,7 +10024,7 @@ const richTextFormatButtonIconStyle = (theme, isSelected) => {
|
|
9971
10024
|
const editBoxRichTextEditorStyle = () => {
|
9972
10025
|
return {
|
9973
10026
|
minHeight: '2.25rem',
|
9974
|
-
maxHeight: '
|
10027
|
+
maxHeight: '8rem'
|
9975
10028
|
};
|
9976
10029
|
};
|
9977
10030
|
/**
|
@@ -9979,8 +10032,8 @@ const editBoxRichTextEditorStyle = () => {
|
|
9979
10032
|
*/
|
9980
10033
|
const sendBoxRichTextEditorStyle = (isExpanded) => {
|
9981
10034
|
return {
|
9982
|
-
minHeight: isExpanded ? '
|
9983
|
-
maxHeight: '
|
10035
|
+
minHeight: isExpanded ? '4rem' : '1.25rem',
|
10036
|
+
maxHeight: '8rem'
|
9984
10037
|
};
|
9985
10038
|
};
|
9986
10039
|
/**
|
@@ -10227,16 +10280,19 @@ const MaxColumnsNumber = 5;
|
|
10227
10280
|
const dividerRibbonButton = (theme, key) => {
|
10228
10281
|
return {
|
10229
10282
|
key: key,
|
10230
|
-
|
10283
|
+
// the icon will be set in `onRender` callback
|
10284
|
+
// this is needed to make the divider unavailable for keyboard navigation
|
10285
|
+
iconName: '',
|
10286
|
+
// no text is needed here as we don't want to show a tooltip for the divider
|
10231
10287
|
unlocalizedText: '',
|
10232
10288
|
onClick: () => { },
|
10233
10289
|
isDisabled: () => true,
|
10234
10290
|
commandBarProperties: {
|
10235
10291
|
// show the item correctly for the overflow menu
|
10236
10292
|
itemType: react.ContextualMenuItemType.Divider,
|
10237
|
-
buttonStyles: ribbonDividerStyle(theme),
|
10238
10293
|
// this is still needed to remove checkmark icon space even though it is a divider
|
10239
|
-
canCheck: false
|
10294
|
+
canCheck: false,
|
10295
|
+
onRender: () => React.createElement(react.Icon, { iconName: "RichTextDividerIcon", className: ribbonDividerStyle(theme) })
|
10240
10296
|
}
|
10241
10297
|
};
|
10242
10298
|
};
|
@@ -10404,13 +10460,22 @@ const getEditingTable = (editor, node) => {
|
|
10404
10460
|
* CopyPastePlugin is a plugin for handling copy and paste events in the editor.
|
10405
10461
|
*/
|
10406
10462
|
class CopyPastePlugin {
|
10463
|
+
constructor() {
|
10464
|
+
this.editor = null;
|
10465
|
+
}
|
10407
10466
|
getName() {
|
10408
10467
|
return 'CopyPastePlugin';
|
10409
10468
|
}
|
10410
|
-
initialize() {
|
10469
|
+
initialize(editor) {
|
10470
|
+
this.editor = editor;
|
10471
|
+
}
|
10411
10472
|
dispose() { }
|
10412
10473
|
onPluginEvent(event) {
|
10413
10474
|
removeImageElement(event);
|
10475
|
+
if (this.editor !== null && !this.editor.isDisposed()) {
|
10476
|
+
// scroll the editor to the correct position after pasting content
|
10477
|
+
scrollToBottomAfterContentPaste(event, this.editor);
|
10478
|
+
}
|
10414
10479
|
}
|
10415
10480
|
}
|
10416
10481
|
/**
|
@@ -10432,6 +10497,38 @@ const removeImageElement = (event) => {
|
|
10432
10497
|
});
|
10433
10498
|
}
|
10434
10499
|
};
|
10500
|
+
/**
|
10501
|
+
* Scrolls the editor's scroll container to the bottom after content is pasted.
|
10502
|
+
* @param event - The plugin event.
|
10503
|
+
* @param editor - The editor instance.
|
10504
|
+
*/
|
10505
|
+
const scrollToBottomAfterContentPaste = (event, editor) => {
|
10506
|
+
if (event.eventType === roosterjsEditorTypesCompatible.CompatiblePluginEventType.ContentChanged && event.source === roosterjsEditorTypesCompatible.CompatibleChangeSource.Paste) {
|
10507
|
+
// current focused position in the editor
|
10508
|
+
const focusedPosition = editor.getFocusedPosition();
|
10509
|
+
// the cursor position relative to the viewport
|
10510
|
+
const cursorRect = focusedPosition && roosterjsEditorDom.getPositionRect(focusedPosition);
|
10511
|
+
// the scroll container of the editor
|
10512
|
+
const scrollContainer = editor.getScrollContainer();
|
10513
|
+
// the scrollContainer position relative to the viewport
|
10514
|
+
const scrollContainerRect = roosterjsEditorDom.normalizeRect(scrollContainer.getBoundingClientRect());
|
10515
|
+
if (focusedPosition !== null && cursorRect !== null && cursorRect !== undefined && scrollContainerRect !== null) {
|
10516
|
+
const textElement = focusedPosition.element;
|
10517
|
+
// the caret height is typically the same as the font size of the text
|
10518
|
+
const caretHeight = parseFloat(window.getComputedStyle(textElement).fontSize);
|
10519
|
+
// 1. scrollContainer.scrollTop represents the number of pixels that the content of scrollContainer is scrolled upward.
|
10520
|
+
// 2. subtract the top position of the scrollContainer element (scrollContainerRect.top) to
|
10521
|
+
// translate the scroll position from being relative to the document to being relative to the viewport.
|
10522
|
+
// 3. add the top position of the cursor (cursorRect.top) to moves the scroll position to the cursor's position.
|
10523
|
+
// 4. subtract a caret height to add some space between the cursor and the top edge of the scrollContainer.
|
10524
|
+
const updatedScrollTop = scrollContainer.scrollTop - scrollContainerRect.top + cursorRect.top - caretHeight;
|
10525
|
+
scrollContainer.scrollTo({
|
10526
|
+
top: updatedScrollTop,
|
10527
|
+
behavior: 'smooth'
|
10528
|
+
});
|
10529
|
+
}
|
10530
|
+
}
|
10531
|
+
};
|
10435
10532
|
|
10436
10533
|
// Copyright (c) Microsoft Corporation.
|
10437
10534
|
// Licensed under the MIT License.
|
@@ -10456,6 +10553,10 @@ const RichTextEditor = React.forwardRef((props, ref) => {
|
|
10456
10553
|
if (editor.current) {
|
10457
10554
|
editor.current.setContent('');
|
10458
10555
|
}
|
10556
|
+
},
|
10557
|
+
getPlainContent() {
|
10558
|
+
var _a;
|
10559
|
+
return (_a = editor === null || editor === void 0 ? void 0 : editor.current) === null || _a === void 0 ? void 0 : _a.getContent(roosterjsEditorTypesCompatible.CompatibleGetContentMode.PlainTextFast);
|
10459
10560
|
}
|
10460
10561
|
};
|
10461
10562
|
}, []);
|
@@ -10751,7 +10852,7 @@ const RichTextSendBox = (props) => {
|
|
10751
10852
|
setContentValue(newValue);
|
10752
10853
|
}, []);
|
10753
10854
|
const sendMessageOnClick = React.useCallback(() => {
|
10754
|
-
var _a, _b;
|
10855
|
+
var _a, _b, _c;
|
10755
10856
|
if (disabled || contentValueOverflow) {
|
10756
10857
|
return;
|
10757
10858
|
}
|
@@ -10764,20 +10865,29 @@ const RichTextSendBox = (props) => {
|
|
10764
10865
|
return;
|
10765
10866
|
}
|
10766
10867
|
const message = contentValue;
|
10868
|
+
// get plain text content from the editor to check if the message is empty
|
10869
|
+
// as the content may contain tags even when the content is empty
|
10870
|
+
const plainTextContent = (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.getPlainContent();
|
10871
|
+
const hasContent = !isContentEmpty({
|
10872
|
+
plainTextContent,
|
10873
|
+
content: message,
|
10874
|
+
placeholder: strings.placeholderText
|
10875
|
+
});
|
10767
10876
|
// we don't want to send empty messages including spaces, newlines, tabs
|
10768
10877
|
// Message can be empty if there is a valid attachment upload
|
10769
|
-
if (
|
10878
|
+
if (hasContent ||
|
10770
10879
|
/* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads(activeAttachmentUploads)) {
|
10771
10880
|
onSendMessage(message);
|
10772
10881
|
setContentValue('');
|
10773
|
-
(
|
10882
|
+
(_b = editorComponentRef.current) === null || _b === void 0 ? void 0 : _b.setEmptyContent();
|
10774
10883
|
}
|
10775
|
-
(
|
10884
|
+
(_c = editorComponentRef.current) === null || _c === void 0 ? void 0 : _c.focus();
|
10776
10885
|
}, [
|
10777
10886
|
contentValue,
|
10778
10887
|
contentValueOverflow,
|
10779
10888
|
disabled,
|
10780
10889
|
onSendMessage,
|
10890
|
+
strings.placeholderText,
|
10781
10891
|
/* @conditional-compile-remove(attachment-upload) */ activeAttachmentUploads,
|
10782
10892
|
/* @conditional-compile-remove(attachment-upload) */ strings.attachmentUploadsPendingError
|
10783
10893
|
]);
|
@@ -10797,15 +10907,26 @@ const RichTextSendBox = (props) => {
|
|
10797
10907
|
attachmentUploadsPendingError,
|
10798
10908
|
systemMessage
|
10799
10909
|
]);
|
10800
|
-
const onRenderSendIcon = React.useCallback((isHover) =>
|
10801
|
-
|
10802
|
-
|
10803
|
-
|
10804
|
-
|
10805
|
-
|
10806
|
-
|
10807
|
-
|
10808
|
-
|
10910
|
+
const onRenderSendIcon = React.useCallback((isHover) => {
|
10911
|
+
var _a;
|
10912
|
+
// get plain text content from the editor to check if the message is empty
|
10913
|
+
// as the content may contain tags even when the content is empty
|
10914
|
+
const plainTextContent = (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.getPlainContent();
|
10915
|
+
const hasContent = !isContentEmpty({
|
10916
|
+
plainTextContent: plainTextContent,
|
10917
|
+
content: contentValue,
|
10918
|
+
placeholder: strings.placeholderText
|
10919
|
+
});
|
10920
|
+
return (React.createElement(react.Icon, { iconName: isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend', className: sendIconStyle({
|
10921
|
+
theme,
|
10922
|
+
hasText: hasContent,
|
10923
|
+
/* @conditional-compile-remove(attachment-upload) */
|
10924
|
+
hasAttachment: false,
|
10925
|
+
hasErrorMessage: hasErrorMessage,
|
10926
|
+
defaultTextColor: theme.palette.neutralSecondary,
|
10927
|
+
disabled: disabled
|
10928
|
+
}) }));
|
10929
|
+
}, [contentValue, disabled, hasErrorMessage, strings.placeholderText, theme]);
|
10809
10930
|
const sendBoxErrorsProps = React.useMemo(() => {
|
10810
10931
|
var _a;
|
10811
10932
|
return {
|
@@ -10867,6 +10988,22 @@ const RichTextSendBox = (props) => {
|
|
10867
10988
|
/* @conditional-compile-remove(attachment-upload) */
|
10868
10989
|
hasAttachments: hasAttachmentUploads })));
|
10869
10990
|
};
|
10991
|
+
/**
|
10992
|
+
* Checks if the content of the rich text editor is empty.
|
10993
|
+
*
|
10994
|
+
* @param {Object} params - The parameters for the function.
|
10995
|
+
* @param {string | undefined} params.plainTextContent - The plain text content of the editor.
|
10996
|
+
* @param {string} params.content - The HTML content of the editor.
|
10997
|
+
* @param {string} params.placeholder - The placeholder text of the editor.
|
10998
|
+
* @returns {boolean} - True if the content is empty, false otherwise.
|
10999
|
+
*/
|
11000
|
+
const isContentEmpty = ({ plainTextContent, content, placeholder }) => {
|
11001
|
+
// RoosterJS returns placeholder text as plain text when the editor is empty and in this case,
|
11002
|
+
// plainTextContent contains only placeholder text but content doesn't include the placeholder text
|
11003
|
+
// this needs to be reviewed after migration to the content model packages.
|
11004
|
+
const plainTextContainsPlaceholderOnly = plainTextContent === placeholder && !content.includes(placeholder);
|
11005
|
+
return plainTextContainsPlaceholderOnly || sanitizeText(plainTextContent !== null && plainTextContent !== void 0 ? plainTextContent : '').length === 0;
|
11006
|
+
};
|
10870
11007
|
|
10871
11008
|
// Copyright (c) Microsoft Corporation.
|
10872
11009
|
// Licensed under the MIT License.
|
@@ -12690,7 +12827,7 @@ class ErrorBoundary extends React.Component {
|
|
12690
12827
|
// Copyright (c) Microsoft Corporation.
|
12691
12828
|
// Licensed under the MIT License.
|
12692
12829
|
/* @conditional-compile-remove(rich-text-editor) */
|
12693
|
-
const ChatMessageComponentAsRichTextEditBox = React.lazy(() => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-
|
12830
|
+
const ChatMessageComponentAsRichTextEditBox = React.lazy(() => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-C3t87AZz.js'); }));
|
12694
12831
|
/**
|
12695
12832
|
* @private
|
12696
12833
|
* Use this function to load RoosterJS dependencies early in the lifecycle.
|
@@ -12698,7 +12835,7 @@ const ChatMessageComponentAsRichTextEditBox = React.lazy(() => Promise.resolve()
|
|
12698
12835
|
*
|
12699
12836
|
* @conditional-compile-remove(rich-text-editor)
|
12700
12837
|
*/
|
12701
|
-
const loadChatMessageComponentAsRichTextEditBox = () => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-
|
12838
|
+
const loadChatMessageComponentAsRichTextEditBox = () => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-C3t87AZz.js'); });
|
12702
12839
|
/**
|
12703
12840
|
* @private
|
12704
12841
|
*/
|
@@ -15582,12 +15719,12 @@ const participantsById = (participants) => {
|
|
15582
15719
|
// Licensed under the MIT License.
|
15583
15720
|
const DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS = 6;
|
15584
15721
|
const DEFAULT_MAX_VIDEO_SREAMS = 4;
|
15722
|
+
/**
|
15723
|
+
* @private
|
15724
|
+
*/
|
15585
15725
|
const MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY = 9;
|
15586
15726
|
const getOrganizedParticipants = (props) => {
|
15587
|
-
const { remoteParticipants = [], dominantSpeakers = [],
|
15588
|
-
const maxRemoteVideoStreamsToUse = maxRemoteVideoStreams > MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY
|
15589
|
-
? MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY
|
15590
|
-
: maxRemoteVideoStreams;
|
15727
|
+
const { remoteParticipants = [], dominantSpeakers = [], maxGridParticipants = DEFAULT_MAX_VIDEO_SREAMS, maxOverflowGalleryDominantSpeakers = DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS, isScreenShareActive = false, layout, previousGridParticipants = [], previousOverflowParticipants = [] } = props;
|
15591
15728
|
const remoteParticipantsOrdered = putVideoParticipantsFirst(remoteParticipants);
|
15592
15729
|
const videoParticipants = remoteParticipants.filter((p) => { var _a; return (_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable; });
|
15593
15730
|
const participants = layout === 'floatingLocalVideo' && videoParticipants.length > 0 ? videoParticipants : remoteParticipantsOrdered;
|
@@ -15595,8 +15732,8 @@ const getOrganizedParticipants = (props) => {
|
|
15595
15732
|
participants: participants,
|
15596
15733
|
dominantSpeakers,
|
15597
15734
|
currentParticipants: previousGridParticipants,
|
15598
|
-
maxDominantSpeakers:
|
15599
|
-
}).slice(0,
|
15735
|
+
maxDominantSpeakers: maxGridParticipants
|
15736
|
+
}).slice(0, maxGridParticipants);
|
15600
15737
|
const dominantSpeakerToGrid = layout === 'speaker'
|
15601
15738
|
? dominantSpeakers && dominantSpeakers[0]
|
15602
15739
|
? newGridParticipants.filter((p) => p.userId === dominantSpeakers[0])
|
@@ -15621,14 +15758,14 @@ const getOrganizedParticipants = (props) => {
|
|
15621
15758
|
isScreenShareActive,
|
15622
15759
|
gridParticipants: newGridParticipants,
|
15623
15760
|
overflowGalleryParticipants: newOverflowGalleryParticipants,
|
15624
|
-
|
15761
|
+
maxGridParticipants: maxGridParticipants,
|
15625
15762
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ callingParticipants
|
15626
15763
|
});
|
15627
15764
|
const overflowGalleryParticipants = getOverflowGalleryRemoteParticipants({
|
15628
15765
|
isScreenShareActive,
|
15629
15766
|
gridParticipants: newGridParticipants,
|
15630
15767
|
overflowGalleryParticipants: newOverflowGalleryParticipants,
|
15631
|
-
|
15768
|
+
maxGridParticipants: maxGridParticipants,
|
15632
15769
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ callingParticipants
|
15633
15770
|
});
|
15634
15771
|
return { gridParticipants, overflowGalleryParticipants };
|
@@ -15656,7 +15793,7 @@ const useOrganizedParticipants = (props) => {
|
|
15656
15793
|
const unfocusedParticipants = props.remoteParticipants.filter((p) => !focusedParticipantUserIdSet.has(p.userId));
|
15657
15794
|
const useOrganizedParticipantsProps = Object.assign(Object.assign({}, props), {
|
15658
15795
|
// if there are focused participants then leave no room in the grid by setting maxGridParticipants to 0
|
15659
|
-
|
15796
|
+
maxGridParticipants: focusedParticipants.length > 0 || props.isScreenShareActive ? 0 : props.maxGridParticipants, remoteParticipants: unfocusedParticipants, previousGridParticipants: currentGridParticipants.current, previousOverflowParticipants: currentOverflowGalleryParticipants.current });
|
15660
15797
|
const useOrganizedParticipantsResult = getOrganizedParticipants(useOrganizedParticipantsProps);
|
15661
15798
|
currentGridParticipants.current = useOrganizedParticipantsResult.gridParticipants;
|
15662
15799
|
currentOverflowGalleryParticipants.current = useOrganizedParticipantsResult.overflowGalleryParticipants;
|
@@ -15679,9 +15816,9 @@ const getGridParticipants = (args) => {
|
|
15679
15816
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
|
15680
15817
|
return args.gridParticipants.length > 0
|
15681
15818
|
? args.gridParticipants
|
15682
|
-
: args.overflowGalleryParticipants.length > args.
|
15683
|
-
? args.overflowGalleryParticipants.slice(0, args.
|
15684
|
-
: args.overflowGalleryParticipants.slice(0, args.
|
15819
|
+
: args.overflowGalleryParticipants.length > args.maxGridParticipants
|
15820
|
+
? args.overflowGalleryParticipants.slice(0, args.maxGridParticipants)
|
15821
|
+
: args.overflowGalleryParticipants.slice(0, args.maxGridParticipants).concat(args.callingParticipants);
|
15685
15822
|
};
|
15686
15823
|
const getOverflowGalleryRemoteParticipants = (args) => {
|
15687
15824
|
if (args.isScreenShareActive) {
|
@@ -15697,8 +15834,8 @@ const getOverflowGalleryRemoteParticipants = (args) => {
|
|
15697
15834
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
|
15698
15835
|
return args.gridParticipants.length > 0
|
15699
15836
|
? args.overflowGalleryParticipants.concat(args.callingParticipants)
|
15700
|
-
: args.overflowGalleryParticipants.length > args.
|
15701
|
-
? args.overflowGalleryParticipants.slice(args.
|
15837
|
+
: args.overflowGalleryParticipants.length > args.maxGridParticipants
|
15838
|
+
? args.overflowGalleryParticipants.slice(args.maxGridParticipants).concat(args.callingParticipants)
|
15702
15839
|
: [];
|
15703
15840
|
}
|
15704
15841
|
};
|
@@ -17538,11 +17675,12 @@ const DefaultLayout = (props) => {
|
|
17538
17675
|
// This number will be used for the maxOverflowGalleryDominantSpeakers when organizing the remote participants.
|
17539
17676
|
// We need to add the local participant to the pinned participant count so we are placing the speakers correctly.
|
17540
17677
|
const childrenPerPage = React.useRef(4);
|
17678
|
+
const remoteVideosOn = remoteParticipants.filter((p) => { var _a; return (_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable; }).length > 0;
|
17541
17679
|
const { gridParticipants, overflowGalleryParticipants } = useOrganizedParticipants({
|
17542
17680
|
remoteParticipants,
|
17543
17681
|
localParticipant,
|
17544
17682
|
dominantSpeakers,
|
17545
|
-
maxRemoteVideoStreams,
|
17683
|
+
maxGridParticipants: remoteVideosOn ? maxRemoteVideoStreams : MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY,
|
17546
17684
|
isScreenShareActive: !!screenShareComponent,
|
17547
17685
|
maxOverflowGalleryDominantSpeakers: screenShareComponent
|
17548
17686
|
? childrenPerPage.current - ((pinnedParticipantUserIds.length + 1) % childrenPerPage.current)
|
@@ -18370,10 +18508,11 @@ const FloatingLocalVideoLayout = (props) => {
|
|
18370
18508
|
// This is for tracking the number of children in the first page of overflow gallery.
|
18371
18509
|
// This number will be used for the maxOverflowGalleryDominantSpeakers when organizing the remote participants.
|
18372
18510
|
const childrenPerPage = React.useRef(4);
|
18511
|
+
const remoteVideosOn = remoteParticipants.filter((p) => { var _a; return (_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable; }).length > 0;
|
18373
18512
|
const { gridParticipants, overflowGalleryParticipants } = useOrganizedParticipants({
|
18374
18513
|
remoteParticipants,
|
18375
18514
|
dominantSpeakers,
|
18376
|
-
maxRemoteVideoStreams,
|
18515
|
+
maxGridParticipants: remoteVideosOn ? maxRemoteVideoStreams : MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY,
|
18377
18516
|
isScreenShareActive: !!screenShareComponent,
|
18378
18517
|
maxOverflowGalleryDominantSpeakers: screenShareComponent
|
18379
18518
|
? childrenPerPage.current - (pinnedParticipantUserIds.length % childrenPerPage.current)
|
@@ -18489,7 +18628,7 @@ const SpeakerVideoLayout = (props) => {
|
|
18489
18628
|
const { gridParticipants, overflowGalleryParticipants } = useOrganizedParticipants({
|
18490
18629
|
remoteParticipants,
|
18491
18630
|
dominantSpeakers,
|
18492
|
-
maxRemoteVideoStreams,
|
18631
|
+
maxGridParticipants: maxRemoteVideoStreams,
|
18493
18632
|
isScreenShareActive: !!screenShareComponent,
|
18494
18633
|
maxOverflowGalleryDominantSpeakers: screenShareComponent
|
18495
18634
|
? childrenPerPage.current - (pinnedParticipantUserIds.length % childrenPerPage.current)
|
@@ -18624,7 +18763,7 @@ const LargeGalleryLayout = (props) => {
|
|
18624
18763
|
remoteParticipants,
|
18625
18764
|
localParticipant,
|
18626
18765
|
dominantSpeakers,
|
18627
|
-
|
18766
|
+
maxGridParticipants: maxStreamsTrampoline(),
|
18628
18767
|
isScreenShareActive: !!screenShareComponent,
|
18629
18768
|
maxOverflowGalleryDominantSpeakers: screenShareComponent
|
18630
18769
|
? childrenPerPage.current - ((pinnedParticipantUserIds.length + 1) % childrenPerPage.current)
|
@@ -31178,7 +31317,7 @@ const SidePaneHeader = (props) => {
|
|
31178
31317
|
return React.createElement(SidePaneMobileHeader, Object.assign({}, props));
|
31179
31318
|
}
|
31180
31319
|
return (React.createElement(react.Stack, { horizontal: true, horizontalAlign: "space-between", styles: sidePaneHeaderContainerStyles, verticalAlign: "center" },
|
31181
|
-
React.createElement(react.Stack.Item, { role: "heading", styles: sidePaneHeaderStyles }, props.headingText),
|
31320
|
+
React.createElement(react.Stack.Item, { role: "heading", styles: sidePaneHeaderStyles, "aria-label": props.headingText }, props.headingText),
|
31182
31321
|
React.createElement(react.Stack.Item, null,
|
31183
31322
|
React.createElement(react.CommandBarButton, { ariaLabel: props.dismissSidePaneButtonAriaLabel, styles: sidePaneCloseButtonStyles, iconProps: { iconName: 'cancel' }, onClick: props.onClose }))));
|
31184
31323
|
};
|
@@ -33754,14 +33893,11 @@ const LocalDeviceSettings = (props) => {
|
|
33754
33893
|
const role = (_a = adapter.getState().call) === null || _a === void 0 ? void 0 : _a.role;
|
33755
33894
|
const cameraPermissionGranted = props.cameraPermissionGranted;
|
33756
33895
|
const micPermissionGranted = props.microphonePermissionGranted;
|
33757
|
-
|
33758
|
-
|
33759
|
-
roleCanUseCamera = role === 'Consumer' ? false : true;
|
33760
|
-
roleCanUseMic = role === 'Consumer' ? false : true;
|
33896
|
+
const roleCanUseCamera = role !== 'Consumer';
|
33897
|
+
const roleCanUseMic = role !== 'Consumer';
|
33761
33898
|
// TODO: speaker permission is tied to microphone permission (when you request 'audio' permission using the SDK) its
|
33762
33899
|
// actually granting access to query both microphone and speaker. However the browser popup asks you explicity for
|
33763
33900
|
// 'microphone'. This needs investigation on how we want to handle this and maybe needs follow up with SDK team.
|
33764
|
-
/* @conditional-compile-remove(call-readiness) */
|
33765
33901
|
React.useEffect(() => {
|
33766
33902
|
if (cameraPermissionGranted) {
|
33767
33903
|
adapter.queryCameras();
|
@@ -39675,4 +39811,4 @@ exports.useTeamsCall = useTeamsCall;
|
|
39675
39811
|
exports.useTeamsCallAdapter = useTeamsCallAdapter;
|
39676
39812
|
exports.useTeamsCallAgent = useTeamsCallAgent;
|
39677
39813
|
exports.useTheme = useTheme;
|
39678
|
-
//# sourceMappingURL=index-
|
39814
|
+
//# sourceMappingURL=index-BP7335hI.js.map
|