@azure/communication-react 1.10.1-alpha-202311230013 → 1.10.1-alpha-202311250012

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.
Files changed (90) hide show
  1. package/dist/communication-react.d.ts +17 -14
  2. package/dist/dist-cjs/communication-react/index.js +1215 -1042
  3. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  4. package/dist/dist-esm/acs-ui-common/src/index.d.ts +1 -0
  5. package/dist/dist-esm/acs-ui-common/src/index.js.map +1 -1
  6. package/dist/dist-esm/acs-ui-common/src/telemetry.d.ts +7 -1
  7. package/dist/dist-esm/acs-ui-common/src/telemetry.js +24 -2
  8. package/dist/dist-esm/acs-ui-common/src/telemetry.js.map +1 -1
  9. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  10. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  11. package/dist/dist-esm/calling-stateful-client/src/StatefulCallClient.d.ts +7 -0
  12. package/dist/dist-esm/calling-stateful-client/src/StatefulCallClient.js +12 -4
  13. package/dist/dist-esm/calling-stateful-client/src/StatefulCallClient.js.map +1 -1
  14. package/dist/dist-esm/calling-stateful-client/src/index.d.ts +1 -0
  15. package/dist/dist-esm/calling-stateful-client/src/index.js +1 -0
  16. package/dist/dist-esm/calling-stateful-client/src/index.js.map +1 -1
  17. package/dist/dist-esm/chat-stateful-client/src/StatefulChatClient.d.ts +7 -0
  18. package/dist/dist-esm/chat-stateful-client/src/StatefulChatClient.js +10 -2
  19. package/dist/dist-esm/chat-stateful-client/src/StatefulChatClient.js.map +1 -1
  20. package/dist/dist-esm/chat-stateful-client/src/index.d.ts +1 -1
  21. package/dist/dist-esm/chat-stateful-client/src/index.js +1 -1
  22. package/dist/dist-esm/chat-stateful-client/src/index.js.map +1 -1
  23. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponent.js +2 -2
  24. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponent.js.map +1 -1
  25. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.js +1 -1
  26. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.js.map +1 -1
  27. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.d.ts +46 -0
  28. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.js +53 -0
  29. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.js.map +1 -0
  30. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.d.ts +1 -1
  31. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +16 -10
  32. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
  33. package/dist/dist-esm/react-components/src/components/ChatMessage/DefaultSystemMessage.d.ts +6 -0
  34. package/dist/dist-esm/react-components/src/components/ChatMessage/DefaultSystemMessage.js +38 -0
  35. package/dist/dist-esm/react-components/src/components/ChatMessage/DefaultSystemMessage.js.map +1 -0
  36. package/dist/dist-esm/react-components/src/components/ChatMessage/FluentChatMessageComponentWrapper.d.ts +23 -0
  37. package/dist/dist-esm/react-components/src/components/ChatMessage/FluentChatMessageComponentWrapper.js +183 -0
  38. package/dist/dist-esm/react-components/src/components/ChatMessage/FluentChatMessageComponentWrapper.js.map +1 -0
  39. package/dist/dist-esm/react-components/src/components/MessageThread.d.ts +5 -7
  40. package/dist/dist-esm/react-components/src/components/MessageThread.js +92 -247
  41. package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
  42. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js +1 -3
  43. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js.map +1 -1
  44. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js +3 -2
  45. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js.map +1 -1
  46. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.d.ts +0 -2
  47. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js +5 -4
  48. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js.map +1 -1
  49. package/dist/dist-esm/react-components/src/components/VideoGallery/SpeakerVideoLayout.js +3 -2
  50. package/dist/dist-esm/react-components/src/components/VideoGallery/SpeakerVideoLayout.js.map +1 -1
  51. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.d.ts +19 -7
  52. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +38 -10
  53. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js.map +1 -1
  54. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.d.ts +14 -5
  55. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.js.map +1 -1
  56. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallingSoundSubscriber.d.ts +3 -3
  57. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallingSoundSubscriber.js +10 -13
  58. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallingSoundSubscriber.js.map +1 -1
  59. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/index.d.ts +1 -1
  60. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/index.js +1 -1
  61. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/index.js.map +1 -1
  62. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/SidePane/SidePane.js +1 -1
  63. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/SidePane/SidePane.js.map +1 -1
  64. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/LocalVideoTileSelector.d.ts +1 -0
  65. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/activeVideoBackgroundEffectSelector.d.ts +1 -0
  66. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/callStatusSelector.d.ts +1 -0
  67. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/capabilitiesChangedInfoAndRoleSelector.d.ts +1 -0
  68. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/complianceBannerSelector.d.ts +1 -0
  69. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/deviceCountSelector.d.ts +1 -0
  70. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/devicePermissionSelector.d.ts +1 -0
  71. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/dominantRemoteParticipantSelector.d.ts +1 -0
  72. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/lobbySelector.d.ts +1 -0
  73. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/localAndRemotePIPSelector.d.ts +1 -0
  74. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/localPreviewSelector.d.ts +1 -0
  75. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/localVideoStreamSelector.d.ts +1 -0
  76. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/mediaGallerySelector.d.ts +2 -0
  77. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/mutedNotificationSelector.d.ts +1 -0
  78. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/networkReconnectTileSelector.d.ts +1 -0
  79. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js +6 -8
  80. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js.map +1 -1
  81. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +6 -11
  82. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js.map +1 -1
  83. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatComposite.js +3 -13
  84. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatComposite.js.map +1 -1
  85. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +10 -4
  86. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
  87. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.d.ts +7 -0
  88. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js +13 -5
  89. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js.map +1 -1
  90. package/package.json +1 -1
@@ -18,10 +18,10 @@ var reactFileTypeIcons = require('@fluentui/react-file-type-icons');
18
18
  var uuid = require('uuid');
19
19
  var reactChat = require('@fluentui-contrib/react-chat');
20
20
  var reactComponents = require('@fluentui/react-components');
21
+ var react$1 = require('@griffel/react');
21
22
  var htmlToReact = require('html-to-react');
22
23
  var Linkify = require('react-linkify');
23
24
  var DOMPurify = require('dompurify');
24
- var react$1 = require('@griffel/react');
25
25
  var reactHooks = require('@fluentui/react-hooks');
26
26
  var reactUseDraggableScroll = require('react-use-draggable-scroll');
27
27
  var reactWindowProvider = require('@fluentui/react-window-provider');
@@ -177,7 +177,7 @@ const _isValidIdentifier = (identifier) => {
177
177
  // Copyright (c) Microsoft Corporation.
178
178
  // Licensed under the MIT License.
179
179
  // GENERATED FILE. DO NOT EDIT MANUALLY.
180
- var telemetryVersion = '1.10.1-alpha-202311230013';
180
+ var telemetryVersion = '1.10.1-alpha-202311250012';
181
181
 
182
182
  // Copyright (c) Microsoft Corporation.
183
183
  /**
@@ -192,6 +192,25 @@ const sanitize = (version) => {
192
192
  }
193
193
  return version;
194
194
  };
195
+ /**
196
+ * Takes a telemetry implementation hint and returns the numerical value.
197
+ *
198
+ * @private
199
+ */
200
+ const getTelemetryImplementationHint = (telemetryImplementationHint) => {
201
+ switch (telemetryImplementationHint) {
202
+ case 'Call':
203
+ return 1;
204
+ case 'Chat':
205
+ return 2;
206
+ case 'CallWithChat':
207
+ return 3;
208
+ case 'StatefulComponents':
209
+ return 4;
210
+ default:
211
+ return 0;
212
+ }
213
+ };
195
214
  /**
196
215
  * Application ID to be included in telemetry data from the UI library.
197
216
  * Template: acXYYY/<version>
@@ -207,9 +226,12 @@ const sanitize = (version) => {
207
226
  *
208
227
  * @internal
209
228
  */
210
- const _getApplicationId = () => {
229
+ const _getApplicationId = (telemetryImplementationHint) => {
230
+ const highLevelArtifact = 0;
231
+ const specificImplementation = getTelemetryImplementationHint(telemetryImplementationHint);
232
+ const implementationDetails = 0;
211
233
  const version = telemetryVersion;
212
- return sanitize(`acr/${version}`);
234
+ return sanitize(`acr${highLevelArtifact}${specificImplementation}${implementationDetails}/${version}`);
213
235
  };
214
236
 
215
237
  // Copyright (c) Microsoft Corporation.
@@ -4783,8 +4805,16 @@ class ProxyCallClient {
4783
4805
  * @public
4784
4806
  */
4785
4807
  const createStatefulCallClient = (args, options) => {
4786
- callingStatefulLogger.info(`Creating calling stateful client using library version: ${_getApplicationId()}`);
4787
- return createStatefulCallClientWithDeps(new communicationCalling.CallClient(withTelemetryTag(options === null || options === void 0 ? void 0 : options.callClientOptions)), new CallContext$2(communicationCommon.getIdentifierKind(args.userId), options === null || options === void 0 ? void 0 : options.maxStateChangeListeners,
4808
+ return _createStatefulCallClientInner(args, options);
4809
+ };
4810
+ /**
4811
+ * This inner function is used to allow injection of TelemetryImplementationHint without changing the public API.
4812
+ *
4813
+ * @internal
4814
+ */
4815
+ const _createStatefulCallClientInner = (args, options, telemetryImplementationHint = 'StatefulComponents') => {
4816
+ callingStatefulLogger.info(`Creating calling stateful client using library version: ${_getApplicationId(telemetryImplementationHint)}`);
4817
+ return createStatefulCallClientWithDeps(new communicationCalling.CallClient(withTelemetryTag(telemetryImplementationHint, options === null || options === void 0 ? void 0 : options.callClientOptions)), new CallContext$2(communicationCommon.getIdentifierKind(args.userId), options === null || options === void 0 ? void 0 : options.maxStateChangeListeners,
4788
4818
  /* @conditional-compile-remove(PSTN-calls) */ args.alternateCallerId), new InternalCallContext());
4789
4819
  };
4790
4820
  /**
@@ -4827,10 +4857,10 @@ const createStatefulCallClientWithDeps = (callClient, context, internalContext)
4827
4857
  });
4828
4858
  return new Proxy(callClient, new ProxyCallClient(context, internalContext));
4829
4859
  };
4830
- const withTelemetryTag = (options) => {
4860
+ const withTelemetryTag = (telemetryImplementationHint, options) => {
4831
4861
  var _a, _b;
4832
4862
  const tags = (_b = (_a = options === null || options === void 0 ? void 0 : options.diagnostics) === null || _a === void 0 ? void 0 : _a.tags) !== null && _b !== void 0 ? _b : [];
4833
- tags.push(_getApplicationId());
4863
+ tags.push(_getApplicationId(telemetryImplementationHint));
4834
4864
  return Object.assign(Object.assign({}, options), { diagnostics: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.diagnostics), { tags }) });
4835
4865
  };
4836
4866
 
@@ -9000,168 +9030,697 @@ const delay = (delay) => {
9000
9030
 
9001
9031
  // Copyright (c) Microsoft Corporation.
9002
9032
  /**
9003
- * @private
9004
- */
9005
- const systemMessageIconStyle = react.mergeStyles({
9006
- marginInlineEnd: '0.688rem'
9007
- });
9008
-
9009
- // Copyright (c) Microsoft Corporation.
9010
- /**
9011
- * @private
9033
+ * A utility hook for providing the width of a parent element.
9034
+ * Returns updated width if parent/window resizes.
9035
+ * @param containerRef - Ref of a parent element whose width will be returned.
9036
+ * @internal
9012
9037
  */
9013
- const SystemMessage = (props) => {
9014
- const { iconName, content } = props;
9015
- const Icon = React__default["default"].createElement(react.FontIcon, { iconName: iconName, className: react.mergeStyles(systemMessageIconStyle) });
9016
- return (React__default["default"].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(props === null || props === void 0 ? void 0 : props.containerStyle), tabIndex: 0 },
9017
- Icon,
9018
- React__default["default"].createElement(react.Text, { style: { wordBreak: 'break-word' }, role: "status", title: content, variant: 'small' }, content)));
9038
+ const _useContainerWidth = (containerRef) => {
9039
+ const [width, setWidth] = React.useState(undefined);
9040
+ const observer = React.useRef(new ResizeObserver((entries) => {
9041
+ const { width } = entries[0].contentRect;
9042
+ setWidth(width);
9043
+ }));
9044
+ React.useEffect(() => {
9045
+ if (containerRef.current) {
9046
+ observer.current.observe(containerRef.current);
9047
+ }
9048
+ const currentObserver = observer.current;
9049
+ return () => {
9050
+ currentObserver.disconnect();
9051
+ };
9052
+ }, [containerRef, observer]);
9053
+ return width;
9019
9054
  };
9020
-
9021
- // Copyright (c) Microsoft Corporation.
9022
9055
  /**
9023
- * @private
9056
+ * A utility hook for providing the height of a parent element.
9057
+ * Returns updated height if parent/window resizes.
9058
+ * @param containerRef - Ref of a parent element whose height will be returned.
9059
+ * @internal
9024
9060
  */
9025
- const editBoxStyle = react.mergeStyles({
9026
- marginTop: '0.0875rem',
9027
- marginBottom: '0.0875rem'
9028
- });
9061
+ const _useContainerHeight = (containerRef) => {
9062
+ const [height, setHeight] = React.useState(undefined);
9063
+ const observer = React.useRef(new ResizeObserver((entries) => {
9064
+ const { height } = entries[0].contentRect;
9065
+ setHeight(height);
9066
+ }));
9067
+ React.useEffect(() => {
9068
+ if (containerRef.current) {
9069
+ observer.current.observe(containerRef.current);
9070
+ }
9071
+ const currentObserver = observer.current;
9072
+ return () => {
9073
+ currentObserver.disconnect();
9074
+ };
9075
+ }, [containerRef, observer]);
9076
+ return height;
9077
+ };
9078
+ const NARROW_WIDTH_REM = 30;
9079
+ const SHORT_HEIGHT_REM = 23.75;
9029
9080
  /**
9030
- * @private
9081
+ * Utility function to determine if container width is narrow
9082
+ * @param containerWidthRem container width in rem
9083
+ * @returns boolean
9031
9084
  */
9032
- const editingButtonStyle = react.mergeStyles({
9033
- margin: '0',
9034
- width: '2.125rem',
9035
- height: '2.125rem',
9036
- padding: '0.375rem 0 0 0'
9037
- });
9085
+ const isNarrowWidth = (containerWidthRem) => containerWidthRem <= _convertRemToPx(NARROW_WIDTH_REM);
9038
9086
  /**
9039
- * @private
9087
+ * Utility function to determine if container width is short
9088
+ * @param containerWidthRem container height in rem
9089
+ * @returns boolean
9040
9090
  */
9041
- const inputBoxIcon = react.mergeStyles({
9042
- margin: 'auto',
9043
- '&:hover svg': {
9044
- stroke: 'currentColor'
9045
- }
9046
- });
9091
+ const isShortHeight = (containerHeightRem) => containerHeightRem <= _convertRemToPx(SHORT_HEIGHT_REM);
9092
+
9093
+ // Copyright (c) Microsoft Corporation.
9094
+ // Licensed under the MIT License.
9047
9095
  /**
9048
9096
  * @private
9049
- */
9050
- const editBoxStyleSet = {
9051
- root: {
9052
- minWidth: '6.25rem',
9053
- maxWidth: '100%'
9054
- }
9097
+ *logic: Looking at message A, how do we know it's read number?
9098
+ * Assumption: if user read the latest message, user has read all messages before that
9099
+ * ReadReceipt behaviour: read receipt is only sent to the last message
9100
+ *
9101
+ * If participant read a message that is sent later than message A, then the participant has read message A
9102
+ * How do we check if the message is sent later than message A?
9103
+ * We compare if the messageID of the last read message is larger than or equal to the message A's id
9104
+ * Because messageID is the creation timestamp of each message
9105
+ * Timestamps are in epoch time so lecixographical ordering is the same as time ordering.
9106
+ *
9107
+ * if MessageId of B is larger than message Id of A, then B is created after A
9108
+ * if the last read message is created after the message A is sent, then user should have read message A as well */
9109
+ var getParticipantsWhoHaveReadMessage = (message, readReceiptsBySenderId) => {
9110
+ return (Object.entries(readReceiptsBySenderId)
9111
+ // Filter to only read receipts that match the message OR the participant has read a different message after this message has been created
9112
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9113
+ .filter(([_, readReceipt]) => readReceipt.lastReadMessage >= message.messageId)
9114
+ // make sure the person is not removed from chat
9115
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9116
+ .filter(([_, readReceipt]) => readReceipt.displayName && readReceipt.displayName !== '')
9117
+ // Map properties to useful array
9118
+ .map(([id, readReceipt]) => ({ id, displayName: readReceipt.displayName })));
9055
9119
  };
9056
9120
 
9057
9121
  // Copyright (c) Microsoft Corporation.
9058
- const MINIMUM_TOUCH_TARGET_HEIGHT_REM$1 = 3;
9059
- const errorTextColor = 'var(--errorText)';
9122
+ // Licensed under the MIT License.
9123
+ // These color records are required for createV9Theme
9124
+ // For more info, check https://react.fluentui.dev/iframe.html?viewMode=docs&id=concepts-migration-from-v8-components-theme-migration--page#compatible-themes
9060
9125
  /**
9061
9126
  * @private
9062
9127
  */
9063
- const iconWrapperStyle = (theme, isSubMenuOpen) => ({
9064
- root: {
9065
- margin: _pxToRem(3),
9066
- // Show hover styles when the Edit/Delete menu is showing as this action button is still considered 'active'
9067
- color: isSubMenuOpen ? theme.palette.black : theme.palette.neutralPrimary,
9068
- strokeWidth: isSubMenuOpen ? _pxToRem(0.5) : _pxToRem(0),
9069
- stroke: theme.palette.black,
9070
- ':hover, :focus': {
9071
- color: theme.palette.black,
9072
- strokeWidth: _pxToRem(0.5)
9073
- }
9074
- }
9075
- });
9128
+ const grey = {
9129
+ '0': '#000000',
9130
+ '2': '#050505',
9131
+ '4': '#0a0a0a',
9132
+ '6': '#0f0f0f',
9133
+ '8': '#141414',
9134
+ '10': '#1a1a1a',
9135
+ '12': '#1f1f1f',
9136
+ '14': '#242424',
9137
+ '16': '#292929',
9138
+ '18': '#2e2e2e',
9139
+ '20': '#333333',
9140
+ '22': '#383838',
9141
+ '24': '#3d3d3d',
9142
+ '26': '#424242',
9143
+ '28': '#474747',
9144
+ '30': '#4d4d4d',
9145
+ '32': '#525252',
9146
+ '34': '#575757',
9147
+ '36': '#5c5c5c',
9148
+ '38': '#616161',
9149
+ '40': '#666666',
9150
+ '42': '#6b6b6b',
9151
+ '44': '#707070',
9152
+ '46': '#757575',
9153
+ '48': '#7a7a7a',
9154
+ '50': '#808080',
9155
+ '52': '#858585',
9156
+ '54': '#8a8a8a',
9157
+ '56': '#8f8f8f',
9158
+ '58': '#949494',
9159
+ '60': '#999999',
9160
+ '62': '#9e9e9e',
9161
+ '64': '#a3a3a3',
9162
+ '66': '#a8a8a8',
9163
+ '68': '#adadad',
9164
+ '70': '#b3b3b3',
9165
+ '72': '#b8b8b8',
9166
+ '74': '#bdbdbd',
9167
+ '76': '#c2c2c2',
9168
+ '78': '#c7c7c7',
9169
+ '80': '#cccccc',
9170
+ '82': '#d1d1d1',
9171
+ '84': '#d6d6d6',
9172
+ '86': '#dbdbdb',
9173
+ '88': '#e0e0e0',
9174
+ '90': '#e6e6e6',
9175
+ '92': '#ebebeb',
9176
+ '94': '#f0f0f0',
9177
+ '96': '#f5f5f5',
9178
+ '98': '#fafafa',
9179
+ '100': '#ffffff'
9180
+ };
9076
9181
  /**
9077
9182
  * @private
9078
9183
  */
9079
- const chatMessageDateStyle = react.mergeStyles({
9080
- color: reactComponents.tokens.colorNeutralForeground2,
9081
- fontWeight: react.FontWeights.regular,
9082
- fontSize: '0.75rem'
9083
- });
9184
+ const whiteAlpha = {
9185
+ '5': 'rgba(255, 255, 255, 0.05)',
9186
+ '10': 'rgba(255, 255, 255, 0.1)',
9187
+ '20': 'rgba(255, 255, 255, 0.2)',
9188
+ '30': 'rgba(255, 255, 255, 0.3)',
9189
+ '40': 'rgba(255, 255, 255, 0.4)',
9190
+ '50': 'rgba(255, 255, 255, 0.5)',
9191
+ '60': 'rgba(255, 255, 255, 0.6)',
9192
+ '70': 'rgba(255, 255, 255, 0.7)',
9193
+ '80': 'rgba(255, 255, 255, 0.8)',
9194
+ '90': 'rgba(255, 255, 255, 0.9)'
9195
+ };
9084
9196
  /**
9085
9197
  * @private
9086
9198
  */
9087
- const chatMessageAuthorStyle = react.mergeStyles({
9088
- fontWeight: react.FontWeights.semibold,
9089
- fontSize: '0.75rem'
9090
- });
9199
+ const blackAlpha = {
9200
+ '5': 'rgba(0, 0, 0, 0.05)',
9201
+ '10': 'rgba(0, 0, 0, 0.1)',
9202
+ '20': 'rgba(0, 0, 0, 0.2)',
9203
+ '30': 'rgba(0, 0, 0, 0.3)',
9204
+ '40': 'rgba(0, 0, 0, 0.4)',
9205
+ '50': 'rgba(0, 0, 0, 0.5)',
9206
+ '60': 'rgba(0, 0, 0, 0.6)',
9207
+ '70': 'rgba(0, 0, 0, 0.7)',
9208
+ '80': 'rgba(0, 0, 0, 0.8)',
9209
+ '90': 'rgba(0, 0, 0, 0.9)'
9210
+ };
9091
9211
  /**
9092
9212
  * @private
9093
9213
  */
9094
- const chatMessageEditedTagStyle = (theme) => react.mergeStyles({ fontWeight: react.FontWeights.semibold, color: theme.palette.neutralSecondary });
9214
+ const grey10Alpha = {
9215
+ '5': 'rgba(26, 26, 26, 0.05)',
9216
+ '10': 'rgba(26, 26, 26, 0.1)',
9217
+ '20': 'rgba(26, 26, 26, 0.2)',
9218
+ '30': 'rgba(26, 26, 26, 0.3)',
9219
+ '40': 'rgba(26, 26, 26, 0.4)',
9220
+ '50': 'rgba(26, 26, 26, 0.5)',
9221
+ '60': 'rgba(26, 26, 26, 0.6)',
9222
+ '70': 'rgba(26, 26, 26, 0.7)',
9223
+ '80': 'rgba(26, 26, 26, 0.8)',
9224
+ '90': 'rgba(26, 26, 26, 0.9)'
9225
+ };
9095
9226
  /**
9096
9227
  * @private
9097
9228
  */
9098
- const chatMessageFailedTagStyle = (theme) => react.mergeStyles({
9099
- fontWeight: react.FontWeights.regular,
9100
- color: theme.semanticColors.errorText,
9101
- fontSize: theme.fonts.smallPlus.fontSize,
9102
- lineHeight: '1rem'
9103
- });
9229
+ const grey12Alpha = {
9230
+ '5': 'rgba(31, 31, 31, 0.05)',
9231
+ '10': 'rgba(31, 31, 31, 0.1)',
9232
+ '20': 'rgba(31, 31, 31, 0.2)',
9233
+ '30': 'rgba(31, 31, 31, 0.3)',
9234
+ '40': 'rgba(31, 31, 31, 0.4)',
9235
+ '50': 'rgba(31, 31, 31, 0.5)',
9236
+ '60': 'rgba(31, 31, 31, 0.6)',
9237
+ '70': 'rgba(31, 31, 31, 0.7)',
9238
+ '80': 'rgba(31, 31, 31, 0.8)',
9239
+ '90': 'rgba(31, 31, 31, 0.9)'
9240
+ };
9241
+
9242
+ // Copyright (c) Microsoft Corporation.
9243
+ // These mappings are required for createV9Theme
9244
+ // For more info, check https://react.fluentui.dev/iframe.html?viewMode=docs&id=concepts-migration-from-v8-components-theme-migration--page#compatible-themes
9104
9245
  /**
9105
- * @private
9246
+ * Creates v9 color tokens from a v8 palette.
9106
9247
  */
9107
- const editChatMessageFailedTagStyle = react.mergeStyles({
9108
- marginBottom: '0.5rem'
9109
- });
9248
+ const mapAliasColors = (palette, inverted) => {
9249
+ return {
9250
+ colorNeutralForeground1: palette.neutralPrimary,
9251
+ colorNeutralForeground1Hover: palette.neutralPrimary,
9252
+ colorNeutralForeground1Pressed: palette.neutralPrimary,
9253
+ colorNeutralForeground1Selected: palette.neutralPrimary,
9254
+ colorNeutralForeground2: palette.neutralSecondary,
9255
+ colorNeutralForeground2Hover: palette.neutralPrimary,
9256
+ colorNeutralForeground2Pressed: palette.neutralPrimary,
9257
+ colorNeutralForeground2Selected: palette.neutralPrimary,
9258
+ colorNeutralForeground2BrandHover: palette.themePrimary,
9259
+ colorNeutralForeground2BrandPressed: palette.themeDarkAlt,
9260
+ colorNeutralForeground2BrandSelected: palette.themePrimary,
9261
+ colorNeutralForeground3: palette.neutralTertiary,
9262
+ colorNeutralForeground3Hover: palette.neutralSecondary,
9263
+ colorNeutralForeground3Pressed: palette.neutralSecondary,
9264
+ colorNeutralForeground3Selected: palette.neutralSecondary,
9265
+ colorNeutralForeground3BrandHover: palette.themePrimary,
9266
+ colorNeutralForeground3BrandPressed: palette.themeDarkAlt,
9267
+ colorNeutralForeground3BrandSelected: palette.themePrimary,
9268
+ colorNeutralForeground4: palette.neutralQuaternary,
9269
+ colorNeutralForegroundDisabled: palette.neutralTertiaryAlt,
9270
+ colorNeutralForegroundInvertedDisabled: whiteAlpha[40],
9271
+ colorBrandForegroundLink: palette.themeDarkAlt,
9272
+ colorBrandForegroundLinkHover: palette.themeDark,
9273
+ colorBrandForegroundLinkPressed: palette.themeDarker,
9274
+ colorBrandForegroundLinkSelected: palette.themeDarkAlt,
9275
+ colorNeutralForeground2Link: palette.neutralSecondary,
9276
+ colorNeutralForeground2LinkHover: palette.neutralPrimary,
9277
+ colorNeutralForeground2LinkPressed: palette.neutralPrimary,
9278
+ colorNeutralForeground2LinkSelected: palette.neutralPrimary,
9279
+ colorCompoundBrandForeground1: palette.themePrimary,
9280
+ colorCompoundBrandForeground1Hover: palette.themeDarkAlt,
9281
+ colorCompoundBrandForeground1Pressed: palette.themeDark,
9282
+ colorBrandForeground1: palette.themePrimary,
9283
+ colorBrandForeground2: palette.themeDarkAlt,
9284
+ colorBrandForeground2Hover: palette.themeDarkAlt,
9285
+ colorBrandForeground2Pressed: palette.themeDarkAlt,
9286
+ colorNeutralForeground1Static: palette.neutralPrimary,
9287
+ colorNeutralForegroundInverted: palette.white,
9288
+ colorNeutralForegroundInvertedHover: palette.white,
9289
+ colorNeutralForegroundInvertedPressed: palette.white,
9290
+ colorNeutralForegroundInvertedSelected: palette.white,
9291
+ colorNeutralForegroundOnBrand: palette.white,
9292
+ colorNeutralForegroundStaticInverted: palette.white,
9293
+ colorNeutralForegroundInvertedLink: palette.white,
9294
+ colorNeutralForegroundInvertedLinkHover: palette.white,
9295
+ colorNeutralForegroundInvertedLinkPressed: palette.white,
9296
+ colorNeutralForegroundInvertedLinkSelected: palette.white,
9297
+ colorNeutralForegroundInverted2: palette.white,
9298
+ colorBrandForegroundInverted: palette.themeSecondary,
9299
+ colorBrandForegroundInvertedHover: palette.themeTertiary,
9300
+ colorBrandForegroundInvertedPressed: palette.themeSecondary,
9301
+ colorBrandForegroundOnLight: palette.themePrimary,
9302
+ colorBrandForegroundOnLightHover: palette.themeDarkAlt,
9303
+ colorBrandForegroundOnLightPressed: palette.themeDark,
9304
+ colorBrandForegroundOnLightSelected: palette.themeDark,
9305
+ colorNeutralBackground1: palette.white,
9306
+ colorNeutralBackground1Hover: palette.neutralLighter,
9307
+ colorNeutralBackground1Pressed: palette.neutralQuaternaryAlt,
9308
+ colorNeutralBackground1Selected: palette.neutralLight,
9309
+ colorNeutralBackground2: palette.neutralLighterAlt,
9310
+ colorNeutralBackground2Hover: palette.neutralLighter,
9311
+ colorNeutralBackground2Pressed: palette.neutralQuaternaryAlt,
9312
+ colorNeutralBackground2Selected: palette.neutralLight,
9313
+ colorNeutralBackground3: palette.neutralLighter,
9314
+ colorNeutralBackground3Hover: palette.neutralLight,
9315
+ colorNeutralBackground3Pressed: palette.neutralQuaternary,
9316
+ colorNeutralBackground3Selected: palette.neutralQuaternaryAlt,
9317
+ colorNeutralBackground4: palette.neutralLighter,
9318
+ colorNeutralBackground4Hover: palette.neutralLighterAlt,
9319
+ colorNeutralBackground4Pressed: palette.neutralLighter,
9320
+ colorNeutralBackground4Selected: palette.white,
9321
+ colorNeutralBackground5: palette.neutralLight,
9322
+ colorNeutralBackground5Hover: palette.neutralLighter,
9323
+ colorNeutralBackground5Pressed: palette.neutralLighter,
9324
+ colorNeutralBackground5Selected: palette.neutralLighterAlt,
9325
+ colorNeutralBackground6: palette.neutralLight,
9326
+ colorNeutralBackgroundStatic: grey[20],
9327
+ colorNeutralBackgroundInverted: palette.neutralSecondary,
9328
+ colorNeutralBackgroundAlpha: inverted ? grey10Alpha[50] : whiteAlpha[50],
9329
+ colorNeutralBackgroundAlpha2: inverted ? grey12Alpha[70] : whiteAlpha[80],
9330
+ colorSubtleBackground: 'transparent',
9331
+ colorSubtleBackgroundHover: palette.neutralLighter,
9332
+ colorSubtleBackgroundPressed: palette.neutralQuaternaryAlt,
9333
+ colorSubtleBackgroundSelected: palette.neutralLight,
9334
+ colorSubtleBackgroundLightAlphaHover: inverted ? whiteAlpha[10] : whiteAlpha[80],
9335
+ colorSubtleBackgroundLightAlphaPressed: inverted ? whiteAlpha[5] : whiteAlpha[50],
9336
+ colorSubtleBackgroundLightAlphaSelected: 'transparent',
9337
+ colorSubtleBackgroundInverted: 'transparent',
9338
+ colorSubtleBackgroundInvertedHover: blackAlpha[10],
9339
+ colorSubtleBackgroundInvertedPressed: blackAlpha[30],
9340
+ colorSubtleBackgroundInvertedSelected: blackAlpha[20],
9341
+ colorTransparentBackground: 'transparent',
9342
+ colorTransparentBackgroundHover: 'transparent',
9343
+ colorTransparentBackgroundPressed: 'transparent',
9344
+ colorTransparentBackgroundSelected: 'transparent',
9345
+ colorNeutralBackgroundDisabled: palette.neutralLighter,
9346
+ colorNeutralBackgroundInvertedDisabled: whiteAlpha[10],
9347
+ colorNeutralStencil1: palette.neutralLight,
9348
+ colorNeutralStencil2: palette.neutralLighterAlt,
9349
+ colorNeutralStencil1Alpha: inverted ? whiteAlpha[10] : blackAlpha[10],
9350
+ colorNeutralStencil2Alpha: inverted ? whiteAlpha[5] : blackAlpha[5],
9351
+ colorBackgroundOverlay: blackAlpha[40],
9352
+ colorScrollbarOverlay: blackAlpha[50],
9353
+ colorBrandBackground: palette.themePrimary,
9354
+ colorBrandBackgroundHover: palette.themeDarkAlt,
9355
+ colorBrandBackgroundPressed: palette.themeDarker,
9356
+ colorBrandBackgroundSelected: palette.themeDark,
9357
+ colorCompoundBrandBackground: palette.themePrimary,
9358
+ colorCompoundBrandBackgroundHover: palette.themeDarkAlt,
9359
+ colorCompoundBrandBackgroundPressed: palette.themeDark,
9360
+ colorBrandBackgroundStatic: palette.themePrimary,
9361
+ colorBrandBackground2: palette.themeLighterAlt,
9362
+ colorBrandBackground2Hover: palette.themeLighterAlt,
9363
+ colorBrandBackground2Pressed: palette.themeLighterAlt,
9364
+ colorBrandBackgroundInverted: palette.white,
9365
+ colorBrandBackgroundInvertedHover: palette.themeLighterAlt,
9366
+ colorBrandBackgroundInvertedPressed: palette.themeLight,
9367
+ colorBrandBackgroundInvertedSelected: palette.themeLighter,
9368
+ colorNeutralStrokeAccessible: palette.neutralSecondary,
9369
+ colorNeutralStrokeAccessibleHover: palette.neutralSecondary,
9370
+ colorNeutralStrokeAccessiblePressed: palette.neutralSecondary,
9371
+ colorNeutralStrokeAccessibleSelected: palette.themePrimary,
9372
+ colorNeutralStroke1: palette.neutralQuaternary,
9373
+ colorNeutralStroke1Hover: palette.neutralTertiaryAlt,
9374
+ colorNeutralStroke1Pressed: palette.neutralTertiaryAlt,
9375
+ colorNeutralStroke1Selected: palette.neutralTertiaryAlt,
9376
+ colorNeutralStroke2: palette.neutralQuaternaryAlt,
9377
+ colorNeutralStroke3: palette.neutralLighter,
9378
+ colorNeutralStrokeSubtle: palette.neutralQuaternaryAlt,
9379
+ colorNeutralStrokeOnBrand: palette.white,
9380
+ colorNeutralStrokeOnBrand2: palette.white,
9381
+ colorNeutralStrokeOnBrand2Hover: palette.white,
9382
+ colorNeutralStrokeOnBrand2Pressed: palette.white,
9383
+ colorNeutralStrokeOnBrand2Selected: palette.white,
9384
+ colorBrandStroke1: palette.themePrimary,
9385
+ colorBrandStroke2: palette.themeLight,
9386
+ colorBrandStroke2Hover: palette.themeLight,
9387
+ colorBrandStroke2Pressed: palette.themeLight,
9388
+ colorBrandStroke2Contrast: palette.themeLight,
9389
+ colorCompoundBrandStroke: palette.themePrimary,
9390
+ colorCompoundBrandStrokeHover: palette.themeDarkAlt,
9391
+ colorCompoundBrandStrokePressed: palette.themeDark,
9392
+ colorNeutralStrokeDisabled: palette.neutralQuaternaryAlt,
9393
+ colorNeutralStrokeInvertedDisabled: whiteAlpha[40],
9394
+ colorTransparentStroke: 'transparent',
9395
+ colorTransparentStrokeInteractive: 'transparent',
9396
+ colorTransparentStrokeDisabled: 'transparent',
9397
+ colorNeutralStrokeAlpha: inverted ? whiteAlpha[10] : blackAlpha[5],
9398
+ colorNeutralStrokeAlpha2: whiteAlpha[20],
9399
+ colorStrokeFocus1: palette.white,
9400
+ colorStrokeFocus2: palette.black,
9401
+ colorNeutralShadowAmbient: 'rgba(0,0,0,0.12)',
9402
+ colorNeutralShadowKey: 'rgba(0,0,0,0.14)',
9403
+ colorNeutralShadowAmbientLighter: 'rgba(0,0,0,0.06)',
9404
+ colorNeutralShadowKeyLighter: 'rgba(0,0,0,0.07)',
9405
+ colorNeutralShadowAmbientDarker: 'rgba(0,0,0,0.20)',
9406
+ colorNeutralShadowKeyDarker: 'rgba(0,0,0,0.24)',
9407
+ colorBrandShadowAmbient: 'rgba(0,0,0,0.30)',
9408
+ colorBrandShadowKey: 'rgba(0,0,0,0.25)'
9409
+ };
9410
+ };
9110
9411
  /**
9111
- * @private
9412
+ * Creates v9 shadow tokens from v8 effects.
9112
9413
  */
9113
- const chatMessageFailedTagStackItemStyle = react.mergeStyles({
9114
- alignSelf: 'end'
9115
- });
9414
+ const mapShadowTokens = (effects) => {
9415
+ return {
9416
+ shadow4: effects.elevation4,
9417
+ shadow8: effects.elevation8,
9418
+ shadow16: effects.elevation16,
9419
+ shadow64: effects.elevation64
9420
+ };
9421
+ };
9116
9422
  /**
9117
- * @private
9423
+ * Creates v9 border radius tokens from v8 effects
9118
9424
  */
9119
- const editChatMessageButtonsStackStyle = react.mergeStyles({
9120
- padding: '0 0.5rem',
9121
- marginTop: '-0.25rem'
9122
- });
9425
+ const mapBorderRadiusTokens = (effects) => {
9426
+ return {
9427
+ borderRadiusSmall: effects.roundedCorner2,
9428
+ borderRadiusMedium: effects.roundedCorner4,
9429
+ borderRadiusLarge: effects.roundedCorner6
9430
+ };
9431
+ };
9123
9432
  /**
9433
+ * Creates a v9 theme from a v8 theme and base v9 theme.
9434
+ * FluentUI webLightTheme is used in case if no baseThemeV9 is provided.
9435
+ *
9124
9436
  * @private
9125
9437
  */
9126
- const chatMessageMenuStyle = react.mergeStyles({
9127
- minWidth: '8.5rem',
9128
- height: 'max-content',
9129
- cursor: 'pointer',
9130
- overflow: 'hidden'
9131
- });
9438
+ const createV9Theme = (themeV8, baseThemeV9) => {
9439
+ const baseTheme = baseThemeV9 !== null && baseThemeV9 !== void 0 ? baseThemeV9 : reactComponents.webLightTheme;
9440
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, baseTheme), mapAliasColors(themeV8.palette, themeV8.isInverted)), mapShadowTokens(themeV8.effects)), mapBorderRadiusTokens(themeV8.effects)), { colorBrandBackground2: themeV8.palette.themeLight, colorBrandBackground2Hover: themeV8.palette.themeLight, colorBrandBackground2Pressed: themeV8.palette.themeLight, colorStatusWarningBackground3: '#D83B01', errorText: themeV8.semanticColors.errorText, colorNeutralStroke1Selected: themeV8.palette.neutralQuaternary, colorNeutralForeground2: themeV8.palette.neutralSecondary, colorBrandForegroundLink: themeV8.palette.themePrimary, colorBrandForegroundLinkHover: themeV8.palette.themeDarker,
9441
+ // Fix for an issue with black borders for iOS that are added with 'after' selector
9442
+ colorStrokeFocus2: 'transparent' });
9443
+ };
9444
+
9445
+ // Copyright (c) Microsoft Corporation.
9132
9446
  /**
9133
9447
  * @private
9134
9448
  */
9135
- const useChatMessageEditContainerStyles = reactComponents.makeStyles({
9136
- root: {
9137
- paddingTop: '1.25rem' //height of the menu button + marginBottom
9138
- },
9139
- body: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, reactComponents.shorthands.padding(0)), { backgroundColor: 'transparent', boxSizing: 'border-box' }), reactComponents.shorthands.border(`${defaultSendBoxInactiveBorderThicknessREM}rem`, 'solid')), reactComponents.shorthands.borderRadius(reactComponents.tokens.borderRadiusMedium)), reactComponents.shorthands.margin(`${defaultSendBoxActiveBorderThicknessREM - defaultSendBoxInactiveBorderThicknessREM}rem`)), {
9140
- // Width should be updated on hover to include the border width change
9141
- width: `calc(100% - ${defaultSendBoxActiveBorderThicknessREM}rem)`, '&:hover, &:active, &:focus, &:focus-within': Object.assign(Object.assign(Object.assign({}, reactComponents.shorthands.margin('0rem')), reactComponents.shorthands.borderWidth(`${defaultSendBoxActiveBorderThicknessREM}rem`)), { width: '100%' }) }),
9142
- bodyError: Object.assign({}, reactComponents.shorthands.borderColor(errorTextColor)),
9143
- bodyDefault: Object.assign(Object.assign({}, reactComponents.shorthands.borderColor(reactComponents.tokens.colorNeutralStrokeAccessible)), { '&:hover, &:active, &:focus, &:focus-within': Object.assign({}, reactComponents.shorthands.borderColor(reactComponents.tokens.colorCompoundBrandStroke)) })
9449
+ const useFluentV9Wrapper = reactComponents.makeStyles({
9450
+ body: Object.assign(Object.assign(Object.assign(Object.assign({ height: '100%' }, reactComponents.shorthands.margin(0)), reactComponents.shorthands.overflow('hidden')), reactComponents.shorthands.padding(0)), { width: '100%' })
9144
9451
  });
9145
9452
  /**
9146
- * Styles that can be applied to ensure flyout items have the minimum touch target size.
9147
- *
9148
9453
  * @private
9149
9454
  */
9150
- const menuItemIncreasedSizeStyles = {
9151
- root: {
9152
- height: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9153
- lineHeight: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9154
- maxHeight: 'unset'
9155
- },
9156
- linkContent: {
9157
- height: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9158
- lineHeight: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9159
- maxHeight: 'unset'
9160
- },
9161
- icon: {
9162
- maxHeight: 'unset'
9163
- }
9164
- };
9455
+ const FluentV9ThemeProvider = (props) => {
9456
+ const { v8Theme, children } = props;
9457
+ const v9Theme = createV9Theme(v8Theme);
9458
+ const dir = v8Theme.rtl ? 'rtl' : 'ltr';
9459
+ return (
9460
+ // TextDirectionProvider is needed to fix issue with direction value update in FluentProvider
9461
+ React__default["default"].createElement(react$1.TextDirectionProvider, { dir: dir },
9462
+ React__default["default"].createElement(FluentProviderWithStylesOverrides, { theme: v9Theme, dir: dir }, children)));
9463
+ };
9464
+ const FluentProviderWithStylesOverrides = (props) => {
9465
+ const classes = useFluentV9Wrapper();
9466
+ return React__default["default"].createElement(reactComponents.FluentProvider, Object.assign({}, props, { className: classes.body }));
9467
+ };
9468
+
9469
+ // Copyright (c) Microsoft Corporation.
9470
+ const offScreenStyle = {
9471
+ border: 0,
9472
+ clip: 'rect(0 0 0 0)',
9473
+ height: '1px',
9474
+ margin: '-1px',
9475
+ overflow: 'hidden',
9476
+ whiteSpace: 'nowrap',
9477
+ padding: 0,
9478
+ width: '1px',
9479
+ position: 'absolute'
9480
+ };
9481
+ /** @private */
9482
+ const MessageBlock = (props) => (React__default["default"].createElement("div", { style: offScreenStyle, role: "log", "aria-live": props.ariaLive }, props.message ? props.message : ''));
9483
+
9484
+ // Copyright (c) Microsoft Corporation.
9485
+ /** @private */
9486
+ const EMPTY_MESSAGE = { message: '', id: '' };
9487
+ /** @private */
9488
+ const Announcer = (props) => {
9489
+ var _a, _b;
9490
+ const newAssertive = (_a = props.assertive) !== null && _a !== void 0 ? _a : EMPTY_MESSAGE;
9491
+ const oldAssertive = React__default["default"].useRef(EMPTY_MESSAGE);
9492
+ const [activeAssertive1, setActiveAssertive1] = React__default["default"].useState(EMPTY_MESSAGE);
9493
+ const [activeAssertive2, setActiveAssertive2] = React__default["default"].useState(EMPTY_MESSAGE);
9494
+ const alternateAssertive = React__default["default"].useRef(false);
9495
+ React.useEffect(() => {
9496
+ if (oldAssertive.current.message !== (newAssertive === null || newAssertive === void 0 ? void 0 : newAssertive.message) || oldAssertive.current.id !== (newAssertive === null || newAssertive === void 0 ? void 0 : newAssertive.id)) {
9497
+ setActiveAssertive1(alternateAssertive.current ? EMPTY_MESSAGE : newAssertive);
9498
+ setActiveAssertive2(alternateAssertive.current ? newAssertive : EMPTY_MESSAGE);
9499
+ oldAssertive.current = newAssertive;
9500
+ alternateAssertive.current = !alternateAssertive.current;
9501
+ }
9502
+ }, [newAssertive]);
9503
+ const newPolite = (_b = props.polite) !== null && _b !== void 0 ? _b : EMPTY_MESSAGE;
9504
+ const oldPolite = React__default["default"].useRef(EMPTY_MESSAGE);
9505
+ const [activePolite1, setActivePolite1] = React__default["default"].useState(EMPTY_MESSAGE);
9506
+ const [activePolite2, setActivePolite2] = React__default["default"].useState(EMPTY_MESSAGE);
9507
+ const alternatePolite = React__default["default"].useRef(false);
9508
+ React.useEffect(() => {
9509
+ if (oldPolite.current.message !== (newPolite === null || newPolite === void 0 ? void 0 : newPolite.message) || oldPolite.current.id !== (newPolite === null || newPolite === void 0 ? void 0 : newPolite.id)) {
9510
+ setActivePolite1(alternatePolite.current ? EMPTY_MESSAGE : newPolite);
9511
+ setActivePolite2(alternatePolite.current ? newPolite : EMPTY_MESSAGE);
9512
+ oldPolite.current = newPolite;
9513
+ alternatePolite.current = !alternatePolite.current;
9514
+ }
9515
+ }, [newPolite]);
9516
+ return (React__default["default"].createElement("div", null,
9517
+ React__default["default"].createElement(MessageBlock, { ariaLive: "assertive", message: activeAssertive1.message }),
9518
+ React__default["default"].createElement(MessageBlock, { ariaLive: "assertive", message: activeAssertive2.message }),
9519
+ React__default["default"].createElement(MessageBlock, { ariaLive: "polite", message: activePolite1.message }),
9520
+ React__default["default"].createElement(MessageBlock, { ariaLive: "polite", message: activePolite2.message })));
9521
+ };
9522
+
9523
+ // Copyright (c) Microsoft Corporation.
9524
+ /** @private */
9525
+ const LiveAnnouncer = (props) => {
9526
+ const [politeMessage, setPoliteMessage] = React__default["default"].useState(EMPTY_MESSAGE);
9527
+ const [assertiveMessage, setAssertiveMessage] = React__default["default"].useState(EMPTY_MESSAGE);
9528
+ const announcePolite = React.useCallback((message, id) => {
9529
+ setPoliteMessage({ message, id });
9530
+ }, []);
9531
+ const announceAssertive = React.useCallback((message, id) => {
9532
+ setAssertiveMessage({ message, id });
9533
+ }, []);
9534
+ const updateFunctions = React.useMemo(() => ({
9535
+ announcePolite,
9536
+ announceAssertive
9537
+ }), [announceAssertive, announcePolite]);
9538
+ return (React__default["default"].createElement(AnnouncerContext.Provider, { value: updateFunctions },
9539
+ props.children,
9540
+ React__default["default"].createElement(Announcer, { assertive: assertiveMessage, polite: politeMessage })));
9541
+ };
9542
+
9543
+ // Copyright (c) Microsoft Corporation.
9544
+ // Licensed under the MIT License.
9545
+ /**
9546
+ * Function to create a React.CSSProperties object from a v8 style object.
9547
+ * This function is still not ideal
9548
+ * as v8Style can use pseudo-class selectors that style objects can't process correctly.
9549
+ *
9550
+ * @private
9551
+ */
9552
+ function createStyleFromV8Style(v8Style) {
9553
+ const result = {};
9554
+ if (v8Style === undefined || v8Style === null || typeof v8Style === 'boolean' || typeof v8Style === 'string') {
9555
+ return undefined;
9556
+ }
9557
+ else if (typeof v8Style === 'object') {
9558
+ // v8Style is a style object
9559
+ for (const record in v8Style) {
9560
+ if (typeof v8Style[record] === 'string') {
9561
+ // v8Style[record] is just a simple style
9562
+ const msSuffix = 'MS';
9563
+ if (record.startsWith(msSuffix)) {
9564
+ // React.CSSProperties uses camelCase for MS properties but v8Style uses PascalCase
9565
+ const newRecord = record.substring(0, msSuffix.length).toLowerCase + record.substring(msSuffix.length);
9566
+ result[newRecord] = v8Style[record];
9567
+ }
9568
+ else {
9569
+ result[record] = v8Style[record];
9570
+ }
9571
+ }
9572
+ else {
9573
+ result[record] = createStyleFromV8Style(v8Style[record]);
9574
+ }
9575
+ }
9576
+ }
9577
+ return result;
9578
+ }
9579
+
9580
+ // Copyright (c) Microsoft Corporation.
9581
+ /**
9582
+ * @private
9583
+ */
9584
+ const editBoxStyle = react.mergeStyles({
9585
+ marginTop: '0.0875rem',
9586
+ marginBottom: '0.0875rem'
9587
+ });
9588
+ /**
9589
+ * @private
9590
+ */
9591
+ const editingButtonStyle = react.mergeStyles({
9592
+ margin: '0',
9593
+ width: '2.125rem',
9594
+ height: '2.125rem',
9595
+ padding: '0.375rem 0 0 0'
9596
+ });
9597
+ /**
9598
+ * @private
9599
+ */
9600
+ const inputBoxIcon = react.mergeStyles({
9601
+ margin: 'auto',
9602
+ '&:hover svg': {
9603
+ stroke: 'currentColor'
9604
+ }
9605
+ });
9606
+ /**
9607
+ * @private
9608
+ */
9609
+ const editBoxStyleSet = {
9610
+ root: {
9611
+ minWidth: '6.25rem',
9612
+ maxWidth: '100%'
9613
+ }
9614
+ };
9615
+
9616
+ // Copyright (c) Microsoft Corporation.
9617
+ const MINIMUM_TOUCH_TARGET_HEIGHT_REM$1 = 3;
9618
+ const errorTextColor = 'var(--errorText)';
9619
+ /**
9620
+ * @private
9621
+ */
9622
+ const iconWrapperStyle = (theme, isSubMenuOpen) => ({
9623
+ root: {
9624
+ margin: _pxToRem(3),
9625
+ // Show hover styles when the Edit/Delete menu is showing as this action button is still considered 'active'
9626
+ color: isSubMenuOpen ? theme.palette.black : theme.palette.neutralPrimary,
9627
+ strokeWidth: isSubMenuOpen ? _pxToRem(0.5) : _pxToRem(0),
9628
+ stroke: theme.palette.black,
9629
+ ':hover, :focus': {
9630
+ color: theme.palette.black,
9631
+ strokeWidth: _pxToRem(0.5)
9632
+ }
9633
+ }
9634
+ });
9635
+ /**
9636
+ * @private
9637
+ */
9638
+ const chatMessageDateStyle = react.mergeStyles({
9639
+ color: reactComponents.tokens.colorNeutralForeground2,
9640
+ fontWeight: react.FontWeights.regular,
9641
+ fontSize: '0.75rem'
9642
+ });
9643
+ /**
9644
+ * @private
9645
+ */
9646
+ const chatMessageAuthorStyle = react.mergeStyles({
9647
+ fontWeight: react.FontWeights.semibold,
9648
+ fontSize: '0.75rem'
9649
+ });
9650
+ /**
9651
+ * @private
9652
+ */
9653
+ const chatMessageEditedTagStyle = (theme) => react.mergeStyles({ fontWeight: react.FontWeights.semibold, color: theme.palette.neutralSecondary });
9654
+ /**
9655
+ * @private
9656
+ */
9657
+ const chatMessageFailedTagStyle = (theme) => react.mergeStyles({
9658
+ fontWeight: react.FontWeights.regular,
9659
+ color: theme.semanticColors.errorText,
9660
+ fontSize: theme.fonts.smallPlus.fontSize,
9661
+ lineHeight: '1rem'
9662
+ });
9663
+ /**
9664
+ * @private
9665
+ */
9666
+ const editChatMessageFailedTagStyle = react.mergeStyles({
9667
+ marginBottom: '0.5rem'
9668
+ });
9669
+ /**
9670
+ * @private
9671
+ */
9672
+ const chatMessageFailedTagStackItemStyle = react.mergeStyles({
9673
+ alignSelf: 'end'
9674
+ });
9675
+ /**
9676
+ * @private
9677
+ */
9678
+ const editChatMessageButtonsStackStyle = react.mergeStyles({
9679
+ padding: '0 0.5rem',
9680
+ marginTop: '-0.25rem'
9681
+ });
9682
+ /**
9683
+ * @private
9684
+ */
9685
+ const chatMessageMenuStyle = react.mergeStyles({
9686
+ minWidth: '8.5rem',
9687
+ height: 'max-content',
9688
+ cursor: 'pointer',
9689
+ overflow: 'hidden'
9690
+ });
9691
+ /**
9692
+ * @private
9693
+ */
9694
+ const useChatMessageEditContainerStyles = reactComponents.makeStyles({
9695
+ root: {
9696
+ paddingTop: '1.25rem' //height of the menu button + marginBottom
9697
+ },
9698
+ body: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, reactComponents.shorthands.padding(0)), { backgroundColor: 'transparent', boxSizing: 'border-box' }), reactComponents.shorthands.border(`${defaultSendBoxInactiveBorderThicknessREM}rem`, 'solid')), reactComponents.shorthands.borderRadius(reactComponents.tokens.borderRadiusMedium)), reactComponents.shorthands.margin(`${defaultSendBoxActiveBorderThicknessREM - defaultSendBoxInactiveBorderThicknessREM}rem`)), {
9699
+ // Width should be updated on hover to include the border width change
9700
+ width: `calc(100% - ${defaultSendBoxActiveBorderThicknessREM}rem)`, '&:hover, &:active, &:focus, &:focus-within': Object.assign(Object.assign(Object.assign({}, reactComponents.shorthands.margin('0rem')), reactComponents.shorthands.borderWidth(`${defaultSendBoxActiveBorderThicknessREM}rem`)), { width: '100%' }) }),
9701
+ bodyError: Object.assign({}, reactComponents.shorthands.borderColor(errorTextColor)),
9702
+ bodyDefault: Object.assign(Object.assign({}, reactComponents.shorthands.borderColor(reactComponents.tokens.colorNeutralStrokeAccessible)), { '&:hover, &:active, &:focus, &:focus-within': Object.assign({}, reactComponents.shorthands.borderColor(reactComponents.tokens.colorCompoundBrandStroke)) })
9703
+ });
9704
+ /**
9705
+ * Styles that can be applied to ensure flyout items have the minimum touch target size.
9706
+ *
9707
+ * @private
9708
+ */
9709
+ const menuItemIncreasedSizeStyles = {
9710
+ root: {
9711
+ height: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9712
+ lineHeight: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9713
+ maxHeight: 'unset'
9714
+ },
9715
+ linkContent: {
9716
+ height: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9717
+ lineHeight: `${MINIMUM_TOUCH_TARGET_HEIGHT_REM$1}rem`,
9718
+ maxHeight: 'unset'
9719
+ },
9720
+ icon: {
9721
+ maxHeight: 'unset'
9722
+ }
9723
+ };
9165
9724
  /**
9166
9725
  * @private
9167
9726
  */
@@ -9564,21 +10123,27 @@ const MessageContentWithLiveAria = (props) => {
9564
10123
  props.content));
9565
10124
  };
9566
10125
  const MessageContentAsRichTextHTML = (props) => {
10126
+ const {
10127
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10128
+ // message is used only in useEffect that is under teams-inline-images-and-file-sharing cc
10129
+ message,
10130
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10131
+ attachmentsMap,
10132
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10133
+ onFetchAttachments } = props;
9567
10134
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9568
10135
  React.useEffect(() => {
9569
10136
  var _a;
9570
- const attachments = (_a = props.message.attachedFilesMetadata) === null || _a === void 0 ? void 0 : _a.filter((fileMetadata) => {
9571
- return fileMetadata.attachmentType === 'inlineImage';
10137
+ if (!attachmentsMap || !onFetchAttachments) {
10138
+ return;
10139
+ }
10140
+ const attachments = (_a = message.attachedFilesMetadata) === null || _a === void 0 ? void 0 : _a.filter((fileMetadata) => {
10141
+ return fileMetadata.attachmentType === 'inlineImage' && attachmentsMap[fileMetadata.id] === undefined;
9572
10142
  });
9573
- if (props.attachmentsMap && attachments) {
9574
- attachments.forEach((fileMetadata) => {
9575
- if (props.onFetchAttachment && props.attachmentsMap && props.attachmentsMap[fileMetadata.id] === undefined) {
9576
- props.onFetchAttachment([fileMetadata], props.message.messageId);
9577
- return;
9578
- }
9579
- });
10143
+ if (attachments && attachments.length > 0) {
10144
+ onFetchAttachments(attachments, message.messageId);
9580
10145
  }
9581
- }, [props]);
10146
+ }, [message.attachedFilesMetadata, message.messageId, onFetchAttachments, attachmentsMap]);
9582
10147
  return (React__default["default"].createElement(MessageContentWithLiveAria, { message: props.message, liveMessage: generateLiveMessage(props), ariaLabel: messageContentAriaText(props), content: processHtmlToReact(props) }));
9583
10148
  };
9584
10149
  const MessageContentAsText = (props) => {
@@ -9821,43 +10386,6 @@ const useLocaleStringsTrampoline = () => {
9821
10386
  return useLocale$1().strings.messageThread;
9822
10387
  };
9823
10388
 
9824
- // Copyright (c) Microsoft Corporation.
9825
- // Licensed under the MIT License.
9826
- /**
9827
- * Function to create a React.CSSProperties object from a v8 style object.
9828
- * This function is still not ideal
9829
- * as v8Style can use pseudo-class selectors that style objects can't process correctly.
9830
- *
9831
- * @private
9832
- */
9833
- function createStyleFromV8Style(v8Style) {
9834
- const result = {};
9835
- if (v8Style === undefined || v8Style === null || typeof v8Style === 'boolean' || typeof v8Style === 'string') {
9836
- return undefined;
9837
- }
9838
- else if (typeof v8Style === 'object') {
9839
- // v8Style is a style object
9840
- for (const record in v8Style) {
9841
- if (typeof v8Style[record] === 'string') {
9842
- // v8Style[record] is just a simple style
9843
- const msSuffix = 'MS';
9844
- if (record.startsWith(msSuffix)) {
9845
- // React.CSSProperties uses camelCase for MS properties but v8Style uses PascalCase
9846
- const newRecord = record.substring(0, msSuffix.length).toLowerCase + record.substring(msSuffix.length);
9847
- result[newRecord] = v8Style[record];
9848
- }
9849
- else {
9850
- result[record] = v8Style[record];
9851
- }
9852
- }
9853
- else {
9854
- result[record] = createStyleFromV8Style(v8Style[record]);
9855
- }
9856
- }
9857
- }
9858
- return result;
9859
- }
9860
-
9861
10389
  // Copyright (c) Microsoft Corporation.
9862
10390
  // Licensed under the MIT License.
9863
10391
  var __awaiter$x = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
@@ -9966,7 +10494,7 @@ const MessageBubble = (props) => {
9966
10494
  return (React__default["default"].createElement("div", { tabIndex: 0, className: "ui-chat__message__content" },
9967
10495
  React__default["default"].createElement(ChatMessageContent, { message: message, strings: strings,
9968
10496
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9969
- onFetchAttachment: props.onFetchAttachments,
10497
+ onFetchAttachments: props.onFetchAttachments,
9970
10498
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9971
10499
  attachmentsMap: props.attachmentsMap,
9972
10500
  /* @conditional-compile-remove(mention) */
@@ -10052,590 +10580,355 @@ const MessageBubble = (props) => {
10052
10580
  className: chatMessageStyles.root,
10053
10581
  // make body not focusable to remove repetitions from narrators.
10054
10582
  // inner components are already focusable
10055
- tabIndex: -1,
10056
- role: 'none'
10057
- }, author: React__default["default"].createElement(react.Text, { className: chatMessageAuthorStyle }, message.senderDisplayName), body: {
10058
- className: chatItemMessageContainerClassName,
10059
- style: Object.assign({}, createStyleFromV8Style(messageContainerStyle))
10060
- }, "data-ui-id": "chat-composite-message", timestamp: React__default["default"].createElement(react.Text, { className: chatMessageDateStyle, "data-ui-id": ids.messageTimestamp }, formattedTimestamp) }, getContent()))),
10061
- chatActionsEnabled && (React__default["default"].createElement(ChatMessageActionFlyout, { hidden: !chatMessageActionFlyoutTarget, target: chatMessageActionFlyoutTarget, increaseFlyoutItemSize: wasInteractionByTouch, onDismiss: onActionFlyoutDismiss, onEditClick: onEditClick, onRemoveClick: onRemoveClick, onResendClick: onResendClick, strings: strings, messageReadBy: messageReadBy, messageStatus: messageStatus !== null && messageStatus !== void 0 ? messageStatus : 'failed', remoteParticipantsCount: remoteParticipantsCount, onRenderAvatar: onRenderAvatar, showMessageStatus: showMessageStatus }))));
10062
- return chatMessage;
10063
- };
10064
- /** @private */
10065
- const ChatMessageComponentAsMessageBubble = React__default["default"].memo(MessageBubble);
10066
-
10067
- // Copyright (c) Microsoft Corporation.
10068
- // Licensed under the MIT License.
10069
- var __awaiter$w = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
10070
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10071
- return new (P || (P = Promise))(function (resolve, reject) {
10072
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10073
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10074
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10075
- step((generator = generator.apply(thisArg, _arguments || [])).next());
10076
- });
10077
- };
10078
- /**
10079
- * @private
10080
- */
10081
- const ChatMessageComponent = (props) => {
10082
- var _a, _b;
10083
- const [isEditing, setIsEditing] = React.useState(false);
10084
- const onEditClick = React.useCallback(() => setIsEditing(true), [setIsEditing]);
10085
- const { onDeleteMessage, onSendMessage, message } = props;
10086
- const clientMessageId = 'clientMessageId' in message ? message.clientMessageId : undefined;
10087
- const content = 'content' in message ? message.content : undefined;
10088
- const onRemoveClick = React.useCallback(() => {
10089
- if (onDeleteMessage && message.messageId) {
10090
- onDeleteMessage(message.messageId);
10091
- }
10092
- // when fail to send, message does not have message id, delete message using clientMessageId
10093
- else if (onDeleteMessage && message.messageType === 'chat' && clientMessageId) {
10094
- onDeleteMessage(clientMessageId);
10095
- }
10096
- }, [onDeleteMessage, message.messageId, message.messageType, clientMessageId]);
10097
- const onResendClick = React.useCallback(() => {
10098
- onDeleteMessage && clientMessageId && onDeleteMessage(clientMessageId);
10099
- onSendMessage && onSendMessage(content !== undefined ? content : '');
10100
- }, [clientMessageId, content, onSendMessage, onDeleteMessage]);
10101
- if (isEditing && message.messageType === 'chat') {
10102
- return (React__default["default"].createElement(ChatMessageComponentAsEditBox, { message: message, strings: props.strings, onSubmit: (text, metadata, options) => __awaiter$w(void 0, void 0, void 0, function* () {
10103
- props.onUpdateMessage &&
10104
- message.messageId &&
10105
- (yield props.onUpdateMessage(message.messageId, text, metadata, options));
10106
- setIsEditing(false);
10107
- }), onCancel: (messageId) => {
10108
- props.onCancelEditMessage && props.onCancelEditMessage(messageId);
10109
- setIsEditing(false);
10110
- },
10111
- /* @conditional-compile-remove(mention) */
10112
- mentionLookupOptions: (_a = props.mentionOptions) === null || _a === void 0 ? void 0 : _a.lookupOptions }));
10113
- }
10114
- else {
10115
- return (React__default["default"].createElement(ChatMessageComponentAsMessageBubble, Object.assign({}, props, { onRemoveClick: onRemoveClick, onEditClick: onEditClick, onResendClick: onResendClick, onRenderAvatar: props.onRenderAvatar,
10116
- /* @conditional-compile-remove(date-time-customization) */
10117
- onDisplayDateTimeString: props.onDisplayDateTimeString, strings: props.strings,
10118
- /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10119
- onFetchAttachments: props.onFetchAttachments,
10120
- /* @conditional-compile-remove(image-gallery) */
10121
- onInlineImageClicked: props.onInlineImageClicked,
10122
- /* @conditional-compile-remove(image-gallery) */
10123
- attachmentsMap: props.attachmentsMap,
10124
- /* @conditional-compile-remove(mention) */
10125
- mentionDisplayOptions: (_b = props.mentionOptions) === null || _b === void 0 ? void 0 : _b.displayOptions })));
10126
- }
10127
- };
10128
-
10129
- // Copyright (c) Microsoft Corporation.
10130
- /**
10131
- * A utility hook for providing the width of a parent element.
10132
- * Returns updated width if parent/window resizes.
10133
- * @param containerRef - Ref of a parent element whose width will be returned.
10134
- * @internal
10135
- */
10136
- const _useContainerWidth = (containerRef) => {
10137
- const [width, setWidth] = React.useState(undefined);
10138
- const observer = React.useRef(new ResizeObserver((entries) => {
10139
- const { width } = entries[0].contentRect;
10140
- setWidth(width);
10141
- }));
10142
- React.useEffect(() => {
10143
- if (containerRef.current) {
10144
- observer.current.observe(containerRef.current);
10145
- }
10146
- const currentObserver = observer.current;
10147
- return () => {
10148
- currentObserver.disconnect();
10149
- };
10150
- }, [containerRef, observer]);
10151
- return width;
10152
- };
10153
- /**
10154
- * A utility hook for providing the height of a parent element.
10155
- * Returns updated height if parent/window resizes.
10156
- * @param containerRef - Ref of a parent element whose height will be returned.
10157
- * @internal
10158
- */
10159
- const _useContainerHeight = (containerRef) => {
10160
- const [height, setHeight] = React.useState(undefined);
10161
- const observer = React.useRef(new ResizeObserver((entries) => {
10162
- const { height } = entries[0].contentRect;
10163
- setHeight(height);
10164
- }));
10165
- React.useEffect(() => {
10166
- if (containerRef.current) {
10167
- observer.current.observe(containerRef.current);
10168
- }
10169
- const currentObserver = observer.current;
10170
- return () => {
10171
- currentObserver.disconnect();
10172
- };
10173
- }, [containerRef, observer]);
10174
- return height;
10175
- };
10176
- const NARROW_WIDTH_REM = 30;
10177
- const SHORT_HEIGHT_REM = 23.75;
10178
- /**
10179
- * Utility function to determine if container width is narrow
10180
- * @param containerWidthRem container width in rem
10181
- * @returns boolean
10182
- */
10183
- const isNarrowWidth = (containerWidthRem) => containerWidthRem <= _convertRemToPx(NARROW_WIDTH_REM);
10184
- /**
10185
- * Utility function to determine if container width is short
10186
- * @param containerWidthRem container height in rem
10187
- * @returns boolean
10188
- */
10189
- const isShortHeight = (containerHeightRem) => containerHeightRem <= _convertRemToPx(SHORT_HEIGHT_REM);
10190
-
10191
- // Copyright (c) Microsoft Corporation.
10192
- // Licensed under the MIT License.
10193
- /**
10194
- * @private
10195
- *logic: Looking at message A, how do we know it's read number?
10196
- * Assumption: if user read the latest message, user has read all messages before that
10197
- * ReadReceipt behaviour: read receipt is only sent to the last message
10198
- *
10199
- * If participant read a message that is sent later than message A, then the participant has read message A
10200
- * How do we check if the message is sent later than message A?
10201
- * We compare if the messageID of the last read message is larger than or equal to the message A's id
10202
- * Because messageID is the creation timestamp of each message
10203
- * Timestamps are in epoch time so lecixographical ordering is the same as time ordering.
10204
- *
10205
- * if MessageId of B is larger than message Id of A, then B is created after A
10206
- * if the last read message is created after the message A is sent, then user should have read message A as well */
10207
- var getParticipantsWhoHaveReadMessage = (message, readReceiptsBySenderId) => {
10208
- return (Object.entries(readReceiptsBySenderId)
10209
- // Filter to only read receipts that match the message OR the participant has read a different message after this message has been created
10210
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
10211
- .filter(([_, readReceipt]) => readReceipt.lastReadMessage >= message.messageId)
10212
- // make sure the person is not removed from chat
10213
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
10214
- .filter(([_, readReceipt]) => readReceipt.displayName && readReceipt.displayName !== '')
10215
- // Map properties to useful array
10216
- .map(([id, readReceipt]) => ({ id, displayName: readReceipt.displayName })));
10217
- };
10218
-
10219
- // Copyright (c) Microsoft Corporation.
10220
- // Licensed under the MIT License.
10221
- // These color records are required for createV9Theme
10222
- // For more info, check https://react.fluentui.dev/iframe.html?viewMode=docs&id=concepts-migration-from-v8-components-theme-migration--page#compatible-themes
10223
- /**
10224
- * @private
10225
- */
10226
- const grey = {
10227
- '0': '#000000',
10228
- '2': '#050505',
10229
- '4': '#0a0a0a',
10230
- '6': '#0f0f0f',
10231
- '8': '#141414',
10232
- '10': '#1a1a1a',
10233
- '12': '#1f1f1f',
10234
- '14': '#242424',
10235
- '16': '#292929',
10236
- '18': '#2e2e2e',
10237
- '20': '#333333',
10238
- '22': '#383838',
10239
- '24': '#3d3d3d',
10240
- '26': '#424242',
10241
- '28': '#474747',
10242
- '30': '#4d4d4d',
10243
- '32': '#525252',
10244
- '34': '#575757',
10245
- '36': '#5c5c5c',
10246
- '38': '#616161',
10247
- '40': '#666666',
10248
- '42': '#6b6b6b',
10249
- '44': '#707070',
10250
- '46': '#757575',
10251
- '48': '#7a7a7a',
10252
- '50': '#808080',
10253
- '52': '#858585',
10254
- '54': '#8a8a8a',
10255
- '56': '#8f8f8f',
10256
- '58': '#949494',
10257
- '60': '#999999',
10258
- '62': '#9e9e9e',
10259
- '64': '#a3a3a3',
10260
- '66': '#a8a8a8',
10261
- '68': '#adadad',
10262
- '70': '#b3b3b3',
10263
- '72': '#b8b8b8',
10264
- '74': '#bdbdbd',
10265
- '76': '#c2c2c2',
10266
- '78': '#c7c7c7',
10267
- '80': '#cccccc',
10268
- '82': '#d1d1d1',
10269
- '84': '#d6d6d6',
10270
- '86': '#dbdbdb',
10271
- '88': '#e0e0e0',
10272
- '90': '#e6e6e6',
10273
- '92': '#ebebeb',
10274
- '94': '#f0f0f0',
10275
- '96': '#f5f5f5',
10276
- '98': '#fafafa',
10277
- '100': '#ffffff'
10278
- };
10279
- /**
10280
- * @private
10281
- */
10282
- const whiteAlpha = {
10283
- '5': 'rgba(255, 255, 255, 0.05)',
10284
- '10': 'rgba(255, 255, 255, 0.1)',
10285
- '20': 'rgba(255, 255, 255, 0.2)',
10286
- '30': 'rgba(255, 255, 255, 0.3)',
10287
- '40': 'rgba(255, 255, 255, 0.4)',
10288
- '50': 'rgba(255, 255, 255, 0.5)',
10289
- '60': 'rgba(255, 255, 255, 0.6)',
10290
- '70': 'rgba(255, 255, 255, 0.7)',
10291
- '80': 'rgba(255, 255, 255, 0.8)',
10292
- '90': 'rgba(255, 255, 255, 0.9)'
10293
- };
10294
- /**
10295
- * @private
10296
- */
10297
- const blackAlpha = {
10298
- '5': 'rgba(0, 0, 0, 0.05)',
10299
- '10': 'rgba(0, 0, 0, 0.1)',
10300
- '20': 'rgba(0, 0, 0, 0.2)',
10301
- '30': 'rgba(0, 0, 0, 0.3)',
10302
- '40': 'rgba(0, 0, 0, 0.4)',
10303
- '50': 'rgba(0, 0, 0, 0.5)',
10304
- '60': 'rgba(0, 0, 0, 0.6)',
10305
- '70': 'rgba(0, 0, 0, 0.7)',
10306
- '80': 'rgba(0, 0, 0, 0.8)',
10307
- '90': 'rgba(0, 0, 0, 0.9)'
10308
- };
10309
- /**
10310
- * @private
10311
- */
10312
- const grey10Alpha = {
10313
- '5': 'rgba(26, 26, 26, 0.05)',
10314
- '10': 'rgba(26, 26, 26, 0.1)',
10315
- '20': 'rgba(26, 26, 26, 0.2)',
10316
- '30': 'rgba(26, 26, 26, 0.3)',
10317
- '40': 'rgba(26, 26, 26, 0.4)',
10318
- '50': 'rgba(26, 26, 26, 0.5)',
10319
- '60': 'rgba(26, 26, 26, 0.6)',
10320
- '70': 'rgba(26, 26, 26, 0.7)',
10321
- '80': 'rgba(26, 26, 26, 0.8)',
10322
- '90': 'rgba(26, 26, 26, 0.9)'
10323
- };
10324
- /**
10325
- * @private
10326
- */
10327
- const grey12Alpha = {
10328
- '5': 'rgba(31, 31, 31, 0.05)',
10329
- '10': 'rgba(31, 31, 31, 0.1)',
10330
- '20': 'rgba(31, 31, 31, 0.2)',
10331
- '30': 'rgba(31, 31, 31, 0.3)',
10332
- '40': 'rgba(31, 31, 31, 0.4)',
10333
- '50': 'rgba(31, 31, 31, 0.5)',
10334
- '60': 'rgba(31, 31, 31, 0.6)',
10335
- '70': 'rgba(31, 31, 31, 0.7)',
10336
- '80': 'rgba(31, 31, 31, 0.8)',
10337
- '90': 'rgba(31, 31, 31, 0.9)'
10338
- };
10339
-
10340
- // Copyright (c) Microsoft Corporation.
10341
- // These mappings are required for createV9Theme
10342
- // For more info, check https://react.fluentui.dev/iframe.html?viewMode=docs&id=concepts-migration-from-v8-components-theme-migration--page#compatible-themes
10343
- /**
10344
- * Creates v9 color tokens from a v8 palette.
10345
- */
10346
- const mapAliasColors = (palette, inverted) => {
10347
- return {
10348
- colorNeutralForeground1: palette.neutralPrimary,
10349
- colorNeutralForeground1Hover: palette.neutralPrimary,
10350
- colorNeutralForeground1Pressed: palette.neutralPrimary,
10351
- colorNeutralForeground1Selected: palette.neutralPrimary,
10352
- colorNeutralForeground2: palette.neutralSecondary,
10353
- colorNeutralForeground2Hover: palette.neutralPrimary,
10354
- colorNeutralForeground2Pressed: palette.neutralPrimary,
10355
- colorNeutralForeground2Selected: palette.neutralPrimary,
10356
- colorNeutralForeground2BrandHover: palette.themePrimary,
10357
- colorNeutralForeground2BrandPressed: palette.themeDarkAlt,
10358
- colorNeutralForeground2BrandSelected: palette.themePrimary,
10359
- colorNeutralForeground3: palette.neutralTertiary,
10360
- colorNeutralForeground3Hover: palette.neutralSecondary,
10361
- colorNeutralForeground3Pressed: palette.neutralSecondary,
10362
- colorNeutralForeground3Selected: palette.neutralSecondary,
10363
- colorNeutralForeground3BrandHover: palette.themePrimary,
10364
- colorNeutralForeground3BrandPressed: palette.themeDarkAlt,
10365
- colorNeutralForeground3BrandSelected: palette.themePrimary,
10366
- colorNeutralForeground4: palette.neutralQuaternary,
10367
- colorNeutralForegroundDisabled: palette.neutralTertiaryAlt,
10368
- colorNeutralForegroundInvertedDisabled: whiteAlpha[40],
10369
- colorBrandForegroundLink: palette.themeDarkAlt,
10370
- colorBrandForegroundLinkHover: palette.themeDark,
10371
- colorBrandForegroundLinkPressed: palette.themeDarker,
10372
- colorBrandForegroundLinkSelected: palette.themeDarkAlt,
10373
- colorNeutralForeground2Link: palette.neutralSecondary,
10374
- colorNeutralForeground2LinkHover: palette.neutralPrimary,
10375
- colorNeutralForeground2LinkPressed: palette.neutralPrimary,
10376
- colorNeutralForeground2LinkSelected: palette.neutralPrimary,
10377
- colorCompoundBrandForeground1: palette.themePrimary,
10378
- colorCompoundBrandForeground1Hover: palette.themeDarkAlt,
10379
- colorCompoundBrandForeground1Pressed: palette.themeDark,
10380
- colorBrandForeground1: palette.themePrimary,
10381
- colorBrandForeground2: palette.themeDarkAlt,
10382
- colorBrandForeground2Hover: palette.themeDarkAlt,
10383
- colorBrandForeground2Pressed: palette.themeDarkAlt,
10384
- colorNeutralForeground1Static: palette.neutralPrimary,
10385
- colorNeutralForegroundInverted: palette.white,
10386
- colorNeutralForegroundInvertedHover: palette.white,
10387
- colorNeutralForegroundInvertedPressed: palette.white,
10388
- colorNeutralForegroundInvertedSelected: palette.white,
10389
- colorNeutralForegroundOnBrand: palette.white,
10390
- colorNeutralForegroundStaticInverted: palette.white,
10391
- colorNeutralForegroundInvertedLink: palette.white,
10392
- colorNeutralForegroundInvertedLinkHover: palette.white,
10393
- colorNeutralForegroundInvertedLinkPressed: palette.white,
10394
- colorNeutralForegroundInvertedLinkSelected: palette.white,
10395
- colorNeutralForegroundInverted2: palette.white,
10396
- colorBrandForegroundInverted: palette.themeSecondary,
10397
- colorBrandForegroundInvertedHover: palette.themeTertiary,
10398
- colorBrandForegroundInvertedPressed: palette.themeSecondary,
10399
- colorBrandForegroundOnLight: palette.themePrimary,
10400
- colorBrandForegroundOnLightHover: palette.themeDarkAlt,
10401
- colorBrandForegroundOnLightPressed: palette.themeDark,
10402
- colorBrandForegroundOnLightSelected: palette.themeDark,
10403
- colorNeutralBackground1: palette.white,
10404
- colorNeutralBackground1Hover: palette.neutralLighter,
10405
- colorNeutralBackground1Pressed: palette.neutralQuaternaryAlt,
10406
- colorNeutralBackground1Selected: palette.neutralLight,
10407
- colorNeutralBackground2: palette.neutralLighterAlt,
10408
- colorNeutralBackground2Hover: palette.neutralLighter,
10409
- colorNeutralBackground2Pressed: palette.neutralQuaternaryAlt,
10410
- colorNeutralBackground2Selected: palette.neutralLight,
10411
- colorNeutralBackground3: palette.neutralLighter,
10412
- colorNeutralBackground3Hover: palette.neutralLight,
10413
- colorNeutralBackground3Pressed: palette.neutralQuaternary,
10414
- colorNeutralBackground3Selected: palette.neutralQuaternaryAlt,
10415
- colorNeutralBackground4: palette.neutralLighter,
10416
- colorNeutralBackground4Hover: palette.neutralLighterAlt,
10417
- colorNeutralBackground4Pressed: palette.neutralLighter,
10418
- colorNeutralBackground4Selected: palette.white,
10419
- colorNeutralBackground5: palette.neutralLight,
10420
- colorNeutralBackground5Hover: palette.neutralLighter,
10421
- colorNeutralBackground5Pressed: palette.neutralLighter,
10422
- colorNeutralBackground5Selected: palette.neutralLighterAlt,
10423
- colorNeutralBackground6: palette.neutralLight,
10424
- colorNeutralBackgroundStatic: grey[20],
10425
- colorNeutralBackgroundInverted: palette.neutralSecondary,
10426
- colorNeutralBackgroundAlpha: inverted ? grey10Alpha[50] : whiteAlpha[50],
10427
- colorNeutralBackgroundAlpha2: inverted ? grey12Alpha[70] : whiteAlpha[80],
10428
- colorSubtleBackground: 'transparent',
10429
- colorSubtleBackgroundHover: palette.neutralLighter,
10430
- colorSubtleBackgroundPressed: palette.neutralQuaternaryAlt,
10431
- colorSubtleBackgroundSelected: palette.neutralLight,
10432
- colorSubtleBackgroundLightAlphaHover: inverted ? whiteAlpha[10] : whiteAlpha[80],
10433
- colorSubtleBackgroundLightAlphaPressed: inverted ? whiteAlpha[5] : whiteAlpha[50],
10434
- colorSubtleBackgroundLightAlphaSelected: 'transparent',
10435
- colorSubtleBackgroundInverted: 'transparent',
10436
- colorSubtleBackgroundInvertedHover: blackAlpha[10],
10437
- colorSubtleBackgroundInvertedPressed: blackAlpha[30],
10438
- colorSubtleBackgroundInvertedSelected: blackAlpha[20],
10439
- colorTransparentBackground: 'transparent',
10440
- colorTransparentBackgroundHover: 'transparent',
10441
- colorTransparentBackgroundPressed: 'transparent',
10442
- colorTransparentBackgroundSelected: 'transparent',
10443
- colorNeutralBackgroundDisabled: palette.neutralLighter,
10444
- colorNeutralBackgroundInvertedDisabled: whiteAlpha[10],
10445
- colorNeutralStencil1: palette.neutralLight,
10446
- colorNeutralStencil2: palette.neutralLighterAlt,
10447
- colorNeutralStencil1Alpha: inverted ? whiteAlpha[10] : blackAlpha[10],
10448
- colorNeutralStencil2Alpha: inverted ? whiteAlpha[5] : blackAlpha[5],
10449
- colorBackgroundOverlay: blackAlpha[40],
10450
- colorScrollbarOverlay: blackAlpha[50],
10451
- colorBrandBackground: palette.themePrimary,
10452
- colorBrandBackgroundHover: palette.themeDarkAlt,
10453
- colorBrandBackgroundPressed: palette.themeDarker,
10454
- colorBrandBackgroundSelected: palette.themeDark,
10455
- colorCompoundBrandBackground: palette.themePrimary,
10456
- colorCompoundBrandBackgroundHover: palette.themeDarkAlt,
10457
- colorCompoundBrandBackgroundPressed: palette.themeDark,
10458
- colorBrandBackgroundStatic: palette.themePrimary,
10459
- colorBrandBackground2: palette.themeLighterAlt,
10460
- colorBrandBackground2Hover: palette.themeLighterAlt,
10461
- colorBrandBackground2Pressed: palette.themeLighterAlt,
10462
- colorBrandBackgroundInverted: palette.white,
10463
- colorBrandBackgroundInvertedHover: palette.themeLighterAlt,
10464
- colorBrandBackgroundInvertedPressed: palette.themeLight,
10465
- colorBrandBackgroundInvertedSelected: palette.themeLighter,
10466
- colorNeutralStrokeAccessible: palette.neutralSecondary,
10467
- colorNeutralStrokeAccessibleHover: palette.neutralSecondary,
10468
- colorNeutralStrokeAccessiblePressed: palette.neutralSecondary,
10469
- colorNeutralStrokeAccessibleSelected: palette.themePrimary,
10470
- colorNeutralStroke1: palette.neutralQuaternary,
10471
- colorNeutralStroke1Hover: palette.neutralTertiaryAlt,
10472
- colorNeutralStroke1Pressed: palette.neutralTertiaryAlt,
10473
- colorNeutralStroke1Selected: palette.neutralTertiaryAlt,
10474
- colorNeutralStroke2: palette.neutralQuaternaryAlt,
10475
- colorNeutralStroke3: palette.neutralLighter,
10476
- colorNeutralStrokeSubtle: palette.neutralQuaternaryAlt,
10477
- colorNeutralStrokeOnBrand: palette.white,
10478
- colorNeutralStrokeOnBrand2: palette.white,
10479
- colorNeutralStrokeOnBrand2Hover: palette.white,
10480
- colorNeutralStrokeOnBrand2Pressed: palette.white,
10481
- colorNeutralStrokeOnBrand2Selected: palette.white,
10482
- colorBrandStroke1: palette.themePrimary,
10483
- colorBrandStroke2: palette.themeLight,
10484
- colorBrandStroke2Hover: palette.themeLight,
10485
- colorBrandStroke2Pressed: palette.themeLight,
10486
- colorBrandStroke2Contrast: palette.themeLight,
10487
- colorCompoundBrandStroke: palette.themePrimary,
10488
- colorCompoundBrandStrokeHover: palette.themeDarkAlt,
10489
- colorCompoundBrandStrokePressed: palette.themeDark,
10490
- colorNeutralStrokeDisabled: palette.neutralQuaternaryAlt,
10491
- colorNeutralStrokeInvertedDisabled: whiteAlpha[40],
10492
- colorTransparentStroke: 'transparent',
10493
- colorTransparentStrokeInteractive: 'transparent',
10494
- colorTransparentStrokeDisabled: 'transparent',
10495
- colorNeutralStrokeAlpha: inverted ? whiteAlpha[10] : blackAlpha[5],
10496
- colorNeutralStrokeAlpha2: whiteAlpha[20],
10497
- colorStrokeFocus1: palette.white,
10498
- colorStrokeFocus2: palette.black,
10499
- colorNeutralShadowAmbient: 'rgba(0,0,0,0.12)',
10500
- colorNeutralShadowKey: 'rgba(0,0,0,0.14)',
10501
- colorNeutralShadowAmbientLighter: 'rgba(0,0,0,0.06)',
10502
- colorNeutralShadowKeyLighter: 'rgba(0,0,0,0.07)',
10503
- colorNeutralShadowAmbientDarker: 'rgba(0,0,0,0.20)',
10504
- colorNeutralShadowKeyDarker: 'rgba(0,0,0,0.24)',
10505
- colorBrandShadowAmbient: 'rgba(0,0,0,0.30)',
10506
- colorBrandShadowKey: 'rgba(0,0,0,0.25)'
10507
- };
10583
+ tabIndex: -1,
10584
+ role: 'none'
10585
+ }, author: React__default["default"].createElement(react.Text, { className: chatMessageAuthorStyle }, message.senderDisplayName), body: {
10586
+ className: chatItemMessageContainerClassName,
10587
+ style: Object.assign({}, createStyleFromV8Style(messageContainerStyle))
10588
+ }, "data-ui-id": "chat-composite-message", timestamp: React__default["default"].createElement(react.Text, { className: chatMessageDateStyle, "data-ui-id": ids.messageTimestamp }, formattedTimestamp) }, getContent()))),
10589
+ chatActionsEnabled && (React__default["default"].createElement(ChatMessageActionFlyout, { hidden: !chatMessageActionFlyoutTarget, target: chatMessageActionFlyoutTarget, increaseFlyoutItemSize: wasInteractionByTouch, onDismiss: onActionFlyoutDismiss, onEditClick: onEditClick, onRemoveClick: onRemoveClick, onResendClick: onResendClick, strings: strings, messageReadBy: messageReadBy, messageStatus: messageStatus !== null && messageStatus !== void 0 ? messageStatus : 'failed', remoteParticipantsCount: remoteParticipantsCount, onRenderAvatar: onRenderAvatar, showMessageStatus: showMessageStatus }))));
10590
+ return chatMessage;
10508
10591
  };
10509
- /**
10510
- * Creates v9 shadow tokens from v8 effects.
10511
- */
10512
- const mapShadowTokens = (effects) => {
10513
- return {
10514
- shadow4: effects.elevation4,
10515
- shadow8: effects.elevation8,
10516
- shadow16: effects.elevation16,
10517
- shadow64: effects.elevation64
10518
- };
10592
+ /** @private */
10593
+ const ChatMessageComponentAsMessageBubble = React__default["default"].memo(MessageBubble);
10594
+
10595
+ // Copyright (c) Microsoft Corporation.
10596
+ // Licensed under the MIT License.
10597
+ var __awaiter$w = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
10598
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10599
+ return new (P || (P = Promise))(function (resolve, reject) {
10600
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10601
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10602
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10603
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10604
+ });
10519
10605
  };
10520
10606
  /**
10521
- * Creates v9 border radius tokens from v8 effects
10607
+ * @private
10522
10608
  */
10523
- const mapBorderRadiusTokens = (effects) => {
10524
- return {
10525
- borderRadiusSmall: effects.roundedCorner2,
10526
- borderRadiusMedium: effects.roundedCorner4,
10527
- borderRadiusLarge: effects.roundedCorner6
10528
- };
10609
+ const ChatMessageComponent = (props) => {
10610
+ var _a, _b;
10611
+ const { onDeleteMessage, onSendMessage, message } = props;
10612
+ const [isEditing, setIsEditing] = React.useState(false);
10613
+ const onEditClick = React.useCallback(() => setIsEditing(true), [setIsEditing]);
10614
+ const clientMessageId = 'clientMessageId' in message ? message.clientMessageId : undefined;
10615
+ const content = 'content' in message ? message.content : undefined;
10616
+ const onRemoveClick = React.useCallback(() => {
10617
+ if (onDeleteMessage && message.messageId) {
10618
+ onDeleteMessage(message.messageId);
10619
+ }
10620
+ // when fail to send, message does not have message id, delete message using clientMessageId
10621
+ else if (onDeleteMessage && message.messageType === 'chat' && clientMessageId) {
10622
+ onDeleteMessage(clientMessageId);
10623
+ }
10624
+ }, [onDeleteMessage, message.messageId, message.messageType, clientMessageId]);
10625
+ const onResendClick = React.useCallback(() => {
10626
+ onDeleteMessage && clientMessageId && onDeleteMessage(clientMessageId);
10627
+ onSendMessage && onSendMessage(content !== undefined ? content : '');
10628
+ }, [clientMessageId, content, onSendMessage, onDeleteMessage]);
10629
+ if (isEditing && message.messageType === 'chat') {
10630
+ return (React__default["default"].createElement(ChatMessageComponentAsEditBox, { message: message, strings: props.strings, onSubmit: (text, metadata, options) => __awaiter$w(void 0, void 0, void 0, function* () {
10631
+ props.onUpdateMessage &&
10632
+ message.messageId &&
10633
+ (yield props.onUpdateMessage(message.messageId, text, metadata, options));
10634
+ setIsEditing(false);
10635
+ }), onCancel: (messageId) => {
10636
+ props.onCancelEditMessage && props.onCancelEditMessage(messageId);
10637
+ setIsEditing(false);
10638
+ },
10639
+ /* @conditional-compile-remove(mention) */
10640
+ mentionLookupOptions: (_a = props.mentionOptions) === null || _a === void 0 ? void 0 : _a.lookupOptions }));
10641
+ }
10642
+ else {
10643
+ return (React__default["default"].createElement(ChatMessageComponentAsMessageBubble, Object.assign({}, props, { onRemoveClick: onRemoveClick, onEditClick: onEditClick, onResendClick: onResendClick, onRenderAvatar: props.onRenderAvatar,
10644
+ /* @conditional-compile-remove(date-time-customization) */
10645
+ onDisplayDateTimeString: props.onDisplayDateTimeString, strings: props.strings,
10646
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10647
+ onFetchAttachments: props.onFetchAttachments,
10648
+ /* @conditional-compile-remove(image-gallery) */
10649
+ onInlineImageClicked: props.onInlineImageClicked,
10650
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10651
+ attachmentsMap: props.attachmentsMap,
10652
+ /* @conditional-compile-remove(mention) */
10653
+ mentionDisplayOptions: (_b = props.mentionOptions) === null || _b === void 0 ? void 0 : _b.displayOptions })));
10654
+ }
10529
10655
  };
10656
+
10657
+ // Copyright (c) Microsoft Corporation.
10530
10658
  /**
10531
- * Creates a v9 theme from a v8 theme and base v9 theme.
10532
- * FluentUI webLightTheme is used in case if no baseThemeV9 is provided.
10659
+ * The component for rendering a chat message using Fluent UI components
10660
+ * and handling default and custom renderers.
10661
+ * This component handles rendering for chat message body, avatar and message status.
10662
+ * The chat message body, avatar and message status should be shown for both default and custom renderers.
10533
10663
  *
10534
10664
  * @private
10535
10665
  */
10536
- const createV9Theme = (themeV8, baseThemeV9) => {
10537
- const baseTheme = baseThemeV9 !== null && baseThemeV9 !== void 0 ? baseThemeV9 : reactComponents.webLightTheme;
10538
- return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, baseTheme), mapAliasColors(themeV8.palette, themeV8.isInverted)), mapShadowTokens(themeV8.effects)), mapBorderRadiusTokens(themeV8.effects)), { colorBrandBackground2: themeV8.palette.themeLight, colorBrandBackground2Hover: themeV8.palette.themeLight, colorBrandBackground2Pressed: themeV8.palette.themeLight, colorStatusWarningBackground3: '#D83B01', errorText: themeV8.semanticColors.errorText, colorNeutralStroke1Selected: themeV8.palette.neutralQuaternary, colorNeutralForeground2: themeV8.palette.neutralSecondary, colorBrandForegroundLink: themeV8.palette.themePrimary, colorBrandForegroundLinkHover: themeV8.palette.themeDarker,
10539
- // Fix for an issue with black borders for iOS that are added with 'after' selector
10540
- colorStrokeFocus2: 'transparent' });
10666
+ const FluentChatMessageComponentWrapper = (props) => {
10667
+ const { message, styles, shouldOverlapAvatarAndMessage, onRenderMessage, onRenderAvatar, showMessageStatus, onRenderMessageStatus, participantCount, readCount, onActionButtonClick,
10668
+ /* @conditional-compile-remove(date-time-customization) */
10669
+ onDisplayDateTimeString,
10670
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10671
+ onFetchInlineAttachment,
10672
+ /* @conditional-compile-remove(image-gallery) */
10673
+ onInlineImageClicked,
10674
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10675
+ inlineAttachments,
10676
+ /* @conditional-compile-remove(mention) */
10677
+ mentionOptions,
10678
+ /* @conditional-compile-remove(file-sharing) */
10679
+ fileDownloadHandler, userId,
10680
+ /* @conditional-compile-remove(file-sharing) */
10681
+ onRenderFileDownloads, defaultStatusRenderer, statusToRender } = props;
10682
+ const chatMessageRenderStyles = useChatMessageRenderStyles();
10683
+ const onRenderFileDownloadsMemo = React.useMemo(() => {
10684
+ /* @conditional-compile-remove(file-sharing) */
10685
+ return onRenderFileDownloads;
10686
+ }, [/* @conditional-compile-remove(file-sharing) */ onRenderFileDownloads]);
10687
+ // To rerender the defaultChatMessageRenderer if app running across days(every new day chat time stamp
10688
+ // needs to be regenerated), the dependency on "new Date().toDateString()"" is added.
10689
+ const defaultChatMessageRenderer = React.useCallback((messageProps) => {
10690
+ var _a;
10691
+ if (messageProps.message.messageType === 'chat' ||
10692
+ /* @conditional-compile-remove(data-loss-prevention) */ messageProps.message.messageType === 'blocked') {
10693
+ return (React__default["default"].createElement(ChatMessageComponent, Object.assign({}, messageProps, {
10694
+ /* @conditional-compile-remove(file-sharing) */
10695
+ onRenderFileDownloads: onRenderFileDownloadsMemo,
10696
+ /* @conditional-compile-remove(file-sharing) */
10697
+ strings: messageProps.strings, message: messageProps.message, userId: userId, remoteParticipantsCount: participantCount ? participantCount - 1 : 0, shouldOverlapAvatarAndMessage: shouldOverlapAvatarAndMessage, onRenderAvatar: onRenderAvatar, showMessageStatus: showMessageStatus, messageStatus: messageProps.message.status, onActionButtonClick: onActionButtonClick,
10698
+ /* @conditional-compile-remove(date-time-customization) */
10699
+ onDisplayDateTimeString: onDisplayDateTimeString,
10700
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10701
+ onFetchAttachments: onFetchInlineAttachment,
10702
+ /* @conditional-compile-remove(image-gallery) */
10703
+ onInlineImageClicked: onInlineImageClicked,
10704
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10705
+ attachmentsMap: (_a = inlineAttachments[messageProps.message.messageId]) !== null && _a !== void 0 ? _a : {},
10706
+ /* @conditional-compile-remove(mention) */
10707
+ mentionOptions: mentionOptions,
10708
+ /* @conditional-compile-remove(file-sharing) */
10709
+ fileDownloadHandler: fileDownloadHandler })));
10710
+ }
10711
+ return React__default["default"].createElement(React__default["default"].Fragment, null);
10712
+ }, [
10713
+ onActionButtonClick,
10714
+ onRenderAvatar,
10715
+ onRenderFileDownloadsMemo,
10716
+ participantCount,
10717
+ shouldOverlapAvatarAndMessage,
10718
+ showMessageStatus,
10719
+ userId,
10720
+ /* @conditional-compile-remove(date-time-customization) */
10721
+ onDisplayDateTimeString,
10722
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10723
+ onFetchInlineAttachment,
10724
+ /* @conditional-compile-remove(image-gallery) */
10725
+ onInlineImageClicked,
10726
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10727
+ inlineAttachments,
10728
+ /* @conditional-compile-remove(mention) */
10729
+ mentionOptions,
10730
+ /* @conditional-compile-remove(file-sharing) */
10731
+ fileDownloadHandler,
10732
+ // eslint-disable-next-line react-hooks/exhaustive-deps
10733
+ new Date().toDateString()
10734
+ ]);
10735
+ const messageRenderer = React.useCallback((messageProps) => {
10736
+ return onRenderMessage === undefined
10737
+ ? defaultChatMessageRenderer(Object.assign({}, messageProps))
10738
+ : onRenderMessage(messageProps, defaultChatMessageRenderer);
10739
+ }, [defaultChatMessageRenderer, onRenderMessage]);
10740
+ const messageStatusRenderer = React.useCallback((onRenderMessageStatus, defaultStatusRenderer, showMessageStatus, participantCount, readCount) => {
10741
+ return showMessageStatus && statusToRender ? (onRenderMessageStatus ? (onRenderMessageStatus({ status: message.status })) : (defaultStatusRenderer(message, participantCount !== null && participantCount !== void 0 ? participantCount : 0, readCount !== null && readCount !== void 0 ? readCount : 0, message.status))) : (React__default["default"].createElement("div", { className: react.mergeStyles(noMessageStatusStyle) }));
10742
+ }, [message, statusToRender]);
10743
+ const shouldShowAvatar = React.useMemo(() => {
10744
+ return message.attached === 'top' || message.attached === false;
10745
+ }, [message.attached]);
10746
+ const attached = React.useMemo(() => {
10747
+ return shouldShowAvatar ? 'top' : 'center';
10748
+ }, [shouldShowAvatar]);
10749
+ const myMessageRootProps = React.useMemo(() => {
10750
+ return {
10751
+ // myChatItemMessageContainer used in className and style prop as style prop can't handle CSS selectors
10752
+ className: reactComponents.mergeClasses(chatMessageRenderStyles.rootMyMessage, chatMessageRenderStyles.rootCommon, react.mergeStyles(styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer)),
10753
+ style: (styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer) !== undefined
10754
+ ? createStyleFromV8Style(styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer)
10755
+ : {},
10756
+ role: 'none'
10757
+ };
10758
+ }, [chatMessageRenderStyles.rootCommon, chatMessageRenderStyles.rootMyMessage, styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer]);
10759
+ const myMessageBodyProps = React.useMemo(() => {
10760
+ return {
10761
+ className: reactComponents.mergeClasses(chatMessageRenderStyles.bodyCommon, chatMessageRenderStyles.bodyMyMessage),
10762
+ // make body not focusable to remove repetitions from narrators.
10763
+ // inner components are already focusable
10764
+ tabIndex: -1,
10765
+ role: 'none'
10766
+ };
10767
+ }, [chatMessageRenderStyles.bodyCommon, chatMessageRenderStyles.bodyMyMessage]);
10768
+ const myMessageStatusIcon = React.useMemo(() => {
10769
+ var _a;
10770
+ return (React__default["default"].createElement("div", { className: react.mergeStyles({ paddingLeft: '0.25rem' }, (styles === null || styles === void 0 ? void 0 : styles.messageStatusContainer) ? styles.messageStatusContainer((_a = message.mine) !== null && _a !== void 0 ? _a : false) : '') }, message.status
10771
+ ? messageStatusRenderer(onRenderMessageStatus, defaultStatusRenderer, showMessageStatus, participantCount, readCount)
10772
+ : undefined));
10773
+ }, [
10774
+ defaultStatusRenderer,
10775
+ message.mine,
10776
+ message.status,
10777
+ messageStatusRenderer,
10778
+ onRenderMessageStatus,
10779
+ participantCount,
10780
+ readCount,
10781
+ showMessageStatus,
10782
+ styles
10783
+ ]);
10784
+ const messageRootProps = React.useMemo(() => {
10785
+ return { className: reactComponents.mergeClasses(chatMessageRenderStyles.rootMessage, chatMessageRenderStyles.rootCommon) };
10786
+ }, [chatMessageRenderStyles.rootCommon, chatMessageRenderStyles.rootMessage]);
10787
+ const messageBodyProps = React.useMemo(() => {
10788
+ return {
10789
+ // chatItemMessageContainer used in className and style prop as style prop can't handle CSS selectors
10790
+ className: reactComponents.mergeClasses(chatMessageRenderStyles.bodyCommon, !shouldShowAvatar ? chatMessageRenderStyles.bodyWithoutAvatar : chatMessageRenderStyles.bodyWithAvatar, shouldOverlapAvatarAndMessage ? chatMessageRenderStyles.avatarOverlap : chatMessageRenderStyles.avatarNoOverlap, react.mergeStyles(styles === null || styles === void 0 ? void 0 : styles.chatItemMessageContainer)),
10791
+ style: (styles === null || styles === void 0 ? void 0 : styles.chatItemMessageContainer) !== undefined ? createStyleFromV8Style(styles === null || styles === void 0 ? void 0 : styles.chatItemMessageContainer) : {},
10792
+ // make body not focusable to remove repetitions from narrators.
10793
+ // inner components are already focusable
10794
+ tabIndex: -1,
10795
+ role: 'none'
10796
+ };
10797
+ }, [
10798
+ chatMessageRenderStyles.avatarNoOverlap,
10799
+ chatMessageRenderStyles.avatarOverlap,
10800
+ chatMessageRenderStyles.bodyCommon,
10801
+ chatMessageRenderStyles.bodyWithAvatar,
10802
+ chatMessageRenderStyles.bodyWithoutAvatar,
10803
+ shouldOverlapAvatarAndMessage,
10804
+ shouldShowAvatar,
10805
+ styles === null || styles === void 0 ? void 0 : styles.chatItemMessageContainer
10806
+ ]);
10807
+ const avatar = React.useMemo(() => {
10808
+ const chatAvatarStyle = shouldShowAvatar ? gutterWithAvatar : gutterWithHiddenAvatar;
10809
+ const personaOptions = {
10810
+ hidePersonaDetails: true,
10811
+ size: react.PersonaSize.size32,
10812
+ text: message.senderDisplayName,
10813
+ showOverflowTooltip: false
10814
+ };
10815
+ return (React__default["default"].createElement("div", { className: react.mergeStyles(chatAvatarStyle) }, onRenderAvatar ? onRenderAvatar === null || onRenderAvatar === void 0 ? void 0 : onRenderAvatar(message.senderId, personaOptions) : React__default["default"].createElement(react.Persona, Object.assign({}, personaOptions))));
10816
+ }, [message.senderDisplayName, message.senderId, onRenderAvatar, shouldShowAvatar]);
10817
+ // Fluent UI message components are used here as for default message renderer,
10818
+ // timestamp and author name should be shown but they aren't shown for custom renderer.
10819
+ // More investigations are needed to check if this can be simplified with states.
10820
+ // Status and avatar should be shown for both custom and default renderers.
10821
+ if (message.mine === true) {
10822
+ return (React__default["default"].createElement("div", null,
10823
+ React__default["default"].createElement(reactChat.ChatMyMessage, { attached: attached, root: myMessageRootProps, body: myMessageBodyProps, statusIcon: myMessageStatusIcon }, messageRenderer(Object.assign({}, props)))));
10824
+ }
10825
+ else {
10826
+ return (React__default["default"].createElement("div", null,
10827
+ React__default["default"].createElement(reactChat.ChatMessage, { attached: attached, root: messageRootProps, body: messageBodyProps, avatar: avatar }, messageRenderer(Object.assign({}, props)))));
10828
+ }
10541
10829
  };
10542
10830
 
10543
10831
  // Copyright (c) Microsoft Corporation.
10544
10832
  /**
10545
10833
  * @private
10546
10834
  */
10547
- const useFluentV9Wrapper = reactComponents.makeStyles({
10548
- body: Object.assign(Object.assign(Object.assign(Object.assign({ height: '100%' }, reactComponents.shorthands.margin(0)), reactComponents.shorthands.overflow('hidden')), reactComponents.shorthands.padding(0)), { width: '100%' })
10835
+ const systemMessageIconStyle = react.mergeStyles({
10836
+ marginInlineEnd: '0.688rem'
10549
10837
  });
10838
+
10839
+ // Copyright (c) Microsoft Corporation.
10550
10840
  /**
10551
10841
  * @private
10552
10842
  */
10553
- const FluentV9ThemeProvider = (props) => {
10554
- const { v8Theme, children } = props;
10555
- const v9Theme = createV9Theme(v8Theme);
10556
- const dir = v8Theme.rtl ? 'rtl' : 'ltr';
10557
- return (
10558
- // TextDirectionProvider is needed to fix issue with direction value update in FluentProvider
10559
- React__default["default"].createElement(react$1.TextDirectionProvider, { dir: dir },
10560
- React__default["default"].createElement(FluentProviderWithStylesOverrides, { theme: v9Theme, dir: dir }, children)));
10561
- };
10562
- const FluentProviderWithStylesOverrides = (props) => {
10563
- const classes = useFluentV9Wrapper();
10564
- return React__default["default"].createElement(reactComponents.FluentProvider, Object.assign({}, props, { className: classes.body }));
10843
+ const SystemMessage = (props) => {
10844
+ const { iconName, content } = props;
10845
+ const Icon = React__default["default"].createElement(react.FontIcon, { iconName: iconName, className: react.mergeStyles(systemMessageIconStyle) });
10846
+ return (React__default["default"].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(props === null || props === void 0 ? void 0 : props.containerStyle), tabIndex: 0 },
10847
+ Icon,
10848
+ React__default["default"].createElement(react.Text, { style: { wordBreak: 'break-word' }, role: "status", title: content, variant: 'small' }, content)));
10565
10849
  };
10566
10850
 
10567
10851
  // Copyright (c) Microsoft Corporation.
10568
- const offScreenStyle = {
10569
- border: 0,
10570
- clip: 'rect(0 0 0 0)',
10571
- height: '1px',
10572
- margin: '-1px',
10573
- overflow: 'hidden',
10574
- whiteSpace: 'nowrap',
10575
- padding: 0,
10576
- width: '1px',
10577
- position: 'absolute'
10852
+ /**
10853
+ * @private
10854
+ */
10855
+ const DefaultSystemMessage = (props) => {
10856
+ var _a;
10857
+ const message = props.message;
10858
+ switch (message.messageType) {
10859
+ case 'system':
10860
+ switch (message.systemMessageType) {
10861
+ case 'content':
10862
+ return (React__default["default"].createElement(SystemMessage, { iconName: (message.iconName ? message.iconName : ''), content: (_a = message.content) !== null && _a !== void 0 ? _a : '', containerStyle: props === null || props === void 0 ? void 0 : props.messageContainerStyle }));
10863
+ case 'participantAdded':
10864
+ case 'participantRemoved':
10865
+ return (React__default["default"].createElement(ParticipantSystemMessageComponent, { message: message, style: props.messageContainerStyle, defaultName: props.strings.noDisplayNameSub }));
10866
+ }
10867
+ }
10868
+ return React__default["default"].createElement(React__default["default"].Fragment, null);
10578
10869
  };
10579
- /** @private */
10580
- const MessageBlock = (props) => (React__default["default"].createElement("div", { style: offScreenStyle, role: "log", "aria-live": props.ariaLive }, props.message ? props.message : ''));
10581
-
10582
- // Copyright (c) Microsoft Corporation.
10583
- /** @private */
10584
- const EMPTY_MESSAGE = { message: '', id: '' };
10585
- /** @private */
10586
- const Announcer = (props) => {
10587
- var _a, _b;
10588
- const newAssertive = (_a = props.assertive) !== null && _a !== void 0 ? _a : EMPTY_MESSAGE;
10589
- const oldAssertive = React__default["default"].useRef(EMPTY_MESSAGE);
10590
- const [activeAssertive1, setActiveAssertive1] = React__default["default"].useState(EMPTY_MESSAGE);
10591
- const [activeAssertive2, setActiveAssertive2] = React__default["default"].useState(EMPTY_MESSAGE);
10592
- const alternateAssertive = React__default["default"].useRef(false);
10593
- React.useEffect(() => {
10594
- if (oldAssertive.current.message !== (newAssertive === null || newAssertive === void 0 ? void 0 : newAssertive.message) || oldAssertive.current.id !== (newAssertive === null || newAssertive === void 0 ? void 0 : newAssertive.id)) {
10595
- setActiveAssertive1(alternateAssertive.current ? EMPTY_MESSAGE : newAssertive);
10596
- setActiveAssertive2(alternateAssertive.current ? newAssertive : EMPTY_MESSAGE);
10597
- oldAssertive.current = newAssertive;
10598
- alternateAssertive.current = !alternateAssertive.current;
10599
- }
10600
- }, [newAssertive]);
10601
- const newPolite = (_b = props.polite) !== null && _b !== void 0 ? _b : EMPTY_MESSAGE;
10602
- const oldPolite = React__default["default"].useRef(EMPTY_MESSAGE);
10603
- const [activePolite1, setActivePolite1] = React__default["default"].useState(EMPTY_MESSAGE);
10604
- const [activePolite2, setActivePolite2] = React__default["default"].useState(EMPTY_MESSAGE);
10605
- const alternatePolite = React__default["default"].useRef(false);
10606
- React.useEffect(() => {
10607
- if (oldPolite.current.message !== (newPolite === null || newPolite === void 0 ? void 0 : newPolite.message) || oldPolite.current.id !== (newPolite === null || newPolite === void 0 ? void 0 : newPolite.id)) {
10608
- setActivePolite1(alternatePolite.current ? EMPTY_MESSAGE : newPolite);
10609
- setActivePolite2(alternatePolite.current ? newPolite : EMPTY_MESSAGE);
10610
- oldPolite.current = newPolite;
10611
- alternatePolite.current = !alternatePolite.current;
10612
- }
10613
- }, [newPolite]);
10614
- return (React__default["default"].createElement("div", null,
10615
- React__default["default"].createElement(MessageBlock, { ariaLive: "assertive", message: activeAssertive1.message }),
10616
- React__default["default"].createElement(MessageBlock, { ariaLive: "assertive", message: activeAssertive2.message }),
10617
- React__default["default"].createElement(MessageBlock, { ariaLive: "polite", message: activePolite1.message }),
10618
- React__default["default"].createElement(MessageBlock, { ariaLive: "polite", message: activePolite2.message })));
10870
+ const ParticipantSystemMessageComponent = ({ message, style, defaultName }) => {
10871
+ const { strings } = useLocale$1();
10872
+ const participantsStr = generateParticipantsStr(message.participants, defaultName);
10873
+ const messageSuffix = message.systemMessageType === 'participantAdded'
10874
+ ? strings.messageThread.participantJoined
10875
+ : strings.messageThread.participantLeft;
10876
+ if (participantsStr !== '') {
10877
+ return (React__default["default"].createElement(SystemMessage, { iconName: (message.iconName ? message.iconName : ''), content: `${participantsStr} ${messageSuffix}`, containerStyle: style }));
10878
+ }
10879
+ return React__default["default"].createElement(React__default["default"].Fragment, null);
10619
10880
  };
10881
+ const generateParticipantsStr = (participants, defaultName) => participants
10882
+ .map((participant) => `${!participant.displayName || participant.displayName === '' ? defaultName : participant.displayName}`)
10883
+ .join(', ');
10620
10884
 
10621
10885
  // Copyright (c) Microsoft Corporation.
10622
- /** @private */
10623
- const LiveAnnouncer = (props) => {
10624
- const [politeMessage, setPoliteMessage] = React__default["default"].useState(EMPTY_MESSAGE);
10625
- const [assertiveMessage, setAssertiveMessage] = React__default["default"].useState(EMPTY_MESSAGE);
10626
- const announcePolite = React.useCallback((message, id) => {
10627
- setPoliteMessage({ message, id });
10886
+ /**
10887
+ * The wrapper component to display different types of chat message.
10888
+ *
10889
+ * @private
10890
+ */
10891
+ const ChatMessageComponentWrapper = (props) => {
10892
+ var _a, _b;
10893
+ const { message, styles, onRenderMessage, key: messageKey } = props;
10894
+ const systemMessageStyle = React.useMemo(() => {
10895
+ return {
10896
+ paddingTop: '0.5rem'
10897
+ };
10628
10898
  }, []);
10629
- const announceAssertive = React.useCallback((message, id) => {
10630
- setAssertiveMessage({ message, id });
10899
+ const customMessageStyle = React.useMemo(() => {
10900
+ return { paddingTop: '1rem', paddingBottom: '0.25rem' };
10631
10901
  }, []);
10632
- const updateFunctions = React.useMemo(() => ({
10633
- announcePolite,
10634
- announceAssertive
10635
- }), [announceAssertive, announcePolite]);
10636
- return (React__default["default"].createElement(AnnouncerContext.Provider, { value: updateFunctions },
10637
- props.children,
10638
- React__default["default"].createElement(Announcer, { assertive: assertiveMessage, polite: politeMessage })));
10902
+ /* @conditional-compile-remove(data-loss-prevention) */
10903
+ // Similar logic as switch statement case 'chat', if statement for conditional compile (merge logic to switch case when stabilize)
10904
+ if (message.messageType === 'blocked') {
10905
+ const myChatMessageStyle = message.status === 'failed'
10906
+ ? (_a = styles === null || styles === void 0 ? void 0 : styles.failedMyChatMessageContainer) !== null && _a !== void 0 ? _a : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer
10907
+ : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer;
10908
+ const blockedMessageStyle = styles === null || styles === void 0 ? void 0 : styles.blockedMessageContainer;
10909
+ const messageContainerStyle = message.mine ? myChatMessageStyle : blockedMessageStyle;
10910
+ return (React__default["default"].createElement(FluentChatMessageComponentWrapper, Object.assign({}, props, { message: message, messageContainerStyle: messageContainerStyle })));
10911
+ }
10912
+ switch (message.messageType) {
10913
+ case 'chat': {
10914
+ const myChatMessageStyle = message.status === 'failed'
10915
+ ? (_b = styles === null || styles === void 0 ? void 0 : styles.failedMyChatMessageContainer) !== null && _b !== void 0 ? _b : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer
10916
+ : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer;
10917
+ const chatMessageStyle = styles === null || styles === void 0 ? void 0 : styles.chatMessageContainer;
10918
+ const messageContainerStyle = message.mine ? myChatMessageStyle : chatMessageStyle;
10919
+ return (React__default["default"].createElement(FluentChatMessageComponentWrapper, Object.assign({}, props, { message: message, messageContainerStyle: messageContainerStyle })));
10920
+ }
10921
+ case 'system': {
10922
+ const messageContainerStyle = styles === null || styles === void 0 ? void 0 : styles.systemMessageContainer;
10923
+ const systemMessageComponent = onRenderMessage === undefined ? (React__default["default"].createElement(DefaultSystemMessage, Object.assign({}, props))) : (onRenderMessage(Object.assign(Object.assign({}, props), { messageContainerStyle }), (props) => React__default["default"].createElement(DefaultSystemMessage, Object.assign({}, props))));
10924
+ return (React__default["default"].createElement("div", { key: messageKey, style: systemMessageStyle }, systemMessageComponent));
10925
+ }
10926
+ default: {
10927
+ // We do not handle custom type message by default, users can handle custom type by using onRenderMessage function.
10928
+ const customMessageComponent = onRenderMessage === undefined ? React__default["default"].createElement(React__default["default"].Fragment, null) : onRenderMessage(Object.assign({}, props));
10929
+ return (React__default["default"].createElement("div", { key: messageKey, style: customMessageStyle }, customMessageComponent));
10930
+ }
10931
+ }
10639
10932
  };
10640
10933
 
10641
10934
  // Copyright (c) Microsoft Corporation.
@@ -10706,38 +10999,37 @@ const DefaultJumpToNewMessageButton = (props) => {
10706
10999
  const { text, onClick } = props;
10707
11000
  return (React__default["default"].createElement(react.PrimaryButton, { className: newMessageButtonStyle, styles: buttonWithIconStyles$1, text: text, onClick: onClick, onRenderIcon: () => React__default["default"].createElement(react.Icon, { iconName: "Down", className: DownIconStyle }) }));
10708
11001
  };
10709
- const generateParticipantsStr = (participants, defaultName) => participants
10710
- .map((participant) => `${!participant.displayName || participant.displayName === '' ? defaultName : participant.displayName}`)
10711
- .join(', ');
10712
- const ParticipantSystemMessageComponent = ({ message, style, defaultName }) => {
10713
- const { strings } = useLocale$1();
10714
- const participantsStr = generateParticipantsStr(message.participants, defaultName);
10715
- const messageSuffix = message.systemMessageType === 'participantAdded'
10716
- ? strings.messageThread.participantJoined
10717
- : strings.messageThread.participantLeft;
10718
- if (participantsStr !== '') {
10719
- return (React__default["default"].createElement(SystemMessage, { iconName: (message.iconName ? message.iconName : ''), content: `${participantsStr} ${messageSuffix}`, containerStyle: style }));
10720
- }
10721
- return React__default["default"].createElement(React__default["default"].Fragment, null);
10722
- };
10723
- const DefaultSystemMessage = (props) => {
10724
- var _a;
10725
- const message = props.message;
10726
- switch (message.messageType) {
10727
- case 'system':
10728
- switch (message.systemMessageType) {
10729
- case 'content':
10730
- return (React__default["default"].createElement(SystemMessage, { iconName: (message.iconName ? message.iconName : ''), content: (_a = message.content) !== null && _a !== void 0 ? _a : '', containerStyle: props === null || props === void 0 ? void 0 : props.messageContainerStyle }));
10731
- case 'participantAdded':
10732
- case 'participantRemoved':
10733
- return (React__default["default"].createElement(ParticipantSystemMessageComponent, { message: message, style: props.messageContainerStyle, defaultName: props.strings.noDisplayNameSub }));
11002
+ const memoizeAllMessages = memoizeFnAll((message, showMessageDate, showMessageStatus, strings, index, onUpdateMessage, onCancelEditMessage, onDeleteMessage, onSendMessage, disableEditing, lastSeenChatMessage, lastSendingChatMessage, lastDeliveredChatMessage) => {
11003
+ let key = message.messageId;
11004
+ let statusToRender = undefined;
11005
+ if (message.messageType === 'chat' ||
11006
+ /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked') {
11007
+ if ((!message.messageId || message.messageId === '') && 'clientMessageId' in message) {
11008
+ key = message.clientMessageId;
11009
+ }
11010
+ if (showMessageStatus && message.mine) {
11011
+ switch (message.messageId) {
11012
+ case lastSeenChatMessage: {
11013
+ statusToRender = 'seen';
11014
+ break;
11015
+ }
11016
+ case lastSendingChatMessage: {
11017
+ statusToRender = 'sending';
11018
+ break;
11019
+ }
11020
+ case lastDeliveredChatMessage: {
11021
+ statusToRender = 'delivered';
11022
+ break;
11023
+ }
10734
11024
  }
11025
+ }
11026
+ if (message.mine && message.status === 'failed') {
11027
+ statusToRender = 'failed';
11028
+ }
10735
11029
  }
10736
- return React__default["default"].createElement(React__default["default"].Fragment, null);
10737
- };
10738
- const memoizeAllMessages = memoizeFnAll((_messageKey, message, showMessageDate, showMessageStatus, onRenderAvatar, shouldOverlapAvatarAndMessage, styles, onRenderMessageStatus, defaultStatusRenderer, defaultChatMessageRenderer, strings, theme, chatMessageRenderStyles, _attached, statusToRender, participantCount, readCount, onRenderMessage, onUpdateMessage, onCancelEditMessage, onDeleteMessage, onSendMessage, disableEditing) => {
10739
- var _a, _b;
10740
- const messageProps = {
11030
+ return {
11031
+ key: key !== null && key !== void 0 ? key : 'id_' + index,
11032
+ statusToRender,
10741
11033
  message,
10742
11034
  strings,
10743
11035
  showDate: showMessageDate,
@@ -10745,92 +11037,9 @@ const memoizeAllMessages = memoizeFnAll((_messageKey, message, showMessageDate,
10745
11037
  onCancelEditMessage,
10746
11038
  onDeleteMessage,
10747
11039
  onSendMessage,
10748
- disableEditing
10749
- };
10750
- const chatMessage = (message, messageProps) => {
10751
- var _a;
10752
- const messageStatusRenderer = showMessageStatus && statusToRender
10753
- ? onRenderMessageStatus
10754
- ? (status) => onRenderMessageStatus({ status })
10755
- : (status) => defaultStatusRenderer(message, status, participantCount !== null && participantCount !== void 0 ? participantCount : 0, readCount !== null && readCount !== void 0 ? readCount : 0)
10756
- : () => React__default["default"].createElement("div", { className: react.mergeStyles(noMessageStatusStyle) });
10757
- let chatMessageComponent;
10758
- const shouldShowAvatar = message.attached === 'top' || message.attached === false;
10759
- const attached = shouldShowAvatar ? 'top' : 'center';
10760
- if (message.mine === true) {
10761
- chatMessageComponent = (React__default["default"].createElement(reactChat.ChatMyMessage, { attached: attached, root: {
10762
- // myChatItemMessageContainer used in className and style prop as style prop can't handle CSS selectors
10763
- className: reactComponents.mergeClasses(chatMessageRenderStyles.rootMyMessage, chatMessageRenderStyles.rootCommon, react.mergeStyles(styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer)),
10764
- style: (styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer) !== undefined
10765
- ? createStyleFromV8Style(styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer)
10766
- : {},
10767
- role: 'none'
10768
- }, body: {
10769
- className: reactComponents.mergeClasses(chatMessageRenderStyles.bodyCommon, chatMessageRenderStyles.bodyMyMessage),
10770
- // make body not focusable to remove repetitions from narrators.
10771
- // inner components are already focusable
10772
- tabIndex: -1,
10773
- role: 'none'
10774
- }, statusIcon: React__default["default"].createElement("div", { className: react.mergeStyles({ paddingLeft: '0.25rem' }, (styles === null || styles === void 0 ? void 0 : styles.messageStatusContainer) ? styles.messageStatusContainer((_a = message.mine) !== null && _a !== void 0 ? _a : false) : '') }, message.status ? messageStatusRenderer(message.status) : undefined) }, onRenderMessage === undefined
10775
- ? defaultChatMessageRenderer(Object.assign(Object.assign({}, messageProps), { messageStatusRenderer }))
10776
- : onRenderMessage(messageProps, defaultChatMessageRenderer)));
10777
- }
10778
- else {
10779
- const chatAvatarStyle = shouldShowAvatar ? gutterWithAvatar : gutterWithHiddenAvatar;
10780
- const personaOptions = {
10781
- hidePersonaDetails: true,
10782
- size: react.PersonaSize.size32,
10783
- text: message.senderDisplayName,
10784
- showOverflowTooltip: false
10785
- };
10786
- chatMessageComponent = (React__default["default"].createElement(reactChat.ChatMessage, { attached: attached, root: { className: reactComponents.mergeClasses(chatMessageRenderStyles.rootMessage, chatMessageRenderStyles.rootCommon) }, body: {
10787
- // chatItemMessageContainer used in className and style prop as style prop can't handle CSS selectors
10788
- className: reactComponents.mergeClasses(chatMessageRenderStyles.bodyCommon, !shouldShowAvatar ? chatMessageRenderStyles.bodyWithoutAvatar : chatMessageRenderStyles.bodyWithAvatar, shouldOverlapAvatarAndMessage
10789
- ? chatMessageRenderStyles.avatarOverlap
10790
- : chatMessageRenderStyles.avatarNoOverlap, react.mergeStyles(styles === null || styles === void 0 ? void 0 : styles.chatItemMessageContainer)),
10791
- style: (styles === null || styles === void 0 ? void 0 : styles.chatItemMessageContainer) !== undefined
10792
- ? createStyleFromV8Style(styles === null || styles === void 0 ? void 0 : styles.chatItemMessageContainer)
10793
- : {},
10794
- // make body not focusable to remove repetitions from narrators.
10795
- // inner components are already focusable
10796
- tabIndex: -1,
10797
- role: 'none'
10798
- }, avatar: React__default["default"].createElement("div", { className: react.mergeStyles(chatAvatarStyle) }, onRenderAvatar ? onRenderAvatar === null || onRenderAvatar === void 0 ? void 0 : onRenderAvatar(message.senderId, personaOptions) : React__default["default"].createElement(react.Persona, Object.assign({}, personaOptions))) }, onRenderMessage === undefined
10799
- ? defaultChatMessageRenderer(Object.assign(Object.assign({}, messageProps), { messageStatusRenderer }))
10800
- : onRenderMessage(messageProps, defaultChatMessageRenderer)));
10801
- }
10802
- return React__default["default"].createElement("div", { key: _messageKey }, chatMessageComponent);
11040
+ disableEditing,
11041
+ showMessageStatus
10803
11042
  };
10804
- /* @conditional-compile-remove(data-loss-prevention) */
10805
- // Similar logic as switch statement case 'chat', if statement for conditional compile (merge logic to switch case when stabilize)
10806
- if (message.messageType === 'blocked') {
10807
- const myChatMessageStyle = message.status === 'failed'
10808
- ? (_a = styles === null || styles === void 0 ? void 0 : styles.failedMyChatMessageContainer) !== null && _a !== void 0 ? _a : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer
10809
- : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer;
10810
- const blockedMessageStyle = styles === null || styles === void 0 ? void 0 : styles.blockedMessageContainer;
10811
- messageProps.messageContainerStyle = message.mine ? myChatMessageStyle : blockedMessageStyle;
10812
- return chatMessage(message, messageProps);
10813
- }
10814
- switch (message.messageType) {
10815
- case 'chat': {
10816
- const myChatMessageStyle = message.status === 'failed'
10817
- ? (_b = styles === null || styles === void 0 ? void 0 : styles.failedMyChatMessageContainer) !== null && _b !== void 0 ? _b : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer
10818
- : styles === null || styles === void 0 ? void 0 : styles.myChatMessageContainer;
10819
- const chatMessageStyle = styles === null || styles === void 0 ? void 0 : styles.chatMessageContainer;
10820
- messageProps.messageContainerStyle = message.mine ? myChatMessageStyle : chatMessageStyle;
10821
- return chatMessage(message, messageProps);
10822
- }
10823
- case 'system': {
10824
- messageProps.messageContainerStyle = styles === null || styles === void 0 ? void 0 : styles.systemMessageContainer;
10825
- const systemMessageComponent = onRenderMessage === undefined ? (React__default["default"].createElement(DefaultSystemMessage, Object.assign({}, messageProps))) : (onRenderMessage(messageProps, (props) => React__default["default"].createElement(DefaultSystemMessage, Object.assign({}, props))));
10826
- return (React__default["default"].createElement("div", { key: _messageKey, style: { paddingTop: '0.5rem' } }, systemMessageComponent));
10827
- }
10828
- default: {
10829
- // We do not handle custom type message by default, users can handle custom type by using onRenderMessage function.
10830
- const customMessageComponent = onRenderMessage === undefined ? React__default["default"].createElement(React__default["default"].Fragment, null) : onRenderMessage(messageProps);
10831
- return (React__default["default"].createElement("div", { key: _messageKey, style: { paddingTop: '1rem', paddingBottom: '0.25rem' } }, customMessageComponent));
10832
- }
10833
- }
10834
11043
  });
10835
11044
  const getLastChatMessageIdWithStatus = (messages, status) => {
10836
11045
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -10874,9 +11083,9 @@ const MessageThreadWrapper = (props) => {
10874
11083
  /* @conditional-compile-remove(mention) */
10875
11084
  mentionOptions,
10876
11085
  /* @conditional-compile-remove(image-gallery) */
10877
- onInlineImageClicked } = props;
10878
- const onRenderFileDownloads = onRenderFileDownloadsTrampoline(props);
10879
- const [messages, setMessages] = React.useState([]);
11086
+ onInlineImageClicked,
11087
+ /* @conditional-compile-remove(file-sharing) */
11088
+ onRenderFileDownloads } = props;
10880
11089
  // We need this state to wait for one tick and scroll to bottom after messages have been initialized.
10881
11090
  // Otherwise chatScrollDivRef.current.clientHeight is wrong if we scroll to bottom before messages are initialized.
10882
11091
  const [chatMessagesInitialized, setChatMessagesInitialized] = React.useState(false);
@@ -10895,19 +11104,24 @@ const MessageThreadWrapper = (props) => {
10895
11104
  const [inlineAttachments, setInlineAttachments] = React.useState({});
10896
11105
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
10897
11106
  const onFetchInlineAttachment = React.useCallback((attachments, messageId) => __awaiter$v(void 0, void 0, void 0, function* () {
10898
- if (!onFetchAttachments) {
11107
+ if (!onFetchAttachments || attachments.length === 0) {
10899
11108
  return;
10900
11109
  }
10901
11110
  const attachmentDownloadResult = yield onFetchAttachments(attachments);
10902
- const listOfAttachments = inlineAttachments[messageId];
10903
- for (const result of attachmentDownloadResult) {
10904
- const { attachmentId, blobUrl } = result;
10905
- listOfAttachments[attachmentId] = blobUrl;
10906
- }
10907
- if (Object.keys(listOfAttachments).length > 0) {
10908
- setInlineAttachments((prev) => (Object.assign(Object.assign({}, prev), { [messageId]: listOfAttachments })));
11111
+ if (attachmentDownloadResult.length > 0) {
11112
+ setInlineAttachments((prev) => {
11113
+ var _a;
11114
+ // The new state should always be based on the previous one
11115
+ // otherwise there can be issues with renders
11116
+ const listOfAttachments = (_a = prev[messageId]) !== null && _a !== void 0 ? _a : {};
11117
+ for (const result of attachmentDownloadResult) {
11118
+ const { attachmentId, blobUrl } = result;
11119
+ listOfAttachments[attachmentId] = blobUrl;
11120
+ }
11121
+ return Object.assign(Object.assign({}, prev), { [messageId]: listOfAttachments });
11122
+ });
10909
11123
  }
10910
- }), [inlineAttachments, onFetchAttachments]);
11124
+ }), [onFetchAttachments]);
10911
11125
  const isAllChatMessagesLoadedRef = React.useRef(false);
10912
11126
  // isAllChatMessagesLoadedRef needs to be updated every time when a new adapter is set in order to display correct data
10913
11127
  // onLoadPreviousChatMessages is updated when a new adapter is set
@@ -10925,10 +11139,12 @@ const MessageThreadWrapper = (props) => {
10925
11139
  const messageIdSeenByMeRef = React.useRef('');
10926
11140
  const chatScrollDivRef = React.useRef(null);
10927
11141
  const isLoadingChatMessagesRef = React.useRef(false);
11142
+ const messages = React.useMemo(() => {
11143
+ return newMessages;
11144
+ }, [newMessages]);
10928
11145
  const messagesRef = React.useRef(messages);
10929
11146
  const setMessagesRef = (messagesWithAttachedValue) => {
10930
11147
  messagesRef.current = messagesWithAttachedValue;
10931
- setMessages(messagesWithAttachedValue);
10932
11148
  };
10933
11149
  const isAtBottomOfScrollRef = React.useRef(isAtBottomOfScroll);
10934
11150
  const setIsAtBottomOfScrollRef = (isAtBottomOfScrollValue) => {
@@ -11114,52 +11330,7 @@ const MessageThreadWrapper = (props) => {
11114
11330
  }, []);
11115
11331
  const localeStrings = useLocale$1().strings.messageThread;
11116
11332
  const strings = React.useMemo(() => (Object.assign(Object.assign({}, localeStrings), props.strings)), [localeStrings, props.strings]);
11117
- // To rerender the defaultChatMessageRenderer if app running across days(every new day chat time stamp need to be regenerated)
11118
- const defaultChatMessageRenderer = React.useCallback((messageProps) => {
11119
- var _a;
11120
- /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
11121
- if (inlineAttachments[messageProps.message.messageId] === undefined) {
11122
- setInlineAttachments((prev) => (Object.assign(Object.assign({}, prev), { [messageProps.message.messageId]: {} })));
11123
- }
11124
- if (messageProps.message.messageType === 'chat' ||
11125
- /* @conditional-compile-remove(data-loss-prevention) */ messageProps.message.messageType === 'blocked') {
11126
- return (React__default["default"].createElement(ChatMessageComponent, Object.assign({}, messageProps, { onRenderFileDownloads: onRenderFileDownloads,
11127
- /* @conditional-compile-remove(file-sharing) */
11128
- strings: strings, message: messageProps.message, userId: props.userId, remoteParticipantsCount: participantCount ? participantCount - 1 : 0, shouldOverlapAvatarAndMessage: isNarrow, onRenderAvatar: onRenderAvatar, showMessageStatus: showMessageStatus, messageStatus: messageProps.message.status, onActionButtonClick: onActionButtonClickMemo,
11129
- /* @conditional-compile-remove(date-time-customization) */
11130
- onDisplayDateTimeString: onDisplayDateTimeString,
11131
- /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
11132
- onFetchAttachments: onFetchInlineAttachment,
11133
- /* @conditional-compile-remove(image-gallery) */
11134
- onInlineImageClicked: onInlineImageClicked,
11135
- /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
11136
- attachmentsMap: (_a = inlineAttachments[messageProps.message.messageId]) !== null && _a !== void 0 ? _a : {},
11137
- /* @conditional-compile-remove(mention) */
11138
- mentionOptions: mentionOptions })));
11139
- }
11140
- return React__default["default"].createElement(React__default["default"].Fragment, null);
11141
- }, [
11142
- onRenderFileDownloads,
11143
- /* @conditional-compile-remove(file-sharing) */
11144
- strings,
11145
- props.userId,
11146
- participantCount,
11147
- isNarrow,
11148
- onRenderAvatar,
11149
- showMessageStatus,
11150
- onActionButtonClickMemo,
11151
- /* @conditional-compile-remove(date-time-customization) */
11152
- onDisplayDateTimeString,
11153
- /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
11154
- onFetchInlineAttachment,
11155
- /* @conditional-compile-remove(image-gallery) */
11156
- onInlineImageClicked,
11157
- /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
11158
- inlineAttachments,
11159
- /* @conditional-compile-remove(mention) */
11160
- mentionOptions
11161
- ]);
11162
- const defaultStatusRenderer = React.useCallback((message, status, participantCount, readCount) => {
11333
+ const defaultStatusRenderer = React.useCallback((message, participantCount, readCount, status) => {
11163
11334
  const onToggleToolTip = (isToggled) => {
11164
11335
  if (isToggled && readReceiptsBySenderIdRef.current) {
11165
11336
  setReadCountForHoveredIndicator(getParticipantsWhoHaveReadMessage(message, readReceiptsBySenderIdRef.current).length);
@@ -11173,87 +11344,56 @@ const MessageThreadWrapper = (props) => {
11173
11344
  remoteParticipantsCount: participantCount ? participantCount - 1 : 0 }));
11174
11345
  }, []);
11175
11346
  const theme = useTheme();
11176
- const chatMessageRenderStyles = useChatMessageRenderStyles();
11177
- const messagesToDisplay = React.useMemo(() => memoizeAllMessages((memoizedMessageFn) => {
11178
- return messages.map((message, index) => {
11179
- let key = message.messageId;
11180
- let statusToRender = undefined;
11181
- if (message.messageType === 'chat' ||
11182
- /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked') {
11183
- if ((!message.messageId || message.messageId === '') && 'clientMessageId' in message) {
11184
- key = message.clientMessageId;
11185
- }
11186
- if (showMessageStatus && message.mine) {
11187
- switch (message.messageId) {
11188
- case lastSeenChatMessage: {
11189
- statusToRender = 'seen';
11190
- break;
11191
- }
11192
- case lastSendingChatMessage: {
11193
- statusToRender = 'sending';
11194
- break;
11195
- }
11196
- case lastDeliveredChatMessage: {
11197
- statusToRender = 'delivered';
11198
- break;
11199
- }
11200
- }
11201
- }
11202
- if (message.mine && message.status === 'failed') {
11203
- statusToRender = 'failed';
11204
- }
11205
- }
11206
- return memoizedMessageFn(key !== null && key !== void 0 ? key : 'id_' + index, message, showMessageDate, showMessageStatus, onRenderAvatar, isNarrow, styles, onRenderMessageStatus, defaultStatusRenderer, defaultChatMessageRenderer, strings, theme, chatMessageRenderStyles,
11207
- // Temporary solution to make sure we re-render if attach attribute is changed.
11208
- // The proper fix should be in selector.
11209
- message.messageType === 'chat' ||
11210
- /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked'
11211
- ? message.attached
11212
- : undefined, statusToRender, participantCount, readCountForHoveredIndicator, onRenderMessage, onUpdateMessage, onCancelEditMessage, onDeleteMessage, onSendMessage, props.disableEditing);
11347
+ const messagesToDisplay = React.useMemo(() => {
11348
+ return memoizeAllMessages((memoizedMessageFn) => {
11349
+ return messages.map((message, index) => {
11350
+ return memoizedMessageFn(message, showMessageDate, showMessageStatus, strings, index, onUpdateMessage, onCancelEditMessage, onDeleteMessage, onSendMessage, props.disableEditing, lastDeliveredChatMessage, lastSeenChatMessage, lastSendingChatMessage);
11351
+ });
11213
11352
  });
11214
- }), [
11353
+ }, [
11354
+ lastDeliveredChatMessage,
11355
+ lastSeenChatMessage,
11356
+ lastSendingChatMessage,
11215
11357
  messages,
11216
- showMessageDate,
11217
- showMessageStatus,
11218
- onRenderAvatar,
11219
- isNarrow,
11220
- styles,
11221
- onRenderMessageStatus,
11222
- defaultStatusRenderer,
11223
- defaultChatMessageRenderer,
11224
- strings,
11225
- theme,
11226
- chatMessageRenderStyles,
11227
- participantCount,
11228
- readCountForHoveredIndicator,
11229
- onRenderMessage,
11230
- onUpdateMessage,
11231
11358
  onCancelEditMessage,
11232
11359
  onDeleteMessage,
11233
11360
  onSendMessage,
11361
+ onUpdateMessage,
11234
11362
  props.disableEditing,
11235
- lastSeenChatMessage,
11236
- lastSendingChatMessage,
11237
- lastDeliveredChatMessage
11363
+ showMessageDate,
11364
+ showMessageStatus,
11365
+ strings
11238
11366
  ]);
11239
11367
  const classes = useChatStyles();
11240
- const chatBody = React.useMemo(() => {
11241
- return (React__default["default"].createElement(LiveAnnouncer, null,
11368
+ return (React__default["default"].createElement("div", { className: react.mergeStyles(messageThreadWrapperContainerStyle), ref: chatThreadRef },
11369
+ existsNewChatMessage && !disableJumpToNewMessageButton && (React__default["default"].createElement("div", { className: react.mergeStyles(newMessageButtonContainerStyle, styles === null || styles === void 0 ? void 0 : styles.newMessageButtonContainer) }, onRenderJumpToNewMessageButton ? (onRenderJumpToNewMessageButton({ text: strings.newMessagesIndicator, onClick: scrollToBottom })) : (React__default["default"].createElement(DefaultJumpToNewMessageButton, { text: strings.newMessagesIndicator, onClick: scrollToBottom })))),
11370
+ React__default["default"].createElement(LiveAnnouncer, null,
11242
11371
  React__default["default"].createElement(FluentV9ThemeProvider, { v8Theme: theme },
11243
11372
  React__default["default"].createElement(reactChat.Chat
11244
11373
  // styles?.chatContainer used in className and style prop as style prop can't handle CSS selectors
11245
11374
  , {
11246
11375
  // styles?.chatContainer used in className and style prop as style prop can't handle CSS selectors
11247
- className: reactComponents.mergeClasses(classes.root, react.mergeStyles(styles === null || styles === void 0 ? void 0 : styles.chatContainer)), ref: chatScrollDivRef, style: Object.assign({}, createStyleFromV8Style(styles === null || styles === void 0 ? void 0 : styles.chatContainer)) }, messagesToDisplay))));
11248
- }, [theme, classes.root, styles === null || styles === void 0 ? void 0 : styles.chatContainer, messagesToDisplay]);
11249
- return (React__default["default"].createElement("div", { className: react.mergeStyles(messageThreadWrapperContainerStyle), ref: chatThreadRef },
11250
- existsNewChatMessage && !disableJumpToNewMessageButton && (React__default["default"].createElement("div", { className: react.mergeStyles(newMessageButtonContainerStyle, styles === null || styles === void 0 ? void 0 : styles.newMessageButtonContainer) }, onRenderJumpToNewMessageButton ? (onRenderJumpToNewMessageButton({ text: strings.newMessagesIndicator, onClick: scrollToBottom })) : (React__default["default"].createElement(DefaultJumpToNewMessageButton, { text: strings.newMessagesIndicator, onClick: scrollToBottom })))),
11251
- chatBody));
11252
- };
11253
- const onRenderFileDownloadsTrampoline = (props) => {
11254
- /* @conditional-compile-remove(file-sharing) */
11255
- return props.onRenderFileDownloads;
11256
- };
11376
+ className: reactComponents.mergeClasses(classes.root, react.mergeStyles(styles === null || styles === void 0 ? void 0 : styles.chatContainer)), ref: chatScrollDivRef, style: Object.assign({}, createStyleFromV8Style(styles === null || styles === void 0 ? void 0 : styles.chatContainer)) }, messagesToDisplay.map((message) => {
11377
+ return (React__default["default"].createElement(MemoChatMessageComponentWrapper, Object.assign({}, message, { userId: userId, key: message.key, styles: styles, shouldOverlapAvatarAndMessage: isNarrow, strings: strings, onRenderAvatar: onRenderAvatar, onRenderMessage: onRenderMessage, onRenderMessageStatus: onRenderMessageStatus, defaultStatusRenderer: defaultStatusRenderer, onActionButtonClick: onActionButtonClickMemo, readCount: readCountForHoveredIndicator, participantCount: participantCount,
11378
+ /* @conditional-compile-remove(file-sharing) */
11379
+ fileDownloadHandler: props.fileDownloadHandler,
11380
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
11381
+ onFetchInlineAttachment: onFetchInlineAttachment,
11382
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
11383
+ inlineAttachments: inlineAttachments,
11384
+ /* @conditional-compile-remove(image-gallery) */
11385
+ onInlineImageClicked: onInlineImageClicked,
11386
+ /* @conditional-compile-remove(date-time-customization) */
11387
+ onDisplayDateTimeString: onDisplayDateTimeString,
11388
+ /* @conditional-compile-remove(mention) */
11389
+ mentionOptions: mentionOptions,
11390
+ /* @conditional-compile-remove(file-sharing) */
11391
+ onRenderFileDownloads: onRenderFileDownloads })));
11392
+ }))))));
11393
+ };
11394
+ const MemoChatMessageComponentWrapper = React__default["default"].memo((obj) => {
11395
+ return React__default["default"].createElement(ChatMessageComponentWrapper, Object.assign({}, obj));
11396
+ });
11257
11397
 
11258
11398
  // Copyright (c) Microsoft Corporation.
11259
11399
  /**
@@ -14122,13 +14262,13 @@ const OverflowGallery = (props) => {
14122
14262
  const scrollableHorizontalGalleryContainerStyles = React.useMemo(() => {
14123
14263
  if (isNarrow && parentWidth) {
14124
14264
  return {
14125
- width: props.layout === 'default'
14126
- ? `${_convertPxToRem(parentWidth) - 1}rem`
14127
- : `${_convertPxToRem(parentWidth) - SMALL_FLOATING_MODAL_SIZE_REM.width - 1}rem`
14265
+ width: shouldFloatLocalVideo
14266
+ ? `${_convertPxToRem(parentWidth) - SMALL_FLOATING_MODAL_SIZE_REM.width - 1}rem`
14267
+ : `${_convertPxToRem(parentWidth) - 1}rem`
14128
14268
  };
14129
14269
  }
14130
14270
  return undefined;
14131
- }, [isNarrow, parentWidth, props.layout]);
14271
+ }, [isNarrow, parentWidth, shouldFloatLocalVideo]);
14132
14272
  /* @conditional-compile-remove(vertical-gallery) */
14133
14273
  if (overflowGalleryPosition === 'verticalRight') {
14134
14274
  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)]));
@@ -14210,9 +14350,7 @@ const DefaultLayout = (props) => {
14210
14350
  /* @conditional-compile-remove(vertical-gallery) */
14211
14351
  overflowGalleryPosition: overflowGalleryPosition, onFetchTilesToRender: setIndexesToRender, onChildrenPerPageChange: (n) => {
14212
14352
  childrenPerPage.current = n;
14213
- },
14214
- /* @conditional-compile-remove(gallery-layouts) */
14215
- layout: 'default', parentWidth: parentWidth }));
14353
+ }, parentWidth: parentWidth }));
14216
14354
  }, [
14217
14355
  isNarrow,
14218
14356
  /* @conditional-compile-remove(vertical-gallery) */ isShort,
@@ -15076,7 +15214,7 @@ const FloatingLocalVideoLayout = (props) => {
15076
15214
  /* @conditional-compile-remove(vertical-gallery) */
15077
15215
  , {
15078
15216
  /* @conditional-compile-remove(vertical-gallery) */
15079
- isShort: isShort, onFetchTilesToRender: setIndexesToRender, isNarrow: isNarrow, shouldFloatLocalVideo: true, overflowGalleryElements: overflowGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
15217
+ isShort: isShort, onFetchTilesToRender: setIndexesToRender, isNarrow: isNarrow, shouldFloatLocalVideo: !!localVideoComponent, overflowGalleryElements: overflowGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
15080
15218
  /* @conditional-compile-remove(vertical-gallery) */
15081
15219
  verticalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.verticalGallery,
15082
15220
  /* @conditional-compile-remove(vertical-gallery) */
@@ -15092,7 +15230,8 @@ const FloatingLocalVideoLayout = (props) => {
15092
15230
  /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryPosition,
15093
15231
  setIndexesToRender,
15094
15232
  /* @conditional-compile-remove(vertical-gallery) */ styles === null || styles === void 0 ? void 0 : styles.verticalGallery,
15095
- parentWidth
15233
+ parentWidth,
15234
+ localVideoComponent
15096
15235
  ]);
15097
15236
  return (React__default["default"].createElement(react.Stack, { styles: rootLayoutStyle },
15098
15237
  wrappedLocalVideoComponent,
@@ -15205,7 +15344,7 @@ const SpeakerVideoLayout = (props) => {
15205
15344
  /* @conditional-compile-remove(vertical-gallery) */
15206
15345
  , {
15207
15346
  /* @conditional-compile-remove(vertical-gallery) */
15208
- isShort: isShort, onFetchTilesToRender: setIndexesToRender, isNarrow: isNarrow, shouldFloatLocalVideo: true, overflowGalleryElements: overflowGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
15347
+ isShort: isShort, onFetchTilesToRender: setIndexesToRender, isNarrow: isNarrow, shouldFloatLocalVideo: !!localVideoComponent, overflowGalleryElements: overflowGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
15209
15348
  /* @conditional-compile-remove(vertical-gallery) */
15210
15349
  verticalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.verticalGallery,
15211
15350
  /* @conditional-compile-remove(vertical-gallery) */
@@ -15221,7 +15360,8 @@ const SpeakerVideoLayout = (props) => {
15221
15360
  /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryPosition,
15222
15361
  setIndexesToRender,
15223
15362
  /* @conditional-compile-remove(vertical-gallery) */ styles === null || styles === void 0 ? void 0 : styles.verticalGallery,
15224
- parentWidth
15363
+ parentWidth,
15364
+ localVideoComponent
15225
15365
  ]);
15226
15366
  return (React__default["default"].createElement(react.Stack, { styles: rootLayoutStyle },
15227
15367
  wrappedLocalVideoComponent,
@@ -21001,8 +21141,16 @@ const proxyChatClient = {
21001
21141
  * @public
21002
21142
  */
21003
21143
  const createStatefulChatClient = (args, options) => {
21004
- chatStatefulLogger.info(`Creating chat stateful client using library version: ${_getApplicationId()}`);
21005
- const tweakedOptions = Object.assign(Object.assign({}, options), { chatClientOptions: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.chatClientOptions), { userAgentOptions: { userAgentPrefix: _getApplicationId() } }) });
21144
+ return _createStatefulChatClientInner(args, options);
21145
+ };
21146
+ /**
21147
+ * This inner function is used to allow injection of TelemetryImplementationHint without changing the public API.
21148
+ *
21149
+ * @internal
21150
+ */
21151
+ const _createStatefulChatClientInner = (args, options, telemetryImplementationHint = 'StatefulComponents') => {
21152
+ chatStatefulLogger.info(`Creating chat stateful client using library version: ${_getApplicationId(telemetryImplementationHint)}`);
21153
+ const tweakedOptions = Object.assign(Object.assign({}, options), { chatClientOptions: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.chatClientOptions), { userAgentOptions: { userAgentPrefix: _getApplicationId(telemetryImplementationHint) } }) });
21006
21154
  return _createStatefulChatClientWithDeps(new communicationChat.ChatClient(args.endpoint, args.credential, tweakedOptions.chatClientOptions), args, tweakedOptions);
21007
21155
  };
21008
21156
  /**
@@ -21858,15 +22006,23 @@ const convertEventType = (type) => {
21858
22006
  * @public
21859
22007
  */
21860
22008
  const createAzureCommunicationChatAdapter = ({ endpoint: endpointUrl, userId, displayName, credential, threadId }) => __awaiter$k(void 0, void 0, void 0, function* () {
22009
+ return _createAzureCommunicationChatAdapterInner(endpointUrl, userId, displayName, credential, threadId);
22010
+ });
22011
+ /**
22012
+ * This inner function is used to allow injection of TelemetryImplementationHint without changing the public API.
22013
+ *
22014
+ * @internal
22015
+ */
22016
+ const _createAzureCommunicationChatAdapterInner = (endpoint, userId, displayName, credential, threadId, telemetryImplementationHint = 'Chat') => __awaiter$k(void 0, void 0, void 0, function* () {
21861
22017
  if (!_isValidIdentifier(userId)) {
21862
22018
  throw new Error('Provided userId is invalid. Please provide valid identifier object.');
21863
22019
  }
21864
- const chatClient = createStatefulChatClient({
22020
+ const chatClient = _createStatefulChatClientInner({
21865
22021
  userId,
21866
22022
  displayName,
21867
- endpoint: endpointUrl,
21868
- credential: credential
21869
- });
22023
+ endpoint,
22024
+ credential
22025
+ }, undefined, telemetryImplementationHint);
21870
22026
  const chatThreadClient = yield chatClient.getChatThreadClient(threadId);
21871
22027
  yield chatClient.startRealtimeNotifications();
21872
22028
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
@@ -22642,9 +22798,15 @@ const ChatScreen = (props) => {
22642
22798
  const onRenderAvatarCallback = React.useCallback((userId, defaultOptions) => {
22643
22799
  return (React__default["default"].createElement(AvatarPersona, Object.assign({ userId: userId, hidePersonaDetails: true }, defaultOptions, { dataProvider: onFetchAvatarPersonaData })));
22644
22800
  }, [onFetchAvatarPersonaData]);
22645
- const messageThreadStyles = Object.assign({}, messageThreadChatCompositeStyles(theme.semanticColors.bodyBackground), styles === null || styles === void 0 ? void 0 : styles.messageThread);
22646
- const typingIndicatorStyles = Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.typingIndicator);
22647
- const sendBoxStyles = Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.sendBox);
22801
+ const messageThreadStyles = React.useMemo(() => {
22802
+ return Object.assign({}, messageThreadChatCompositeStyles(theme.semanticColors.bodyBackground), styles === null || styles === void 0 ? void 0 : styles.messageThread);
22803
+ }, [styles === null || styles === void 0 ? void 0 : styles.messageThread, theme.semanticColors.bodyBackground]);
22804
+ const typingIndicatorStyles = React.useMemo(() => {
22805
+ return Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.typingIndicator);
22806
+ }, [styles === null || styles === void 0 ? void 0 : styles.typingIndicator]);
22807
+ const sendBoxStyles = React.useMemo(() => {
22808
+ return Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.sendBox);
22809
+ }, [styles === null || styles === void 0 ? void 0 : styles.sendBox]);
22648
22810
  const userId = toFlatCommunicationIdentifier(adapter.getState().userId);
22649
22811
  const fileUploadButtonOnChange = React.useCallback((files) => {
22650
22812
  if (!files) {
@@ -22795,21 +22957,12 @@ const ChatScreen = (props) => {
22795
22957
  const ChatComposite = (props) => {
22796
22958
  const { adapter, options, onFetchAvatarPersonaData, onRenderTypingIndicator, onRenderMessage, onFetchParticipantMenuItems } = props;
22797
22959
  const formFactor = props['formFactor'] || 'desktop';
22798
- /**
22799
- * @TODO Remove this function and pass the props directly when file-sharing is promoted to stable.
22800
- * @private
22801
- */
22802
- // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
22803
- const fileSharingOptions = () => {
22804
- /* @conditional-compile-remove(file-sharing) */
22805
- return {
22806
- fileSharing: options === null || options === void 0 ? void 0 : options.fileSharing
22807
- };
22808
- };
22809
22960
  return (React__default["default"].createElement("div", { className: chatScreenContainerStyle },
22810
22961
  React__default["default"].createElement(BaseProvider, Object.assign({}, props),
22811
22962
  React__default["default"].createElement(ChatAdapterProvider, { adapter: adapter },
22812
- React__default["default"].createElement(ChatScreen, Object.assign({ formFactor: formFactor, options: options, onFetchAvatarPersonaData: onFetchAvatarPersonaData, onRenderTypingIndicator: onRenderTypingIndicator, onRenderMessage: onRenderMessage, onFetchParticipantMenuItems: onFetchParticipantMenuItems }, fileSharingOptions()))))));
22963
+ React__default["default"].createElement(ChatScreen, { formFactor: formFactor, options: options, onFetchAvatarPersonaData: onFetchAvatarPersonaData, onRenderTypingIndicator: onRenderTypingIndicator, onRenderMessage: onRenderMessage, onFetchParticipantMenuItems: onFetchParticipantMenuItems,
22964
+ /* @conditional-compile-remove(file-sharing) */
22965
+ fileSharing: options === null || options === void 0 ? void 0 : options.fileSharing })))));
22813
22966
  };
22814
22967
 
22815
22968
  // Copyright (c) Microsoft Corporation.
@@ -26054,7 +26207,7 @@ const SidePane = (props) => {
26054
26207
  props.onPeopleButtonClicked,
26055
26208
  props.disablePeopleButton,
26056
26209
  props.disableChatButton,
26057
- sidePaneRenderer,
26210
+ sidePaneRenderer === null || sidePaneRenderer === void 0 ? void 0 : sidePaneRenderer.id,
26058
26211
  closePane
26059
26212
  ]);
26060
26213
  const HeaderToRender = props.mobileView && (overrideSidePaneId === 'chat' || (sidePaneRenderer === null || sidePaneRenderer === void 0 ? void 0 : sidePaneRenderer.id) === 'people') ? LegacyHeader : Header();
@@ -30117,11 +30270,11 @@ const CALL_REJECTED_CODE = 603;
30117
30270
  * @private
30118
30271
  */
30119
30272
  class CallingSoundSubscriber {
30120
- constructor(call, locator, sounds) {
30273
+ constructor(call, callee, sounds) {
30121
30274
  this.onCallStateChanged = () => {
30122
30275
  this.call.on('stateChanged', () => {
30123
30276
  var _a, _b, _c, _d, _e;
30124
- if (shouldPlayRingingSound(this.call, this.callLocator) && ((_a = this.soundsLoaded) === null || _a === void 0 ? void 0 : _a.callRingingSound)) {
30277
+ if (isPSTNCall(this.call, this.callee) && ((_a = this.soundsLoaded) === null || _a === void 0 ? void 0 : _a.callRingingSound)) {
30125
30278
  this.soundsLoaded.callRingingSound.loop = true;
30126
30279
  this.playSound(this.soundsLoaded.callRingingSound);
30127
30280
  }
@@ -30141,7 +30294,7 @@ class CallingSoundSubscriber {
30141
30294
  });
30142
30295
  };
30143
30296
  this.call = call;
30144
- this.callLocator = locator;
30297
+ this.callee = callee;
30145
30298
  if (sounds) {
30146
30299
  this.soundsLoaded = this.loadSounds(sounds);
30147
30300
  this.subscribeCallSoundEvents();
@@ -30161,17 +30314,17 @@ class CallingSoundSubscriber {
30161
30314
  var _a, _b, _c;
30162
30315
  let callEndedSound;
30163
30316
  if (sounds === null || sounds === void 0 ? void 0 : sounds.callEnded) {
30164
- callEndedSound = new Audio((_a = sounds === null || sounds === void 0 ? void 0 : sounds.callEnded) === null || _a === void 0 ? void 0 : _a.path);
30317
+ callEndedSound = new Audio((_a = sounds === null || sounds === void 0 ? void 0 : sounds.callEnded) === null || _a === void 0 ? void 0 : _a.url);
30165
30318
  callEndedSound.preload = 'auto';
30166
30319
  }
30167
30320
  let callRingingSound;
30168
30321
  if (sounds === null || sounds === void 0 ? void 0 : sounds.callRinging) {
30169
- callRingingSound = new Audio((_b = sounds === null || sounds === void 0 ? void 0 : sounds.callRinging) === null || _b === void 0 ? void 0 : _b.path);
30322
+ callRingingSound = new Audio((_b = sounds === null || sounds === void 0 ? void 0 : sounds.callRinging) === null || _b === void 0 ? void 0 : _b.url);
30170
30323
  callRingingSound.preload = 'auto';
30171
30324
  }
30172
30325
  let callBusySound;
30173
30326
  if (sounds === null || sounds === void 0 ? void 0 : sounds.callBusy) {
30174
- callBusySound = new Audio((_c = sounds === null || sounds === void 0 ? void 0 : sounds.callBusy) === null || _c === void 0 ? void 0 : _c.path);
30327
+ callBusySound = new Audio((_c = sounds === null || sounds === void 0 ? void 0 : sounds.callBusy) === null || _c === void 0 ? void 0 : _c.url);
30175
30328
  callBusySound.preload = 'auto';
30176
30329
  }
30177
30330
  return {
@@ -30190,12 +30343,11 @@ class CallingSoundSubscriber {
30190
30343
  * Helper function to allow the calling sound subscriber to determine when to play the ringing
30191
30344
  * sound when making an outbound call.
30192
30345
  */
30193
- const shouldPlayRingingSound = (call, locator) => {
30346
+ const isPSTNCall = (call, callee) => {
30194
30347
  /* @conditional-compile-remove(calling-sounds) */
30195
- const callee = locator.participantIds;
30196
- /* @conditional-compile-remove(calling-sounds) */
30197
- if (callee.length >= 1 &&
30198
- !communicationCommon.isPhoneNumberIdentifier(fromFlatCommunicationIdentifier(callee[0])) &&
30348
+ if (callee &&
30349
+ callee.length >= 1 &&
30350
+ !communicationCommon.isPhoneNumberIdentifier(callee[0]) &&
30199
30351
  (call.state === 'Ringing' || call.state === 'Connecting')) {
30200
30352
  return true;
30201
30353
  }
@@ -30220,7 +30372,7 @@ class CallContext {
30220
30372
  constructor(clientState, isTeamsCall,
30221
30373
  /* @conditional-compile-remove(rooms) */
30222
30374
  isRoomsCall, options) {
30223
- var _a, _b, _c, _d, _e;
30375
+ var _a, _b, _c, _d;
30224
30376
  this.emitter = new EventEmitter.EventEmitter();
30225
30377
  this.state = {
30226
30378
  isLocalPreviewMicrophoneEnabled: false,
@@ -30228,6 +30380,7 @@ class CallContext {
30228
30380
  displayName: (_a = clientState.callAgent) === null || _a === void 0 ? void 0 : _a.displayName,
30229
30381
  devices: clientState.deviceManager,
30230
30382
  call: undefined,
30383
+ /* @conditional-compile-remove(calling-sounds) */ targetCallees: undefined,
30231
30384
  page: 'configuration',
30232
30385
  latestErrors: clientState.latestErrors,
30233
30386
  isTeamsCall,
@@ -30240,9 +30393,9 @@ class CallContext {
30240
30393
  onResolveVideoEffectDependency: (_c = options === null || options === void 0 ? void 0 : options.videoBackgroundOptions) === null || _c === void 0 ? void 0 : _c.onResolveDependency,
30241
30394
  /* @conditional-compile-remove(video-background-effects) */ selectedVideoBackgroundEffect: undefined,
30242
30395
  cameraStatus: undefined,
30243
- /* @conditional-compile-remove(calling-sounds) */ sounds: (_d = options === null || options === void 0 ? void 0 : options.soundOptions) === null || _d === void 0 ? void 0 : _d.callingSounds
30396
+ /* @conditional-compile-remove(calling-sounds) */ sounds: options === null || options === void 0 ? void 0 : options.callingSounds
30244
30397
  };
30245
- this.emitter.setMaxListeners((_e = options === null || options === void 0 ? void 0 : options.maxListeners) !== null && _e !== void 0 ? _e : 50);
30398
+ this.emitter.setMaxListeners((_d = options === null || options === void 0 ? void 0 : options.maxListeners) !== null && _d !== void 0 ? _d : 50);
30246
30399
  this.bindPublicMethods();
30247
30400
  this.displayNameModifier = (options === null || options === void 0 ? void 0 : options.onFetchProfile)
30248
30401
  ? createProfileStateModifier(options.onFetchProfile, () => {
@@ -30274,6 +30427,10 @@ class CallContext {
30274
30427
  setCurrentCallId(callId) {
30275
30428
  this.callId = callId;
30276
30429
  }
30430
+ /* @conditional-compile-remove(calling-sounds) */
30431
+ setTargetCallee(targetCallees) {
30432
+ this.setState(Object.assign(Object.assign({}, this.state), { targetCallees }));
30433
+ }
30277
30434
  onCallEnded(handler) {
30278
30435
  this.emitter.on('callEnded', handler);
30279
30436
  }
@@ -30888,6 +31045,8 @@ class AzureCommunicationCallAdapter {
30888
31045
  }
30889
31046
  return backendId;
30890
31047
  });
31048
+ /* @conditional-compile-remove(calling-sounds) */
31049
+ this.context.setTargetCallee(idsToAdd);
30891
31050
  const call = this.handlers.onStartCall(idsToAdd, options);
30892
31051
  if (!call) {
30893
31052
  throw new Error('Unable to start call.');
@@ -31026,7 +31185,7 @@ class AzureCommunicationCallAdapter {
31026
31185
  var _a, _b, _c, _d, _e, _f, _g, _h;
31027
31186
  /* @conditional-compile-remove(calling-sounds) */
31028
31187
  if (this.call) {
31029
- this.callingSoundSubscriber = new CallingSoundSubscriber(this.call, this.locator, this.getState().sounds);
31188
+ this.callingSoundSubscriber = new CallingSoundSubscriber(this.call, this.getState().targetCallees, this.getState().sounds);
31030
31189
  }
31031
31190
  (_a = this.call) === null || _a === void 0 ? void 0 : _a.on('remoteParticipantsUpdated', this.onRemoteParticipantsUpdated.bind(this));
31032
31191
  (_b = this.call) === null || _b === void 0 ? void 0 : _b.on('isMutedChanged', this.isMyMutedChanged.bind(this));
@@ -31149,6 +31308,7 @@ class AzureCommunicationCallAdapter {
31149
31308
  if (((_a = this.call) === null || _a === void 0 ? void 0 : _a.role) === 'Consumer') {
31150
31309
  (_b = this.call) === null || _b === void 0 ? void 0 : _b.feature(communicationCalling.Features.RaiseHand).lowerHand();
31151
31310
  }
31311
+ this.emitter.emit('roleChanged');
31152
31312
  }
31153
31313
  callIdChanged() {
31154
31314
  var _a;
@@ -31203,13 +31363,33 @@ class AzureCommunicationCallAdapter {
31203
31363
  const createAzureCommunicationCallAdapter = ({ userId, displayName, credential, locator,
31204
31364
  /* @conditional-compile-remove(PSTN-calls) */ alternateCallerId,
31205
31365
  /* @conditional-compile-remove(video-background-effects) */ options }) => __awaiter$5(void 0, void 0, void 0, function* () {
31366
+ return _createAzureCommunicationCallAdapterInner({
31367
+ userId,
31368
+ displayName,
31369
+ credential,
31370
+ locator,
31371
+ /* @conditional-compile-remove(PSTN-calls) */
31372
+ alternateCallerId,
31373
+ /* @conditional-compile-remove(video-background-effects) */
31374
+ options
31375
+ });
31376
+ });
31377
+ /**
31378
+ * This inner function is used to allow injection of TelemetryImplementationHint without changing the public API.
31379
+ *
31380
+ * @internal
31381
+ */
31382
+ const _createAzureCommunicationCallAdapterInner = ({ userId, displayName, credential, locator,
31383
+ /* @conditional-compile-remove(PSTN-calls) */ alternateCallerId,
31384
+ /* @conditional-compile-remove(video-background-effects) */ options, telemetryImplementationHint = 'Call' }) => __awaiter$5(void 0, void 0, void 0, function* () {
31206
31385
  if (!_isValidIdentifier(userId)) {
31207
31386
  throw new Error('Invalid identifier. Please provide valid identifier object.');
31208
31387
  }
31209
- const callClient = createStatefulCallClient({
31388
+ const callClient = _createStatefulCallClientInner({
31210
31389
  userId,
31211
- /* @conditional-compile-remove(PSTN-calls) */ alternateCallerId
31212
- });
31390
+ /* @conditional-compile-remove(PSTN-calls) */
31391
+ alternateCallerId
31392
+ }, undefined, telemetryImplementationHint);
31213
31393
  const callAgent = yield callClient.createCallAgent(credential, {
31214
31394
  displayName
31215
31395
  });
@@ -31222,9 +31402,9 @@ const createAzureCommunicationCallAdapter = ({ userId, displayName, credential,
31222
31402
  * @beta
31223
31403
  */
31224
31404
  const createTeamsCallAdapter = ({ userId, credential, locator, options }) => __awaiter$5(void 0, void 0, void 0, function* () {
31225
- const callClient = createStatefulCallClient({
31405
+ const callClient = _createStatefulCallClientInner({
31226
31406
  userId
31227
- });
31407
+ }, undefined, 'Call');
31228
31408
  const callAgent = yield callClient.createTeamsCallAgent(credential, {
31229
31409
  undefined
31230
31410
  });
@@ -31982,10 +32162,8 @@ const CallWithChatScreen = (props) => {
31982
32162
  callWithChatAdapter.offStateChange(updateCallWithChatPage);
31983
32163
  };
31984
32164
  }, [callWithChatAdapter]);
31985
- const chatProps = React.useMemo(() => {
31986
- return {
31987
- adapter: new CallWithChatBackedChatAdapter(callWithChatAdapter)
31988
- };
32165
+ const chatAdapter = React.useMemo(() => {
32166
+ return new CallWithChatBackedChatAdapter(callWithChatAdapter);
31989
32167
  }, [callWithChatAdapter]);
31990
32168
  /** Constant setting of id for the parent stack of the composite */
31991
32169
  const compositeParentDivId = reactHooks.useId('callWithChatCompositeParentDiv-internal');
@@ -32034,7 +32212,7 @@ const CallWithChatScreen = (props) => {
32034
32212
  disabled: chatButtonDisabled
32035
32213
  }
32036
32214
  : undefined, [chatButtonDisabled, mobileView, toggleChat, showChatButton]);
32037
- const unreadChatMessagesCount = useUnreadMessagesTracker(chatProps.adapter, isChatOpen);
32215
+ const unreadChatMessagesCount = useUnreadMessagesTracker(chatAdapter, isChatOpen);
32038
32216
  const customChatButton = React.useCallback((args) => ({
32039
32217
  placement: mobileView ? 'primary' : 'secondary',
32040
32218
  onRenderButton: () => (React__default["default"].createElement(ChatButtonWithUnreadMessagesBadge, { checked: isChatOpen, showLabel: args.displayType !== 'compact', onClick: toggleChat, disabled: chatButtonDisabled, strings: chatButtonStrings, styles: commonButtonStyles, newMessageLabel: callWithChatStrings.chatButtonNewMessageNotificationLabel, unreadChatMessagesCount: unreadChatMessagesCount,
@@ -32108,14 +32286,14 @@ const CallWithChatScreen = (props) => {
32108
32286
  /* @conditional-compile-remove(custom-branding) */
32109
32287
  props.backgroundImage
32110
32288
  ]);
32111
- const onRenderChatContent = React.useCallback(() => (React__default["default"].createElement(ChatComposite, Object.assign({}, chatProps, { fluentTheme: theme, options: {
32289
+ const onRenderChatContent = React.useCallback(() => (React__default["default"].createElement(ChatComposite, { adapter: chatAdapter, fluentTheme: theme, options: {
32112
32290
  topic: false,
32113
32291
  /* @conditional-compile-remove(chat-composite-participant-pane) */
32114
32292
  participantPane: false,
32115
32293
  /* @conditional-compile-remove(file-sharing) */
32116
32294
  fileSharing: props.fileSharing
32117
- }, onFetchAvatarPersonaData: props.onFetchAvatarPersonaData }))), [
32118
- chatProps,
32295
+ }, onFetchAvatarPersonaData: props.onFetchAvatarPersonaData })), [
32296
+ chatAdapter,
32119
32297
  /* @conditional-compile-remove(file-sharing) */ props.fileSharing,
32120
32298
  props.onFetchAvatarPersonaData,
32121
32299
  theme
@@ -32915,24 +33093,19 @@ const createAzureCommunicationCallWithChatAdapter = ({ userId, displayName, cred
32915
33093
  /* @conditional-compile-remove(PSTN-calls) */ alternateCallerId,
32916
33094
  /* @conditional-compile-remove(video-background-effects) */ callAdapterOptions }) => __awaiter$2(void 0, void 0, void 0, function* () {
32917
33095
  const callAdapterLocator = isTeamsMeetingLinkLocator(locator) ? locator : locator.callLocator;
32918
- const createCallAdapterPromise = createAzureCommunicationCallAdapter({
33096
+ const createCallAdapterPromise = _createAzureCommunicationCallAdapterInner({
32919
33097
  userId,
32920
33098
  displayName,
32921
33099
  credential,
32922
33100
  locator: callAdapterLocator,
32923
33101
  /* @conditional-compile-remove(PSTN-calls) */ alternateCallerId,
32924
- /* @conditional-compile-remove(video-background-effects) */ options: callAdapterOptions
33102
+ /* @conditional-compile-remove(video-background-effects) */ options: callAdapterOptions,
33103
+ telemetryImplementationHint: 'CallWithChat'
32925
33104
  });
32926
33105
  const threadId = isTeamsMeetingLinkLocator(locator)
32927
33106
  ? getChatThreadFromTeamsLink(locator.meetingLink)
32928
33107
  : locator.chatThreadId;
32929
- const createChatAdapterPromise = createAzureCommunicationChatAdapter({
32930
- endpoint,
32931
- userId,
32932
- displayName,
32933
- credential,
32934
- threadId
32935
- });
33108
+ const createChatAdapterPromise = _createAzureCommunicationChatAdapterInner(endpoint, userId, displayName, credential, threadId, 'CallWithChat');
32936
33109
  const [callAdapter, chatAdapter] = yield Promise.all([createCallAdapterPromise, createChatAdapterPromise]);
32937
33110
  return new AzureCommunicationCallWithChatAdapter(callAdapter, chatAdapter);
32938
33111
  });