@azure/communication-react 1.11.1-alpha-202401050013 → 1.11.1-alpha-202401090013

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 (49) hide show
  1. package/dist/communication-react.d.ts +38 -4
  2. package/dist/dist-cjs/communication-react/index.js +157 -34
  3. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  4. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  5. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  6. package/dist/dist-esm/react-components/src/components/MentionPopover.js +14 -13
  7. package/dist/dist-esm/react-components/src/components/MentionPopover.js.map +1 -1
  8. package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.d.ts +16 -0
  9. package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js +13 -0
  10. package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js.map +1 -0
  11. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +11 -0
  12. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
  13. package/dist/dist-esm/react-components/src/components/index.d.ts +2 -0
  14. package/dist/dist-esm/react-components/src/components/index.js +2 -0
  15. package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
  16. package/dist/dist-esm/react-components/src/components/styles/MentionPopover.style.d.ts +1 -1
  17. package/dist/dist-esm/react-components/src/components/styles/MentionPopover.style.js +6 -5
  18. package/dist/dist-esm/react-components/src/components/styles/MentionPopover.style.js.map +1 -1
  19. package/dist/dist-esm/react-components/src/components/styles/Stack.style.d.ts +5 -0
  20. package/dist/dist-esm/react-components/src/components/styles/Stack.style.js +32 -0
  21. package/dist/dist-esm/react-components/src/components/styles/Stack.style.js.map +1 -0
  22. package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts +1 -1
  23. package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.js.map +1 -1
  24. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +10 -1
  25. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js.map +1 -1
  26. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.d.ts +4 -3
  27. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.js.map +1 -1
  28. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.js +15 -5
  29. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.js.map +1 -1
  30. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/ConfigurationPage.js +9 -1
  31. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/ConfigurationPage.js.map +1 -1
  32. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.d.ts +1 -1
  33. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.js +2 -2
  34. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.js.map +1 -1
  35. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/ChatButton/useUnreadMessagesTracker.js +24 -5
  36. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/ChatButton/useUnreadMessagesTracker.js.map +1 -1
  37. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.d.ts +5 -1
  38. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +12 -0
  39. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js.map +1 -1
  40. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.d.ts +6 -2
  41. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.js.map +1 -1
  42. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.d.ts +7 -1
  43. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js +30 -2
  44. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js.map +1 -1
  45. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/ChatAdapter.d.ts +28 -0
  46. package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/ChatAdapter.js.map +1 -1
  47. package/dist/dist-esm/react-composites/src/composites/ChatComposite/index.d.ts +1 -1
  48. package/dist/dist-esm/react-composites/src/composites/ChatComposite/index.js.map +1 -1
  49. package/package.json +1 -1
@@ -2303,7 +2303,7 @@ export declare interface CallCompositeStrings {
2303
2303
  /**
2304
2304
  * String for title when the call is rejected by the callee
2305
2305
  */
2306
- callRejectedTitle: string;
2306
+ callRejectedTitle?: string;
2307
2307
  /**
2308
2308
  * String for more details when the call is rejected by the callee
2309
2309
  */
@@ -2448,7 +2448,7 @@ export declare type CallingHandlersOptions = {
2448
2448
  export declare type CallingReturnProps<Component extends (props: any) => JSX.Element> = GetCallingSelector<Component> extends (state: CallClientState, props: any) => any ? ReturnType<GetCallingSelector<Component>> & Common<CallingHandlers, Parameters<Component>[0]> : never;
2449
2449
 
2450
2450
  /**
2451
- * @beta
2451
+ * @public
2452
2452
  * Type for representing a set of sounds to use for different calling events
2453
2453
  */
2454
2454
  export declare type CallingSounds = {
@@ -3135,12 +3135,16 @@ export declare interface CallWithChatAdapterSubscriptions {
3135
3135
  off(event: 'isSpokenLanguageChanged', listener: IsSpokenLanguageChangedListener): void;
3136
3136
  off(event: 'capabilitiesChanged', listener: CapabilitiesChangedListener): void;
3137
3137
  on(event: 'messageReceived', listener: MessageReceivedListener): void;
3138
+ on(event: 'messageEdited', listener: MessageEditedListener): void;
3139
+ on(event: 'messageDeleted', listener: MessageDeletedListener): void;
3138
3140
  on(event: 'messageSent', listener: MessageSentListener): void;
3139
3141
  on(event: 'messageRead', listener: MessageReadListener): void;
3140
3142
  on(event: 'chatParticipantsAdded', listener: ParticipantsAddedListener): void;
3141
3143
  on(event: 'chatParticipantsRemoved', listener: ParticipantsRemovedListener): void;
3142
3144
  on(event: 'chatError', listener: (e: AdapterError) => void): void;
3143
3145
  off(event: 'messageReceived', listener: MessageReceivedListener): void;
3146
+ off(event: 'messageEdited', listener: MessageEditedListener): void;
3147
+ off(event: 'messageDeleted', listener: MessageDeletedListener): void;
3144
3148
  off(event: 'messageSent', listener: MessageSentListener): void;
3145
3149
  off(event: 'messageRead', listener: MessageReadListener): void;
3146
3150
  off(event: 'chatParticipantsAdded', listener: ParticipantsAddedListener): void;
@@ -3680,7 +3684,7 @@ export declare interface CallWithChatControlOptions extends CommonCallControlOpt
3680
3684
  *
3681
3685
  * @public
3682
3686
  */
3683
- export declare type CallWithChatEvent = 'callError' | 'chatError' | 'callEnded' | 'isMutedChanged' | 'callIdChanged' | 'isLocalScreenSharingActiveChanged' | 'displayNameChanged' | 'isSpeakingChanged' | 'callParticipantsJoined' | 'callParticipantsLeft' | 'selectedMicrophoneChanged' | 'selectedSpeakerChanged' | /* @conditional-compile-remove(close-captions) */ 'isCaptionsActiveChanged' | /* @conditional-compile-remove(close-captions) */ 'captionsReceived' | /* @conditional-compile-remove(close-captions) */ 'isCaptionLanguageChanged' | /* @conditional-compile-remove(close-captions) */ 'isSpokenLanguageChanged' | /* @conditional-compile-remove(capabilities) */ 'capabilitiesChanged' | 'messageReceived' | 'messageSent' | 'messageRead' | 'chatParticipantsAdded' | 'chatParticipantsRemoved';
3687
+ export declare type CallWithChatEvent = 'callError' | 'chatError' | 'callEnded' | 'isMutedChanged' | 'callIdChanged' | 'isLocalScreenSharingActiveChanged' | 'displayNameChanged' | 'isSpeakingChanged' | 'callParticipantsJoined' | 'callParticipantsLeft' | 'selectedMicrophoneChanged' | 'selectedSpeakerChanged' | /* @conditional-compile-remove(close-captions) */ 'isCaptionsActiveChanged' | /* @conditional-compile-remove(close-captions) */ 'captionsReceived' | /* @conditional-compile-remove(close-captions) */ 'isCaptionLanguageChanged' | /* @conditional-compile-remove(close-captions) */ 'isSpokenLanguageChanged' | /* @conditional-compile-remove(capabilities) */ 'capabilitiesChanged' | 'messageReceived' | 'messageEdited' | 'messageDeleted' | 'messageSent' | 'messageRead' | 'chatParticipantsAdded' | 'chatParticipantsRemoved';
3684
3688
 
3685
3689
  /**
3686
3690
  * @beta
@@ -4116,6 +4120,14 @@ export declare interface ChatAdapterSubscribers {
4116
4120
  * Subscribe function for 'messageReceived' event.
4117
4121
  */
4118
4122
  on(event: 'messageReceived', listener: MessageReceivedListener): void;
4123
+ /**
4124
+ * Subscribe function for 'messageEdited' event.
4125
+ */
4126
+ on(event: 'messageEdited', listener: MessageEditedListener): void;
4127
+ /**
4128
+ * Subscribe function for 'messageDeleted' event.
4129
+ */
4130
+ on(event: 'messageDeleted', listener: MessageDeletedListener): void;
4119
4131
  /**
4120
4132
  * Subscribe function for 'messageSent' event.
4121
4133
  */
@@ -4144,6 +4156,14 @@ export declare interface ChatAdapterSubscribers {
4144
4156
  * Unsubscribe function for 'messageReceived' event.
4145
4157
  */
4146
4158
  off(event: 'messageReceived', listener: MessageReceivedListener): void;
4159
+ /**
4160
+ * Unsubscribe function for 'messageEdited' event.
4161
+ */
4162
+ off(event: 'messageEdited', listener: MessageEditedListener): void;
4163
+ /**
4164
+ * Unsubscribe function for 'messageDeleted' event.
4165
+ */
4166
+ off(event: 'messageDeleted', listener: MessageDeletedListener): void;
4147
4167
  /**
4148
4168
  * Unsubscribe function for 'messageSent' event.
4149
4169
  */
@@ -7638,6 +7658,20 @@ export declare interface MessageCommon {
7638
7658
  */
7639
7659
  export declare type MessageContentType = 'text' | 'html' | 'richtext/html' | 'unknown';
7640
7660
 
7661
+ /**
7662
+ * Callback for {@link ChatAdapterSubscribers} 'messageDeleted' event.
7663
+ *
7664
+ * @public
7665
+ */
7666
+ export declare type MessageDeletedListener = MessageReceivedListener;
7667
+
7668
+ /**
7669
+ * Callback for {@link ChatAdapterSubscribers} 'messageEdited' event.
7670
+ *
7671
+ * @public
7672
+ */
7673
+ export declare type MessageEditedListener = MessageReceivedListener;
7674
+
7641
7675
  /**
7642
7676
  * Props to render a single message.
7643
7677
  *
@@ -9331,7 +9365,7 @@ export declare interface SitePermissionsStyles extends BaseCustomStyles {
9331
9365
  }
9332
9366
 
9333
9367
  /**
9334
- * @beta
9368
+ * @public
9335
9369
  * Type for representing a custom sound to use for a calling event
9336
9370
  */
9337
9371
  export declare type SoundEffect = {
@@ -11,11 +11,11 @@ var React = require('react');
11
11
  var react = require('@fluentui/react');
12
12
  var reactIcons = require('@fluentui/react-icons');
13
13
  var textareaCaretTs = require('textarea-caret-ts');
14
+ var reactComponents = require('@fluentui/react-components');
14
15
  var useDebounce = require('use-debounce');
15
16
  var reactFileTypeIcons = require('@fluentui/react-file-type-icons');
16
17
  var uuid = require('uuid');
17
18
  var reactChat = require('@fluentui-contrib/react-chat');
18
- var reactComponents = require('@fluentui/react-components');
19
19
  var react$1 = require('@griffel/react');
20
20
  var htmlToReact = require('html-to-react');
21
21
  var Linkify = require('react-linkify');
@@ -170,7 +170,7 @@ function getDefaultExportFromCjs (x) {
170
170
  // Copyright (c) Microsoft Corporation.
171
171
  // Licensed under the MIT License.
172
172
  // GENERATED FILE. DO NOT EDIT MANUALLY.
173
- var telemetryVersion = '1.11.1-alpha-202401050013';
173
+ var telemetryVersion = '1.11.1-alpha-202401090013';
174
174
 
175
175
 
176
176
  var telemetryVersion$1 = /*@__PURE__*/getDefaultExportFromCjs(telemetryVersion);
@@ -7361,17 +7361,17 @@ react.mergeStyles({
7361
7361
  /**
7362
7362
  * @private
7363
7363
  */
7364
- const suggestionListStyle = react.mergeStyles({
7365
- padding: '0.25rem 0rem 0',
7366
- overflow: 'visible',
7367
- overflowY: 'scroll'
7364
+ const useSuggestionListStyle = reactComponents.makeStyles({
7365
+ root: Object.assign(Object.assign(Object.assign({}, reactComponents.shorthands.padding('0.25rem', '0rem', '0rem')), reactComponents.shorthands.overflow('visible')), { overflowY: 'scroll' })
7368
7366
  });
7369
7367
  /**
7370
7368
  * @private
7371
7369
  */
7372
7370
  const suggestionItemWrapperStyle = (theme) => {
7373
7371
  return react.mergeStyles({
7374
- margin: '0.05rem 0',
7372
+ margin: '0.0625rem 0',
7373
+ 'scroll-margin-top': '0.0625rem',
7374
+ 'scroll-margin-bottom': '0.0625rem',
7375
7375
  '&:focus-visible': {
7376
7376
  outline: `${theme.palette.black} solid 0.1rem`
7377
7377
  }
@@ -7391,6 +7391,37 @@ const suggestionItemStackStyle = (theme, isSuggestionHovered, activeBorder) => {
7391
7391
  });
7392
7392
  };
7393
7393
 
7394
+ // Copyright (c) Microsoft Corporation.
7395
+ // Licensed under the MIT License.
7396
+ // These are styles that should be used during the migration from FluentUI v8 Stack component to flex.
7397
+ // https://react.fluentui.dev/?path=/docs/concepts-migration-from-v8-components-flex-stack--page
7398
+ /**
7399
+ * @private
7400
+ */
7401
+ const useDefaultStackStyles = reactComponents.makeStyles({
7402
+ root: {
7403
+ display: 'flex',
7404
+ flexDirection: 'column',
7405
+ flexWrap: 'nowrap',
7406
+ width: 'auto',
7407
+ height: 'auto',
7408
+ boxSizing: 'border-box',
7409
+ '> *': {
7410
+ textOverflow: 'ellipsis'
7411
+ }
7412
+ // As per CSS props, these two styles are not in the original Stack styles
7413
+ // (and they have higher specificity that just classes and will be applied instead of rules in classes).
7414
+ // They also break a layout for the first selected item in MentionPopover if applied.
7415
+ // Please check that component, if you want to apply these styles
7416
+ // '> :not(:first-child)': {
7417
+ // marginTop: '0px'
7418
+ // },
7419
+ // '> *:not(.ms-StackItem)': {
7420
+ // flexShrink: 1
7421
+ // }
7422
+ }
7423
+ });
7424
+
7394
7425
  // Copyright (c) Microsoft Corporation.
7395
7426
  // Licensed under the MIT License.
7396
7427
  /**
@@ -7405,9 +7436,11 @@ const _MentionPopover = (props) => {
7405
7436
  const ids = useIdentifiers();
7406
7437
  const localeStrings = useLocale$1().strings;
7407
7438
  const popoverRef = React.useRef();
7439
+ const suggestionsListRef = React.useRef(null);
7408
7440
  const [position, setPosition] = React.useState();
7409
7441
  const [hoveredSuggestion, setHoveredSuggestion] = React.useState(undefined);
7410
- const [changedSelection, setChangedSelection] = React.useState(undefined); // Selection UI as per teams
7442
+ const suggestionListStyle = useSuggestionListStyle();
7443
+ const defaultStackStyles = useDefaultStackStyles();
7411
7444
  const dismissPopoverWhenClickingOutside = React.useCallback((e) => {
7412
7445
  const target = e.target;
7413
7446
  if (popoverRef.current && !popoverRef.current.contains(target)) {
@@ -7415,13 +7448,13 @@ const _MentionPopover = (props) => {
7415
7448
  }
7416
7449
  }, [onDismiss]);
7417
7450
  React.useEffect(() => {
7418
- if (changedSelection === undefined) {
7419
- setChangedSelection(false);
7420
- }
7421
- else if (changedSelection === false) {
7422
- setChangedSelection(true);
7451
+ if (suggestionsListRef.current && activeSuggestionIndex !== undefined && activeSuggestionIndex >= 0) {
7452
+ const selectedItem = suggestionsListRef.current.children[activeSuggestionIndex];
7453
+ if (selectedItem) {
7454
+ selectedItem.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
7455
+ }
7423
7456
  }
7424
- }, [activeSuggestionIndex, changedSelection]);
7457
+ }, [activeSuggestionIndex]);
7425
7458
  React.useEffect(() => {
7426
7459
  window && window.addEventListener('click', dismissPopoverWhenClickingOutside);
7427
7460
  return () => {
@@ -7475,14 +7508,13 @@ const _MentionPopover = (props) => {
7475
7508
  return (React.createElement("div", { "data-is-focusable": true, "data-ui-id": ids.mentionSuggestionItem, key: suggestion.id, onClick: () => onSuggestionSelected(suggestion), onMouseEnter: () => setHoveredSuggestion(suggestion), onMouseLeave: () => setHoveredSuggestion(undefined), onKeyDown: (e) => {
7476
7509
  handleOnKeyDown(e);
7477
7510
  }, className: suggestionItemWrapperStyle(theme) },
7478
- React.createElement(react.Stack, { horizontal: true, className: suggestionItemStackStyle(theme, (hoveredSuggestion === null || hoveredSuggestion === void 0 ? void 0 : hoveredSuggestion.id) === suggestion.id, (changedSelection !== null && changedSelection !== void 0 ? changedSelection : false) && active) }, personaRenderer(suggestion.displayText))));
7511
+ React.createElement(react.Stack, { horizontal: true, className: suggestionItemStackStyle(theme, (hoveredSuggestion === null || hoveredSuggestion === void 0 ? void 0 : hoveredSuggestion.id) === suggestion.id, active) }, personaRenderer(suggestion.displayText))));
7479
7512
  }, [
7480
7513
  handleOnKeyDown,
7481
7514
  theme,
7482
7515
  /* @conditional-compile-remove(mention) */
7483
7516
  ids,
7484
7517
  hoveredSuggestion,
7485
- changedSelection,
7486
7518
  personaRenderer
7487
7519
  ]);
7488
7520
  const getHeaderTitle = React.useCallback(() => {
@@ -7497,9 +7529,7 @@ const _MentionPopover = (props) => {
7497
7529
  maxWidth: position.maxWidth
7498
7530
  }, mentionPopoverContainerStyle(theme), Object.assign(Object.assign({}, position), { position: 'absolute' })) },
7499
7531
  React.createElement(react.Stack.Item, { styles: headerStyleThemed(theme), "aria-label": title }, getHeaderTitle()),
7500
- React.createElement(react.Stack
7501
- /* @conditional-compile-remove(mention) */
7502
- , { "data-ui-id": ids.mentionSuggestionList, className: suggestionListStyle }, suggestions.map((suggestion, index) => {
7532
+ React.createElement("div", { className: reactComponents.mergeClasses(defaultStackStyles.root, suggestionListStyle.root), "data-ui-id": ids.mentionSuggestionList, ref: suggestionsListRef }, suggestions.map((suggestion, index) => {
7503
7533
  const active = index === activeSuggestionIndex;
7504
7534
  return onRenderSuggestionItem
7505
7535
  ? onRenderSuggestionItem(suggestion, onSuggestionSelected, active)
@@ -7643,6 +7673,7 @@ const TextFieldWithMention = (props) => {
7643
7673
  if (isEnterKeyEventFromCompositionSession(ev)) {
7644
7674
  return;
7645
7675
  }
7676
+ let isActiveSuggestionIndexUpdated = false;
7646
7677
  if (mentionSuggestions.length > 0) {
7647
7678
  if (ev.key === 'ArrowUp') {
7648
7679
  ev.preventDefault();
@@ -7650,6 +7681,7 @@ const TextFieldWithMention = (props) => {
7650
7681
  ? mentionSuggestions.length - 1
7651
7682
  : Math.max(activeSuggestionIndex - 1, 0);
7652
7683
  setActiveSuggestionIndex(newActiveIndex);
7684
+ isActiveSuggestionIndexUpdated = true;
7653
7685
  }
7654
7686
  else if (ev.key === 'ArrowDown') {
7655
7687
  ev.preventDefault();
@@ -7657,9 +7689,13 @@ const TextFieldWithMention = (props) => {
7657
7689
  ? 0
7658
7690
  : Math.min(activeSuggestionIndex + 1, mentionSuggestions.length - 1);
7659
7691
  setActiveSuggestionIndex(newActiveIndex);
7692
+ isActiveSuggestionIndexUpdated = true;
7660
7693
  }
7661
7694
  else if (ev.key === 'Escape') {
7662
7695
  updateMentionSuggestions([]);
7696
+ // reset active suggestion index when suggestions are closed
7697
+ setActiveSuggestionIndex(undefined);
7698
+ isActiveSuggestionIndexUpdated = true;
7663
7699
  }
7664
7700
  }
7665
7701
  if (ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline)) {
@@ -7674,6 +7710,11 @@ const TextFieldWithMention = (props) => {
7674
7710
  }
7675
7711
  onEnterKeyDown && onEnterKeyDown();
7676
7712
  }
7713
+ else if (!isActiveSuggestionIndexUpdated) {
7714
+ // Update the active suggestion index if the user is typing,
7715
+ // otherwise the focus will be lost
7716
+ setActiveSuggestionIndex(undefined);
7717
+ }
7677
7718
  onKeyDown && onKeyDown(ev);
7678
7719
  }, [
7679
7720
  onEnterKeyDown,
@@ -22834,6 +22875,22 @@ class AzureCommunicationChatAdapter {
22834
22875
  this.emitter.emit('messageSent', { message });
22835
22876
  }
22836
22877
  }
22878
+ messageEditedListener(event) {
22879
+ const isCurrentChatAdapterThread = event.threadId === this.chatThreadClient.threadId;
22880
+ if (!isCurrentChatAdapterThread) {
22881
+ return;
22882
+ }
22883
+ const message = convertEventToChatMessage(event);
22884
+ this.emitter.emit('messageEdited', { message });
22885
+ }
22886
+ messageDeletedListener(event) {
22887
+ const isCurrentChatAdapterThread = event.threadId === this.chatThreadClient.threadId;
22888
+ if (!isCurrentChatAdapterThread) {
22889
+ return;
22890
+ }
22891
+ const message = convertEventToChatMessage(event);
22892
+ this.emitter.emit('messageDeleted', { message });
22893
+ }
22837
22894
  messageReadListener({ chatMessageId, recipient }) {
22838
22895
  const message = this.getState().thread.chatMessages[chatMessageId];
22839
22896
  if (message) {
@@ -22854,6 +22911,8 @@ class AzureCommunicationChatAdapter {
22854
22911
  this.chatClient.on('participantsAdded', this.participantsAddedListener.bind(this));
22855
22912
  this.chatClient.on('participantsRemoved', this.participantsRemovedListener.bind(this));
22856
22913
  this.chatClient.on('chatMessageReceived', this.messageReceivedListener.bind(this));
22914
+ this.chatClient.on('chatMessageEdited', this.messageEditedListener.bind(this));
22915
+ this.chatClient.on('chatMessageDeleted', this.messageDeletedListener.bind(this));
22857
22916
  this.chatClient.on('readReceiptReceived', this.messageReadListener.bind(this));
22858
22917
  this.chatClient.on('participantsRemoved', this.participantsRemovedListener.bind(this));
22859
22918
  }
@@ -22862,6 +22921,8 @@ class AzureCommunicationChatAdapter {
22862
22921
  this.chatClient.off('participantsAdded', this.participantsAddedListener.bind(this));
22863
22922
  this.chatClient.off('participantsRemoved', this.participantsRemovedListener.bind(this));
22864
22923
  this.chatClient.off('chatMessageReceived', this.messageReceivedListener.bind(this));
22924
+ this.chatClient.off('chatMessageEdited', this.messageEditedListener.bind(this));
22925
+ this.chatClient.off('chatMessageDeleted', this.messageDeletedListener.bind(this));
22865
22926
  this.chatClient.off('readReceiptReceived', this.messageReadListener.bind(this));
22866
22927
  this.chatClient.off('participantsRemoved', this.participantsRemovedListener.bind(this));
22867
22928
  }
@@ -22891,14 +22952,22 @@ const convertEventToChatMessage = (event) => {
22891
22952
  return {
22892
22953
  id: event.id,
22893
22954
  version: event.version,
22894
- content: { message: event.message },
22955
+ content: isChatMessageDeletedEvent(event) ? undefined : { message: event.message },
22895
22956
  type: convertEventType(event.type),
22896
22957
  sender: event.sender,
22897
22958
  senderDisplayName: event.senderDisplayName,
22898
22959
  sequenceId: '',
22899
- createdOn: new Date(event.createdOn)
22960
+ createdOn: new Date(event.createdOn),
22961
+ editedOn: isChatMessageEditedEvent(event) ? event.editedOn : undefined,
22962
+ deletedOn: isChatMessageDeletedEvent(event) ? event.deletedOn : undefined
22900
22963
  };
22901
22964
  };
22965
+ const isChatMessageEditedEvent = (event) => {
22966
+ return event['editedOn'] !== undefined;
22967
+ };
22968
+ const isChatMessageDeletedEvent = (event) => {
22969
+ return event['deletedOn'] !== undefined;
22970
+ };
22902
22971
  // only text/html message type will be received from event
22903
22972
  const convertEventType = (type) => {
22904
22973
  const lowerCaseType = type.toLowerCase();
@@ -29367,9 +29436,9 @@ const configurationSectionStyle = {
29367
29436
  /**
29368
29437
  * @private
29369
29438
  */
29370
- const selectionContainerStyle = (theme) => react.mergeStyles({
29439
+ const selectionContainerStyle = (theme, noSpeakerDropdownShown) => react.mergeStyles({
29371
29440
  width: '100%',
29372
- height: `${CONFIGURATION_PAGE_SECTION_HEIGHT_REM}rem`,
29441
+ height: noSpeakerDropdownShown ? 'auto' : `${CONFIGURATION_PAGE_SECTION_HEIGHT_REM}rem`,
29373
29442
  padding: '1rem',
29374
29443
  borderRadius: theme.effects.roundedCorner6,
29375
29444
  border: `0.0625rem solid ${theme.palette.neutralLight}`,
@@ -29628,7 +29697,7 @@ const localVideoViewOptions = {
29628
29697
  * @private
29629
29698
  */
29630
29699
  const LocalDeviceSettings = (props) => {
29631
- var _a, _b;
29700
+ var _a, _b, _c;
29632
29701
  const theme = useTheme();
29633
29702
  const locale = useLocale();
29634
29703
  /* @conditional-compile-remove(call-readiness) */ /* @conditional-compile-remove(video-background-effects) */ /* @conditional-compile-remove(rooms) */
@@ -29669,13 +29738,15 @@ const LocalDeviceSettings = (props) => {
29669
29738
  const hasCameras = props.cameras.length > 0;
29670
29739
  const hasMicrophones = props.microphones.length > 0;
29671
29740
  const hasSpeakers = props.speakers.length > 0;
29741
+ /* @conditional-compile-remove(unsupported-browser) */
29742
+ const isSafariWithNoSpeakers = ((_b = adapter.getState().environmentInfo) === null || _b === void 0 ? void 0 : _b.environment.browser.toLowerCase()) === 'safari' && !hasSpeakers;
29672
29743
  const cameraGrantedDropdown = (React.createElement(react.Dropdown, { "data-ui-id": "call-composite-local-camera-settings", "aria-labelledby": 'call-composite-local-camera-settings-label', placeholder: hasCameras ? defaultPlaceHolder : noCameraLabel, options: cameraPermissionGranted ? getDropDownList(props.cameras) : [{ key: 'deniedOrUnknown', text: '' }], styles: dropDownStyles(theme), disabled: !cameraPermissionGranted || !hasCameras, errorMessage: props.cameraPermissionGranted === undefined || props.cameraPermissionGranted
29673
29744
  ? undefined
29674
29745
  : locale.strings.call.cameraPermissionDenied, defaultSelectedKey: micPermissionGranted
29675
29746
  ? props.selectedCamera
29676
29747
  ? props.selectedCamera.id
29677
29748
  : props.cameras
29678
- ? (_b = props.cameras[0]) === null || _b === void 0 ? void 0 : _b.id
29749
+ ? (_c = props.cameras[0]) === null || _c === void 0 ? void 0 : _c.id
29679
29750
  : ''
29680
29751
  : 'deniedOrUnknown', onChange: (event, option, index) => {
29681
29752
  props.onSelectCamera(props.cameras[index !== null && index !== void 0 ? index : 0], localVideoViewOptions);
@@ -29689,6 +29760,16 @@ const LocalDeviceSettings = (props) => {
29689
29760
  : 'deniedOrUnknown', onChange: (event, option, index) => {
29690
29761
  props.onSelectMicrophone(props.microphones[index !== null && index !== void 0 ? index : 0]);
29691
29762
  }, onRenderTitle: (props) => onRenderTitle('Microphone', props) }))));
29763
+ const speakerDropdown = (React.createElement(react.Dropdown, { "aria-labelledby": 'call-composite-local-sound-settings-label', placeholder: hasSpeakers ? defaultPlaceHolder : noSpeakersLabel, styles: dropDownStyles(theme), disabled: props.speakers.length === 0, options: getDropDownList(props.speakers), defaultSelectedKey: props.selectedSpeaker ? props.selectedSpeaker.id : defaultDeviceId(props.speakers), onChange: (event, option, index) => {
29764
+ props.onSelectSpeaker(props.speakers[index !== null && index !== void 0 ? index : 0]);
29765
+ }, onRenderTitle: (props) => onRenderTitle('Speaker', props) }));
29766
+ const SafariBrowserSpeakerDropdownTrampoline = () => {
29767
+ /* @conditional-compile-remove(unsupported-browser) */
29768
+ if (isSafariWithNoSpeakers) {
29769
+ return React.createElement(React.Fragment, null);
29770
+ }
29771
+ return speakerDropdown;
29772
+ };
29692
29773
  return (React.createElement(react.Stack, { "data-ui-id": "call-composite-device-settings", tokens: mainStackTokens },
29693
29774
  roleCanUseCamera && (React.createElement(react.Stack, null,
29694
29775
  React.createElement(react.Stack, { horizontal: true, horizontalAlign: "space-between", styles: cameraAndVideoEffectsContainerStyleDesktop },
@@ -29708,9 +29789,7 @@ const LocalDeviceSettings = (props) => {
29708
29789
  dropdownProps: dropdownProps,
29709
29790
  /* @conditional-compile-remove(call-readiness) */
29710
29791
  onClickEnableDevicePermission: props.onClickEnableDevicePermission }),
29711
- React.createElement(react.Dropdown, { "aria-labelledby": 'call-composite-local-sound-settings-label', placeholder: hasSpeakers ? defaultPlaceHolder : noSpeakersLabel, styles: dropDownStyles(theme), disabled: props.speakers.length === 0, options: getDropDownList(props.speakers), defaultSelectedKey: props.selectedSpeaker ? props.selectedSpeaker.id : defaultDeviceId(props.speakers), onChange: (event, option, index) => {
29712
- props.onSelectSpeaker(props.speakers[index !== null && index !== void 0 ? index : 0]);
29713
- }, onRenderTitle: (props) => onRenderTitle('Speaker', props) })))));
29792
+ React.createElement(SafariBrowserSpeakerDropdownTrampoline, null)))));
29714
29793
  };
29715
29794
  const defaultDeviceId = (devices) => {
29716
29795
  if (devices.length === 0) {
@@ -30403,7 +30482,10 @@ const ConfigurationPage = (props) => {
30403
30482
  localPreviewTrampoline(mobileWithPreview,
30404
30483
  /* @conditional-compile-remove(rooms) */ !!(role === 'Consumer')),
30405
30484
  React.createElement(react.Stack, { styles: mobileView ? undefined : configurationSectionStyle },
30406
- !mobileWithPreview && (React.createElement(react.Stack, { className: mobileView ? undefined : selectionContainerStyle(theme) },
30485
+ !mobileWithPreview && (React.createElement(react.Stack, { className: mobileView
30486
+ ? undefined
30487
+ : selectionContainerStyle(theme, isSafariBrowserEnvironmentTrampoline(
30488
+ /* @conditional-compile-remove(unsupported-browser) */ environmentInfo)) },
30407
30489
  React.createElement(LocalDeviceSettings, Object.assign({}, options, localDeviceSettingsHandlers, { cameraPermissionGranted: cameraPermissionGrantedTrampoline(cameraPermissionGranted,
30408
30490
  /* @conditional-compile-remove(call-readiness) */ videoState), microphonePermissionGranted: micPermissionGrantedTrampoline(microphonePermissionGranted,
30409
30491
  /* @conditional-compile-remove(call-readiness) */ audioState),
@@ -30445,6 +30527,10 @@ const Logo = (props) => {
30445
30527
  }
30446
30528
  return React.createElement(react.Image, { styles: logoStyles(props.logo.shape), src: props.logo.url, alt: props.logo.alt });
30447
30529
  };
30530
+ const isSafariBrowserEnvironmentTrampoline = (environmentInfo) => {
30531
+ /* @conditional-compile-remove(unsupported-browser) */
30532
+ return environmentInfo && (environmentInfo === null || environmentInfo === void 0 ? void 0 : environmentInfo.environment.browser.toLowerCase()) === 'safari';
30533
+ };
30448
30534
 
30449
30535
  // Copyright (c) Microsoft Corporation.
30450
30536
  // Licensed under the MIT License.
@@ -32809,6 +32895,9 @@ class AzureCommunicationCallAdapter {
32809
32895
  const createAzureCommunicationCallAdapter = ({ userId, displayName, credential, locator,
32810
32896
  /* @conditional-compile-remove(PSTN-calls) */ alternateCallerId,
32811
32897
  /* @conditional-compile-remove(video-background-effects) */ options }) => __awaiter$5(void 0, void 0, void 0, function* () {
32898
+ if (communicationCommon.isMicrosoftTeamsUserIdentifier(userId)) {
32899
+ throw new Error('Microsoft Teams user identifier is not supported by AzureCommunicationCallAdapter. Instead use TeamsCallAdapter.');
32900
+ }
32812
32901
  return _createAzureCommunicationCallAdapterInner({
32813
32902
  userId,
32814
32903
  displayName,
@@ -32848,6 +32937,9 @@ const _createAzureCommunicationCallAdapterInner = ({ userId, displayName, creden
32848
32937
  * @beta
32849
32938
  */
32850
32939
  const createTeamsCallAdapter = ({ userId, credential, locator, options }) => __awaiter$5(void 0, void 0, void 0, function* () {
32940
+ if (communicationCommon.isCommunicationUserIdentifier(userId)) {
32941
+ throw new Error('Communication User identifier is not supported by TeamsCallAdapter, please use our AzureCommunicationCallAdapter.');
32942
+ }
32851
32943
  const callClient = _createStatefulCallClientInner({
32852
32944
  userId
32853
32945
  }, undefined, 'Call');
@@ -33570,23 +33662,42 @@ const chatNotificationContainerStyles = {
33570
33662
  * @private
33571
33663
  */
33572
33664
  const useUnreadMessagesTracker = (chatAdapter, isChatPaneVisible) => {
33573
- const [unreadChatMessagesCount, setUnreadChatMessagesCount] = React.useState(0);
33665
+ // Store messageIds of unread messages
33666
+ const [unreadChatMessages, setUnreadChatMessages] = React.useState(new Set());
33574
33667
  React.useEffect(() => {
33668
+ // Clear unread messages when chat pane is opened
33575
33669
  if (isChatPaneVisible) {
33576
- setUnreadChatMessagesCount(0);
33670
+ setUnreadChatMessages(new Set());
33577
33671
  return;
33578
33672
  }
33673
+ // Increment unread messages when a new message is received and the chat pane is closed
33579
33674
  const incrementUnreadChatMessagesCount = (event) => {
33580
33675
  if (!isChatPaneVisible && validNewChatMessage(event.message)) {
33581
- setUnreadChatMessagesCount(unreadChatMessagesCount + 1);
33676
+ setUnreadChatMessages((prevUnreadChatMessages) => {
33677
+ const newUnreadChatMessages = new Set(prevUnreadChatMessages);
33678
+ newUnreadChatMessages.add(event.message.id);
33679
+ return newUnreadChatMessages;
33680
+ });
33681
+ }
33682
+ };
33683
+ // Decrement unread messages when a message is deleted and the chat pane is closed
33684
+ const decrementUnreadChatMessagesCount = (event) => {
33685
+ if (!isChatPaneVisible) {
33686
+ setUnreadChatMessages((prevUnreadChatMessages) => {
33687
+ const newUnreadChatMessages = new Set(prevUnreadChatMessages);
33688
+ newUnreadChatMessages.delete(event.message.id);
33689
+ return newUnreadChatMessages;
33690
+ });
33582
33691
  }
33583
33692
  };
33584
33693
  chatAdapter.on('messageReceived', incrementUnreadChatMessagesCount);
33694
+ chatAdapter.on('messageDeleted', decrementUnreadChatMessagesCount);
33585
33695
  return () => {
33586
33696
  chatAdapter.off('messageReceived', incrementUnreadChatMessagesCount);
33697
+ chatAdapter.off('messageDeleted', decrementUnreadChatMessagesCount);
33587
33698
  };
33588
- }, [chatAdapter, setUnreadChatMessagesCount, isChatPaneVisible, unreadChatMessagesCount]);
33589
- return unreadChatMessagesCount;
33699
+ }, [chatAdapter, setUnreadChatMessages, isChatPaneVisible]);
33700
+ return unreadChatMessages.size;
33590
33701
  };
33591
33702
  /**
33592
33703
  * Helper function to determine if the message in the event is a valid one from a user.
@@ -34453,6 +34564,12 @@ class AzureCommunicationCallWithChatAdapter {
34453
34564
  case 'messageReceived':
34454
34565
  this.chatAdapter.on('messageReceived', listener);
34455
34566
  break;
34567
+ case 'messageEdited':
34568
+ this.chatAdapter.on('messageEdited', listener);
34569
+ break;
34570
+ case 'messageDeleted':
34571
+ this.chatAdapter.on('messageDeleted', listener);
34572
+ break;
34456
34573
  case 'messageSent':
34457
34574
  this.chatAdapter.on('messageSent', listener);
34458
34575
  break;
@@ -34527,6 +34644,12 @@ class AzureCommunicationCallWithChatAdapter {
34527
34644
  case 'messageReceived':
34528
34645
  this.chatAdapter.off('messageReceived', listener);
34529
34646
  break;
34647
+ case 'messageEdited':
34648
+ this.chatAdapter.off('messageEdited', listener);
34649
+ break;
34650
+ case 'messageDeleted':
34651
+ this.chatAdapter.off('messageDeleted', listener);
34652
+ break;
34530
34653
  case 'messageSent':
34531
34654
  this.chatAdapter.off('messageSent', listener);
34532
34655
  break;