@droppii-org/chat-sdk 0.3.8 → 0.4.0
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/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 +1 -1
- 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-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 +1 -1
- 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.js +1 -1
- 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 +115 -25
- 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/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/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 +9 -0
- package/dist/locales/vi/conversation-inbox.json +4 -0
- package/dist/store/auth.js +1 -1
- package/dist/store/conversation.d.ts.map +1 -1
- package/dist/store/conversation.js +93 -51
- package/dist/store/type.d.ts +6 -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/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
|
@@ -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;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/MessageBubble.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/MessageBubble.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6CD,QAAA,MAAM,aAAa,GAAI,qGAUpB,kBAAkB,4CAkEpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -8,7 +8,7 @@ const MessageBubbleTail = ({ isMine, isInternal, }) => (_jsx("div", { className:
|
|
|
8
8
|
? "text-chat-internal"
|
|
9
9
|
: isMine
|
|
10
10
|
? "text-chat-bubble-mine"
|
|
11
|
-
: "text-chat-bubble-neutral"), children: _jsx("div", { className: "flex-none", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "4", height: "18", viewBox: "0 0 4 18", fill: "none", "aria-hidden": true, children: _jsx("path", { d: isMine ? OUTGOING_TAIL_PATH : INCOMING_TAIL_PATH, fill: "currentColor", fillOpacity: "0.1" }) }) }) }));
|
|
11
|
+
: "text-chat-bubble-neutral"), "data-cp-name": "MessageBubbleTail", children: _jsx("div", { className: "flex-none", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "4", height: "18", viewBox: "0 0 4 18", fill: "none", "aria-hidden": true, children: _jsx("path", { d: isMine ? OUTGOING_TAIL_PATH : INCOMING_TAIL_PATH, fill: "currentColor", fillOpacity: "0.1" }) }) }) }));
|
|
12
12
|
const MessageBubble = ({ isMine, content, senderName, showSenderName, showTip = true, isInternal = false, id, isTransparent = false, timeLabel, }) => {
|
|
13
13
|
const showTail = showTip && !isTransparent;
|
|
14
14
|
const [timeRevealed, setTimeRevealed] = useState(false);
|
|
@@ -24,7 +24,7 @@ const MessageBubble = ({ isMine, content, senderName, showSenderName, showTip =
|
|
|
24
24
|
: isMine
|
|
25
25
|
? "bg-chat-bubble-mine/10"
|
|
26
26
|
: "bg-chat-bubble-neutral/10"));
|
|
27
|
-
return (_jsxs("div", { className: "relative flex items-end", "data-testid": "message-bubble", onClick: () => {
|
|
27
|
+
return (_jsxs("div", { className: "relative flex items-end", "data-testid": "message-bubble", "data-cp-name": "MessageBubble", onClick: () => {
|
|
28
28
|
if (!showTip && timeLabel)
|
|
29
29
|
setTimeRevealed((prev) => !prev);
|
|
30
30
|
}, children: [!isMine && showTail && (_jsx(MessageBubbleTail, { isMine: isMine, isInternal: isInternal })), _jsx("div", { className: bubbleClass, id: id, children: _jsxs("div", { className: clsx("flex flex-col gap-1", !isTransparent && "px-1"), children: [showSenderName && senderName && (_jsx("span", { className: "text-[12px] font-medium leading-[160%] tracking-[0.12px] text-gray-400", children: senderName })), _jsx("div", { className: "flex flex-col gap-2", children: content })] }) }), isMine && showTail && (_jsx(MessageBubbleTail, { isMine: isMine, isInternal: isInternal })), showTimeLabel && (_jsx("span", { "data-testid": "message-time-label", className: clsx("absolute -bottom-2 flex h-[19px] w-[30px] items-center justify-center rounded-full bg-white text-[10px] text-gray-400 shadow-sm", isMine ? "right-1" : "left-1"), children: timeLabel }))] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuoteMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/QuoteMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,UAAU,qBAAqB;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,QAAA,MAAM,gBAAgB,GAAI,mCAGvB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"QuoteMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/QuoteMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,UAAU,qBAAqB;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,QAAA,MAAM,gBAAgB,GAAI,mCAGvB,qBAAqB,mDAmDvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -36,6 +36,6 @@ const QuoteMessageItem = ({ message, onPressQuoteMessage, }) => {
|
|
|
36
36
|
name: quoteMessage.senderNickname,
|
|
37
37
|
id: quoteMessage.sendID,
|
|
38
38
|
});
|
|
39
|
-
return (_jsx("div", { className: "flex cursor-pointer items-center overflow-hidden rounded-r-xl bg-white/70", onClick: () => onPressQuoteMessage === null || onPressQuoteMessage === void 0 ? void 0 : onPressQuoteMessage(quoteMessage.clientMsgID || ""), children: _jsx(ReplyQuoteContent, { message: quoteMessage, title: title }) }));
|
|
39
|
+
return (_jsx("div", { className: "flex cursor-pointer items-center overflow-hidden rounded-r-xl bg-white/70", onClick: () => onPressQuoteMessage === null || onPressQuoteMessage === void 0 ? void 0 : onPressQuoteMessage(quoteMessage.clientMsgID || ""), "data-cp-name": "QuoteMessageItem", children: _jsx(ReplyQuoteContent, { message: quoteMessage, title: title }) }));
|
|
40
40
|
};
|
|
41
41
|
export default QuoteMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevokeMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/RevokeMessage.tsx"],"names":[],"mappings":"AAIA,UAAU,sBAAsB;CAAG;AACnC,QAAA,MAAM,iBAAiB,GAAI,GAAG,sBAAsB,
|
|
1
|
+
{"version":3,"file":"RevokeMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/RevokeMessage.tsx"],"names":[],"mappings":"AAIA,UAAU,sBAAsB;CAAG;AACnC,QAAA,MAAM,iBAAiB,GAAI,GAAG,sBAAsB,4CAWnD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -3,6 +3,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useTranslation } from "react-i18next";
|
|
4
4
|
const RevokeMessageItem = (_) => {
|
|
5
5
|
const { t } = useTranslation();
|
|
6
|
-
return (_jsx("span", { className: "whitespace-pre-wrap text-[16px] leading-[160%] italic text-gray-500", children: t("revoked") }));
|
|
6
|
+
return (_jsx("span", { className: "whitespace-pre-wrap text-[16px] leading-[160%] italic text-gray-500", "data-cp-name": "RevokeMessageItem", children: t("revoked") }));
|
|
7
7
|
};
|
|
8
8
|
export default RevokeMessageItem;
|
|
@@ -13,6 +13,6 @@ const VideoMessageItem = (props) => {
|
|
|
13
13
|
snapshotHeight: videoElem === null || videoElem === void 0 ? void 0 : videoElem.snapshotHeight,
|
|
14
14
|
});
|
|
15
15
|
const isSending = message.status === MessageStatus.Sending;
|
|
16
|
-
return (_jsx(Spin, { spinning: isSending, children: _jsx("div", { className: "relative max-w-[200px] overflow-hidden rounded-xl", style: minStyle, children: _jsx("video", { src: videoUrl, poster: posterUrl, controls: true, className: "block rounded-xl object-cover", style: { width: minStyle.width } }) }) }));
|
|
16
|
+
return (_jsx(Spin, { spinning: isSending, "data-cp-name": "VideoMessageItem", children: _jsx("div", { className: "relative max-w-[200px] overflow-hidden rounded-xl", style: minStyle, children: _jsx("video", { src: videoUrl, poster: posterUrl, controls: true, className: "block rounded-xl object-cover", style: { width: minStyle.width } }) }) }));
|
|
17
17
|
};
|
|
18
18
|
export default VideoMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,WAAW,IAAI,eAAe,EAG/B,MAAM,8BAA8B,CAAC;AAmCtC,UAAU,gBAAgB;IACxB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACpD,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,WAAW,IAAI,eAAe,EAG/B,MAAM,8BAA8B,CAAC;AAmCtC,UAAU,gBAAgB;IACxB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACpD,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA0BD,QAAA,MAAM,WAAW,GAAI,qMAalB,gBAAgB,mDA+SlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -28,7 +28,7 @@ const GROUPING_GAP_MINUTES = 5;
|
|
|
28
28
|
const isOrderMessage = (message) => { var _a; return ((_a = message === null || message === void 0 ? void 0 : message.customElem) === null || _a === void 0 ? void 0 : _a.extension) === CustomMessageType.Order; };
|
|
29
29
|
const MessageAvatar = ({ avatarUrl, senderNickname, }) => {
|
|
30
30
|
var _a;
|
|
31
|
-
return (_jsx(Avatar, { size: MESSAGE_AVATAR_SIZE, src: avatarUrl, className: "shrink-0 self-end", children: ((_a = senderNickname === null || senderNickname === void 0 ? void 0 : senderNickname.charAt) === null || _a === void 0 ? void 0 : _a.call(senderNickname, 0)) || "A" }));
|
|
31
|
+
return (_jsx(Avatar, { size: MESSAGE_AVATAR_SIZE, src: avatarUrl, className: "shrink-0 self-end", "data-cp-name": "MessageAvatar", children: ((_a = senderNickname === null || senderNickname === void 0 ? void 0 : senderNickname.charAt) === null || _a === void 0 ? void 0 : _a.call(senderNickname, 0)) || "A" }));
|
|
32
32
|
};
|
|
33
33
|
const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip = false, contextMenuOpen, onContextMenuOpenChange, onRevokeMessage, onQuoteMessage, onPressQuoteMessage, onPinMessage, onUnpinMessage, enableLongPress = false, }) => {
|
|
34
34
|
var _a;
|
|
@@ -152,7 +152,7 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
152
152
|
const showAvatar = showPeerInfo && !isMine && !nextSameUser;
|
|
153
153
|
const showSenderName = showPeerInfo && !isMine && !prevSameUser;
|
|
154
154
|
const showTip = forceHideTip ? false : !nextSameUser;
|
|
155
|
-
if (isMessageHiddenForViewer(message, isCrm)) {
|
|
155
|
+
if (isMessageHiddenForViewer(message, isCrm, conversationData !== null && conversationData !== void 0 ? conversationData : undefined)) {
|
|
156
156
|
return null;
|
|
157
157
|
}
|
|
158
158
|
const messageContainerProps = {
|
|
@@ -174,7 +174,7 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
174
174
|
const showPinnedBadge = Boolean(message === null || message === void 0 ? void 0 : message.isPinned);
|
|
175
175
|
const pinnedBadgeNode = showPinnedBadge ? (_jsx("span", { "data-testid": "message-pinned-badge", className: clsx("absolute -top-2.5 z-[1] flex h-[22px] w-[26px] items-center justify-center rounded-full border border-white bg-gray-25", isMine ? "left-0" : "right-0"), children: _jsx(Icon, { icon: "thumbtack-b", size: 12, className: "text-primary-400" }) })) : null;
|
|
176
176
|
const wrappedBubble = hasContextMenu ? (_jsx(Dropdown, { menu: { items: contextMenuItems }, trigger: ["contextMenu"], open: contextMenuOpen, onOpenChange: onContextMenuOpenChange, overlayClassName: MESSAGE_TOOLBOX_OVERLAY_CLASSNAME, children: _jsxs("div", { ref: bubbleWrapperRef, className: "relative min-w-0", children: [bubbleNode, pinnedBadgeNode] }) })) : (_jsxs("div", { className: "relative min-w-0", children: [bubbleNode, pinnedBadgeNode] }));
|
|
177
|
-
return (_createElement("div", Object.assign({}, messageContainerProps, { key: message === null || message === void 0 ? void 0 : message.clientMsgID }),
|
|
177
|
+
return (_createElement("div", Object.assign({}, messageContainerProps, { key: message === null || message === void 0 ? void 0 : message.clientMsgID, "data-cp-name": "MessageItem" }),
|
|
178
178
|
timeBreakNode,
|
|
179
179
|
_jsxs("div", { className: clsx("flex min-w-0 items-end gap-1", isMine ? "justify-end pl-12 pr-3" : "justify-start pl-3 pr-12"), children: [!isMine &&
|
|
180
180
|
showPeerInfo &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderMessageContent.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/renderMessageContent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,eAAe,EAAe,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"renderMessageContent.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/renderMessageContent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,eAAe,EAAe,MAAM,8BAA8B,CAAC;AAe3F,eAAO,MAAM,mBAAmB,GAAI,SAAS,eAAe,4CA8C3D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,eAAe,EACxB,sBAAsB,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,4CAwBpD,CAAC"}
|