@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.
@@ -2,5 +2,5 @@
2
2
  // Copyright (c) Microsoft Corporation.
3
3
  // Licensed under the MIT license.
4
4
  // GENERATED FILE. DO NOT EDIT MANUALLY.
5
- module.exports = '1.7.0-alpha-202307060015';
5
+ module.exports = '1.7.0-alpha-202307070015';
6
6
  //# sourceMappingURL=telemetryVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../../acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,0BAA0B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n// GENERATED FILE. DO NOT EDIT MANUALLY.\n\nmodule.exports = '1.7.0-alpha-202307060015';\n"]}
1
+ {"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../../acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,0BAA0B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n// GENERATED FILE. DO NOT EDIT MANUALLY.\n\nmodule.exports = '1.7.0-alpha-202307070015';\n"]}
@@ -4,10 +4,12 @@ import { ErrorBar, MessageThread, ParticipantList, SendBox, TypingIndicator } fr
4
4
  import { useHandlers } from './useHandlers';
5
5
  import { useSelector } from './useSelector';
6
6
  import { sendBoxSelector } from '../sendBoxSelector';
7
- import { messageThreadSelector } from '../messageThreadSelector';
7
+ import { messageThreadSelectorWithThread } from '../messageThreadSelector';
8
8
  import { typingIndicatorSelector } from '../typingIndicatorSelector';
9
9
  import { chatParticipantListSelector } from '../chatParticipantListSelector';
10
10
  import { errorBarSelector } from '../errorBarSelector';
11
+ import { ChatThreadClientContext } from '../providers/ChatThreadClientProvider';
12
+ import { useContext } from 'react';
11
13
  /**
12
14
  * Primary hook to get all hooks necessary for a chat Component.
13
15
  *
@@ -46,12 +48,26 @@ export const usePropsFor = (component) => {
46
48
  export const getSelector = (component) => {
47
49
  return findSelector(component);
48
50
  };
51
+ const messageThreadSelectorsByThread = {};
49
52
  const findSelector = (component) => {
53
+ // For the message thread selector we need to create a new one for each thread
54
+ // If we have just one for the entire app, then we will have updates when not expecting due to
55
+ // the arguments changing
56
+ const getMessageThreadSelector = () => {
57
+ var _a, _b;
58
+ const threadId = (_b = (_a = useContext(ChatThreadClientContext)) === null || _a === void 0 ? void 0 : _a.threadId) !== null && _b !== void 0 ? _b : 'default-id-when-not-in-provider';
59
+ let messageThreadSelectorImpl = messageThreadSelectorsByThread[threadId];
60
+ if (!messageThreadSelectorImpl) {
61
+ messageThreadSelectorsByThread[threadId] = messageThreadSelectorWithThread();
62
+ messageThreadSelectorImpl = messageThreadSelectorsByThread[threadId];
63
+ }
64
+ return messageThreadSelectorImpl;
65
+ };
50
66
  switch (component) {
51
67
  case SendBox:
52
68
  return sendBoxSelector;
53
69
  case MessageThread:
54
- return messageThreadSelector;
70
+ return getMessageThreadSelector();
55
71
  case TypingIndicator:
56
72
  return typingIndicatorSelector;
57
73
  case ParticipantList:
@@ -1 +1 @@
1
- {"version":3,"file":"usePropsFor.js","sourceRoot":"","sources":["../../../../../../chat-component-bindings/src/hooks/usePropsFor.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,sCAAmC;AAEhH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAmB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAyB,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAA2B,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAG9F,OAAO,EAA+B,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC1G,OAAO,EAAoB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,SAAoB,EAGR,EAAE;IACd,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,WAAW,CAA2B,SAAS,CAAC,CAAC;IAClE,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,OAAO,gCAAK,KAAK,GAAK,QAAQ,CAAS,CAAC;KACzC;IACD,OAAO,SAAgB,CAAC;AAC1B,CAAC,CAAC;AAsBF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,SAAoB,EACI,EAAE;IAC1B,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,SAAkD,EAAO,EAAE;IAC/E,QAAQ,SAAS,EAAE;QACjB,KAAK,OAAO;YACV,OAAO,eAAe,CAAC;QACzB,KAAK,aAAa;YAChB,OAAO,qBAAqB,CAAC;QAC/B,KAAK,eAAe;YAClB,OAAO,uBAAuB,CAAC;QACjC,KAAK,eAAe;YAClB,OAAO,2BAA2B,CAAC;QACrC,KAAK,QAAQ;YACX,OAAO,gBAAgB,CAAC;KAC3B;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { ErrorBar, MessageThread, ParticipantList, SendBox, TypingIndicator } from '@internal/react-components';\n\nimport { useHandlers } from './useHandlers';\nimport { useSelector } from './useSelector';\nimport { SendBoxSelector, sendBoxSelector } from '../sendBoxSelector';\nimport { MessageThreadSelector, messageThreadSelector } from '../messageThreadSelector';\nimport { TypingIndicatorSelector, typingIndicatorSelector } from '../typingIndicatorSelector';\nimport { Common, AreEqual } from '@internal/acs-ui-common';\nimport { ChatHandlers } from '../handlers/createHandlers';\nimport { ChatParticipantListSelector, chatParticipantListSelector } from '../chatParticipantListSelector';\nimport { ErrorBarSelector, errorBarSelector } from '../errorBarSelector';\n\n/**\n * Primary hook to get all hooks necessary for a chat Component.\n *\n * Most straightforward usage of chat components looks like:\n *\n * @example\n * ```\n * import { ParticipantList, usePropsFor } from '@azure/communication-react';\n *\n * const App = (): JSX.Element => {\n * // ... code to setup Providers ...\n *\n * return <ParticipantList {...usePropsFor(ParticipantList)}/>\n * }\n * ```\n *\n * @public\n */\nexport const usePropsFor = <Component extends (props: any) => JSX.Element>(\n component: Component\n): GetSelector<Component> extends (props: any) => any\n ? ReturnType<GetSelector<Component>> & Common<ChatHandlers, Parameters<Component>[0]>\n : undefined => {\n const selector = getSelector(component);\n const props = useSelector(selector);\n const handlers = useHandlers<Parameters<Component>[0]>(component);\n if (props !== undefined) {\n return { ...props, ...handlers } as any;\n }\n return undefined as any;\n};\n\n/**\n * Specific type of the selector applicable to a given Component.\n *\n * @public\n */\nexport type GetSelector<Component extends (props: any) => JSX.Element | undefined> = AreEqual<\n Component,\n typeof SendBox\n> extends true\n ? SendBoxSelector\n : AreEqual<Component, typeof MessageThread> extends true\n ? MessageThreadSelector\n : AreEqual<Component, typeof TypingIndicator> extends true\n ? TypingIndicatorSelector\n : AreEqual<Component, typeof ParticipantList> extends true\n ? ChatParticipantListSelector\n : AreEqual<Component, typeof ErrorBar> extends true\n ? ErrorBarSelector\n : undefined;\n\n/**\n * Get the selector for a specified component.\n *\n * Useful when implementing a custom component that utilizes the providers\n * exported from this library.\n *\n * @public\n */\nexport const getSelector = <Component extends (props: any) => JSX.Element | undefined>(\n component: Component\n): GetSelector<Component> => {\n return findSelector(component);\n};\n\nconst findSelector = (component: (props: any) => JSX.Element | undefined): any => {\n switch (component) {\n case SendBox:\n return sendBoxSelector;\n case MessageThread:\n return messageThreadSelector;\n case TypingIndicator:\n return typingIndicatorSelector;\n case ParticipantList:\n return chatParticipantListSelector;\n case ErrorBar:\n return errorBarSelector;\n }\n return undefined;\n};\n\"../../../react-components/src\"\"../../../acs-ui-common/src\""]}
1
+ {"version":3,"file":"usePropsFor.js","sourceRoot":"","sources":["../../../../../../chat-component-bindings/src/hooks/usePropsFor.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,sCAAmC;AAEhH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAmB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAyB,+BAA+B,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EAA2B,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAG9F,OAAO,EAA+B,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC1G,OAAO,EAAoB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,SAAoB,EAGR,EAAE;IACd,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,WAAW,CAA2B,SAAS,CAAC,CAAC;IAClE,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,OAAO,gCAAK,KAAK,GAAK,QAAQ,CAAS,CAAC;KACzC;IACD,OAAO,SAAgB,CAAC;AAC1B,CAAC,CAAC;AAsBF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,SAAoB,EACI,EAAE;IAC1B,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAE1C,MAAM,YAAY,GAAG,CAAC,SAAkD,EAAO,EAAE;IAC/E,8EAA8E;IAC9E,8FAA8F;IAC9F,yBAAyB;IACzB,MAAM,wBAAwB,GAAgC,GAAG,EAAE;;QACjE,MAAM,QAAQ,GAAG,MAAA,MAAA,UAAU,CAAC,uBAAuB,CAAC,0CAAE,QAAQ,mCAAI,iCAAiC,CAAC;QACpG,IAAI,yBAAyB,GAAG,8BAA8B,CAAC,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC,yBAAyB,EAAE;YAC9B,8BAA8B,CAAC,QAAQ,CAAC,GAAG,+BAA+B,EAAE,CAAC;YAC7E,yBAAyB,GAAG,8BAA8B,CAAC,QAAQ,CAAC,CAAC;SACtE;QACD,OAAO,yBAAyB,CAAC;IACnC,CAAC,CAAC;IAEF,QAAQ,SAAS,EAAE;QACjB,KAAK,OAAO;YACV,OAAO,eAAe,CAAC;QACzB,KAAK,aAAa;YAChB,OAAO,wBAAwB,EAAE,CAAC;QACpC,KAAK,eAAe;YAClB,OAAO,uBAAuB,CAAC;QACjC,KAAK,eAAe;YAClB,OAAO,2BAA2B,CAAC;QACrC,KAAK,QAAQ;YACX,OAAO,gBAAgB,CAAC;KAC3B;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { ErrorBar, MessageThread, ParticipantList, SendBox, TypingIndicator } from '@internal/react-components';\n\nimport { useHandlers } from './useHandlers';\nimport { useSelector } from './useSelector';\nimport { SendBoxSelector, sendBoxSelector } from '../sendBoxSelector';\nimport { MessageThreadSelector, messageThreadSelectorWithThread } from '../messageThreadSelector';\nimport { TypingIndicatorSelector, typingIndicatorSelector } from '../typingIndicatorSelector';\nimport { Common, AreEqual } from '@internal/acs-ui-common';\nimport { ChatHandlers } from '../handlers/createHandlers';\nimport { ChatParticipantListSelector, chatParticipantListSelector } from '../chatParticipantListSelector';\nimport { ErrorBarSelector, errorBarSelector } from '../errorBarSelector';\nimport { ChatThreadClientContext } from '../providers/ChatThreadClientProvider';\nimport { useContext } from 'react';\n\n/**\n * Primary hook to get all hooks necessary for a chat Component.\n *\n * Most straightforward usage of chat components looks like:\n *\n * @example\n * ```\n * import { ParticipantList, usePropsFor } from '@azure/communication-react';\n *\n * const App = (): JSX.Element => {\n * // ... code to setup Providers ...\n *\n * return <ParticipantList {...usePropsFor(ParticipantList)}/>\n * }\n * ```\n *\n * @public\n */\nexport const usePropsFor = <Component extends (props: any) => JSX.Element>(\n component: Component\n): GetSelector<Component> extends (props: any) => any\n ? ReturnType<GetSelector<Component>> & Common<ChatHandlers, Parameters<Component>[0]>\n : undefined => {\n const selector = getSelector(component);\n const props = useSelector(selector);\n const handlers = useHandlers<Parameters<Component>[0]>(component);\n if (props !== undefined) {\n return { ...props, ...handlers } as any;\n }\n return undefined as any;\n};\n\n/**\n * Specific type of the selector applicable to a given Component.\n *\n * @public\n */\nexport type GetSelector<Component extends (props: any) => JSX.Element | undefined> = AreEqual<\n Component,\n typeof SendBox\n> extends true\n ? SendBoxSelector\n : AreEqual<Component, typeof MessageThread> extends true\n ? MessageThreadSelector\n : AreEqual<Component, typeof TypingIndicator> extends true\n ? TypingIndicatorSelector\n : AreEqual<Component, typeof ParticipantList> extends true\n ? ChatParticipantListSelector\n : AreEqual<Component, typeof ErrorBar> extends true\n ? ErrorBarSelector\n : undefined;\n\n/**\n * Get the selector for a specified component.\n *\n * Useful when implementing a custom component that utilizes the providers\n * exported from this library.\n *\n * @public\n */\nexport const getSelector = <Component extends (props: any) => JSX.Element | undefined>(\n component: Component\n): GetSelector<Component> => {\n return findSelector(component);\n};\n\nconst messageThreadSelectorsByThread = {};\n\nconst findSelector = (component: (props: any) => JSX.Element | undefined): any => {\n // For the message thread selector we need to create a new one for each thread\n // If we have just one for the entire app, then we will have updates when not expecting due to\n // the arguments changing\n const getMessageThreadSelector: () => MessageThreadSelector = () => {\n const threadId = useContext(ChatThreadClientContext)?.threadId ?? 'default-id-when-not-in-provider';\n let messageThreadSelectorImpl = messageThreadSelectorsByThread[threadId];\n if (!messageThreadSelectorImpl) {\n messageThreadSelectorsByThread[threadId] = messageThreadSelectorWithThread();\n messageThreadSelectorImpl = messageThreadSelectorsByThread[threadId];\n }\n return messageThreadSelectorImpl;\n };\n\n switch (component) {\n case SendBox:\n return sendBoxSelector;\n case MessageThread:\n return getMessageThreadSelector();\n case TypingIndicator:\n return typingIndicatorSelector;\n case ParticipantList:\n return chatParticipantListSelector;\n case ErrorBar:\n return errorBarSelector;\n }\n return undefined;\n};\n\"../../../react-components/src\"\"../../../acs-ui-common/src\""]}
@@ -11,6 +11,11 @@ export declare type MessageThreadSelector = (state: ChatClientState, props: Chat
11
11
  showMessageStatus: boolean;
12
12
  messages: Message[];
13
13
  };
14
+ /**
15
+ *
16
+ * @private
17
+ */
18
+ export declare const messageThreadSelectorWithThread: () => MessageThreadSelector;
14
19
  /**
15
20
  * Selector for {@link MessageThread} component.
16
21
  *
@@ -165,11 +165,10 @@ const convertToUiSystemMessage = (message) => {
165
165
  /** Returns `true` if the message has participants and at least one participant has a display name. */
166
166
  const hasValidParticipant = (chatMessage) => { var _a; return !!((_a = chatMessage.content) === null || _a === void 0 ? void 0 : _a.participants) && chatMessage.content.participants.some((p) => !!p.displayName); };
167
167
  /**
168
- * Selector for {@link MessageThread} component.
169
168
  *
170
- * @public
169
+ * @private
171
170
  */
172
- export const messageThreadSelector = createSelector([getUserId, getChatMessages, getLatestReadTime, getIsLargeGroup, getReadReceipts, getParticipants], (userId, chatMessages, latestReadTime, isLargeGroup, readReceipts, participants) => {
171
+ export const messageThreadSelectorWithThread = () => createSelector([getUserId, getChatMessages, getLatestReadTime, getIsLargeGroup, getReadReceipts, getParticipants], (userId, chatMessages, latestReadTime, isLargeGroup, readReceipts, participants) => {
173
172
  // We can't get displayName in teams meeting interop for now, disable rr feature when it is teams interop
174
173
  const isTeamsInterop = Object.values(participants).find((p) => 'microsoftTeamsUserId' in p.id) !== undefined;
175
174
  // get number of participants
@@ -180,7 +179,7 @@ export const messageThreadSelector = createSelector([getUserId, getChatMessages,
180
179
  : Object.values(participants).filter((p) => p.displayName && p.displayName !== '').length;
181
180
  // creating key value pairs of senderID: last read message information
182
181
  const readReceiptsBySenderId = {};
183
- // readReceiptsBySenderId[senderID] gets updated everytime a new message is read by this sender
182
+ // readReceiptsBySenderId[senderID] gets updated every time a new message is read by this sender
184
183
  // in this way we can make sure that we are only saving the latest read message id and read on time for each sender
185
184
  readReceipts
186
185
  .filter((r) => r.sender && toFlatCommunicationIdentifier(r.sender) !== userId)
@@ -237,4 +236,10 @@ const isMessageValidToRender = (message) => {
237
236
  }
238
237
  return !!(message.content && ((_c = message.content) === null || _c === void 0 ? void 0 : _c.message) !== '');
239
238
  };
239
+ /**
240
+ * Selector for {@link MessageThread} component.
241
+ *
242
+ * @public
243
+ */
244
+ export const messageThreadSelector = messageThreadSelectorWithThread();
240
245
  //# sourceMappingURL=messageThreadSelector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"messageThreadSelector.js","sourceRoot":"","sources":["../../../../../chat-component-bindings/src/messageThreadSelector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n ChatBaseSelectorProps,\n getChatMessages,\n getIsLargeGroup,\n getLatestReadTime,\n getParticipants,\n getReadReceipts,\n getUserId\n} from './baseSelectors';\nimport { toFlatCommunicationIdentifier } from '@internal/acs-ui-common';\nimport { ChatClientState, ChatMessageWithStatus } from '@internal/chat-stateful-client';\nimport { memoizeFnAll } from '@internal/acs-ui-common';\nimport {\n ChatMessage,\n Message,\n CommunicationParticipant,\n SystemMessage,\n MessageContentType,\n ReadReceiptsBySenderId\n} from '@internal/react-components';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '@internal/react-components';\nimport { createSelector } from 'reselect';\nimport { ACSKnownMessageType } from './utils/constants';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { DEFAULT_DATA_LOSS_PREVENTION_POLICY_URL } from './utils/constants';\nimport { updateMessagesWithAttached } from './utils/updateMessagesWithAttached';\n\n/* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { FileMetadata, FileMetadataAttachmentType } from '@internal/react-components';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { AttachmentType, ChatAttachment } from '@azure/communication-chat';\n\nconst memoizedAllConvertChatMessage = memoizeFnAll(\n (\n _key: string,\n chatMessage: ChatMessageWithStatus,\n userId: string,\n isSeen: boolean,\n isLargeGroup: boolean\n ): Message => {\n const messageType = chatMessage.type.toLowerCase();\n /* @conditional-compile-remove(data-loss-prevention) */\n if (chatMessage.policyViolation) {\n return convertToUiBlockedMessage(chatMessage, userId, isSeen, isLargeGroup);\n }\n if (\n messageType === ACSKnownMessageType.text ||\n messageType === ACSKnownMessageType.richtextHtml ||\n messageType === ACSKnownMessageType.html\n ) {\n return convertToUiChatMessage(chatMessage, userId, isSeen, isLargeGroup);\n } else {\n return convertToUiSystemMessage(chatMessage);\n }\n }\n);\n\n/* @conditional-compile-remove(file-sharing) */\nconst extractAttachedFilesMetadata = (metadata: Record<string, string>): FileMetadata[] => {\n const fileMetadata = metadata['fileSharingMetadata'];\n if (!fileMetadata) {\n return [];\n }\n try {\n return JSON.parse(fileMetadata);\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst extractTeamsAttachmentsMetadata = (attachments: ChatAttachment[]): FileMetadata[] => {\n return attachments.map((attachment) => ({\n attachmentType: mapAttachmentType(attachment.attachmentType),\n id: attachment.id,\n name: attachment.name ?? '',\n extension: attachment.contentType ?? '',\n url: extractAttachmentUrl(attachment),\n previewUrl: attachment.previewUrl\n }));\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst mapAttachmentType = (attachmentType: AttachmentType): FileMetadataAttachmentType => {\n if (attachmentType === 'teamsImage' || attachmentType === 'teamsInlineImage') {\n return 'teamsInlineImage';\n } else if (attachmentType === 'file') {\n return 'fileSharing';\n }\n return 'unknown';\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst extractAttachmentUrl = (attachment: ChatAttachment): string => {\n return attachment.attachmentType === 'file' && attachment.previewUrl ? attachment.previewUrl : attachment.url;\n};\n\nconst processChatMessageContent = (message: ChatMessageWithStatus): string | undefined => {\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n if (sanitizedMessageContentType(message.type).includes('html') && message.content?.attachments) {\n const attachments: ChatAttachment[] = message.content?.attachments;\n const teamsImageHtmlContent = attachments\n .filter((attachment) => attachment.attachmentType === 'teamsImage')\n .map((attachment) => generateImageAttachmentImgHtml(attachment))\n .join('');\n\n if (teamsImageHtmlContent) {\n return (message.content?.message ?? '') + teamsImageHtmlContent;\n }\n }\n return message.content?.message;\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst generateImageAttachmentImgHtml = (attachment: ChatAttachment): string => {\n return `\\r\\n<p><img alt=\"image\" src=\"\" itemscope=\"${attachment.contentType}\" id=\"${attachment.id}\"></p>`;\n};\n\n/* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst extractFilesMetadata = (message: ChatMessageWithStatus): FileMetadata[] => {\n let fileMetadata: FileMetadata[] = [];\n\n /* @conditional-compile-remove(file-sharing) */\n if (message.metadata) {\n fileMetadata = fileMetadata.concat(extractAttachedFilesMetadata(message.metadata));\n }\n\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n if (message.content?.attachments) {\n fileMetadata = fileMetadata.concat(extractTeamsAttachmentsMetadata(message.content?.attachments));\n }\n\n return fileMetadata;\n};\n\n/* @conditional-compile-remove(data-loss-prevention) */\nconst convertToUiBlockedMessage = (\n message: ChatMessageWithStatus,\n userId: string,\n isSeen: boolean,\n isLargeGroup: boolean\n): BlockedMessage => {\n const messageSenderId = message.sender !== undefined ? toFlatCommunicationIdentifier(message.sender) : userId;\n return {\n messageType: 'blocked',\n createdOn: message.createdOn,\n warningText: undefined,\n status: !isLargeGroup && message.status === 'delivered' && isSeen ? 'seen' : message.status,\n senderDisplayName: message.senderDisplayName,\n senderId: messageSenderId,\n messageId: message.id,\n deletedOn: message.deletedOn,\n mine: messageSenderId === userId,\n link: DEFAULT_DATA_LOSS_PREVENTION_POLICY_URL\n };\n};\n\nconst convertToUiChatMessage = (\n message: ChatMessageWithStatus,\n userId: string,\n isSeen: boolean,\n isLargeGroup: boolean\n): ChatMessage => {\n const messageSenderId = message.sender !== undefined ? toFlatCommunicationIdentifier(message.sender) : userId;\n return {\n messageType: 'chat',\n createdOn: message.createdOn,\n content: processChatMessageContent(message),\n contentType: sanitizedMessageContentType(message.type),\n status: !isLargeGroup && message.status === 'delivered' && isSeen ? 'seen' : message.status,\n senderDisplayName: message.senderDisplayName,\n senderId: messageSenderId,\n messageId: message.id,\n clientMessageId: message.clientMessageId,\n editedOn: message.editedOn,\n deletedOn: message.deletedOn,\n mine: messageSenderId === userId,\n metadata: message.metadata,\n /* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n attachedFilesMetadata: extractFilesMetadata(message)\n };\n};\n\nconst convertToUiSystemMessage = (message: ChatMessageWithStatus): SystemMessage => {\n const systemMessageType = message.type;\n if (systemMessageType === 'participantAdded' || systemMessageType === 'participantRemoved') {\n return {\n messageType: 'system',\n systemMessageType,\n createdOn: message.createdOn,\n participants:\n message.content?.participants\n // TODO: In our moderator logic, we use undefined name as our displayName for moderator, which should be filtered out\n // Once we have a better solution to identify the moderator, remove this line\n ?.filter((participant) => participant.displayName && participant.displayName !== '')\n .map(\n (participant): CommunicationParticipant => ({\n userId: toFlatCommunicationIdentifier(participant.id),\n displayName: participant.displayName\n })\n ) ?? [],\n messageId: message.id,\n iconName: systemMessageType === 'participantAdded' ? 'PeopleAdd' : 'PeopleBlock'\n };\n } else {\n // Only topic updated type left, according to ACSKnown type\n return {\n messageType: 'system',\n systemMessageType: 'topicUpdated',\n createdOn: message.createdOn,\n topic: message.content?.topic ?? '',\n messageId: message.id,\n iconName: 'Edit'\n };\n }\n};\n\n/**\n * Selector type for {@link MessageThread} component.\n *\n * @public\n */\nexport type MessageThreadSelector = (\n state: ChatClientState,\n props: ChatBaseSelectorProps\n) => {\n userId: string;\n showMessageStatus: boolean;\n messages: Message[];\n};\n\n/** Returns `true` if the message has participants and at least one participant has a display name. */\nconst hasValidParticipant = (chatMessage: ChatMessageWithStatus): boolean =>\n !!chatMessage.content?.participants && chatMessage.content.participants.some((p) => !!p.displayName);\n\n/**\n * Selector for {@link MessageThread} component.\n *\n * @public\n */\nexport const messageThreadSelector: MessageThreadSelector = createSelector(\n [getUserId, getChatMessages, getLatestReadTime, getIsLargeGroup, getReadReceipts, getParticipants],\n (userId, chatMessages, latestReadTime, isLargeGroup, readReceipts, participants) => {\n // We can't get displayName in teams meeting interop for now, disable rr feature when it is teams interop\n const isTeamsInterop = Object.values(participants).find((p) => 'microsoftTeamsUserId' in p.id) !== undefined;\n\n // get number of participants\n // filter out the non valid participants (no display name)\n // Read Receipt details will be disabled when participant count is 0\n const participantCount = isTeamsInterop\n ? undefined\n : Object.values(participants).filter((p) => p.displayName && p.displayName !== '').length;\n\n // creating key value pairs of senderID: last read message information\n\n const readReceiptsBySenderId: ReadReceiptsBySenderId = {};\n\n // readReceiptsBySenderId[senderID] gets updated everytime a new message is read by this sender\n // in this way we can make sure that we are only saving the latest read message id and read on time for each sender\n readReceipts\n .filter((r) => r.sender && toFlatCommunicationIdentifier(r.sender) !== userId)\n .forEach((r) => {\n readReceiptsBySenderId[toFlatCommunicationIdentifier(r.sender)] = {\n lastReadMessage: r.chatMessageId,\n displayName: participants[toFlatCommunicationIdentifier(r.sender)]?.displayName ?? ''\n };\n });\n\n // A function takes parameter above and generate return value\n const convertedMessages = memoizedAllConvertChatMessage((memoizedFn) =>\n Object.values(chatMessages)\n .filter(\n (message) =>\n message.type.toLowerCase() === ACSKnownMessageType.text ||\n message.type.toLowerCase() === ACSKnownMessageType.richtextHtml ||\n message.type.toLowerCase() === ACSKnownMessageType.html ||\n (message.type === ACSKnownMessageType.participantAdded && hasValidParticipant(message)) ||\n (message.type === ACSKnownMessageType.participantRemoved && hasValidParticipant(message)) ||\n // TODO: Add support for topicUpdated system messages in MessageThread component.\n // message.type === ACSKnownMessageType.topicUpdated ||\n message.clientMessageId !== undefined\n )\n .filter(isMessageValidToRender)\n .map((message) => {\n return memoizedFn(\n message.id ?? message.clientMessageId,\n message,\n userId,\n message.createdOn <= latestReadTime,\n isLargeGroup\n );\n })\n );\n\n updateMessagesWithAttached(convertedMessages);\n return {\n userId,\n showMessageStatus: true,\n messages: convertedMessages,\n participantCount,\n readReceiptsBySenderId\n };\n }\n);\n\nconst sanitizedMessageContentType = (type: string): MessageContentType => {\n const lowerCaseType = type.toLowerCase();\n return lowerCaseType === 'text' || lowerCaseType === 'html' || lowerCaseType === 'richtext/html'\n ? lowerCaseType\n : 'unknown';\n};\n\nconst isMessageValidToRender = (message: ChatMessageWithStatus): boolean => {\n if (message.deletedOn) {\n return false;\n }\n if (\n message.metadata?.['fileSharingMetadata'] ||\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ message.content?.attachments\n ) {\n return true;\n }\n /* @conditional-compile-remove(data-loss-prevention) */\n if (message.policyViolation) {\n return true;\n }\n return !!(message.content && message.content?.message !== '');\n};\n\"../../acs-ui-common/src\"\"../../chat-stateful-client/src\"\"../../react-components/src\""]}
1
+ {"version":3,"file":"messageThreadSelector.js","sourceRoot":"","sources":["../../../../../chat-component-bindings/src/messageThreadSelector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n ChatBaseSelectorProps,\n getChatMessages,\n getIsLargeGroup,\n getLatestReadTime,\n getParticipants,\n getReadReceipts,\n getUserId\n} from './baseSelectors';\nimport { toFlatCommunicationIdentifier } from '@internal/acs-ui-common';\nimport { ChatClientState, ChatMessageWithStatus } from '@internal/chat-stateful-client';\nimport { memoizeFnAll } from '@internal/acs-ui-common';\nimport {\n ChatMessage,\n Message,\n CommunicationParticipant,\n SystemMessage,\n MessageContentType,\n ReadReceiptsBySenderId\n} from '@internal/react-components';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '@internal/react-components';\nimport { createSelector } from 'reselect';\nimport { ACSKnownMessageType } from './utils/constants';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { DEFAULT_DATA_LOSS_PREVENTION_POLICY_URL } from './utils/constants';\nimport { updateMessagesWithAttached } from './utils/updateMessagesWithAttached';\n\n/* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { FileMetadata, FileMetadataAttachmentType } from '@internal/react-components';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { AttachmentType, ChatAttachment } from '@azure/communication-chat';\n\nconst memoizedAllConvertChatMessage = memoizeFnAll(\n (\n _key: string,\n chatMessage: ChatMessageWithStatus,\n userId: string,\n isSeen: boolean,\n isLargeGroup: boolean\n ): Message => {\n const messageType = chatMessage.type.toLowerCase();\n /* @conditional-compile-remove(data-loss-prevention) */\n if (chatMessage.policyViolation) {\n return convertToUiBlockedMessage(chatMessage, userId, isSeen, isLargeGroup);\n }\n if (\n messageType === ACSKnownMessageType.text ||\n messageType === ACSKnownMessageType.richtextHtml ||\n messageType === ACSKnownMessageType.html\n ) {\n return convertToUiChatMessage(chatMessage, userId, isSeen, isLargeGroup);\n } else {\n return convertToUiSystemMessage(chatMessage);\n }\n }\n);\n\n/* @conditional-compile-remove(file-sharing) */\nconst extractAttachedFilesMetadata = (metadata: Record<string, string>): FileMetadata[] => {\n const fileMetadata = metadata['fileSharingMetadata'];\n if (!fileMetadata) {\n return [];\n }\n try {\n return JSON.parse(fileMetadata);\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst extractTeamsAttachmentsMetadata = (attachments: ChatAttachment[]): FileMetadata[] => {\n return attachments.map((attachment) => ({\n attachmentType: mapAttachmentType(attachment.attachmentType),\n id: attachment.id,\n name: attachment.name ?? '',\n extension: attachment.contentType ?? '',\n url: extractAttachmentUrl(attachment),\n previewUrl: attachment.previewUrl\n }));\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst mapAttachmentType = (attachmentType: AttachmentType): FileMetadataAttachmentType => {\n if (attachmentType === 'teamsImage' || attachmentType === 'teamsInlineImage') {\n return 'teamsInlineImage';\n } else if (attachmentType === 'file') {\n return 'fileSharing';\n }\n return 'unknown';\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst extractAttachmentUrl = (attachment: ChatAttachment): string => {\n return attachment.attachmentType === 'file' && attachment.previewUrl ? attachment.previewUrl : attachment.url;\n};\n\nconst processChatMessageContent = (message: ChatMessageWithStatus): string | undefined => {\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n if (sanitizedMessageContentType(message.type).includes('html') && message.content?.attachments) {\n const attachments: ChatAttachment[] = message.content?.attachments;\n const teamsImageHtmlContent = attachments\n .filter((attachment) => attachment.attachmentType === 'teamsImage')\n .map((attachment) => generateImageAttachmentImgHtml(attachment))\n .join('');\n\n if (teamsImageHtmlContent) {\n return (message.content?.message ?? '') + teamsImageHtmlContent;\n }\n }\n return message.content?.message;\n};\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst generateImageAttachmentImgHtml = (attachment: ChatAttachment): string => {\n return `\\r\\n<p><img alt=\"image\" src=\"\" itemscope=\"${attachment.contentType}\" id=\"${attachment.id}\"></p>`;\n};\n\n/* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst extractFilesMetadata = (message: ChatMessageWithStatus): FileMetadata[] => {\n let fileMetadata: FileMetadata[] = [];\n\n /* @conditional-compile-remove(file-sharing) */\n if (message.metadata) {\n fileMetadata = fileMetadata.concat(extractAttachedFilesMetadata(message.metadata));\n }\n\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n if (message.content?.attachments) {\n fileMetadata = fileMetadata.concat(extractTeamsAttachmentsMetadata(message.content?.attachments));\n }\n\n return fileMetadata;\n};\n\n/* @conditional-compile-remove(data-loss-prevention) */\nconst convertToUiBlockedMessage = (\n message: ChatMessageWithStatus,\n userId: string,\n isSeen: boolean,\n isLargeGroup: boolean\n): BlockedMessage => {\n const messageSenderId = message.sender !== undefined ? toFlatCommunicationIdentifier(message.sender) : userId;\n return {\n messageType: 'blocked',\n createdOn: message.createdOn,\n warningText: undefined,\n status: !isLargeGroup && message.status === 'delivered' && isSeen ? 'seen' : message.status,\n senderDisplayName: message.senderDisplayName,\n senderId: messageSenderId,\n messageId: message.id,\n deletedOn: message.deletedOn,\n mine: messageSenderId === userId,\n link: DEFAULT_DATA_LOSS_PREVENTION_POLICY_URL\n };\n};\n\nconst convertToUiChatMessage = (\n message: ChatMessageWithStatus,\n userId: string,\n isSeen: boolean,\n isLargeGroup: boolean\n): ChatMessage => {\n const messageSenderId = message.sender !== undefined ? toFlatCommunicationIdentifier(message.sender) : userId;\n return {\n messageType: 'chat',\n createdOn: message.createdOn,\n content: processChatMessageContent(message),\n contentType: sanitizedMessageContentType(message.type),\n status: !isLargeGroup && message.status === 'delivered' && isSeen ? 'seen' : message.status,\n senderDisplayName: message.senderDisplayName,\n senderId: messageSenderId,\n messageId: message.id,\n clientMessageId: message.clientMessageId,\n editedOn: message.editedOn,\n deletedOn: message.deletedOn,\n mine: messageSenderId === userId,\n metadata: message.metadata,\n /* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n attachedFilesMetadata: extractFilesMetadata(message)\n };\n};\n\nconst convertToUiSystemMessage = (message: ChatMessageWithStatus): SystemMessage => {\n const systemMessageType = message.type;\n if (systemMessageType === 'participantAdded' || systemMessageType === 'participantRemoved') {\n return {\n messageType: 'system',\n systemMessageType,\n createdOn: message.createdOn,\n participants:\n message.content?.participants\n // TODO: In our moderator logic, we use undefined name as our displayName for moderator, which should be filtered out\n // Once we have a better solution to identify the moderator, remove this line\n ?.filter((participant) => participant.displayName && participant.displayName !== '')\n .map(\n (participant): CommunicationParticipant => ({\n userId: toFlatCommunicationIdentifier(participant.id),\n displayName: participant.displayName\n })\n ) ?? [],\n messageId: message.id,\n iconName: systemMessageType === 'participantAdded' ? 'PeopleAdd' : 'PeopleBlock'\n };\n } else {\n // Only topic updated type left, according to ACSKnown type\n return {\n messageType: 'system',\n systemMessageType: 'topicUpdated',\n createdOn: message.createdOn,\n topic: message.content?.topic ?? '',\n messageId: message.id,\n iconName: 'Edit'\n };\n }\n};\n\n/**\n * Selector type for {@link MessageThread} component.\n *\n * @public\n */\nexport type MessageThreadSelector = (\n state: ChatClientState,\n props: ChatBaseSelectorProps\n) => {\n userId: string;\n showMessageStatus: boolean;\n messages: Message[];\n};\n\n/** Returns `true` if the message has participants and at least one participant has a display name. */\nconst hasValidParticipant = (chatMessage: ChatMessageWithStatus): boolean =>\n !!chatMessage.content?.participants && chatMessage.content.participants.some((p) => !!p.displayName);\n\n/**\n *\n * @private\n */\nexport const messageThreadSelectorWithThread: () => MessageThreadSelector = () =>\n createSelector(\n [getUserId, getChatMessages, getLatestReadTime, getIsLargeGroup, getReadReceipts, getParticipants],\n (userId, chatMessages, latestReadTime, isLargeGroup, readReceipts, participants) => {\n // We can't get displayName in teams meeting interop for now, disable rr feature when it is teams interop\n const isTeamsInterop = Object.values(participants).find((p) => 'microsoftTeamsUserId' in p.id) !== undefined;\n\n // get number of participants\n // filter out the non valid participants (no display name)\n // Read Receipt details will be disabled when participant count is 0\n const participantCount = isTeamsInterop\n ? undefined\n : Object.values(participants).filter((p) => p.displayName && p.displayName !== '').length;\n\n // creating key value pairs of senderID: last read message information\n\n const readReceiptsBySenderId: ReadReceiptsBySenderId = {};\n\n // readReceiptsBySenderId[senderID] gets updated every time a new message is read by this sender\n // in this way we can make sure that we are only saving the latest read message id and read on time for each sender\n readReceipts\n .filter((r) => r.sender && toFlatCommunicationIdentifier(r.sender) !== userId)\n .forEach((r) => {\n readReceiptsBySenderId[toFlatCommunicationIdentifier(r.sender)] = {\n lastReadMessage: r.chatMessageId,\n displayName: participants[toFlatCommunicationIdentifier(r.sender)]?.displayName ?? ''\n };\n });\n\n // A function takes parameter above and generate return value\n const convertedMessages = memoizedAllConvertChatMessage((memoizedFn) =>\n Object.values(chatMessages)\n .filter(\n (message) =>\n message.type.toLowerCase() === ACSKnownMessageType.text ||\n message.type.toLowerCase() === ACSKnownMessageType.richtextHtml ||\n message.type.toLowerCase() === ACSKnownMessageType.html ||\n (message.type === ACSKnownMessageType.participantAdded && hasValidParticipant(message)) ||\n (message.type === ACSKnownMessageType.participantRemoved && hasValidParticipant(message)) ||\n // TODO: Add support for topicUpdated system messages in MessageThread component.\n // message.type === ACSKnownMessageType.topicUpdated ||\n message.clientMessageId !== undefined\n )\n .filter(isMessageValidToRender)\n .map((message) => {\n return memoizedFn(\n message.id ?? message.clientMessageId,\n message,\n userId,\n message.createdOn <= latestReadTime,\n isLargeGroup\n );\n })\n );\n\n updateMessagesWithAttached(convertedMessages);\n return {\n userId,\n showMessageStatus: true,\n messages: convertedMessages,\n participantCount,\n readReceiptsBySenderId\n };\n }\n );\n\nconst sanitizedMessageContentType = (type: string): MessageContentType => {\n const lowerCaseType = type.toLowerCase();\n return lowerCaseType === 'text' || lowerCaseType === 'html' || lowerCaseType === 'richtext/html'\n ? lowerCaseType\n : 'unknown';\n};\n\nconst isMessageValidToRender = (message: ChatMessageWithStatus): boolean => {\n if (message.deletedOn) {\n return false;\n }\n if (\n message.metadata?.['fileSharingMetadata'] ||\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ message.content?.attachments\n ) {\n return true;\n }\n /* @conditional-compile-remove(data-loss-prevention) */\n if (message.policyViolation) {\n return true;\n }\n return !!(message.content && message.content?.message !== '');\n};\n\n/**\n * Selector for {@link MessageThread} component.\n *\n * @public\n */\nexport const messageThreadSelector: MessageThreadSelector = messageThreadSelectorWithThread();\n\"../../acs-ui-common/src\"\"../../chat-stateful-client/src\"\"../../react-components/src\""]}
@@ -36,6 +36,8 @@ export const TextFieldWithMention = (props) => {
36
36
  // Index of the current trigger character in the text field
37
37
  const [currentTriggerStartIndex, setCurrentTriggerStartIndex] = useState(-1);
38
38
  const [inputTextValue, setInputTextValue] = useState('');
39
+ // Internal value for text value prop
40
+ const [internalTextValue, setInternalTextValue] = useState('');
39
41
  const [tagsValue, setTagsValue] = useState([]);
40
42
  // Index of the previous selection start in the text field
41
43
  const [selectionStartValue, setSelectionStartValue] = useState();
@@ -58,14 +60,19 @@ export const TextFieldWithMention = (props) => {
58
60
  const updateMentionSuggestions = useCallback((suggestions) => {
59
61
  setMentionSuggestions(suggestions);
60
62
  }, [setMentionSuggestions]);
63
+ useEffect(() => {
64
+ setInternalTextValue(textValue);
65
+ // update mention suggestions before the next render cycle
66
+ updateMentionSuggestions([]);
67
+ }, [textValue, updateMentionSuggestions]);
61
68
  // Parse the text and get the plain text version to display in the input box
62
69
  useEffect(() => {
63
70
  const trigger = (mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger) || DEFAULT_MENTION_TRIGGER;
64
- const parsedHTMLData = textToTagParser(textValue, trigger);
71
+ const parsedHTMLData = textToTagParser(internalTextValue, trigger);
65
72
  setInputTextValue(parsedHTMLData.plainText);
66
73
  setTagsValue(parsedHTMLData.tags);
67
74
  updateMentionSuggestions([]);
68
- }, [textValue, mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger, updateMentionSuggestions]);
75
+ }, [internalTextValue, mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger, updateMentionSuggestions]);
69
76
  useEffect(() => {
70
77
  var _a;
71
78
  // effect for caret index update
@@ -81,7 +88,7 @@ export const TextFieldWithMention = (props) => {
81
88
  (_a = textFieldRef === null || textFieldRef === void 0 ? void 0 : textFieldRef.current) === null || _a === void 0 ? void 0 : _a.setSelectionRange(updatedCaretIndex, updatedCaretIndex);
82
89
  setSelectionStartValue(updatedCaretIndex);
83
90
  setSelectionEndValue(updatedCaretIndex);
84
- }, [caretIndex, inputTextValue.length, textFieldRef, setSelectionStartValue, setSelectionEndValue]);
91
+ }, [caretIndex, inputTextValue, textFieldRef, setSelectionStartValue, setSelectionEndValue]);
85
92
  const onSuggestionSelected = useCallback((suggestion) => {
86
93
  var _a, _b, _c;
87
94
  let selectionEnd = ((_a = textFieldRef === null || textFieldRef === void 0 ? void 0 : textFieldRef.current) === null || _a === void 0 ? void 0 : _a.selectionEnd) || -1;
@@ -97,7 +104,7 @@ export const TextFieldWithMention = (props) => {
97
104
  const triggerText = (_b = mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger) !== null && _b !== void 0 ? _b : DEFAULT_MENTION_TRIGGER;
98
105
  // update html text with updated plain text
99
106
  const updatedContent = updateHTML({
100
- htmlText: textValue,
107
+ htmlText: internalTextValue,
101
108
  oldPlainText,
102
109
  tags: tagsValue,
103
110
  startIndex: currentTriggerStartIndex,
@@ -105,6 +112,7 @@ export const TextFieldWithMention = (props) => {
105
112
  change: mention,
106
113
  mentionTrigger: triggerText
107
114
  });
115
+ setInternalTextValue(updatedContent.updatedHTML);
108
116
  const displayName = getDisplayNameForMentionSuggestion(suggestion, localeStrings);
109
117
  const newCaretIndex = currentTriggerStartIndex + displayName.length + triggerText.length;
110
118
  // move the caret in the text field to the end of the mention plain text
@@ -123,7 +131,7 @@ export const TextFieldWithMention = (props) => {
123
131
  currentTriggerStartIndex,
124
132
  mentionLookupOptions === null || mentionLookupOptions === void 0 ? void 0 : mentionLookupOptions.trigger,
125
133
  onChange,
126
- textValue,
134
+ internalTextValue,
127
135
  tagsValue,
128
136
  updateMentionSuggestions,
129
137
  localeStrings
@@ -437,6 +445,7 @@ export const TextFieldWithMention = (props) => {
437
445
  change,
438
446
  mentionTrigger: triggerText
439
447
  });
448
+ setInternalTextValue(updatedContent.updatedHTML);
440
449
  // update caret index if needed
441
450
  if (updatedContent.updatedSelectionIndex !== undefined) {
442
451
  setCaretIndex(updatedContent.updatedSelectionIndex);
@@ -491,7 +500,7 @@ export const TextFieldWithMention = (props) => {
491
500
  handleOnChange({
492
501
  event: e,
493
502
  tagsValue,
494
- htmlTextValue: textValue,
503
+ htmlTextValue: internalTextValue,
495
504
  inputTextValue,
496
505
  currentTriggerStartIndex,
497
506
  previousSelectionStart: nullToUndefined(selectionStartValue),
@@ -509,7 +518,9 @@ export const TextFieldWithMention = (props) => {
509
518
  if (caretIndex !== e.currentTarget.selectionStart || caretIndex !== e.currentTarget.selectionEnd) {
510
519
  e.currentTarget.setSelectionRange(caretIndex, caretIndex);
511
520
  }
512
- setCaretIndex(undefined);
521
+ // caret index should not be set to undefined here
522
+ // as it will cause issues when suggestion is selected by mouse
523
+ // caret index will be set to undefined during keyboard/mouse or touch interactions
513
524
  return;
514
525
  }
515
526
  handleOnSelect({
@@ -551,11 +562,9 @@ export const TextFieldWithMention = (props) => {
551
562
  }, onTouchEnd: () => {
552
563
  handleOnInteractionCompleted;
553
564
  }, onBlur: () => {
554
- // setup all flags to default values when text field loses focus
565
+ // setup shouldHandleOnMouseDownDuringSelect to false when text field loses focus
566
+ // as the click should be handled by text field anymore
555
567
  setShouldHandleOnMouseDownDuringSelect(false);
556
- setCaretIndex(undefined);
557
- setSelectionStartValue(undefined);
558
- setSelectionEndValue(undefined);
559
568
  }, onKeyDown: onTextFieldKeyDown, elementRef: inputBoxRef }))));
560
569
  };
561
570
  /**