@droppii-org/chat-sdk 0.3.8 → 0.4.1
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.
- package/dist/components/canned-response/CannedResponseBody.js +1 -1
- package/dist/components/canned-response/CannedResponseFooter.js +1 -1
- package/dist/components/canned-response/CannedResponseHeader.js +1 -1
- package/dist/components/canned-response/index.js +1 -1
- package/dist/components/canned-response/team/TeamItem.js +1 -1
- package/dist/components/common/ConfirmModal.d.ts.map +1 -1
- package/dist/components/common/ConfirmModal.js +1 -1
- package/dist/components/common/InfoModal.d.ts.map +1 -1
- package/dist/components/common/InfoModal.js +1 -1
- package/dist/components/compose/ComposeNewMessageModal.d.ts.map +1 -1
- package/dist/components/compose/ComposeNewMessageModal.js +1 -1
- package/dist/components/conversation/ConversationByGroupItem.d.ts.map +1 -1
- package/dist/components/conversation/ConversationByGroupItem.js +2 -1
- package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
- package/dist/components/conversation/ConversationBySessionItem.js +2 -1
- package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
- package/dist/components/conversation/DeskConversationList.js +1 -1
- package/dist/components/conversation/MentionIndicatorIcon.d.ts +7 -0
- package/dist/components/conversation/MentionIndicatorIcon.d.ts.map +1 -0
- package/dist/components/conversation/MentionIndicatorIcon.js +17 -0
- package/dist/components/conversation/SwipeActionButton.d.ts.map +1 -1
- package/dist/components/conversation/SwipeActionButton.js +1 -1
- package/dist/components/conversation/SwipeableRow.d.ts.map +1 -1
- package/dist/components/conversation/SwipeableRow.js +1 -1
- package/dist/components/conversation/ThreadCard.d.ts +2 -1
- package/dist/components/conversation/ThreadCard.d.ts.map +1 -1
- package/dist/components/conversation/ThreadCard.js +4 -4
- package/dist/components/conversation-detail/ConversationDetailHeader.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationDetailHeader.js +2 -2
- package/dist/components/conversation-detail/ConversationDetailInput.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationDetailInput.js +5 -1
- package/dist/components/conversation-detail/ConversationMessageList.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationMessageList.js +1 -1
- package/dist/components/conversation-detail/ConversationMoreOptionItem.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationMoreOptionItem.js +1 -1
- package/dist/components/conversation-detail/ConversationMoreOptionPanel.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationMoreOptionPanel.js +1 -1
- package/dist/components/conversation-detail/LeaveGroupBlockedModal.d.ts +12 -0
- package/dist/components/conversation-detail/LeaveGroupBlockedModal.d.ts.map +1 -0
- package/dist/components/conversation-detail/LeaveGroupBlockedModal.js +18 -0
- package/dist/components/conversation-detail/LeaveGroupConfirmModal.d.ts +16 -0
- package/dist/components/conversation-detail/LeaveGroupConfirmModal.d.ts.map +1 -0
- package/dist/components/conversation-detail/LeaveGroupConfirmModal.js +21 -0
- package/dist/components/conversation-detail/PinLimitModal.d.ts.map +1 -1
- package/dist/components/conversation-detail/PinLimitModal.js +1 -1
- package/dist/components/conversation-detail/PinnedMessageBar.d.ts.map +1 -1
- package/dist/components/conversation-detail/PinnedMessageBar.js +8 -4
- package/dist/components/conversation-detail/PinnedMessageItem.d.ts.map +1 -1
- package/dist/components/conversation-detail/PinnedMessageItem.js +1 -1
- package/dist/components/conversation-detail/PinnedMessagesPanel.d.ts.map +1 -1
- package/dist/components/conversation-detail/PinnedMessagesPanel.js +1 -1
- package/dist/components/conversation-detail/ThreadProfilePanel.d.ts.map +1 -1
- package/dist/components/conversation-detail/ThreadProfilePanel.js +12 -2
- package/dist/components/conversation-detail/bot/BotButtonMessage.d.ts.map +1 -1
- package/dist/components/conversation-detail/bot/BotButtonMessage.js +1 -1
- package/dist/components/conversation-detail/bot/BotInactiveNotice.d.ts.map +1 -1
- package/dist/components/conversation-detail/bot/BotInactiveNotice.js +1 -1
- package/dist/components/conversation-detail/bot/BotMenuSheet.d.ts.map +1 -1
- package/dist/components/conversation-detail/bot/BotMenuSheet.js +1 -1
- package/dist/components/conversation-detail/bot/BotStartButton.d.ts.map +1 -1
- package/dist/components/conversation-detail/bot/BotStartButton.js +1 -1
- package/dist/components/conversation-detail/bot/BotSuggest.d.ts.map +1 -1
- package/dist/components/conversation-detail/bot/BotSuggest.js +2 -2
- package/dist/components/conversation-detail/bot/CsSessionConfirmModal.d.ts.map +1 -1
- package/dist/components/conversation-detail/bot/CsSessionConfirmModal.js +1 -1
- package/dist/components/conversation-detail/index.d.ts +4 -0
- package/dist/components/conversation-detail/index.d.ts.map +1 -1
- package/dist/components/conversation-detail/index.js +2 -0
- package/dist/components/conversation-inbox/ConversationInboxHeader.d.ts.map +1 -1
- package/dist/components/conversation-inbox/ConversationInboxHeader.js +1 -1
- package/dist/components/conversation-inbox/ConversationInboxItem.d.ts.map +1 -1
- package/dist/components/conversation-inbox/ConversationInboxItem.js +2 -1
- package/dist/components/conversation-inbox/ConversationInboxList.d.ts.map +1 -1
- package/dist/components/conversation-inbox/ConversationInboxList.js +1 -1
- package/dist/components/conversation-inbox/ConversationInboxTitle.d.ts.map +1 -1
- package/dist/components/conversation-inbox/ConversationInboxTitle.js +1 -1
- package/dist/components/conversation-inbox/ConversationPeerAvatar.d.ts.map +1 -1
- package/dist/components/conversation-inbox/ConversationPeerAvatar.js +1 -1
- package/dist/components/conversation-inbox/MuteConversationConfirmModal.d.ts.map +1 -1
- package/dist/components/conversation-inbox/MuteConversationConfirmModal.js +1 -1
- package/dist/components/group/AddMemberModal.d.ts.map +1 -1
- package/dist/components/group/AddMemberModal.js +1 -1
- package/dist/components/group/CreateGroupForm.d.ts.map +1 -1
- package/dist/components/group/CreateGroupForm.js +1 -3
- package/dist/components/group/GroupMemberPicker.js +1 -1
- package/dist/components/group/MemberPermissionPanel.js +1 -1
- package/dist/components/icon/index.d.ts.map +1 -1
- package/dist/components/icon/index.js +1 -1
- package/dist/components/media-collection/FileCollection.d.ts.map +1 -1
- package/dist/components/media-collection/FileCollection.js +1 -1
- package/dist/components/media-collection/ImageCollection.d.ts.map +1 -1
- package/dist/components/media-collection/ImageCollection.js +1 -1
- package/dist/components/media-collection/LinkCollection.d.ts.map +1 -1
- package/dist/components/media-collection/LinkCollection.js +2 -2
- package/dist/components/media-collection/VideoCollection.d.ts.map +1 -1
- package/dist/components/media-collection/VideoCollection.js +1 -1
- package/dist/components/media-collection/index.js +1 -1
- package/dist/components/media-resources/FileResourceList.d.ts.map +1 -1
- package/dist/components/media-resources/FileResourceList.js +1 -1
- package/dist/components/media-resources/ImageResourceGrid.d.ts.map +1 -1
- package/dist/components/media-resources/ImageResourceGrid.js +1 -1
- package/dist/components/media-resources/LinkResourceItem.d.ts.map +1 -1
- package/dist/components/media-resources/LinkResourceItem.js +1 -1
- package/dist/components/media-resources/LinkResourceList.d.ts.map +1 -1
- package/dist/components/media-resources/LinkResourceList.js +1 -1
- package/dist/components/media-resources/MediaEntryCard.d.ts.map +1 -1
- package/dist/components/media-resources/MediaEntryCard.js +1 -1
- package/dist/components/media-resources/MediaResourcePanel.d.ts.map +1 -1
- package/dist/components/media-resources/MediaResourcePanel.js +1 -1
- package/dist/components/media-resources/MediaResourceTabBar.d.ts.map +1 -1
- package/dist/components/media-resources/MediaResourceTabBar.js +1 -1
- package/dist/components/media-resources/MediaResourceTabs.js +1 -1
- package/dist/components/media-resources/ResourceEmptyState.d.ts.map +1 -1
- package/dist/components/media-resources/ResourceEmptyState.js +1 -1
- package/dist/components/media-resources/ResourceScrollContainer.d.ts.map +1 -1
- package/dist/components/media-resources/ResourceScrollContainer.js +1 -1
- package/dist/components/media-resources/VideoResourceGrid.d.ts.map +1 -1
- package/dist/components/media-resources/VideoResourceGrid.js +1 -1
- package/dist/components/message/GroupMembersDrawer.js +1 -1
- package/dist/components/message/MessageHeader.d.ts.map +1 -1
- package/dist/components/message/MessageHeader.js +3 -2
- package/dist/components/message/MessageInfiniteScroll.d.ts.map +1 -1
- package/dist/components/message/MessageInfiniteScroll.js +1 -1
- package/dist/components/message/MessageList.d.ts.map +1 -1
- package/dist/components/message/MessageList.js +22 -12
- package/dist/components/message/SelectSession.js +1 -1
- package/dist/components/message/UnassignedSessionFooter.d.ts.map +1 -1
- package/dist/components/message/UnassignedSessionFooter.js +1 -1
- package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
- package/dist/components/message/footer/ActionBar.js +4 -1
- package/dist/components/message/footer/ComposerEditor.js +1 -1
- package/dist/components/message/footer/ComposerTabs.d.ts.map +1 -1
- package/dist/components/message/footer/ComposerTabs.js +1 -1
- package/dist/components/message/footer/EmojiPicker.js +1 -1
- package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
- package/dist/components/message/footer/EnterHandler.js +10 -1
- package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
- package/dist/components/message/footer/FilePreview.js +4 -4
- package/dist/components/message/footer/LinkInputPreview.d.ts.map +1 -1
- package/dist/components/message/footer/LinkInputPreview.js +1 -1
- package/dist/components/message/footer/MediaActions.js +1 -1
- package/dist/components/message/footer/SessionClosedModal.d.ts.map +1 -1
- package/dist/components/message/footer/SessionClosedModal.js +1 -1
- package/dist/components/message/footer/ToolbarPlugin.js +1 -1
- package/dist/components/message/footer/editorConfig.d.ts +2 -1
- package/dist/components/message/footer/editorConfig.d.ts.map +1 -1
- package/dist/components/message/footer/editorConfig.js +2 -0
- package/dist/components/message/footer/index.d.ts.map +1 -1
- package/dist/components/message/footer/index.js +16 -2
- package/dist/components/message/footer/mention/MentionMenu.d.ts +6 -0
- package/dist/components/message/footer/mention/MentionMenu.d.ts.map +1 -0
- package/dist/components/message/footer/mention/MentionMenu.js +51 -0
- package/dist/components/message/footer/mention/MentionNode.d.ts +20 -0
- package/dist/components/message/footer/mention/MentionNode.d.ts.map +1 -0
- package/dist/components/message/footer/mention/MentionNode.js +39 -0
- package/dist/components/message/footer/mention/extractMentions.d.ts +6 -0
- package/dist/components/message/footer/mention/extractMentions.d.ts.map +1 -0
- package/dist/components/message/footer/mention/extractMentions.js +66 -0
- package/dist/components/message/footer/mention/useMentionOptions.d.ts +8 -0
- package/dist/components/message/footer/mention/useMentionOptions.d.ts.map +1 -0
- package/dist/components/message/footer/mention/useMentionOptions.js +45 -0
- package/dist/components/message/item/AtTextMessage.d.ts +16 -0
- package/dist/components/message/item/AtTextMessage.d.ts.map +1 -0
- package/dist/components/message/item/AtTextMessage.js +112 -0
- package/dist/components/message/item/FileMessage.js +1 -1
- package/dist/components/message/item/GroupNotificationMessage.d.ts.map +1 -1
- package/dist/components/message/item/GroupNotificationMessage.js +2 -2
- package/dist/components/message/item/ImageMessage.js +1 -1
- package/dist/components/message/item/LinkCard.d.ts.map +1 -1
- package/dist/components/message/item/LinkCard.js +1 -1
- package/dist/components/message/item/LinkText.d.ts.map +1 -1
- package/dist/components/message/item/LinkText.js +1 -1
- package/dist/components/message/item/MergeImageMessage.js +1 -1
- package/dist/components/message/item/MessageBubble.d.ts.map +1 -1
- package/dist/components/message/item/MessageBubble.js +2 -2
- package/dist/components/message/item/QuoteMessage.d.ts.map +1 -1
- package/dist/components/message/item/QuoteMessage.js +1 -1
- package/dist/components/message/item/RevokeMessage.d.ts.map +1 -1
- package/dist/components/message/item/RevokeMessage.js +1 -1
- package/dist/components/message/item/VideoMessage.js +1 -1
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +3 -3
- package/dist/components/message/item/renderMessageContent.d.ts.map +1 -1
- package/dist/components/message/item/renderMessageContent.js +3 -0
- package/dist/components/message/reply/ReplyPreviewBar.d.ts.map +1 -1
- package/dist/components/message/reply/ReplyPreviewBar.js +1 -1
- package/dist/components/message/reply/ReplyQuoteContent.d.ts.map +1 -1
- package/dist/components/message/reply/ReplyQuoteContent.js +7 -5
- package/dist/components/message/toolbox/MessageToolboxMenu.js +1 -1
- package/dist/components/message/toolbox/getCopyableMessageText.d.ts.map +1 -1
- package/dist/components/message/toolbox/getCopyableMessageText.js +5 -3
- package/dist/components/message/toolbox/isPinnableMessageType.d.ts.map +1 -1
- package/dist/components/message/toolbox/isPinnableMessageType.js +1 -0
- package/dist/components/search-conversation/SearchAll.d.ts.map +1 -1
- package/dist/components/search-conversation/SearchAll.js +9 -3
- package/dist/components/search-conversation/SearchConversationAsGroups.d.ts +6 -0
- package/dist/components/search-conversation/SearchConversationAsGroups.d.ts.map +1 -0
- package/dist/components/search-conversation/SearchConversationAsGroups.js +20 -0
- package/dist/components/search-conversation/SearchConversationAsMessages.d.ts.map +1 -1
- package/dist/components/search-conversation/SearchConversationAsMessages.js +1 -1
- package/dist/components/search-conversation/SearchConversationAsUsers.d.ts.map +1 -1
- package/dist/components/search-conversation/SearchConversationAsUsers.js +1 -1
- package/dist/components/search-conversation/SearchConversationMyInbox.js +1 -1
- package/dist/components/search-conversation/SearchDrawer.js +1 -1
- package/dist/components/search-conversation/SearchMessageOnCurrentConversation.d.ts.map +1 -1
- package/dist/components/search-conversation/SearchMessageOnCurrentConversation.js +1 -1
- package/dist/components/search-conversation/index.d.ts +2 -1
- package/dist/components/search-conversation/index.d.ts.map +1 -1
- package/dist/components/search-conversation/index.js +8 -1
- package/dist/components/search-conversation/item/SearchItemAsGroup.d.ts +8 -0
- package/dist/components/search-conversation/item/SearchItemAsGroup.d.ts.map +1 -0
- package/dist/components/search-conversation/item/SearchItemAsGroup.js +34 -0
- package/dist/components/search-conversation/item/SearchItemAsMessage.d.ts.map +1 -1
- package/dist/components/search-conversation/item/SearchItemAsMessage.js +1 -1
- package/dist/components/search-conversation/item/SearchItemAsUser.d.ts.map +1 -1
- package/dist/components/search-conversation/item/SearchItemAsUser.js +1 -1
- package/dist/components/session/DeskTeamInbox.d.ts.map +1 -1
- package/dist/components/session/DeskTeamInbox.js +3 -2
- package/dist/components/session/SessionFilterMenu.d.ts.map +1 -1
- package/dist/components/session/SessionFilterMenu.js +1 -1
- package/dist/components/thread/AssignConfirmModal.d.ts.map +1 -1
- package/dist/components/thread/AssignConfirmModal.js +1 -1
- package/dist/components/thread/GroupThreadInfo.d.ts.map +1 -1
- package/dist/components/thread/GroupThreadInfo.js +7 -4
- package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
- package/dist/components/thread/ManualAssignPopover.js +1 -1
- package/dist/components/thread/SessionSection.d.ts.map +1 -1
- package/dist/components/thread/SessionSection.js +2 -2
- package/dist/components/thread/SingleThreadInfo.d.ts.map +1 -1
- package/dist/components/thread/SingleThreadInfo.js +1 -1
- package/dist/components/thread/ThreadInfo.js +1 -1
- package/dist/components/thread/UserSection.d.ts.map +1 -1
- package/dist/components/thread/UserSection.js +1 -1
- package/dist/components/video-player/VideoPlayerModal.d.ts.map +1 -1
- package/dist/components/video-player/VideoPlayerModal.js +1 -1
- package/dist/context/ChatContext.d.ts +1 -1
- package/dist/context/ChatContext.d.ts.map +1 -1
- package/dist/context/ChatContext.js +2 -1
- package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
- package/dist/hooks/global/useGlobalEvent.js +125 -25
- package/dist/hooks/group/useConversationGroups.d.ts +5 -1
- package/dist/hooks/group/useConversationGroups.d.ts.map +1 -1
- package/dist/hooks/group/useConversationGroups.js +3 -3
- package/dist/hooks/group/useGroupPermission.d.ts +1 -1
- package/dist/hooks/group/useGroupPermission.d.ts.map +1 -1
- package/dist/hooks/group/useGroupPermission.js +2 -2
- package/dist/hooks/group/useLeaveGroupAction.d.ts +24 -0
- package/dist/hooks/group/useLeaveGroupAction.d.ts.map +1 -0
- package/dist/hooks/group/useLeaveGroupAction.js +79 -0
- package/dist/hooks/group/useQuitGroup.d.ts +6 -0
- package/dist/hooks/group/useQuitGroup.d.ts.map +1 -0
- package/dist/hooks/group/useQuitGroup.js +62 -0
- package/dist/hooks/message/useMessage.d.ts +4 -1
- package/dist/hooks/message/useMessage.d.ts.map +1 -1
- package/dist/hooks/message/useMessage.js +9 -2
- package/dist/hooks/message/useSendMessage.d.ts +8 -4
- package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
- package/dist/hooks/message/useSendMessage.js +46 -12
- package/dist/hooks/search/useSearchGroups.d.ts +16 -0
- package/dist/hooks/search/useSearchGroups.d.ts.map +1 -0
- package/dist/hooks/search/useSearchGroups.js +65 -0
- package/dist/hooks/session/useConversationSessionState.d.ts +2 -1
- package/dist/hooks/session/useConversationSessionState.d.ts.map +1 -1
- package/dist/hooks/session/useConversationSessionState.js +5 -5
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +10 -1
- package/dist/locales/vi/common.json +12 -0
- package/dist/locales/vi/conversation-inbox.json +18 -1
- package/dist/services/query.d.ts +1 -0
- package/dist/services/query.d.ts.map +1 -1
- package/dist/services/query.js +1 -0
- package/dist/services/routes.d.ts +1 -0
- package/dist/services/routes.d.ts.map +1 -1
- package/dist/services/routes.js +1 -0
- package/dist/store/auth.js +1 -1
- package/dist/store/conversation.d.ts.map +1 -1
- package/dist/store/conversation.js +96 -51
- package/dist/store/type.d.ts +8 -2
- package/dist/store/type.d.ts.map +1 -1
- package/dist/styles/global.css +1 -1
- package/dist/types/chat.d.ts +28 -2
- package/dist/types/chat.d.ts.map +1 -1
- package/dist/types/dto.d.ts +3 -1
- package/dist/types/dto.d.ts.map +1 -1
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +19 -9
- package/dist/utils/messageLog.d.ts +2 -2
- package/dist/utils/messageLog.d.ts.map +1 -1
- package/dist/utils/messageLog.js +33 -3
- package/package.json +17 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LinkNode } from "@lexical/link";
|
|
2
2
|
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
3
3
|
import { ListItemNode, ListNode } from "@lexical/list";
|
|
4
|
+
import { MentionNode } from "./mention/MentionNode";
|
|
4
5
|
export declare const editorTheme: {
|
|
5
6
|
text: {
|
|
6
7
|
bold: string;
|
|
@@ -18,7 +19,7 @@ export declare const editorTheme: {
|
|
|
18
19
|
};
|
|
19
20
|
link: string;
|
|
20
21
|
};
|
|
21
|
-
export declare const editorNodes: (typeof HeadingNode | typeof ListNode | typeof ListItemNode | typeof QuoteNode | typeof LinkNode)[];
|
|
22
|
+
export declare const editorNodes: (typeof MentionNode | typeof HeadingNode | typeof ListNode | typeof ListItemNode | typeof QuoteNode | typeof LinkNode)[];
|
|
22
23
|
export declare const editorOnError: (error: Error) => void;
|
|
23
24
|
export declare const DOCUMENT_TYPES: string[];
|
|
24
25
|
//# sourceMappingURL=editorConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editorConfig.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/editorConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"editorConfig.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/editorConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;CAcvB,CAAC;AAEF,eAAO,MAAM,WAAW,0HAOvB,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,SAEzC,CAAC;AAEF,eAAO,MAAM,cAAc,UAI1B,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LinkNode } from "@lexical/link";
|
|
2
2
|
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
3
3
|
import { ListItemNode, ListNode } from "@lexical/list";
|
|
4
|
+
import { MentionNode } from "./mention/MentionNode";
|
|
4
5
|
export const editorTheme = {
|
|
5
6
|
text: {
|
|
6
7
|
bold: "font-bold",
|
|
@@ -22,6 +23,7 @@ export const editorNodes = [
|
|
|
22
23
|
ListItemNode,
|
|
23
24
|
QuoteNode,
|
|
24
25
|
LinkNode,
|
|
26
|
+
MentionNode,
|
|
25
27
|
];
|
|
26
28
|
export const editorOnError = (error) => {
|
|
27
29
|
console.error(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAGL,wBAAwB,EAEzB,MAAM,cAAc,CAAC;AAStB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoB/C,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AASD,eAAO,MAAM,oBAAoB,mDAc/B,CAAC;AAEH,eAAO,MAAM,uBAAuB,gCAAyC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,GAAI,4CAG5B,kBAAkB,4CAuUpB,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -27,6 +27,7 @@ import useConversationStore from "../../../store/conversation";
|
|
|
27
27
|
import { useCurrentUserAccountType } from "../../../hooks/user/useCurrentUserAccountType";
|
|
28
28
|
import ComposerTabs from "./ComposerTabs";
|
|
29
29
|
import ComposerEditor from "./ComposerEditor";
|
|
30
|
+
import MentionMenu from "./mention/MentionMenu";
|
|
30
31
|
import SessionClosedModal from "./SessionClosedModal";
|
|
31
32
|
import { useCreateSession, useReopenSession, } from "../../../hooks/session/useReopenOrCreateSession";
|
|
32
33
|
import { emit } from "../../../utils/events";
|
|
@@ -49,10 +50,13 @@ export const MessageFooterContext = createContext({
|
|
|
49
50
|
setActiveCannedIndex: () => { },
|
|
50
51
|
maxActiveCannedIndex: 0,
|
|
51
52
|
setMaxActiveCannedIndex: () => { },
|
|
53
|
+
isMentionMenuOpen: false,
|
|
54
|
+
setIsMentionMenuOpen: () => { },
|
|
52
55
|
});
|
|
53
56
|
export const useMessageFooterContext = () => useContext(MessageFooterContext);
|
|
54
57
|
const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
55
58
|
const { t } = useTranslation();
|
|
59
|
+
const { t: tConversationInbox } = useTranslation("conversation-inbox");
|
|
56
60
|
const { sendMergeMessage } = useSendMessage();
|
|
57
61
|
const accountType = useCurrentUserAccountType();
|
|
58
62
|
const [listUploadFiles, setListUploadFiles] = useState([]);
|
|
@@ -64,8 +68,10 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
64
68
|
const [activeCannedIndex, setActiveCannedIndex] = useState(0);
|
|
65
69
|
const [maxActiveCannedIndex, setMaxActiveCannedIndex] = useState(0);
|
|
66
70
|
const [isInternal, setIsInternal] = useState(false);
|
|
71
|
+
const [isMentionMenuOpen, setIsMentionMenuOpen] = useState(false);
|
|
67
72
|
const quotedMessage = useConversationStore((state) => state.quotedMessage);
|
|
68
73
|
const conversationData = useConversationStore((state) => state.conversationData);
|
|
74
|
+
const isViewOnlyMember = useConversationStore((state) => state.isViewOnlyMember);
|
|
69
75
|
// Internal notes are a CX-support concept (team-only remarks not sent to
|
|
70
76
|
// the customer) — meaningless inside a real member-managed group, where
|
|
71
77
|
// everyone in the thread already is the "team".
|
|
@@ -112,7 +118,7 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
112
118
|
const placeholderText = isInternal
|
|
113
119
|
? t("enter_internal_message")
|
|
114
120
|
: t("enter_message");
|
|
115
|
-
const onSendMessage = useCallback(({ plainText, richText, type, isInternal, }) => {
|
|
121
|
+
const onSendMessage = useCallback(({ plainText, richText, type, isInternal, mentions, }) => {
|
|
116
122
|
if ((currentSession === null || currentSession === void 0 ? void 0 : currentSession.isClosed) && !isInternal) {
|
|
117
123
|
pendingMessageRef.current = {
|
|
118
124
|
plainText,
|
|
@@ -121,6 +127,7 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
121
127
|
isInternal,
|
|
122
128
|
files: [...listUploadFiles],
|
|
123
129
|
urlMetadata: resolveUrlMetadata(),
|
|
130
|
+
mentions,
|
|
124
131
|
};
|
|
125
132
|
openSessionClosedModal();
|
|
126
133
|
return false;
|
|
@@ -132,6 +139,7 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
132
139
|
currentSession,
|
|
133
140
|
isInternal,
|
|
134
141
|
urlMetadata: resolveUrlMetadata(),
|
|
142
|
+
mentions,
|
|
135
143
|
});
|
|
136
144
|
setListUploadFiles([]);
|
|
137
145
|
return true;
|
|
@@ -154,6 +162,7 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
154
162
|
currentSession: sessionToUse,
|
|
155
163
|
isInternal: pending.isInternal,
|
|
156
164
|
urlMetadata: pending.urlMetadata,
|
|
165
|
+
mentions: pending.mentions,
|
|
157
166
|
});
|
|
158
167
|
setListUploadFiles([]);
|
|
159
168
|
pendingMessageRef.current = null;
|
|
@@ -206,6 +215,9 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
206
215
|
}
|
|
207
216
|
closeCanned();
|
|
208
217
|
};
|
|
218
|
+
if (isViewOnlyMember) {
|
|
219
|
+
return (_jsx("div", { "data-testid": "message-footer-view-only", className: "flex w-full items-center justify-center border-t border-gray-25 bg-white px-4 py-3 text-center text-sm text-gray-500", children: tConversationInbox("thread_detail.view_only_notice") }));
|
|
220
|
+
}
|
|
209
221
|
return (_jsxs(MessageFooterContext.Provider, { value: {
|
|
210
222
|
onSendMessage,
|
|
211
223
|
isInternal,
|
|
@@ -218,8 +230,10 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
218
230
|
setActiveCannedIndex,
|
|
219
231
|
maxActiveCannedIndex,
|
|
220
232
|
setMaxActiveCannedIndex,
|
|
233
|
+
isMentionMenuOpen,
|
|
234
|
+
setIsMentionMenuOpen,
|
|
221
235
|
}, children: [_jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Popover, { open: isOpenCanned, content: _jsx(CannedResponse, { onClose: closeCanned, openCreateCannedModal: onOpenCreateCannedModal, cannedQuery: cannedQuery }), placement: "topLeft", trigger: "click", arrow: false, classNames: {
|
|
222
236
|
body: "mx-1 !p-0",
|
|
223
|
-
}, destroyOnHidden: true, children: _jsxs("div", { className: "border-t pb-2 flex flex-col gap-1 bg-white", children: [_jsx(ReplyPreviewBar, {}), listUploadFiles.length > 0 && _jsx(FilePreview, {}), showLinkPreview && previewUrl && (_jsx(LinkInputPreview, { url: previewUrl, onRemove: () => setIsLinkPreviewDismissed(true) })), _jsx(ToolbarPlugin, {}), _jsxs("div", { children: [_jsx(ComposerTabs, { canUseInternal: canUseInternal, hintText: t("canned_response_hint"), isInternal: isInternal, lockToInternal: lockToInternal, setIsInternal: setIsInternal }), _jsx(ComposerEditor, { isInternal: isInternal, placeholderText: placeholderText })] }), _jsx(ActionBar, {})] }) }), _jsx(LinkPlugin, {}), _jsx(ListPlugin, {}), _jsx(ComposerTextSyncPlugin, { onChange: setComposerText }), _jsx(EnterHandler, {}), _jsx(PasteAndDropPlugin, {}), isCrm && (_jsx(CannedResponseTriggerPlugin, { onClose: closeCanned, onOpen: onOpenCanned }))] }), _jsx(SessionClosedModal, { open: isSessionClosedModalOpen, loading: isSessionActionLoading, onReopen: handleReopenSession, onCreateNew: handleCreateNewSession, onClose: handleCloseSessionModal })] }));
|
|
237
|
+
}, destroyOnHidden: true, children: _jsxs("div", { className: "border-t pb-2 flex flex-col gap-1 bg-white", children: [_jsx(ReplyPreviewBar, {}), listUploadFiles.length > 0 && _jsx(FilePreview, {}), showLinkPreview && previewUrl && (_jsx(LinkInputPreview, { url: previewUrl, onRemove: () => setIsLinkPreviewDismissed(true) })), _jsx(ToolbarPlugin, {}), _jsxs("div", { children: [_jsx(ComposerTabs, { canUseInternal: canUseInternal, hintText: t("canned_response_hint"), isInternal: isInternal, lockToInternal: lockToInternal, setIsInternal: setIsInternal }), _jsx(ComposerEditor, { isInternal: isInternal, placeholderText: placeholderText })] }), _jsx(ActionBar, {})] }) }), _jsx(LinkPlugin, {}), _jsx(ListPlugin, {}), _jsx(ComposerTextSyncPlugin, { onChange: setComposerText }), _jsx(EnterHandler, {}), _jsx(PasteAndDropPlugin, {}), isGroupConversation(conversationData !== null && conversationData !== void 0 ? conversationData : undefined) && (_jsx(MentionMenu, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID })), isCrm && (_jsx(CannedResponseTriggerPlugin, { onClose: closeCanned, onOpen: onOpenCanned }))] }), _jsx(SessionClosedModal, { open: isSessionClosedModalOpen, loading: isSessionActionLoading, onReopen: handleReopenSession, onCreateNew: handleCreateNewSession, onClose: handleCloseSessionModal })] }));
|
|
224
238
|
};
|
|
225
239
|
export default MessageFooterProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionMenu.d.ts","sourceRoot":"","sources":["../../../../../src/components/message/footer/mention/MentionMenu.tsx"],"names":[],"mappings":"AA0BA,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,QAAA,MAAM,WAAW,GAAI,aAAa,gBAAgB,mDAqGjD,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
6
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
7
|
+
import { LexicalTypeaheadMenuPlugin, MenuOption, useBasicTypeaheadTriggerMatch, } from "@lexical/react/LexicalTypeaheadMenuPlugin";
|
|
8
|
+
import { $createTextNode } from "lexical";
|
|
9
|
+
import { $createMentionNode } from "./MentionNode";
|
|
10
|
+
import { useMentionOptions } from "./useMentionOptions";
|
|
11
|
+
import { Avatar } from "antd";
|
|
12
|
+
import { useMessageFooterContext } from "..";
|
|
13
|
+
class MentionTypeaheadOption extends MenuOption {
|
|
14
|
+
constructor(option) {
|
|
15
|
+
super(option.userID);
|
|
16
|
+
this.option = option;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const MentionMenu = ({ groupID }) => {
|
|
20
|
+
const { t } = useTranslation();
|
|
21
|
+
const [editor] = useLexicalComposerContext();
|
|
22
|
+
const [query, setQuery] = useState(null);
|
|
23
|
+
const { setIsMentionMenuOpen } = useMessageFooterContext();
|
|
24
|
+
const checkForMentionMatch = useBasicTypeaheadTriggerMatch("@", {
|
|
25
|
+
minLength: 0,
|
|
26
|
+
});
|
|
27
|
+
const options = useMentionOptions(groupID, query !== null && query !== void 0 ? query : "");
|
|
28
|
+
const typeaheadOptions = useMemo(() => options.map((option) => new MentionTypeaheadOption(option)), [options]);
|
|
29
|
+
const onSelectOption = useCallback((selected, textNodeContainingQuery, closeMenu) => {
|
|
30
|
+
editor.update(() => {
|
|
31
|
+
const mentionNode = $createMentionNode(selected.option.userID, selected.option.isAtAll, `@${selected.option.displayName}`);
|
|
32
|
+
if (textNodeContainingQuery) {
|
|
33
|
+
textNodeContainingQuery.replace(mentionNode);
|
|
34
|
+
}
|
|
35
|
+
// Trailing space detaches the cursor from the segmented mention
|
|
36
|
+
// node — without it, typing right after would extend/replace it.
|
|
37
|
+
const spaceNode = $createTextNode(" ");
|
|
38
|
+
mentionNode.insertAfter(spaceNode);
|
|
39
|
+
spaceNode.select();
|
|
40
|
+
});
|
|
41
|
+
closeMenu();
|
|
42
|
+
}, [editor]);
|
|
43
|
+
if (!groupID)
|
|
44
|
+
return null;
|
|
45
|
+
return (_jsx(LexicalTypeaheadMenuPlugin, { onQueryChange: setQuery, onSelectOption: onSelectOption, onOpen: () => setIsMentionMenuOpen(true), onClose: () => setIsMentionMenuOpen(false), triggerFn: checkForMentionMatch, options: typeaheadOptions, menuRenderFn: (anchorElementRef, { selectedIndex, setHighlightedIndex, selectOptionAndCleanUp }) => {
|
|
46
|
+
if (!anchorElementRef.current)
|
|
47
|
+
return null;
|
|
48
|
+
return createPortal(_jsxs("div", { "data-cp-name": "MentionMenu", className: "z-50 max-h-[220px] w-[260px] overflow-y-auto rounded-md border border-gray-200 bg-white py-1 shadow-lg", children: [_jsx("div", { className: "px-3 py-1 text-xs font-medium text-gray-400", children: t("mention.menu_title") }), typeaheadOptions.length === 0 ? (_jsx("div", { className: "px-3 py-2 text-sm text-gray-500", children: t("mention.no_result") })) : (typeaheadOptions.map((option, index) => (_jsxs("button", { type: "button", className: `flex w-full items-center gap-2 px-3 py-2 text-left text-sm ${index === selectedIndex ? "bg-blue-50" : "hover:bg-gray-50"}`, onMouseEnter: () => setHighlightedIndex(index), onClick: () => selectOptionAndCleanUp(option), children: [option.option.isAtAll ? (_jsx("span", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-gray-100 text-gray-500", children: "@" })) : (_jsx(Avatar, { size: 24, src: option.option.faceURL, children: option.option.displayName.charAt(0) })), _jsx("span", { className: "min-w-0 flex-1 truncate", children: option.option.displayName })] }, option.key))))] }), anchorElementRef.current);
|
|
49
|
+
} }));
|
|
50
|
+
};
|
|
51
|
+
export default MentionMenu;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { TextNode, type EditorConfig, type LexicalNode, type NodeKey, type SerializedTextNode, type Spread } from "lexical";
|
|
2
|
+
export type SerializedMentionNode = Spread<{
|
|
3
|
+
userID: string;
|
|
4
|
+
isAtAll: boolean;
|
|
5
|
+
}, SerializedTextNode>;
|
|
6
|
+
export declare class MentionNode extends TextNode {
|
|
7
|
+
__userID: string;
|
|
8
|
+
__isAtAll: boolean;
|
|
9
|
+
static getType(): string;
|
|
10
|
+
static clone(node: MentionNode): MentionNode;
|
|
11
|
+
constructor(userID: string, isAtAll: boolean, text: string, key?: NodeKey);
|
|
12
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
13
|
+
static importJSON(serializedNode: SerializedMentionNode): MentionNode;
|
|
14
|
+
exportJSON(): SerializedMentionNode;
|
|
15
|
+
canInsertTextBefore(): boolean;
|
|
16
|
+
isTextEntity(): true;
|
|
17
|
+
}
|
|
18
|
+
export declare function $createMentionNode(userID: string, isAtAll: boolean, displayText: string): MentionNode;
|
|
19
|
+
export declare function $isMentionNode(node: LexicalNode | null | undefined): node is MentionNode;
|
|
20
|
+
//# sourceMappingURL=MentionNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionNode.d.ts","sourceRoot":"","sources":["../../../../../src/components/message/footer/mention/MentionNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACvB,KAAK,MAAM,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,qBAAqB,GAAG,MAAM,CACxC;IACE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,EACD,kBAAkB,CACnB,CAAC;AAEF,qBAAa,WAAY,SAAQ,QAAQ;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IAEnB,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW;gBAU1C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,OAAO;IAOf,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAM5C,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,qBAAqB,GAAG,WAAW;IAQrE,UAAU,IAAI,qBAAqB;IASnC,mBAAmB,IAAI,OAAO;IAI9B,YAAY,IAAI,IAAI;CAGrB;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,GAClB,WAAW,CAIb;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACnC,IAAI,IAAI,WAAW,CAErB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { $applyNodeReplacement, TextNode, } from "lexical";
|
|
2
|
+
export class MentionNode extends TextNode {
|
|
3
|
+
static getType() {
|
|
4
|
+
return "mention";
|
|
5
|
+
}
|
|
6
|
+
static clone(node) {
|
|
7
|
+
return new MentionNode(node.__userID, node.__isAtAll, node.__text, node.__key);
|
|
8
|
+
}
|
|
9
|
+
constructor(userID, isAtAll, text, key) {
|
|
10
|
+
super(text, key);
|
|
11
|
+
this.__userID = userID;
|
|
12
|
+
this.__isAtAll = isAtAll;
|
|
13
|
+
}
|
|
14
|
+
createDOM(config) {
|
|
15
|
+
const dom = super.createDOM(config);
|
|
16
|
+
dom.className = "text-blue-500 font-medium";
|
|
17
|
+
return dom;
|
|
18
|
+
}
|
|
19
|
+
static importJSON(serializedNode) {
|
|
20
|
+
return $createMentionNode(serializedNode.userID, serializedNode.isAtAll, serializedNode.text).updateFromJSON(serializedNode);
|
|
21
|
+
}
|
|
22
|
+
exportJSON() {
|
|
23
|
+
return Object.assign(Object.assign({}, super.exportJSON()), { userID: this.__userID, isAtAll: this.__isAtAll, type: "mention" });
|
|
24
|
+
}
|
|
25
|
+
canInsertTextBefore() {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
isTextEntity() {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function $createMentionNode(userID, isAtAll, displayText) {
|
|
33
|
+
const node = new MentionNode(userID, isAtAll, displayText);
|
|
34
|
+
node.setMode("segmented").toggleDirectionless();
|
|
35
|
+
return $applyNodeReplacement(node);
|
|
36
|
+
}
|
|
37
|
+
export function $isMentionNode(node) {
|
|
38
|
+
return node instanceof MentionNode;
|
|
39
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type LexicalEditor } from "lexical";
|
|
2
|
+
import type { MentionSendPayload } from "../../../../types/chat";
|
|
3
|
+
declare const ALL_MEMBERS_USER_ID = "__all__";
|
|
4
|
+
export declare const extractMentions: (editor: LexicalEditor) => MentionSendPayload;
|
|
5
|
+
export { ALL_MEMBERS_USER_ID };
|
|
6
|
+
//# sourceMappingURL=extractMentions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractMentions.d.ts","sourceRoot":"","sources":["../../../../../src/components/message/footer/mention/extractMentions.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD,QAAA,MAAM,mBAAmB,YAAY,CAAC;AA2DtC,eAAO,MAAM,eAAe,GAAI,QAAQ,aAAa,KAAG,kBAavD,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { $getRoot, $isElementNode, } from "lexical";
|
|
2
|
+
import { $isMentionNode } from "./MentionNode";
|
|
3
|
+
const ALL_MEMBERS_USER_ID = "__all__";
|
|
4
|
+
// Single pass, mirroring ElementNode.getTextContent()'s own join logic
|
|
5
|
+
// (child text content, plus a double line break between non-inline block
|
|
6
|
+
// children) so offsets always match the plainText Lexical actually
|
|
7
|
+
// produces. One pass — not a separate node-collection step — so the
|
|
8
|
+
// offsets and the atUserIDList/atUsersInfo they describe can never drift
|
|
9
|
+
// out of sync with each other.
|
|
10
|
+
const walk = (node, state) => {
|
|
11
|
+
if ($isMentionNode(node)) {
|
|
12
|
+
const text = node.getTextContent();
|
|
13
|
+
if (node.__isAtAll) {
|
|
14
|
+
state.payload.isAtAll = true;
|
|
15
|
+
state.payload.mentionOffsets.push({
|
|
16
|
+
userID: ALL_MEMBERS_USER_ID,
|
|
17
|
+
offset: state.offset,
|
|
18
|
+
length: text.length,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
state.payload.atUserIDList.push(node.__userID);
|
|
23
|
+
state.payload.atUsersInfo.push({
|
|
24
|
+
atUserID: node.__userID,
|
|
25
|
+
groupNickname: text.replace(/^@/, ""),
|
|
26
|
+
});
|
|
27
|
+
state.payload.mentionOffsets.push({
|
|
28
|
+
userID: node.__userID,
|
|
29
|
+
offset: state.offset,
|
|
30
|
+
length: text.length,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
state.offset += text.length;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!$isElementNode(node)) {
|
|
37
|
+
state.offset += node.getTextContent().length;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const children = node.getChildren();
|
|
41
|
+
children.forEach((child, index) => {
|
|
42
|
+
walk(child, state);
|
|
43
|
+
const isLastChild = index === children.length - 1;
|
|
44
|
+
if ($isElementNode(child) && !isLastChild && !child.isInline()) {
|
|
45
|
+
state.offset += 2; // DOUBLE_LINE_BREAK
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
// Reads MentionNode instances straight from the editor state at send time —
|
|
50
|
+
// only list-selected mentions become MentionNode, so free-typed "@text"
|
|
51
|
+
// stays plain TextNode and is naturally excluded (BR-002). Offsets are
|
|
52
|
+
// captured here because this is the only point with real node identity —
|
|
53
|
+
// once sent, AtTextElem collapses everything into a flat string.
|
|
54
|
+
export const extractMentions = (editor) => {
|
|
55
|
+
const payload = {
|
|
56
|
+
atUserIDList: [],
|
|
57
|
+
atUsersInfo: [],
|
|
58
|
+
isAtAll: false,
|
|
59
|
+
mentionOffsets: [],
|
|
60
|
+
};
|
|
61
|
+
editor.getEditorState().read(() => {
|
|
62
|
+
walk($getRoot(), { offset: 0, payload });
|
|
63
|
+
});
|
|
64
|
+
return payload;
|
|
65
|
+
};
|
|
66
|
+
export { ALL_MEMBERS_USER_ID };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface MentionOption {
|
|
2
|
+
userID: string;
|
|
3
|
+
displayName: string;
|
|
4
|
+
faceURL?: string;
|
|
5
|
+
isAtAll: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const useMentionOptions: (groupID: string | undefined, query: string) => MentionOption[];
|
|
8
|
+
//# sourceMappingURL=useMentionOptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMentionOptions.d.ts","sourceRoot":"","sources":["../../../../../src/components/message/footer/mention/useMentionOptions.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAaD,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,GAAG,SAAS,EAC3B,OAAO,MAAM,KACZ,aAAa,EAuCf,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useTranslation } from "react-i18next";
|
|
3
|
+
import { useGroupMembers } from "../../../../hooks/group/useGroupMembers";
|
|
4
|
+
const ALL_MEMBERS_USER_ID = "__all__";
|
|
5
|
+
// Prefix matches rank above mid-string matches, then alphabetical — matches
|
|
6
|
+
// the "closest match first" ranking spec'd for this feature (not just a
|
|
7
|
+
// plain filter). No keyword: falls back to plain A-Z (AC-Open default).
|
|
8
|
+
const matchRank = (displayName, keyword) => {
|
|
9
|
+
const lower = displayName.toLowerCase();
|
|
10
|
+
if (lower.startsWith(keyword))
|
|
11
|
+
return 0;
|
|
12
|
+
return 1;
|
|
13
|
+
};
|
|
14
|
+
export const useMentionOptions = (groupID, query) => {
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const { members } = useGroupMembers(groupID);
|
|
17
|
+
return useMemo(() => {
|
|
18
|
+
const keyword = query.trim().toLowerCase();
|
|
19
|
+
// Self-tagging is a valid, ordinary mention target per spec — the
|
|
20
|
+
// sender selecting their own name is processed like any other tag.
|
|
21
|
+
const memberOptions = members
|
|
22
|
+
.map((member) => ({
|
|
23
|
+
userID: member.userID,
|
|
24
|
+
displayName: member.nickname || member.userID,
|
|
25
|
+
faceURL: member.faceURL,
|
|
26
|
+
isAtAll: false,
|
|
27
|
+
}))
|
|
28
|
+
.filter((option) => keyword ? option.displayName.toLowerCase().includes(keyword) : true)
|
|
29
|
+
.sort((a, b) => {
|
|
30
|
+
if (!keyword)
|
|
31
|
+
return a.displayName.localeCompare(b.displayName);
|
|
32
|
+
const rankDiff = matchRank(a.displayName, keyword) - matchRank(b.displayName, keyword);
|
|
33
|
+
return rankDiff !== 0
|
|
34
|
+
? rankDiff
|
|
35
|
+
: a.displayName.localeCompare(b.displayName);
|
|
36
|
+
});
|
|
37
|
+
const allOption = {
|
|
38
|
+
userID: ALL_MEMBERS_USER_ID,
|
|
39
|
+
displayName: t("mention.all_members"),
|
|
40
|
+
isAtAll: true,
|
|
41
|
+
};
|
|
42
|
+
const matchesAll = !keyword || allOption.displayName.toLowerCase().includes(keyword);
|
|
43
|
+
return matchesAll ? [allOption, ...memberOptions] : memberOptions;
|
|
44
|
+
}, [members, query, t]);
|
|
45
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MessageItem } from "@droppii-org/wasm-client-sdk";
|
|
2
|
+
import type { MentionOffset } from "../../../types/chat";
|
|
3
|
+
interface AtTextMessageItemProps {
|
|
4
|
+
message: MessageItem;
|
|
5
|
+
}
|
|
6
|
+
export declare const splitByMentions: (text: string, mentionLabels: string[]) => Array<{
|
|
7
|
+
text: string;
|
|
8
|
+
isMention: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const splitByOffsets: (text: string, offsets: MentionOffset[]) => Array<{
|
|
11
|
+
text: string;
|
|
12
|
+
isMention: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
declare const AtTextMessageItem: (props: AtTextMessageItemProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
15
|
+
export default AtTextMessageItem;
|
|
16
|
+
//# sourceMappingURL=AtTextMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AtTextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/AtTextMessage.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAM3D,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,cAAc,CAAC;AAErE,UAAU,sBAAsB;IAC9B,OAAO,EAAE,WAAW,CAAC;CACtB;AAOD,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,eAAe,MAAM,EAAE,KACtB,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAmC5C,CAAC;AAKF,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,SAAS,aAAa,EAAE,KACvB,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAmB5C,CAAC;AAaF,QAAA,MAAM,iBAAiB,GAAI,OAAO,sBAAsB,mDAyDvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Fragment } from "react";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import { extractLinkUrls } from "../../../utils/link";
|
|
6
|
+
import LinkText from "./LinkText";
|
|
7
|
+
import { MESSAGE_TEXT_CLASS } from "./textStyle";
|
|
8
|
+
import { useTranslation } from "react-i18next";
|
|
9
|
+
import { AT_ALL_TAG } from "../../../hooks/message/useSendMessage";
|
|
10
|
+
// AtTextElem has no offset/index, so mentions are recovered by matching
|
|
11
|
+
// "@displayName" text: longest-label-first (avoids "@Anna" being cut short
|
|
12
|
+
// by "@An"), each label consumed only as many times as it's really mentioned.
|
|
13
|
+
// Residual gap (accepted, tracked as follow-up): coincidental "@name" text
|
|
14
|
+
// before the real mention can still be mis-highlighted — needs SDK offsets.
|
|
15
|
+
export const splitByMentions = (text, mentionLabels) => {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
if (mentionLabels.length === 0)
|
|
18
|
+
return [{ text, isMention: false }];
|
|
19
|
+
const remainingCount = new Map();
|
|
20
|
+
for (const label of mentionLabels) {
|
|
21
|
+
remainingCount.set(label, ((_a = remainingCount.get(label)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
22
|
+
}
|
|
23
|
+
const sortedLabels = [...remainingCount.keys()].sort((a, b) => b.length - a.length);
|
|
24
|
+
const segments = [];
|
|
25
|
+
let cursor = 0;
|
|
26
|
+
while (cursor < text.length) {
|
|
27
|
+
const match = sortedLabels
|
|
28
|
+
.filter((label) => { var _a; return ((_a = remainingCount.get(label)) !== null && _a !== void 0 ? _a : 0) > 0; })
|
|
29
|
+
.map((label) => ({ label, index: text.indexOf(label, cursor) }))
|
|
30
|
+
.filter(({ index }) => index !== -1)
|
|
31
|
+
.sort((a, b) => a.index - b.index || b.label.length - a.label.length)[0];
|
|
32
|
+
if (!match) {
|
|
33
|
+
segments.push({ text: text.slice(cursor), isMention: false });
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
if (match.index > cursor) {
|
|
37
|
+
segments.push({ text: text.slice(cursor, match.index), isMention: false });
|
|
38
|
+
}
|
|
39
|
+
segments.push({ text: match.label, isMention: true });
|
|
40
|
+
remainingCount.set(match.label, ((_b = remainingCount.get(match.label)) !== null && _b !== void 0 ? _b : 0) - 1);
|
|
41
|
+
cursor = match.index + match.label.length;
|
|
42
|
+
}
|
|
43
|
+
return segments;
|
|
44
|
+
};
|
|
45
|
+
// Exact split using real offsets recorded at compose time (`ex.mentions`) —
|
|
46
|
+
// no guessing, so it's immune to the substring/coincidental-text gap that
|
|
47
|
+
// splitByMentions has to work around for messages sent before this existed.
|
|
48
|
+
export const splitByOffsets = (text, offsets) => {
|
|
49
|
+
const segments = [];
|
|
50
|
+
const sorted = [...offsets].sort((a, b) => a.offset - b.offset);
|
|
51
|
+
let cursor = 0;
|
|
52
|
+
for (const { offset, length } of sorted) {
|
|
53
|
+
if (offset < cursor || offset + length > text.length)
|
|
54
|
+
continue; // stale/corrupt ex — skip rather than misrender
|
|
55
|
+
if (offset > cursor) {
|
|
56
|
+
segments.push({ text: text.slice(cursor, offset), isMention: false });
|
|
57
|
+
}
|
|
58
|
+
segments.push({ text: text.slice(offset, offset + length), isMention: true });
|
|
59
|
+
cursor = offset + length;
|
|
60
|
+
}
|
|
61
|
+
if (cursor < text.length) {
|
|
62
|
+
segments.push({ text: text.slice(cursor), isMention: false });
|
|
63
|
+
}
|
|
64
|
+
return segments;
|
|
65
|
+
};
|
|
66
|
+
const parseMentionOffsets = (ex) => {
|
|
67
|
+
var _a;
|
|
68
|
+
if (!ex)
|
|
69
|
+
return null;
|
|
70
|
+
try {
|
|
71
|
+
const parsed = JSON.parse(ex);
|
|
72
|
+
const offsets = (_a = parsed === null || parsed === void 0 ? void 0 : parsed.mentions) === null || _a === void 0 ? void 0 : _a.offsets;
|
|
73
|
+
return offsets && offsets.length > 0 ? offsets : null;
|
|
74
|
+
}
|
|
75
|
+
catch (_b) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const AtTextMessageItem = (props) => {
|
|
80
|
+
var _a, _b, _c;
|
|
81
|
+
const { message } = props;
|
|
82
|
+
const { t } = useTranslation();
|
|
83
|
+
const atTextElem = message === null || message === void 0 ? void 0 : message.atTextElem;
|
|
84
|
+
if (!(atTextElem === null || atTextElem === void 0 ? void 0 : atTextElem.text))
|
|
85
|
+
return null;
|
|
86
|
+
const isAtAll = (_a = atTextElem.atUserList) === null || _a === void 0 ? void 0 : _a.some((userID) => userID === AT_ALL_TAG);
|
|
87
|
+
const memberMentionLabels = (_c = (_b = atTextElem.atUsersInfo) === null || _b === void 0 ? void 0 : _b.map((info) => `@${info.groupNickname}`)) !== null && _c !== void 0 ? _c : [];
|
|
88
|
+
const urls = extractLinkUrls(atTextElem.text);
|
|
89
|
+
if (memberMentionLabels.length === 0 &&
|
|
90
|
+
!isAtAll &&
|
|
91
|
+
urls.length > 0) {
|
|
92
|
+
return _jsx(LinkText, { text: atTextElem.text });
|
|
93
|
+
}
|
|
94
|
+
const mentionOffsets = parseMentionOffsets(message === null || message === void 0 ? void 0 : message.ex);
|
|
95
|
+
let segments;
|
|
96
|
+
if (mentionOffsets) {
|
|
97
|
+
segments = splitByOffsets(atTextElem.text, mentionOffsets);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Fallback for messages sent before offsets existed (no `ex.mentions`).
|
|
101
|
+
// "Tất cả" here is matched against the viewer's live translation, not
|
|
102
|
+
// the sender's persisted string — safe only while a single locale exists.
|
|
103
|
+
const allMembersLabel = `@${t("mention.all_members")}`;
|
|
104
|
+
const mentionLabels = [
|
|
105
|
+
...memberMentionLabels,
|
|
106
|
+
...(isAtAll ? [allMembersLabel] : []),
|
|
107
|
+
];
|
|
108
|
+
segments = splitByMentions(atTextElem.text, mentionLabels);
|
|
109
|
+
}
|
|
110
|
+
return (_jsx("p", { className: clsx("min-w-0 whitespace-pre-wrap [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), children: segments.map((segment, index) => (_jsx(Fragment, { children: segment.isMention ? (_jsx("span", { className: "font-medium text-blue-500", children: segment.text })) : (segment.text) }, index))) }));
|
|
111
|
+
};
|
|
112
|
+
export default AtTextMessageItem;
|
|
@@ -22,6 +22,6 @@ const FileMessageItem = (props) => {
|
|
|
22
22
|
const handleDownload = () => {
|
|
23
23
|
downloadFileFromUrl(sourceUrl, fileName);
|
|
24
24
|
};
|
|
25
|
-
return (_jsx(Spin, { spinning: isSending, children: _jsxs("div", { className: "flex h-[51px] w-[292px] items-center gap-3 rounded-xl border border-gray-200/20 bg-white px-3 py-1", children: [_jsx("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden [&>svg]:h-6 [&>svg]:w-6", children: documentIcon }), _jsxs("div", { className: "flex min-w-0 w-[168px] flex-col justify-center", children: [_jsx("span", { className: "truncate text-[14px] font-medium leading-[160%] text-gray-900", children: shortenFileName(fileName) }), _jsx("span", { className: "truncate text-[13px] leading-[160%] text-gray-600", children: renderFileSize(fileSize) })] }), _jsxs("div", { className: "flex w-[52px] shrink-0 items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: handleView, disabled: !hasUrl, "aria-label": "Xem file", className: !hasUrl ? "opacity-30" : undefined, children: _jsx(Icon, { icon: "eye-o", size: 20, className: "text-gray-900" }) }), _jsx("button", { type: "button", onClick: handleDownload, disabled: !hasUrl, "aria-label": "T\u1EA3i xu\u1ED1ng", className: !hasUrl ? "opacity-30" : undefined, children: _jsx(Icon, { icon: "download-o", size: 20, className: "text-gray-900" }) })] })] }) }));
|
|
25
|
+
return (_jsx(Spin, { spinning: isSending, "data-cp-name": "FileMessageItem", children: _jsxs("div", { className: "flex h-[51px] w-[292px] items-center gap-3 rounded-xl border border-gray-200/20 bg-white px-3 py-1", children: [_jsx("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden [&>svg]:h-6 [&>svg]:w-6", children: documentIcon }), _jsxs("div", { className: "flex min-w-0 w-[168px] flex-col justify-center", children: [_jsx("span", { className: "truncate text-[14px] font-medium leading-[160%] text-gray-900", children: shortenFileName(fileName) }), _jsx("span", { className: "truncate text-[13px] leading-[160%] text-gray-600", children: renderFileSize(fileSize) })] }), _jsxs("div", { className: "flex w-[52px] shrink-0 items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: handleView, disabled: !hasUrl, "aria-label": "Xem file", className: !hasUrl ? "opacity-30" : undefined, children: _jsx(Icon, { icon: "eye-o", size: 20, className: "text-gray-900" }) }), _jsx("button", { type: "button", onClick: handleDownload, disabled: !hasUrl, "aria-label": "T\u1EA3i xu\u1ED1ng", className: !hasUrl ? "opacity-30" : undefined, children: _jsx(Icon, { icon: "download-o", size: 20, className: "text-gray-900" }) })] })] }) }));
|
|
26
26
|
};
|
|
27
27
|
export default FileMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupNotificationMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/GroupNotificationMessage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAI3D,UAAU,iCAAiC;IACzC,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,4BAA4B,GAAI,aAAa,iCAAiC,
|
|
1
|
+
{"version":3,"file":"GroupNotificationMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/GroupNotificationMessage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAI3D,UAAU,iCAAiC;IACzC,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,4BAA4B,GAAI,aAAa,iCAAiC,mDAkBnF,CAAC;AAEF,eAAe,4BAA4B,CAAC"}
|
|
@@ -5,9 +5,9 @@ import { getGroupNotificationText } from "../../../utils/messageLog";
|
|
|
5
5
|
const GroupNotificationMessageItem = ({ message }) => {
|
|
6
6
|
var _a;
|
|
7
7
|
const { t } = useTranslation();
|
|
8
|
-
const text = getGroupNotificationText(message.contentType, (_a = message.notificationElem) === null || _a === void 0 ? void 0 : _a.detail, t);
|
|
8
|
+
const text = getGroupNotificationText(message.contentType, (_a = message.notificationElem) === null || _a === void 0 ? void 0 : _a.detail, t, message.senderNickname);
|
|
9
9
|
if (!text)
|
|
10
10
|
return null;
|
|
11
|
-
return (_jsx("div", { className: "flex justify-center", children: _jsx("span", { className: "rounded-full bg-gray-200 px-3 py-1.5 text-center text-[13px] font-normal text-gray-900", children: text }) }));
|
|
11
|
+
return (_jsx("div", { className: "flex justify-center", "data-cp-name": "GroupNotificationMessageItem", children: _jsx("span", { className: "rounded-full bg-gray-200 px-3 py-1.5 text-center text-[13px] font-normal text-gray-900", children: text }) }));
|
|
12
12
|
};
|
|
13
13
|
export default GroupNotificationMessageItem;
|
|
@@ -17,7 +17,7 @@ const ImageMessageItem = (props) => {
|
|
|
17
17
|
snapshotHeight: (_k = pictureElem === null || pictureElem === void 0 ? void 0 : pictureElem.snapshotPicture) === null || _k === void 0 ? void 0 : _k.height,
|
|
18
18
|
});
|
|
19
19
|
const isSending = message.status === MessageStatus.Sending;
|
|
20
|
-
return (_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: "relative flex max-w-[200px] overflow-hidden rounded-xl", style: minStyle, children: _jsx(Image, { src: sourceUrl, width: minStyle.width, className: "block cursor-pointer rounded-xl object-cover", preview: {
|
|
20
|
+
return (_jsx(Spin, { spinning: isSending, "data-cp-name": "ImageMessageItem", children: _jsx("div", { className: "relative flex max-w-[200px] overflow-hidden rounded-xl", style: minStyle, children: _jsx(Image, { src: sourceUrl, width: minStyle.width, className: "block cursor-pointer rounded-xl object-cover", preview: {
|
|
21
21
|
src: bigUrl,
|
|
22
22
|
toolbarRender: (originalNode, info) => { var _a; return renderImagePreviewToolbar(originalNode, (_a = info === null || info === void 0 ? void 0 : info.image) === null || _a === void 0 ? void 0 : _a.url, t); },
|
|
23
23
|
}, placeholder: _jsx("div", { className: "flex items-center justify-center rounded-xl bg-black/10", style: minStyle, children: _jsx(Spin, {}) }) }) }) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkCard.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/LinkCard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,QAAA,MAAM,QAAQ,GAAI,mBAAmB,aAAa,
|
|
1
|
+
{"version":3,"file":"LinkCard.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/LinkCard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,QAAA,MAAM,QAAQ,GAAI,mBAAmB,aAAa,mDA8CjD,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -14,6 +14,6 @@ const LinkCard = ({ metadata, url }) => {
|
|
|
14
14
|
return;
|
|
15
15
|
openLink(url, t);
|
|
16
16
|
};
|
|
17
|
-
return (_jsxs("button", { type: "button", onClick: handleOpen, "data-testid": "link-message-card", className: "flex w-full max-w-[292px] flex-col overflow-hidden rounded-[12px] border border-gray-900/10 bg-white text-left", children: [image && (_jsx("div", { className: "aspect-[16/9] w-full overflow-hidden", children: _jsx("img", { src: image, alt: "", className: "h-full w-full object-cover" }) })), _jsxs("div", { className: "flex flex-col px-3 py-2", children: [title && (_jsx("p", { className: "truncate text-[14px] font-medium leading-[1.6] text-gray-900", children: title })), url && (_jsx("p", { className: "truncate text-[12px] font-medium leading-[1.6] tracking-[0.12px] text-primary-400", children: getHostLabel(url) })), description && (_jsx("p", { className: "line-clamp-2 text-[12px] leading-[1.6] text-gray-600", children: description }))] })] }));
|
|
17
|
+
return (_jsxs("button", { type: "button", onClick: handleOpen, "data-testid": "link-message-card", "data-cp-name": "LinkCard", className: "flex w-full max-w-[292px] flex-col overflow-hidden rounded-[12px] border border-gray-900/10 bg-white text-left", children: [image && (_jsx("div", { className: "aspect-[16/9] w-full overflow-hidden", children: _jsx("img", { src: image, alt: "", className: "h-full w-full object-cover" }) })), _jsxs("div", { className: "flex flex-col px-3 py-2", children: [title && (_jsx("p", { className: "truncate text-[14px] font-medium leading-[1.6] text-gray-900", children: title })), url && (_jsx("p", { className: "truncate text-[12px] font-medium leading-[1.6] tracking-[0.12px] text-primary-400", children: getHostLabel(url) })), description && (_jsx("p", { className: "line-clamp-2 text-[12px] leading-[1.6] text-gray-600", children: description }))] })] }));
|
|
18
18
|
};
|
|
19
19
|
export default LinkCard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkText.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/LinkText.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,QAAA,MAAM,QAAQ,GAAI,UAAU,aAAa,
|
|
1
|
+
{"version":3,"file":"LinkText.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/LinkText.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,QAAA,MAAM,QAAQ,GAAI,UAAU,aAAa,4CA4BxC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -8,6 +8,6 @@ import { MESSAGE_TEXT_CLASS } from "./textStyle";
|
|
|
8
8
|
const LinkText = ({ text }) => {
|
|
9
9
|
const { t } = useTranslation("conversation-inbox");
|
|
10
10
|
const segments = parseTextWithLinks(text);
|
|
11
|
-
return (_jsx("span", { className: clsx("min-w-0 whitespace-pre-wrap text-left [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), children: segments.map((segment, index) => segment.type === "link" ? (_jsx("button", { type: "button", onClick: () => openLink(segment.url, t), className: "inline text-left font-medium text-primary-400 underline-offset-2 hover:underline", children: segment.value }, `${segment.url}-${index}`)) : (_jsx("span", { children: segment.value }, `text-${index}`))) }));
|
|
11
|
+
return (_jsx("span", { className: clsx("min-w-0 whitespace-pre-wrap text-left [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), "data-cp-name": "LinkText", children: segments.map((segment, index) => segment.type === "link" ? (_jsx("button", { type: "button", onClick: () => openLink(segment.url, t), className: "inline text-left font-medium text-primary-400 underline-offset-2 hover:underline", children: segment.value }, `${segment.url}-${index}`)) : (_jsx("span", { children: segment.value }, `text-${index}`))) }));
|
|
12
12
|
};
|
|
13
13
|
export default LinkText;
|
|
@@ -16,7 +16,7 @@ const MergeImageMessageItem = (props) => {
|
|
|
16
16
|
const subMessages = (_b = (_a = message.mergeElem) === null || _a === void 0 ? void 0 : _a.multiMessage) !== null && _b !== void 0 ? _b : [];
|
|
17
17
|
const isSending = message.status === MessageStatus.Sending;
|
|
18
18
|
const cols = Math.min(subMessages.length, 3);
|
|
19
|
-
return (_jsx("div", { className: "-mx-1", children: _jsx(Spin, { spinning: isSending, children: _jsx(Image.PreviewGroup, { preview: {
|
|
19
|
+
return (_jsx("div", { className: "-mx-1", "data-cp-name": "MergeImageMessageItem", children: _jsx(Spin, { spinning: isSending, children: _jsx(Image.PreviewGroup, { preview: {
|
|
20
20
|
toolbarRender: (originalNode, info) => { var _a; return renderImagePreviewToolbar(originalNode, (_a = info === null || info === void 0 ? void 0 : info.image) === null || _a === void 0 ? void 0 : _a.url, t); },
|
|
21
21
|
}, children: _jsx("div", { className: clsx("grid gap-1", MERGE_IMAGE_GRID_COLS_CLASS[cols]), children: subMessages.map((item) => {
|
|
22
22
|
var _a, _b, _c, _d, _e, _f;
|