@azure/communication-react 1.7.0-alpha-202307130015 → 1.7.0-alpha-202307150015

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 (25) hide show
  1. package/dist/communication-react.d.ts +51 -20
  2. package/dist/dist-cjs/communication-react/index.js +80 -31
  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/chat-component-bindings/src/messageThreadSelector.js +26 -11
  7. package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js.map +1 -1
  8. package/dist/dist-esm/communication-react/src/index.d.ts +1 -1
  9. package/dist/dist-esm/communication-react/src/index.js.map +1 -1
  10. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +8 -2
  11. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
  12. package/dist/dist-esm/react-components/src/components/FileDownloadCards.d.ts +33 -5
  13. package/dist/dist-esm/react-components/src/components/FileDownloadCards.js +18 -5
  14. package/dist/dist-esm/react-components/src/components/FileDownloadCards.js.map +1 -1
  15. package/dist/dist-esm/react-components/src/components/MessageThread.js +1 -3
  16. package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
  17. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +23 -5
  18. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
  19. package/dist/dist-esm/react-components/src/components/styles/MentionPopover.style.js +2 -1
  20. package/dist/dist-esm/react-components/src/components/styles/MentionPopover.style.js.map +1 -1
  21. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +1 -1
  22. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
  23. package/dist/dist-esm/react-composites/src/composites/common/TabHeader.js +2 -2
  24. package/dist/dist-esm/react-composites/src/composites/common/TabHeader.js.map +1 -1
  25. package/package.json +8 -8
@@ -428,6 +428,36 @@ export declare interface BaseCustomStyles {
428
428
  root?: IStyle;
429
429
  }
430
430
 
431
+ /**
432
+ * Base interface that all Meta Data should extend.
433
+ * Typically used for ACS to ACS file transfers.
434
+ * @beta
435
+ */
436
+ export declare interface BaseFileMetadata {
437
+ /**
438
+ * File name to be displayed.
439
+ */
440
+ name: string;
441
+ /**
442
+ * Extension is used for rendering the file icon.
443
+ * An unknown extension will be rendered as a generic icon.
444
+ * Example: `jpeg`
445
+ */
446
+ extension: string;
447
+ /**
448
+ * Download URL for the file.
449
+ */
450
+ url: string;
451
+ /**
452
+ * Unique ID of the file.
453
+ */
454
+ id: string;
455
+ /**
456
+ * Attachment Type
457
+ */
458
+ attachmentType: FileMetadataAttachmentType;
459
+ }
460
+
431
461
  /**
432
462
  * Content blocked message type.
433
463
  *
@@ -6097,30 +6127,22 @@ export declare type FileDownloadHandler = (userId: string, fileMetadata: FileMet
6097
6127
  * Meta Data containing information about the uploaded file.
6098
6128
  * @beta
6099
6129
  */
6100
- export declare interface FileMetadata {
6101
- attachmentType: FileMetadataAttachmentType;
6102
- id: string;
6103
- /**
6104
- * File name to be displayed.
6105
- */
6106
- name: string;
6107
- /**
6108
- * Extension is used for rendering the file icon.
6109
- * An unknown extension will be rendered as a generic icon.
6110
- * Example: `jpeg`
6111
- */
6112
- extension: string;
6113
- /**
6114
- * Download URL for the file.
6115
- */
6116
- url: string;
6117
- previewUrl?: string;
6118
- }
6130
+ export declare type FileMetadata = FileSharingMetadata | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ ImageFileMetadata;
6119
6131
 
6120
6132
  /**
6121
6133
  * @beta
6122
6134
  */
6123
- export declare type FileMetadataAttachmentType = 'fileSharing' | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'teamsInlineImage' | 'unknown';
6135
+ export declare type FileMetadataAttachmentType = 'fileSharing' | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'inlineImage' | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'attachedImage' | 'unknown';
6136
+
6137
+ /**
6138
+ * Meta Data containing basic information about the uploaded file.
6139
+ * Typically used for ACS to ACS file transfers.
6140
+ * @beta
6141
+ */
6142
+ export declare interface FileSharingMetadata extends BaseFileMetadata {
6143
+ attachmentType: 'fileSharing';
6144
+ payload?: Record<string, string> | undefined;
6145
+ }
6124
6146
 
6125
6147
  /**
6126
6148
  * Properties for configuring the File Sharing feature.
@@ -6501,6 +6523,15 @@ export declare interface _Identifiers {
6501
6523
  mentionSuggestionItem: string;
6502
6524
  }
6503
6525
 
6526
+ /**
6527
+ * Meta Data containing data for images.
6528
+ * @beta
6529
+ */
6530
+ export declare interface ImageFileMetadata extends BaseFileMetadata {
6531
+ attachmentType: 'inlineImage' | 'attachedImage';
6532
+ previewUrl?: string;
6533
+ }
6534
+
6504
6535
  /**
6505
6536
  * @beta
6506
6537
  * This contains a readonly array that returns all the active `incomingCalls`.
@@ -178,7 +178,7 @@ const _isValidIdentifier = (identifier) => {
178
178
  // Copyright (c) Microsoft Corporation.
179
179
  // Licensed under the MIT license.
180
180
  // GENERATED FILE. DO NOT EDIT MANUALLY.
181
- var telemetryVersion = '1.7.0-alpha-202307130015';
181
+ var telemetryVersion = '1.7.0-alpha-202307150015';
182
182
 
183
183
  // Copyright (c) Microsoft Corporation.
184
184
  /**
@@ -6992,7 +6992,8 @@ react.mergeStyles({
6992
6992
  */
6993
6993
  const suggestionListStyle = react.mergeStyles({
6994
6994
  padding: '0.25rem 0rem 0',
6995
- overflow: 'visible'
6995
+ overflow: 'visible',
6996
+ overflowY: 'scroll'
6996
6997
  });
6997
6998
  /**
6998
6999
  * @private
@@ -7397,7 +7398,14 @@ const TextFieldWithMention = (props) => {
7397
7398
  }, [setSelectionStartValue, setSelectionEndValue]);
7398
7399
  const handleOnSelect = React.useCallback(({ event, inputTextValue, tags, shouldHandleOnMouseDownDuringSelect, selectionStartValue, selectionEndValue, interactionStartSelection }) => {
7399
7400
  var _a;
7400
- if (shouldHandleOnMouseDownDuringSelect) {
7401
+ if (event.currentTarget.selectionStart === 0 && event.currentTarget.selectionEnd === inputTextValue.length) {
7402
+ // entire text is selected, no need to change anything
7403
+ setSelectionStartValue(event.currentTarget.selectionStart);
7404
+ setSelectionEndValue(event.currentTarget.selectionEnd);
7405
+ setInteractionStartSelection(undefined);
7406
+ setShouldHandleOnMouseDownDuringSelect(false);
7407
+ }
7408
+ else if (shouldHandleOnMouseDownDuringSelect) {
7401
7409
  if (interactionStartSelection !== undefined &&
7402
7410
  (interactionStartSelection.start !== event.currentTarget.selectionStart ||
7403
7411
  interactionStartSelection.end !== event.currentTarget.selectionEnd)) {
@@ -7424,15 +7432,27 @@ const TextFieldWithMention = (props) => {
7424
7432
  setInteractionStartSelection(undefined);
7425
7433
  setShouldHandleOnMouseDownDuringSelect(false);
7426
7434
  }
7427
- else if (event.currentTarget.selectionStart !== null) {
7435
+ else if (event.currentTarget.selectionStart !== null && event.currentTarget.selectionEnd !== null) {
7428
7436
  // on select was triggered by mouse down/up with no movement
7429
7437
  const mentionTag = findMentionTagForSelection(tags, event.currentTarget.selectionStart);
7430
7438
  if (mentionTag !== undefined && mentionTag.plainTextBeginIndex !== undefined) {
7431
7439
  // handle mention click by selecting the whole mention
7432
7440
  // if the selection is not on the bounds of the mention
7433
- const mentionEndIndex = (_a = mentionTag.plainTextEndIndex) !== null && _a !== void 0 ? _a : mentionTag.plainTextBeginIndex;
7434
7441
  // disable selection for clicks on mention bounds
7435
- if (event.currentTarget.selectionStart !== event.currentTarget.selectionEnd ||
7442
+ const mentionEndIndex = (_a = mentionTag.plainTextEndIndex) !== null && _a !== void 0 ? _a : mentionTag.plainTextBeginIndex;
7443
+ if (event.currentTarget.selectionStart !== event.currentTarget.selectionEnd &&
7444
+ event.currentTarget.selectionEnd > mentionEndIndex) {
7445
+ // handle triple click when the text starts from mention
7446
+ if (event.currentTarget.selectionDirection === null) {
7447
+ event.currentTarget.setSelectionRange(mentionTag.plainTextBeginIndex, event.currentTarget.selectionEnd);
7448
+ }
7449
+ else {
7450
+ event.currentTarget.setSelectionRange(mentionTag.plainTextBeginIndex, event.currentTarget.selectionEnd, event.currentTarget.selectionDirection);
7451
+ }
7452
+ setSelectionStartValue(mentionTag.plainTextBeginIndex);
7453
+ setSelectionEndValue(event.currentTarget.selectionEnd);
7454
+ }
7455
+ else if (event.currentTarget.selectionStart !== event.currentTarget.selectionEnd ||
7436
7456
  (event.currentTarget.selectionStart !== mentionTag.plainTextBeginIndex &&
7437
7457
  event.currentTarget.selectionStart !== mentionEndIndex)) {
7438
7458
  if (event.currentTarget.selectionDirection === null) {
@@ -7456,7 +7476,6 @@ const TextFieldWithMention = (props) => {
7456
7476
  setSelectionEndValue(nullToUndefined(event.currentTarget.selectionEnd));
7457
7477
  }
7458
7478
  setInteractionStartSelection(undefined);
7459
- setShouldHandleOnMouseDownDuringSelect(false);
7460
7479
  }
7461
7480
  }
7462
7481
  else {
@@ -9066,7 +9085,10 @@ const MessageContentAsRichTextHTML = (props) => {
9066
9085
  React.useEffect(() => {
9067
9086
  var _a;
9068
9087
  (_a = props.message.attachedFilesMetadata) === null || _a === void 0 ? void 0 : _a.map((fileMetadata) => {
9069
- if (props.onFetchAttachment && props.attachmentsMap && props.attachmentsMap[fileMetadata.id] === undefined) {
9088
+ if (props.onFetchAttachment &&
9089
+ props.attachmentsMap &&
9090
+ fileMetadata.attachmentType === 'inlineImage' &&
9091
+ props.attachmentsMap[fileMetadata.id] === undefined) {
9070
9092
  props.onFetchAttachment(fileMetadata);
9071
9093
  }
9072
9094
  });
@@ -9127,12 +9149,15 @@ const processInlineImage = (props) => ({
9127
9149
  // Custom <img> processing
9128
9150
  shouldProcessNode: (node) => {
9129
9151
  var _a;
9152
+ function isImageNode(file) {
9153
+ return file.attachmentType === 'inlineImage' && file.id === node.attribs.id;
9154
+ }
9130
9155
  // Process img node with id in attachments list
9131
9156
  return (node.name &&
9132
9157
  node.name === 'img' &&
9133
9158
  node.attribs &&
9134
9159
  node.attribs.id &&
9135
- ((_a = props.message.attachedFilesMetadata) === null || _a === void 0 ? void 0 : _a.find((f) => f.id === node.attribs.id)));
9160
+ ((_a = props.message.attachedFilesMetadata) === null || _a === void 0 ? void 0 : _a.find(isImageNode)));
9136
9161
  },
9137
9162
  processNode: (node, children, index) => {
9138
9163
  // logic to check id in map/list
@@ -9238,14 +9263,24 @@ const _FileDownloadCards = (props) => {
9238
9263
  var _a, _b;
9239
9264
  return (_b = (_a = props.strings) === null || _a === void 0 ? void 0 : _a.downloadFile) !== null && _b !== void 0 ? _b : localeStrings.downloadFile;
9240
9265
  }, [(_a = props.strings) === null || _a === void 0 ? void 0 : _a.downloadFile, localeStrings.downloadFile]);
9266
+ const isFileSharingAttachment = React.useCallback((attachment) => {
9267
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9268
+ return attachment.attachmentType === 'fileSharing';
9269
+ }, []);
9270
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9271
+ const isShowDownloadIcon = React.useCallback((attachment) => {
9272
+ var _a;
9273
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9274
+ return attachment.attachmentType === 'fileSharing' && ((_a = attachment.payload) === null || _a === void 0 ? void 0 : _a.teamsFileAttachment) !== 'true';
9275
+ }, []);
9241
9276
  const fileCardGroupDescription = React.useMemo(() => () => {
9242
9277
  var _a, _b;
9243
9278
  const fileGroupLocaleString = (_b = (_a = props.strings) === null || _a === void 0 ? void 0 : _a.fileCardGroupMessage) !== null && _b !== void 0 ? _b : localeStrings.fileCardGroupMessage;
9244
9279
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9245
9280
  return _formatString(fileGroupLocaleString, {
9246
- fileCount: `${fileMetadata.filter((file) => file.attachmentType === 'fileSharing').length}`
9281
+ fileCount: `${fileMetadata.filter(isFileSharingAttachment).length}`
9247
9282
  });
9248
- }, [(_b = props.strings) === null || _b === void 0 ? void 0 : _b.fileCardGroupMessage, localeStrings.fileCardGroupMessage, fileMetadata]);
9283
+ }, [(_b = props.strings) === null || _b === void 0 ? void 0 : _b.fileCardGroupMessage, localeStrings.fileCardGroupMessage, fileMetadata, isFileSharingAttachment]);
9249
9284
  const fileDownloadHandler = React.useCallback((userId, file) => __awaiter$v(void 0, void 0, void 0, function* () {
9250
9285
  if (!props.downloadHandler) {
9251
9286
  window.open(file.url, '_blank', 'noopener,noreferrer');
@@ -9269,7 +9304,7 @@ const _FileDownloadCards = (props) => {
9269
9304
  }), [props]);
9270
9305
  if (!fileMetadata ||
9271
9306
  fileMetadata.length === 0 ||
9272
- /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ !fileMetadata.some((attachment) => attachment.attachmentType === 'fileSharing')) {
9307
+ /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ !fileMetadata.some(isFileSharingAttachment)) {
9273
9308
  return React__default['default'].createElement(React__default['default'].Fragment, null);
9274
9309
  }
9275
9310
  return (React__default['default'].createElement("div", { style: fileDownloadCardsStyle, "data-ui-id": "file-download-card-group" },
@@ -9277,9 +9312,10 @@ const _FileDownloadCards = (props) => {
9277
9312
  fileMetadata
9278
9313
  .filter((attachment) => {
9279
9314
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9280
- return attachment.attachmentType === 'fileSharing';
9315
+ return isFileSharingAttachment(attachment);
9281
9316
  })
9282
- .map((file) => (React__default['default'].createElement(_FileCard, { fileName: file.name, key: file.name, fileExtension: file.extension, actionIcon: showSpinner ? (React__default['default'].createElement(react.Spinner, { size: react.SpinnerSize.medium, "aria-live": 'polite', role: 'status' })) : /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ !file.previewUrl ? (React__default['default'].createElement(react.IconButton, { className: iconButtonClassName, ariaLabel: downloadFileButtonString() },
9317
+ .map((file) => (React__default['default'].createElement(_FileCard, { fileName: file.name, key: file.name, fileExtension: file.extension, actionIcon: showSpinner ? (React__default['default'].createElement(react.Spinner, { size: react.SpinnerSize.medium, "aria-live": 'polite', role: 'status' })) : /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9318
+ isShowDownloadIcon(file) ? (React__default['default'].createElement(react.IconButton, { className: iconButtonClassName, ariaLabel: downloadFileButtonString() },
9283
9319
  React__default['default'].createElement(DownloadIconTrampoline, null))) : undefined, actionHandler: () => fileDownloadHandler(userId, file) }))))));
9284
9320
  };
9285
9321
  /**
@@ -9860,9 +9896,7 @@ const MessageThread = (props) => {
9860
9896
  const [inlineAttachments, setInlineAttachments] = React.useState({});
9861
9897
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
9862
9898
  const onFetchInlineAttachment = React.useCallback((attachment) => __awaiter$t(void 0, void 0, void 0, function* () {
9863
- if (!onFetchAttachments ||
9864
- attachment.id in inlineAttachments ||
9865
- attachment.attachmentType !== 'teamsInlineImage') {
9899
+ if (!onFetchAttachments || attachment.attachmentType !== 'inlineImage' || attachment.id in inlineAttachments) {
9866
9900
  return;
9867
9901
  }
9868
9902
  setInlineAttachments((prev) => (Object.assign(Object.assign({}, prev), { [attachment.id]: '' })));
@@ -17390,22 +17424,37 @@ const extractAttachedFilesMetadata = (metadata) => {
17390
17424
  };
17391
17425
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
17392
17426
  const extractTeamsAttachmentsMetadata = (attachments) => {
17393
- return attachments.map((attachment) => {
17394
- var _a, _b;
17395
- return ({
17396
- attachmentType: mapAttachmentType(attachment.attachmentType),
17397
- id: attachment.id,
17398
- name: (_a = attachment.name) !== null && _a !== void 0 ? _a : '',
17399
- extension: (_b = attachment.contentType) !== null && _b !== void 0 ? _b : '',
17400
- url: extractAttachmentUrl(attachment),
17401
- previewUrl: attachment.previewUrl
17402
- });
17427
+ const fileMetadata = [];
17428
+ attachments.forEach((attachment) => {
17429
+ var _a, _b, _c, _d;
17430
+ const attachmentType = mapAttachmentType(attachment.attachmentType);
17431
+ if (attachmentType === 'inlineImage') {
17432
+ fileMetadata.push({
17433
+ attachmentType: attachmentType,
17434
+ id: attachment.id,
17435
+ name: (_a = attachment.name) !== null && _a !== void 0 ? _a : '',
17436
+ extension: (_b = attachment.contentType) !== null && _b !== void 0 ? _b : '',
17437
+ url: extractAttachmentUrl(attachment),
17438
+ previewUrl: attachment.previewUrl
17439
+ });
17440
+ }
17441
+ else if (attachmentType === 'fileSharing') {
17442
+ fileMetadata.push({
17443
+ attachmentType: attachmentType,
17444
+ id: attachment.id,
17445
+ name: (_c = attachment.name) !== null && _c !== void 0 ? _c : '',
17446
+ extension: (_d = attachment.contentType) !== null && _d !== void 0 ? _d : '',
17447
+ url: extractAttachmentUrl(attachment),
17448
+ payload: { teamsFileAttachment: 'true' }
17449
+ });
17450
+ }
17403
17451
  });
17452
+ return fileMetadata;
17404
17453
  };
17405
17454
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
17406
17455
  const mapAttachmentType = (attachmentType) => {
17407
17456
  if (attachmentType === 'teamsImage' || attachmentType === 'teamsInlineImage') {
17408
- return 'teamsInlineImage';
17457
+ return 'inlineImage';
17409
17458
  }
17410
17459
  else if (attachmentType === 'file') {
17411
17460
  return 'fileSharing';
@@ -20643,7 +20692,7 @@ const ChatScreen = (props) => {
20643
20692
  } })), [fileSharing === null || fileSharing === void 0 ? void 0 : fileSharing.downloadHandler]);
20644
20693
  /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
20645
20694
  const onRenderInlineAttachment = React.useCallback((attachment) => __awaiter$g(void 0, void 0, void 0, function* () {
20646
- if (attachment.previewUrl) {
20695
+ if (attachment.attachmentType === 'inlineImage' && attachment.previewUrl) {
20647
20696
  const blob = yield adapter.downloadAttachments({ attachmentUrls: [attachment.previewUrl] });
20648
20697
  return blob;
20649
20698
  }
@@ -23332,8 +23381,8 @@ const PeopleAndChatHeader = (props) => {
23332
23381
  }, [theme, haveMultipleTabs]);
23333
23382
  return (React__default['default'].createElement(react.Stack, { horizontal: true, grow: true, styles: mobilePaneControlBarStyle },
23334
23383
  React__default['default'].createElement(react.DefaultButton, { ariaLabel: strings.returnToCallButtonAriaLabel, ariaDescription: strings.returnToCallButtonAriaDescription, onClick: onClose, styles: mobilePaneBackButtonStyles, onRenderIcon: () => React__default['default'].createElement(CallWithChatCompositeIcon, { iconName: "ChevronLeft" }), autoFocus: true }),
23335
- React__default['default'].createElement(react.Stack.Item, { grow: true }, onChatButtonClicked && (React__default['default'].createElement(react.DefaultButton, { onClick: onChatButtonClicked, styles: mobilePaneButtonStylesThemed, checked: activeTab === 'chat', role: 'tab', disabled: props.disableChatButton }, strings.chatButtonLabel))),
23336
- React__default['default'].createElement(react.Stack.Item, { grow: true }, onPeopleButtonClicked && (React__default['default'].createElement(react.DefaultButton, { onClick: onPeopleButtonClicked, styles: mobilePaneButtonStylesThemed, checked: activeTab === 'people', role: 'tab', disabled: props.disablePeopleButton }, strings.peopleButtonLabel))),
23384
+ React__default['default'].createElement(react.Stack.Item, { grow: true }, onChatButtonClicked && (React__default['default'].createElement(react.DefaultButton, { onClick: onChatButtonClicked, styles: mobilePaneButtonStylesThemed, checked: activeTab === 'chat', "aria-selected": activeTab === 'chat', role: 'tab', disabled: props.disableChatButton }, strings.chatButtonLabel))),
23385
+ React__default['default'].createElement(react.Stack.Item, { grow: true }, onPeopleButtonClicked && (React__default['default'].createElement(react.DefaultButton, { onClick: onPeopleButtonClicked, styles: mobilePaneButtonStylesThemed, checked: activeTab === 'people', "aria-selected": activeTab === 'people', role: 'tab', disabled: props.disablePeopleButton }, strings.peopleButtonLabel))),
23337
23386
  React__default['default'].createElement(react.DefaultButton, { styles: mobilePaneHiddenIconStyles, onRenderIcon: () => React__default['default'].createElement(CallWithChatCompositeIcon, { iconName: "ChevronLeft" }) })));
23338
23387
  };
23339
23388
  // eslint-disable-next-line @typescript-eslint/no-explicit-any