@azure/communication-react 1.7.0-alpha-202307060015 → 1.7.0-alpha-202307070015

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.
@@ -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-202307060015';
181
+ var telemetryVersion = '1.7.0-alpha-202307070015';
182
182
 
183
183
  // Copyright (c) Microsoft Corporation.
184
184
  /**
@@ -6265,7 +6265,7 @@ const handleMentionTagUpdate = (props) => {
6265
6265
  if (rangeStart === tag.plainTextBeginIndex && rangeEnd === plainTextEndIndex) {
6266
6266
  // the whole tag should be removed
6267
6267
  result += htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex) + processedChange;
6268
- plainTextSelectionEndIndex = tag.plainTextBeginIndex + processedChange.length;
6268
+ plainTextSelectionEndIndex = tag.plainTextBeginIndex + change.length;
6269
6269
  processedChange = '';
6270
6270
  lastProcessedHTMLIndex = closeTagIdx + closeTagLength;
6271
6271
  }
@@ -6285,7 +6285,7 @@ const handleMentionTagUpdate = (props) => {
6285
6285
  }
6286
6286
  else {
6287
6287
  // if the change is inside the tag, the selection should start with rangeStart
6288
- plainTextSelectionEndIndex = rangeStart + processedChange.length;
6288
+ plainTextSelectionEndIndex = rangeStart + change.length;
6289
6289
  }
6290
6290
  lastProcessedHTMLIndex = tag.openTagIndex + tag.openTagBody.length + endChangeDiff;
6291
6291
  // processed change should not be changed as it should be added after the tag
@@ -6398,27 +6398,53 @@ const updateHTML = (props) => {
6398
6398
  // the change is between the tag
6399
6399
  if (isMentionTag) {
6400
6400
  if (change !== '') {
6401
- if (startIndex !== tag.plainTextBeginIndex && startIndex !== closingTagInfo.plainTextEndIndex) {
6402
- // mention tag should be deleted when user tries to edit it in the middle
6403
- result += htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex) + processedChange;
6404
- changeNewEndIndex = tag.plainTextBeginIndex + unEscapeHtmlCharacters(processedChange).length;
6405
- lastProcessedHTMLIndex = closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength;
6406
- }
6407
- else if (startIndex === tag.plainTextBeginIndex) {
6408
- // non empty change at the beginning of the mention tag to be added before the mention tag
6409
- result += htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex) + processedChange;
6410
- changeNewEndIndex = tag.plainTextBeginIndex + unEscapeHtmlCharacters(processedChange).length;
6411
- lastProcessedHTMLIndex = tag.openTagIndex;
6412
- }
6413
- else if (startIndex === closingTagInfo.plainTextEndIndex) {
6401
+ // case for startIndex === tag.plainTextBeginIndex and closingTagInfo.plainTextEndIndex === startIndex
6402
+ // is handled in startIndex <= tag.plainTextBeginIndex condition check
6403
+ // the change will be added at the beginning before the mention tag
6404
+ if (startIndex === closingTagInfo.plainTextEndIndex) {
6414
6405
  // non empty change at the end of the mention tag to be added after the mention tag
6415
6406
  result +=
6416
6407
  htmlText.substring(lastProcessedHTMLIndex, closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength) +
6417
6408
  processedChange;
6418
6409
  changeNewEndIndex = closingTagInfo.plainTextEndIndex + unEscapeHtmlCharacters(processedChange).length;
6419
6410
  lastProcessedHTMLIndex = closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength;
6411
+ processedChange = '';
6412
+ // the change is handled; exit
6413
+ break;
6414
+ }
6415
+ else if (startIndex > tag.plainTextBeginIndex &&
6416
+ oldPlainTextEndIndex < closingTagInfo.plainTextEndIndex &&
6417
+ startIndex === oldPlainTextEndIndex) {
6418
+ // mention tag should be deleted when user tries to edit it in the middle
6419
+ result += htmlText.substring(lastProcessedHTMLIndex, tag.openTagIndex) + processedChange;
6420
+ changeNewEndIndex = tag.plainTextBeginIndex + unEscapeHtmlCharacters(processedChange).length;
6421
+ lastProcessedHTMLIndex = closingTagInfo.closeTagIdx + closingTagInfo.closeTagLength;
6422
+ processedChange = '';
6423
+ // the change is handled; exit
6424
+ break;
6425
+ }
6426
+ else {
6427
+ // the selection for more that 1 symbol when 1 of the ends is included
6428
+ const updateMentionTagResult = handleMentionTagUpdate({
6429
+ htmlText,
6430
+ oldPlainText,
6431
+ lastProcessedHTMLIndex,
6432
+ processedChange,
6433
+ change,
6434
+ tag,
6435
+ closeTagIdx: closingTagInfo.closeTagIdx,
6436
+ closeTagLength: closingTagInfo.closeTagLength,
6437
+ plainTextEndIndex: closingTagInfo.plainTextEndIndex,
6438
+ startIndex,
6439
+ oldPlainTextEndIndex,
6440
+ mentionTagLength
6441
+ });
6442
+ result += updateMentionTagResult.result;
6443
+ changeNewEndIndex = updateMentionTagResult.plainTextSelectionEndIndex;
6444
+ processedChange = updateMentionTagResult.updatedChange;
6445
+ lastProcessedHTMLIndex = updateMentionTagResult.htmlIndex;
6446
+ // proceed with the next calculations
6420
6447
  }
6421
- processedChange = '';
6422
6448
  }
6423
6449
  else {
6424
6450
  // When change is empty, it means that this change is a deletion
@@ -6440,6 +6466,8 @@ const updateHTML = (props) => {
6440
6466
  changeNewEndIndex = updateMentionTagResult.plainTextSelectionEndIndex;
6441
6467
  processedChange = updateMentionTagResult.updatedChange;
6442
6468
  lastProcessedHTMLIndex = updateMentionTagResult.htmlIndex;
6469
+ // the change is handled; exit
6470
+ break;
6443
6471
  }
6444
6472
  }
6445
6473
  else if (tag.subTags !== undefined && tag.subTags.length !== 0 && tag.content !== undefined) {
@@ -6457,6 +6485,8 @@ const updateHTML = (props) => {
6457
6485
  });
6458
6486
  result += stringBefore + updatedContent.updatedHTML;
6459
6487
  changeNewEndIndex = updatedContent.updatedSelectionIndex;
6488
+ // the change is handled; exit
6489
+ break;
6460
6490
  }
6461
6491
  else {
6462
6492
  // no subtags
@@ -6472,9 +6502,9 @@ const updateHTML = (props) => {
6472
6502
  else if (oldPlainTextEndIndex === closingTagInfo.plainTextEndIndex) {
6473
6503
  lastProcessedHTMLIndex = closingTagInfo.closeTagIdx;
6474
6504
  }
6505
+ // the change is handled; exit
6506
+ break;
6475
6507
  }
6476
- // the change is handled; exit
6477
- break;
6478
6508
  }
6479
6509
  else if (startIndex > tag.plainTextBeginIndex && oldPlainTextEndIndex > closingTagInfo.plainTextEndIndex) {
6480
6510
  // the change started in the tag but finishes somewhere further
@@ -7121,6 +7151,8 @@ const TextFieldWithMention = (props) => {
7121
7151
  // Index of the current trigger character in the text field
7122
7152
  const [currentTriggerStartIndex, setCurrentTriggerStartIndex] = React.useState(-1);
7123
7153
  const [inputTextValue, setInputTextValue] = React.useState('');
7154
+ // Internal value for text value prop
7155
+ const [internalTextValue, setInternalTextValue] = React.useState('');
7124
7156
  const [tagsValue, setTagsValue] = React.useState([]);
7125
7157
  // Index of the previous selection start in the text field
7126
7158
  const [selectionStartValue, setSelectionStartValue] = React.useState();
@@ -7143,14 +7175,19 @@ const TextFieldWithMention = (props) => {
7143
7175
  const updateMentionSuggestions = React.useCallback((suggestions) => {
7144
7176
  setMentionSuggestions(suggestions);
7145
7177
  }, [setMentionSuggestions]);
7178
+ React.useEffect(() => {
7179
+ setInternalTextValue(textValue);
7180
+ // update mention suggestions before the next render cycle
7181
+ updateMentionSuggestions([]);
7182
+ }, [textValue, updateMentionSuggestions]);
7146
7183
  // Parse the text and get the plain text version to display in the input box
7147
7184
  React.useEffect(() => {
7148
7185
  const trigger = (mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger) || DEFAULT_MENTION_TRIGGER;
7149
- const parsedHTMLData = textToTagParser(textValue, trigger);
7186
+ const parsedHTMLData = textToTagParser(internalTextValue, trigger);
7150
7187
  setInputTextValue(parsedHTMLData.plainText);
7151
7188
  setTagsValue(parsedHTMLData.tags);
7152
7189
  updateMentionSuggestions([]);
7153
- }, [textValue, mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger, updateMentionSuggestions]);
7190
+ }, [internalTextValue, mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger, updateMentionSuggestions]);
7154
7191
  React.useEffect(() => {
7155
7192
  var _a;
7156
7193
  // effect for caret index update
@@ -7166,7 +7203,7 @@ const TextFieldWithMention = (props) => {
7166
7203
  (_a = textFieldRef === null || textFieldRef === void 0 ? void 0 : textFieldRef.current) === null || _a === void 0 ? void 0 : _a.setSelectionRange(updatedCaretIndex, updatedCaretIndex);
7167
7204
  setSelectionStartValue(updatedCaretIndex);
7168
7205
  setSelectionEndValue(updatedCaretIndex);
7169
- }, [caretIndex, inputTextValue.length, textFieldRef, setSelectionStartValue, setSelectionEndValue]);
7206
+ }, [caretIndex, inputTextValue, textFieldRef, setSelectionStartValue, setSelectionEndValue]);
7170
7207
  const onSuggestionSelected = React.useCallback((suggestion) => {
7171
7208
  var _a, _b, _c;
7172
7209
  let selectionEnd = ((_a = textFieldRef === null || textFieldRef === void 0 ? void 0 : textFieldRef.current) === null || _a === void 0 ? void 0 : _a.selectionEnd) || -1;
@@ -7182,7 +7219,7 @@ const TextFieldWithMention = (props) => {
7182
7219
  const triggerText = (_b = mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger) !== null && _b !== void 0 ? _b : DEFAULT_MENTION_TRIGGER;
7183
7220
  // update html text with updated plain text
7184
7221
  const updatedContent = updateHTML({
7185
- htmlText: textValue,
7222
+ htmlText: internalTextValue,
7186
7223
  oldPlainText,
7187
7224
  tags: tagsValue,
7188
7225
  startIndex: currentTriggerStartIndex,
@@ -7190,6 +7227,7 @@ const TextFieldWithMention = (props) => {
7190
7227
  change: mention,
7191
7228
  mentionTrigger: triggerText
7192
7229
  });
7230
+ setInternalTextValue(updatedContent.updatedHTML);
7193
7231
  const displayName = getDisplayNameForMentionSuggestion(suggestion, localeStrings);
7194
7232
  const newCaretIndex = currentTriggerStartIndex + displayName.length + triggerText.length;
7195
7233
  // move the caret in the text field to the end of the mention plain text
@@ -7208,7 +7246,7 @@ const TextFieldWithMention = (props) => {
7208
7246
  currentTriggerStartIndex,
7209
7247
  mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger,
7210
7248
  onChange,
7211
- textValue,
7249
+ internalTextValue,
7212
7250
  tagsValue,
7213
7251
  updateMentionSuggestions,
7214
7252
  localeStrings
@@ -7522,6 +7560,7 @@ const TextFieldWithMention = (props) => {
7522
7560
  change,
7523
7561
  mentionTrigger: triggerText
7524
7562
  });
7563
+ setInternalTextValue(updatedContent.updatedHTML);
7525
7564
  // update caret index if needed
7526
7565
  if (updatedContent.updatedSelectionIndex !== undefined) {
7527
7566
  setCaretIndex(updatedContent.updatedSelectionIndex);
@@ -7576,7 +7615,7 @@ const TextFieldWithMention = (props) => {
7576
7615
  handleOnChange({
7577
7616
  event: e,
7578
7617
  tagsValue,
7579
- htmlTextValue: textValue,
7618
+ htmlTextValue: internalTextValue,
7580
7619
  inputTextValue,
7581
7620
  currentTriggerStartIndex,
7582
7621
  previousSelectionStart: nullToUndefined(selectionStartValue),
@@ -7594,7 +7633,9 @@ const TextFieldWithMention = (props) => {
7594
7633
  if (caretIndex !== e.currentTarget.selectionStart || caretIndex !== e.currentTarget.selectionEnd) {
7595
7634
  e.currentTarget.setSelectionRange(caretIndex, caretIndex);
7596
7635
  }
7597
- setCaretIndex(undefined);
7636
+ // caret index should not be set to undefined here
7637
+ // as it will cause issues when suggestion is selected by mouse
7638
+ // caret index will be set to undefined during keyboard/mouse or touch interactions
7598
7639
  return;
7599
7640
  }
7600
7641
  handleOnSelect({
@@ -7635,11 +7676,9 @@ const TextFieldWithMention = (props) => {
7635
7676
  });
7636
7677
  }, onTouchEnd: () => {
7637
7678
  }, onBlur: () => {
7638
- // setup all flags to default values when text field loses focus
7679
+ // setup shouldHandleOnMouseDownDuringSelect to false when text field loses focus
7680
+ // as the click should be handled by text field anymore
7639
7681
  setShouldHandleOnMouseDownDuringSelect(false);
7640
- setCaretIndex(undefined);
7641
- setSelectionStartValue(undefined);
7642
- setSelectionEndValue(undefined);
7643
7682
  }, onKeyDown: onTextFieldKeyDown, elementRef: inputBoxRef }))));
7644
7683
  };
7645
7684
 
@@ -8327,6 +8366,10 @@ const defaultChatMessageContainer = (theme) => ({
8327
8366
  maxWidth: '100% !important',
8328
8367
  height: 'auto !important'
8329
8368
  },
8369
+ '& video': {
8370
+ maxWidth: '100% !important',
8371
+ height: 'auto !important'
8372
+ },
8330
8373
  '& p': {
8331
8374
  // Deal with awkward padding seen in messages from Teams.
8332
8375
  // For more info see https://github.com/Azure/communication-ui-library/pull/1507
@@ -17465,11 +17508,10 @@ const convertToUiSystemMessage = (message) => {
17465
17508
  /** Returns `true` if the message has participants and at least one participant has a display name. */
17466
17509
  const hasValidParticipant = (chatMessage) => { var _a; return !!((_a = chatMessage.content) === null || _a === void 0 ? void 0 : _a.participants) && chatMessage.content.participants.some((p) => !!p.displayName); };
17467
17510
  /**
17468
- * Selector for {@link MessageThread} component.
17469
17511
  *
17470
- * @public
17512
+ * @private
17471
17513
  */
17472
- const messageThreadSelector = reselect.createSelector([getUserId, getChatMessages, getLatestReadTime, getIsLargeGroup, getReadReceipts, getParticipants], (userId, chatMessages, latestReadTime, isLargeGroup, readReceipts, participants) => {
17514
+ const messageThreadSelectorWithThread = () => reselect.createSelector([getUserId, getChatMessages, getLatestReadTime, getIsLargeGroup, getReadReceipts, getParticipants], (userId, chatMessages, latestReadTime, isLargeGroup, readReceipts, participants) => {
17473
17515
  // We can't get displayName in teams meeting interop for now, disable rr feature when it is teams interop
17474
17516
  const isTeamsInterop = Object.values(participants).find((p) => 'microsoftTeamsUserId' in p.id) !== undefined;
17475
17517
  // get number of participants
@@ -17480,7 +17522,7 @@ const messageThreadSelector = reselect.createSelector([getUserId, getChatMessage
17480
17522
  : Object.values(participants).filter((p) => p.displayName && p.displayName !== '').length;
17481
17523
  // creating key value pairs of senderID: last read message information
17482
17524
  const readReceiptsBySenderId = {};
17483
- // readReceiptsBySenderId[senderID] gets updated everytime a new message is read by this sender
17525
+ // readReceiptsBySenderId[senderID] gets updated every time a new message is read by this sender
17484
17526
  // in this way we can make sure that we are only saving the latest read message id and read on time for each sender
17485
17527
  readReceipts
17486
17528
  .filter((r) => r.sender && toFlatCommunicationIdentifier(r.sender) !== userId)
@@ -17537,6 +17579,12 @@ const isMessageValidToRender = (message) => {
17537
17579
  }
17538
17580
  return !!(message.content && ((_c = message.content) === null || _c === void 0 ? void 0 : _c.message) !== '');
17539
17581
  };
17582
+ /**
17583
+ * Selector for {@link MessageThread} component.
17584
+ *
17585
+ * @public
17586
+ */
17587
+ messageThreadSelectorWithThread();
17540
17588
 
17541
17589
  // Copyright (c) Microsoft Corporation.
17542
17590
  const filterTypingIndicators = (typingIndicators, userId) => {
@@ -17753,12 +17801,26 @@ const latestActiveErrorSatisfying = (errors, activeErrorType, predicate) => {
17753
17801
  const getSelector = (component) => {
17754
17802
  return findSelector(component);
17755
17803
  };
17804
+ const messageThreadSelectorsByThread = {};
17756
17805
  const findSelector = (component) => {
17806
+ // For the message thread selector we need to create a new one for each thread
17807
+ // If we have just one for the entire app, then we will have updates when not expecting due to
17808
+ // the arguments changing
17809
+ const getMessageThreadSelector = () => {
17810
+ var _a, _b;
17811
+ const threadId = (_b = (_a = React.useContext(ChatThreadClientContext)) === null || _a === void 0 ? void 0 : _a.threadId) !== null && _b !== void 0 ? _b : 'default-id-when-not-in-provider';
17812
+ let messageThreadSelectorImpl = messageThreadSelectorsByThread[threadId];
17813
+ if (!messageThreadSelectorImpl) {
17814
+ messageThreadSelectorsByThread[threadId] = messageThreadSelectorWithThread();
17815
+ messageThreadSelectorImpl = messageThreadSelectorsByThread[threadId];
17816
+ }
17817
+ return messageThreadSelectorImpl;
17818
+ };
17757
17819
  switch (component) {
17758
17820
  case SendBox:
17759
17821
  return sendBoxSelector;
17760
17822
  case MessageThread:
17761
- return messageThreadSelector;
17823
+ return getMessageThreadSelector();
17762
17824
  case TypingIndicator:
17763
17825
  return typingIndicatorSelector;
17764
17826
  case ParticipantList: