@droppii-org/chat-sdk 0.1.66 → 0.1.68
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/conversation-detail/PinnedMessageBar.d.ts.map +1 -1
- package/dist/components/conversation-detail/PinnedMessageBar.js +11 -4
- package/dist/components/conversation-detail/PinnedMessagesPanel.js +1 -1
- package/dist/components/conversation-inbox/ConversationInboxItem.d.ts.map +1 -1
- package/dist/components/conversation-inbox/ConversationInboxItem.js +2 -2
- package/dist/components/message/item/CustomMessage.d.ts +7 -0
- package/dist/components/message/item/CustomMessage.d.ts.map +1 -0
- package/dist/components/message/item/CustomMessage.js +26 -0
- package/dist/components/message/item/TextMessage.d.ts.map +1 -1
- package/dist/components/message/item/TextMessage.js +0 -6
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +6 -51
- 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/ReplyQuoteContent.d.ts.map +1 -1
- package/dist/components/message/reply/ReplyQuoteContent.js +1 -1
- package/dist/components/message/toolbox/MessageToolboxMenu.js +1 -1
- package/dist/components/message/toolbox/types.d.ts +1 -0
- package/dist/components/message/toolbox/types.d.ts.map +1 -1
- package/dist/components/message/toolbox/types.js +1 -0
- 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 +8 -10
- package/dist/hooks/message/useMessage.d.ts +1 -0
- package/dist/hooks/message/useMessage.d.ts.map +1 -1
- package/dist/hooks/message/useMessage.js +16 -1
- package/dist/hooks/message/useRevokeMessage.d.ts +1 -0
- package/dist/hooks/message/useRevokeMessage.d.ts.map +1 -1
- package/dist/hooks/message/useRevokeMessage.js +22 -0
- package/dist/hooks/message/useSendCustomMessage.d.ts +7 -0
- package/dist/hooks/message/useSendCustomMessage.d.ts.map +1 -0
- package/dist/hooks/message/useSendCustomMessage.js +5 -0
- package/dist/hooks/message/useSendMessage.d.ts +9 -2
- package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
- package/dist/hooks/message/useSendMessage.js +49 -3
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/locales/vi/common.json +6 -1
- package/dist/store/conversation.d.ts.map +1 -1
- package/dist/store/conversation.js +6 -0
- package/dist/store/type.d.ts +3 -0
- package/dist/store/type.d.ts.map +1 -1
- package/dist/styles/global.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/chat.d.ts +5 -2
- package/dist/types/chat.d.ts.map +1 -1
- package/dist/types/chat.js +4 -4
- package/dist/types/customMessage.d.ts +25 -0
- package/dist/types/customMessage.d.ts.map +1 -0
- package/dist/types/customMessage.js +4 -0
- package/dist/utils/common.d.ts +5 -2
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +26 -11
- package/dist/utils/customMessage.d.ts +5 -0
- package/dist/utils/customMessage.d.ts.map +1 -0
- package/dist/utils/customMessage.js +36 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinnedMessageBar.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/PinnedMessageBar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PinnedMessageBar.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/PinnedMessageBar.tsx"],"names":[],"mappings":"AAgHA,QAAA,MAAM,gBAAgB,sDAyFrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
3
4
|
import clsx from "clsx";
|
|
4
5
|
import { useTranslation } from "react-i18next";
|
|
5
6
|
import { MessageType } from "@openim/wasm-client-sdk";
|
|
@@ -9,6 +10,7 @@ import useAuthStore from "../../store/auth";
|
|
|
9
10
|
import useConversationStore from "../../store/conversation";
|
|
10
11
|
import { usePinnedMessages } from "../../hooks/message/usePinnedMessages";
|
|
11
12
|
import { parseUrlMetadata } from "../../utils/common";
|
|
13
|
+
import PinnedMessagesPanel from "./PinnedMessagesPanel";
|
|
12
14
|
const PINNED_SUBTITLE_KEY_BY_TYPE = {
|
|
13
15
|
[MessageType.UrlTextMessage]: "pinned_from_link",
|
|
14
16
|
[MessageType.PictureMessage]: "pinned_from_image",
|
|
@@ -73,6 +75,7 @@ const PinnedMessageBar = () => {
|
|
|
73
75
|
const selectedConversationId = useConversationStore((state) => state.selectedConversationId);
|
|
74
76
|
const conversationId = selectedConversationId || (conversation === null || conversation === void 0 ? void 0 : conversation.conversationID) || "";
|
|
75
77
|
const { pinnedMessageList, pinnedTotalCount } = usePinnedMessages(conversationId);
|
|
78
|
+
const [isPanelOpen, setIsPanelOpen] = useState(false);
|
|
76
79
|
const latestPinnedMessage = pinnedMessageList[0];
|
|
77
80
|
if (!latestPinnedMessage)
|
|
78
81
|
return null;
|
|
@@ -80,16 +83,20 @@ const PinnedMessageBar = () => {
|
|
|
80
83
|
const senderName = isMe
|
|
81
84
|
? t("your_self")
|
|
82
85
|
: latestPinnedMessage.senderNickname || t("message_sender_unnamed");
|
|
86
|
+
const isRevoked = latestPinnedMessage.contentType === MessageType.RevokeMessage;
|
|
83
87
|
const subtitleKey = PINNED_SUBTITLE_KEY_BY_TYPE[latestPinnedMessage.contentType] ||
|
|
84
88
|
"pinned_from_text";
|
|
85
|
-
const title =
|
|
89
|
+
const title = isRevoked
|
|
90
|
+
? t("revoked")
|
|
91
|
+
: getPinnedMessageTitle(latestPinnedMessage);
|
|
86
92
|
const showTitle = !TITLE_LESS_MESSAGE_TYPES.includes(latestPinnedMessage.contentType) &&
|
|
87
93
|
Boolean(title);
|
|
88
|
-
const hasThumbnail =
|
|
94
|
+
const hasThumbnail = !isRevoked &&
|
|
95
|
+
latestPinnedMessage.contentType !== MessageType.TextMessage &&
|
|
89
96
|
latestPinnedMessage.contentType !== MessageType.QuoteMessage;
|
|
90
97
|
const hasFlushThumbnail = hasThumbnail &&
|
|
91
98
|
latestPinnedMessage.contentType !== MessageType.FileMessage;
|
|
92
99
|
const remainingPinnedCount = pinnedTotalCount - 1;
|
|
93
|
-
return (_jsxs("div", { "data-testid": "pinned-message-bar", className: clsx("flex w-full shrink-0 items-center gap-3 bg-gray-cool-25 pr-3", hasFlushThumbnail ? "py-0 pl-0" : "py-1 pl-3"), children: [hasThumbnail && _jsx(PinnedMessageThumbnail, { message: latestPinnedMessage }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [showTitle && (_jsx("p", { className: "truncate text-sm font-medium leading-[160%] text-gray-900", children: title })), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Icon, { icon: "thumbtack-b", size: 12, className: "text-primary-400" }), _jsx("p", { className: "truncate text-[13px] leading-[160%] text-gray-600", children: t(subtitleKey, { name: senderName }) })] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [remainingPinnedCount > 0 && (_jsxs("span", { className: "flex min-w-[26px] items-center justify-center rounded-full border-2 border-white bg-gradient-danger-light px-1 text-xs font-bold leading-[160%] text-white", children: ["+", remainingPinnedCount] })), _jsx(Icon, { icon: "angle-down-o", size: 20, className: "text-gray-600" })] })] }));
|
|
100
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "pinned-message-bar", role: "button", tabIndex: 0, onClick: () => setIsPanelOpen(true), className: clsx("flex w-full shrink-0 cursor-pointer items-center gap-3 bg-gray-cool-25 pr-3", hasFlushThumbnail ? "py-0 pl-0" : "py-1 pl-3"), children: [hasThumbnail && (_jsx(PinnedMessageThumbnail, { message: latestPinnedMessage })), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [showTitle && (_jsx("p", { className: "truncate text-sm font-medium leading-[160%] text-gray-900", children: title })), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Icon, { icon: "thumbtack-b", size: 12, className: "text-primary-400" }), _jsx("p", { className: "truncate text-[13px] leading-[160%] text-gray-600", children: t(subtitleKey, { name: senderName }) })] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [remainingPinnedCount > 0 && (_jsxs("span", { className: "flex min-w-[26px] items-center justify-center rounded-full border-2 border-white bg-gradient-danger-light px-1 text-xs font-bold leading-[160%] text-white", children: ["+", remainingPinnedCount] })), _jsx(Icon, { icon: "angle-down-o", size: 20, className: "text-gray-600" })] })] }), _jsx(PinnedMessagesPanel, { open: isPanelOpen, onClose: () => setIsPanelOpen(false) })] }));
|
|
94
101
|
};
|
|
95
102
|
export default PinnedMessageBar;
|
|
@@ -26,9 +26,9 @@ const PinnedMessagesPanel = ({ open, onClose }) => {
|
|
|
26
26
|
setOpenContextMenuId(null);
|
|
27
27
|
try {
|
|
28
28
|
await unpinMessage(conversationId, message.clientMsgID);
|
|
29
|
+
toastMessage.success(t("unpin_message_success"));
|
|
29
30
|
}
|
|
30
31
|
catch (error) {
|
|
31
|
-
console.error("unpinMessage failed", error);
|
|
32
32
|
toastMessage.error(t("unpin_message_failed"));
|
|
33
33
|
}
|
|
34
34
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationInboxItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-inbox/ConversationInboxItem.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ConversationInboxItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-inbox/ConversationInboxItem.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAYjE,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,OAAO,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC/C;AAQD,QAAA,MAAM,qBAAqB,GAAI,mBAAmB,0BAA0B,4CA0C3E,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -4,7 +4,7 @@ import dayjs from "dayjs";
|
|
|
4
4
|
import { useTranslation } from "react-i18next";
|
|
5
5
|
import useAuthStore from "../../store/auth";
|
|
6
6
|
import { formatTimestamp, parseLatestMessage } from "../../utils/common";
|
|
7
|
-
import {
|
|
7
|
+
import { resolvePeerBadgeLabel, resolveConversationDisplayName, } from "../../utils/conversation";
|
|
8
8
|
import { useConversationAvatarUrl } from "../../hooks/conversation/useConversationAvatarUrl";
|
|
9
9
|
import ThreadCard from "../../components/conversation/ThreadCard";
|
|
10
10
|
import ConversationPeerAvatar from "./ConversationPeerAvatar";
|
|
@@ -23,7 +23,7 @@ const ConversationInboxItem = ({ item, onClick }) => {
|
|
|
23
23
|
const displayName = resolveConversationDisplayName(item, t);
|
|
24
24
|
const avatarUrl = useConversationAvatarUrl(item);
|
|
25
25
|
const badgeLabel = resolvePeerBadgeLabel(item.peerType, t);
|
|
26
|
-
const latestMessagePreview = parseLatestMessage(item.latestMsg, currentUserId, tCommon
|
|
26
|
+
const latestMessagePreview = parseLatestMessage(item.latestMsg, currentUserId, tCommon);
|
|
27
27
|
const latestMessageTime = formatLatestMessageTime(item.latestMsgSendTime || null);
|
|
28
28
|
const unreadCount = (_a = item.unreadCount) !== null && _a !== void 0 ? _a : 0;
|
|
29
29
|
return (_jsx(ThreadCard, { testId: "conversation-inbox-thread-card", onClick: () => onClick(item), unreadCount: unreadCount, time: latestMessageTime, preview: latestMessagePreview, avatar: _jsx(ConversationPeerAvatar, { peerType: item.peerType, displayName: displayName, avatarUrl: avatarUrl, badgeLabel: badgeLabel }), title: _jsx(ConversationInboxTitle, { peerType: item.peerType, displayName: displayName, hasUnread: unreadCount > 0 }) }));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MessageItem } from "@openim/wasm-client-sdk";
|
|
2
|
+
interface CustomMessageItemProps {
|
|
3
|
+
message: MessageItem;
|
|
4
|
+
}
|
|
5
|
+
declare const CustomMessageItem: ({ message }: CustomMessageItemProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export default CustomMessageItem;
|
|
7
|
+
//# sourceMappingURL=CustomMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CustomMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/CustomMessage.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,UAAU,sBAAsB;IAC9B,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,iBAAiB,GAAI,aAAa,sBAAsB,mDAwC7D,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { useTranslation } from "react-i18next";
|
|
5
|
+
import { useChatContext } from "../../../context/ChatContext";
|
|
6
|
+
import { parseCustomMessagePayload } from "../../../utils/customMessage";
|
|
7
|
+
import { MESSAGE_TEXT_CLASS } from "./textStyle";
|
|
8
|
+
const CustomMessageItem = ({ message }) => {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
const { t } = useTranslation();
|
|
11
|
+
const { renderCustomMessage } = useChatContext();
|
|
12
|
+
const payload = parseCustomMessagePayload(message);
|
|
13
|
+
const renderedContent = renderCustomMessage === null || renderCustomMessage === void 0 ? void 0 : renderCustomMessage({ message, payload });
|
|
14
|
+
if (renderedContent) {
|
|
15
|
+
return _jsx(_Fragment, { children: renderedContent });
|
|
16
|
+
}
|
|
17
|
+
const fallbackText = ((_a = message === null || message === void 0 ? void 0 : message.textElem) === null || _a === void 0 ? void 0 : _a.content) || ((_b = message === null || message === void 0 ? void 0 : message.quoteElem) === null || _b === void 0 ? void 0 : _b.text);
|
|
18
|
+
if (fallbackText) {
|
|
19
|
+
return (_jsx("p", { className: clsx("min-w-0 whitespace-pre-wrap [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), children: fallbackText }));
|
|
20
|
+
}
|
|
21
|
+
if (!payload) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return (_jsx("p", { className: clsx("min-w-0 whitespace-pre-wrap [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), children: t("invalid_message") }));
|
|
25
|
+
};
|
|
26
|
+
export default CustomMessageItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/TextMessage.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"TextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/TextMessage.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAOtD,UAAU,oBAAoB;IAC5B,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,eAAe,GAAI,OAAO,oBAAoB,mDAgDnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import clsx from "clsx";
|
|
4
|
-
import { MessageType } from "@openim/wasm-client-sdk";
|
|
5
|
-
import useAuthStore from "../../../store/auth";
|
|
6
4
|
import { htmlHasFormatting, sanitizeHtml, stripHtml } from "../../../utils/common";
|
|
7
5
|
import { extractLinkUrls } from "../../../utils/link";
|
|
8
6
|
import LinkText from "./LinkText";
|
|
@@ -10,7 +8,6 @@ import { MESSAGE_TEXT_CLASS } from "./textStyle";
|
|
|
10
8
|
const TextMessageItem = (props) => {
|
|
11
9
|
var _a, _b, _c, _d;
|
|
12
10
|
const { message } = props;
|
|
13
|
-
const isCrm = useAuthStore((state) => state.isCrm);
|
|
14
11
|
let extendMessageInfo = null;
|
|
15
12
|
try {
|
|
16
13
|
extendMessageInfo = JSON.parse((message === null || message === void 0 ? void 0 : message.ex) || "{}");
|
|
@@ -19,9 +16,6 @@ const TextMessageItem = (props) => {
|
|
|
19
16
|
extendMessageInfo = {};
|
|
20
17
|
console.error("Failed to parse extendMessageInfo", error);
|
|
21
18
|
}
|
|
22
|
-
if ((message === null || message === void 0 ? void 0 : message.contentType) === MessageType.CustomMessage && !isCrm) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
19
|
const richHtmlContent = ((_b = (_a = extendMessageInfo === null || extendMessageInfo === void 0 ? void 0 : extendMessageInfo.messageInfo) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.content) || "";
|
|
26
20
|
if (richHtmlContent && htmlHasFormatting(richHtmlContent)) {
|
|
27
21
|
const sanitizedContent = sanitizeHtml(richHtmlContent);
|
|
@@ -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,yBAAyB,CAAC;
|
|
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,yBAAyB,CAAC;AAiCjC,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;AAeD,QAAA,MAAM,WAAW,GAAI,qMAalB,gBAAgB,mDA8QlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -1,29 +1,22 @@
|
|
|
1
1
|
import { createElement as _createElement } from "react";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import dayjs from "dayjs";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import { Dropdown, message as toastMessage } from "antd";
|
|
6
6
|
import { MessageStatus, MessageType, } from "@openim/wasm-client-sdk";
|
|
7
|
-
import TextMessageItem from "./TextMessage";
|
|
8
|
-
import ImageMessageItem from "./ImageMessage";
|
|
9
|
-
import FileMessageItem from "./FileMessage";
|
|
10
|
-
import VideoMessageItem from "./VideoMessage";
|
|
11
|
-
import MergeImageMessageItem from "./MergeImageMessage";
|
|
12
7
|
import MessageBubble from "./MessageBubble";
|
|
13
|
-
import {
|
|
8
|
+
import { renderBubbleContent } from "./renderMessageContent";
|
|
9
|
+
import { getVisibleNeighbor, isMessageHiddenForViewer, } from "../../../hooks/message/useMessage";
|
|
14
10
|
import { MSG_ITEM_CONTENT_PREFIX, MSG_ITEM_PREFIX } from "../../../constants";
|
|
15
11
|
import { formatTimestamp } from "../../../utils/common";
|
|
16
12
|
import useAuthStore from "../../../store/auth";
|
|
17
13
|
import useConversationStore from "../../../store/conversation";
|
|
18
|
-
import {
|
|
14
|
+
import { useMemo, useRef } from "react";
|
|
19
15
|
import { useLongPress } from "ahooks";
|
|
20
16
|
import { Trans, useTranslation } from "react-i18next";
|
|
21
|
-
import UrlTextMessageItem from "./UrlTextMessage";
|
|
22
17
|
import MessageStatusIndicator from "./MessageStatusIndicator";
|
|
23
18
|
import { useSendMessage, isMediaResendable, } from "../../../hooks/message/useSendMessage";
|
|
24
19
|
import { Icon } from "../../../components/icon";
|
|
25
|
-
import RevokeMessageItem from "./RevokeMessage";
|
|
26
|
-
import QuoteMessageItem from "./QuoteMessage";
|
|
27
20
|
import SystemLogMessageItem from "./SystemLogMessage";
|
|
28
21
|
import { isSystemLogMessageType } from "../../../utils/messageLog";
|
|
29
22
|
import { buildMessageToolboxMenuItems, getCopyableMessageText, isCopyableMessageType, isPinnableMessageType, MessageToolboxActionKey, MESSAGE_TOOLBOX_OVERLAY_CLASSNAME, useMessageToolboxVisibility, } from "../../../components/message/toolbox";
|
|
@@ -35,29 +28,6 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
35
28
|
const userID = useAuthStore((state) => state.userID);
|
|
36
29
|
const isCrm = useAuthStore((state) => state.isCrm);
|
|
37
30
|
const conversationData = useConversationStore((state) => state.conversationData);
|
|
38
|
-
const renderMessageByType = useCallback((item) => {
|
|
39
|
-
switch (item === null || item === void 0 ? void 0 : item.contentType) {
|
|
40
|
-
case MessageType.TextMessage:
|
|
41
|
-
case MessageType.QuoteMessage:
|
|
42
|
-
return _jsx(TextMessageItem, { message: item });
|
|
43
|
-
case MessageType.PictureMessage:
|
|
44
|
-
return _jsx(ImageMessageItem, { message: item });
|
|
45
|
-
case MessageType.FileMessage:
|
|
46
|
-
return _jsx(FileMessageItem, { message: item });
|
|
47
|
-
case MessageType.VideoMessage:
|
|
48
|
-
return _jsx(VideoMessageItem, { message: item });
|
|
49
|
-
case MessageType.MergeMessage:
|
|
50
|
-
return _jsx(MergeImageMessageItem, { message: item });
|
|
51
|
-
case MessageType.UrlTextMessage:
|
|
52
|
-
return _jsx(UrlTextMessageItem, { message: item });
|
|
53
|
-
case MessageType.LogTextMessage:
|
|
54
|
-
return _jsx(SystemLogMessageItem, { message: item });
|
|
55
|
-
case MessageType.RevokeMessage:
|
|
56
|
-
return _jsx(RevokeMessageItem, {});
|
|
57
|
-
default:
|
|
58
|
-
return _jsx(TextMessageItem, { message: item });
|
|
59
|
-
}
|
|
60
|
-
}, []);
|
|
61
31
|
const { isDeliveredForUi, isRevocable, isMine } = useMessageToolboxVisibility(message, userID);
|
|
62
32
|
const contextMenuItems = useMemo(() => {
|
|
63
33
|
if ((message === null || message === void 0 ? void 0 : message.contentType) === MessageType.RevokeMessage ||
|
|
@@ -157,13 +127,7 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
157
127
|
const showAvatar = showPeerInfo && !isMine && !nextSameUser;
|
|
158
128
|
const showSenderName = showPeerInfo && !isMine && !prevSameUser;
|
|
159
129
|
const showTip = forceHideTip ? false : !nextSameUser;
|
|
160
|
-
if (
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
if ((!isCrm &&
|
|
164
|
-
(MessageType.CustomMessage === (message === null || message === void 0 ? void 0 : message.contentType) ||
|
|
165
|
-
isSystemLogMessage)) ||
|
|
166
|
-
!visibleTypeMessage.includes(message === null || message === void 0 ? void 0 : message.contentType)) {
|
|
130
|
+
if (isMessageHiddenForViewer(message, isCrm)) {
|
|
167
131
|
return null;
|
|
168
132
|
}
|
|
169
133
|
const messageContainerProps = {
|
|
@@ -176,16 +140,7 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
176
140
|
timeBreakNode,
|
|
177
141
|
_jsx(SystemLogMessageItem, { message: message })));
|
|
178
142
|
}
|
|
179
|
-
const
|
|
180
|
-
if (message === null || message === void 0 ? void 0 : message.quoteElem) {
|
|
181
|
-
return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(QuoteMessageItem, { message: message, onPressQuoteMessage: onPressQuoteMessage }), renderMessageByType(message)] }));
|
|
182
|
-
}
|
|
183
|
-
if ((message === null || message === void 0 ? void 0 : message.contentType) === MessageType.MergeMessage) {
|
|
184
|
-
return (_jsxs(_Fragment, { children: [_jsx(MergeImageMessageItem, { message: message }), (message === null || message === void 0 ? void 0 : message.textElem) && _jsx(TextMessageItem, { message: message })] }));
|
|
185
|
-
}
|
|
186
|
-
return renderMessageByType(message);
|
|
187
|
-
};
|
|
188
|
-
const bubbleNode = (_jsx(MessageBubble, { isMine: isMine, isInternal: isInternalMessage, senderName: message === null || message === void 0 ? void 0 : message.senderNickname, showSenderName: showSenderName, showTip: showTip, id: `${MSG_ITEM_CONTENT_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, content: renderBubbleContent() }));
|
|
143
|
+
const bubbleNode = (_jsx(MessageBubble, { isMine: isMine, isInternal: isInternalMessage, senderName: message === null || message === void 0 ? void 0 : message.senderNickname, showSenderName: showSenderName, showTip: showTip, id: `${MSG_ITEM_CONTENT_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, content: renderBubbleContent(message, onPressQuoteMessage) }));
|
|
189
144
|
const showPinnedBadge = Boolean(message === null || message === void 0 ? void 0 : message.isPinned) && Boolean(onPinMessage);
|
|
190
145
|
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;
|
|
191
146
|
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] }));
|
|
@@ -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,yBAAyB,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,yBAAyB,CAAC;AAYtF,eAAO,MAAM,mBAAmB,GAAI,SAAS,eAAe,4CAyB3D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,eAAe,EACxB,sBAAsB,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,4CAwBpD,CAAC"}
|
|
@@ -9,6 +9,7 @@ import UrlTextMessageItem from "./UrlTextMessage";
|
|
|
9
9
|
import RevokeMessageItem from "./RevokeMessage";
|
|
10
10
|
import QuoteMessageItem from "./QuoteMessage";
|
|
11
11
|
import SystemLogMessageItem from "./SystemLogMessage";
|
|
12
|
+
import CustomMessageItem from "./CustomMessage";
|
|
12
13
|
export const renderMessageByType = (message) => {
|
|
13
14
|
switch (message === null || message === void 0 ? void 0 : message.contentType) {
|
|
14
15
|
case MessageType.TextMessage:
|
|
@@ -28,6 +29,8 @@ export const renderMessageByType = (message) => {
|
|
|
28
29
|
return _jsx(SystemLogMessageItem, { message: message });
|
|
29
30
|
case MessageType.RevokeMessage:
|
|
30
31
|
return _jsx(RevokeMessageItem, {});
|
|
32
|
+
case MessageType.CustomMessage:
|
|
33
|
+
return _jsx(CustomMessageItem, { message: message });
|
|
31
34
|
default:
|
|
32
35
|
return _jsx(TextMessageItem, { message: message });
|
|
33
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReplyQuoteContent.d.ts","sourceRoot":"","sources":["../../../../src/components/message/reply/ReplyQuoteContent.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AASnE,eAAO,MAAM,oBAAoB,GAAI,aAAa,WAAW,YACb,CAAC;AAEjD,UAAU,sBAAsB;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,iBAAiB,GAAI,qBAG/B,sBAAsB,
|
|
1
|
+
{"version":3,"file":"ReplyQuoteContent.d.ts","sourceRoot":"","sources":["../../../../src/components/message/reply/ReplyQuoteContent.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AASnE,eAAO,MAAM,oBAAoB,GAAI,aAAa,WAAW,YACb,CAAC;AAEjD,UAAU,sBAAsB;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,iBAAiB,GAAI,qBAG/B,sBAAsB,4CAuBxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -12,6 +12,6 @@ export const ReplyQuoteContent = ({ message, title = "", }) => {
|
|
|
12
12
|
var _a, _b;
|
|
13
13
|
const { t } = useTranslation();
|
|
14
14
|
const hasMedia = hasReplyMediaPreview(message.contentType);
|
|
15
|
-
return (_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-0.5 pr-2 self-stretch", children: [_jsx("div", { className: "w-[3px] shrink-0 self-stretch rounded bg-gray-cool-200" }), hasMedia && _jsx(ReplyPreviewMedia, { message: message }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-center py-1 pl-2", children: [_jsx("p", { className: "truncate text-[14px] font-medium leading-[160%] text-gray-900", children: title }), _jsx("p", { className: "truncate text-[13px] leading-[160%] text-gray-400", children: generateContentBasedOnMessageType(message.contentType, ((_a = message.textElem) === null || _a === void 0 ? void 0 : _a.content) || ((_b = message.quoteElem) === null || _b === void 0 ? void 0 : _b.text), t) })] })] }));
|
|
15
|
+
return (_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-0.5 pr-2 self-stretch", children: [_jsx("div", { className: "w-[3px] shrink-0 self-stretch rounded bg-gray-cool-200" }), hasMedia && _jsx(ReplyPreviewMedia, { message: message }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-center py-1 pl-2", children: [_jsx("p", { className: "truncate text-[14px] font-medium leading-[160%] text-gray-900", children: title }), _jsx("p", { className: "truncate text-[13px] leading-[160%] text-gray-400", children: generateContentBasedOnMessageType(message.contentType, ((_a = message.textElem) === null || _a === void 0 ? void 0 : _a.content) || ((_b = message.quoteElem) === null || _b === void 0 ? void 0 : _b.text), t, message.customElem) })] })] }));
|
|
16
16
|
};
|
|
17
17
|
export default ReplyQuoteContent;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import clsx from "clsx";
|
|
3
3
|
import { Icon } from "../../../components/icon";
|
|
4
|
-
export const MESSAGE_TOOLBOX_OVERLAY_CLASSNAME = clsx("[&_.ant-dropdown-menu]:min-w-[200px]", "[&_.ant-dropdown-menu]:rounded-2xl", "[&_.ant-dropdown-menu]:p-0", "[&_.ant-dropdown-menu]:py-2", "[&_.ant-dropdown-menu]:shadow-message-toolbox", "[&_.ant-dropdown-menu-item]:rounded-none", "[&_.ant-dropdown-menu-item]
|
|
4
|
+
export const MESSAGE_TOOLBOX_OVERLAY_CLASSNAME = clsx("[&_.ant-dropdown-menu]:min-w-[200px]", "[&_.ant-dropdown-menu]:rounded-2xl", "[&_.ant-dropdown-menu]:p-0", "[&_.ant-dropdown-menu]:py-2", "[&_.ant-dropdown-menu]:shadow-message-toolbox", "[&_.ant-dropdown-menu-item]:rounded-none", "[&_.ant-dropdown-menu-item]:!px-4", "[&_.ant-dropdown-menu-item]:!py-1.5");
|
|
5
5
|
const ToolboxMenuRow = ({ icon, label, danger = false }) => (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Icon, { icon: icon, size: 24, className: danger ? "text-danger-400" : "text-gray-900" }), _jsx("span", { className: clsx("text-base font-medium", danger ? "text-danger-400" : "text-gray-900"), children: label })] }));
|
|
6
6
|
export const buildMessageToolboxMenuItems = (actions) => actions.map((action) => ({
|
|
7
7
|
key: action.key,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/message/toolbox/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/message/toolbox/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB;;;;;;;CAO1B,CAAC;AAEX,MAAM,MAAM,uBAAuB,GACjC,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,uBAAuB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB"}
|
|
@@ -2,5 +2,5 @@ import "../styles/global.css";
|
|
|
2
2
|
import { ChatContextType, ChatProviderProps } from "../types/chat";
|
|
3
3
|
export declare const ChatContext: import("react").Context<ChatContextType>;
|
|
4
4
|
export declare const useChatContext: () => ChatContextType;
|
|
5
|
-
export declare const ChatProvider: ({ children, config }: ChatProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare const ChatProvider: ({ children, config, renderCustomMessage, }: ChatProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
//# sourceMappingURL=ChatContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatContext.tsx"],"names":[],"mappings":"AAEA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EACL,eAAe,EACf,iBAAiB,EAGlB,MAAM,cAAc,CAAC;AAStB,eAAO,MAAM,WAAW,0CAOtB,CAAC;AAEH,eAAO,MAAM,cAAc,uBAAgC,CAAC;AAE5D,eAAO,MAAM,YAAY,GAAI,
|
|
1
|
+
{"version":3,"file":"ChatContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatContext.tsx"],"names":[],"mappings":"AAEA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EACL,eAAe,EACf,iBAAiB,EAGlB,MAAM,cAAc,CAAC;AAStB,eAAO,MAAM,WAAW,0CAOtB,CAAC;AAEH,eAAO,MAAM,cAAc,uBAAgC,CAAC;AAE5D,eAAO,MAAM,YAAY,GAAI,4CAI1B,iBAAiB,4CAsGnB,CAAC"}
|
|
@@ -18,7 +18,7 @@ export const ChatContext = createContext({
|
|
|
18
18
|
updateSyncStatus: () => { },
|
|
19
19
|
});
|
|
20
20
|
export const useChatContext = () => useContext(ChatContext);
|
|
21
|
-
export const ChatProvider = ({ children, config }) => {
|
|
21
|
+
export const ChatProvider = ({ children, config, renderCustomMessage, }) => {
|
|
22
22
|
const [connectStatus, setConnectStatus] = useState(ConnectStatus.Disconnected);
|
|
23
23
|
const [syncStatus, setSyncStatus] = useState(SyncStatus.Success);
|
|
24
24
|
const [user, setUser] = useState(null);
|
|
@@ -91,5 +91,6 @@ export const ChatProvider = ({ children, config }) => {
|
|
|
91
91
|
getSelfUserInfo,
|
|
92
92
|
updateConnectStatus,
|
|
93
93
|
updateSyncStatus,
|
|
94
|
+
renderCustomMessage,
|
|
94
95
|
}, children: _jsx(ConfigProvider, { getPopupContainer: (triggerNode) => document.body, children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx(MainLayout, { children: children }) }) }) }));
|
|
95
96
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGlobalEvent.d.ts","sourceRoot":"","sources":["../../../src/hooks/global/useGlobalEvent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useGlobalEvent.d.ts","sourceRoot":"","sources":["../../../src/hooks/global/useGlobalEvent.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,cAAc,YA8U1B,CAAC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
|
+
import { useLatest } from "ahooks";
|
|
2
3
|
import { DChatSDK } from "../../constants/sdk";
|
|
3
4
|
import { CbEvents, MessageType, SessionType, } from "@openim/wasm-client-sdk";
|
|
4
5
|
import { BusinessNotificationType, ConnectStatus, CustomType, SyncStatus, } from "../../types/chat";
|
|
5
6
|
import { pushNewMessage, updateOneMessage } from "../../hooks/message/useMessage";
|
|
6
7
|
import { fetchPinnedMessages } from "../../hooks/message/usePinnedMessages";
|
|
8
|
+
import { applyRevokedMessage } from "../../hooks/message/useRevokeMessage";
|
|
7
9
|
import { useChatContext } from "../../context/ChatContext";
|
|
8
10
|
import useConversationStore from "../../store/conversation";
|
|
9
11
|
import useAuthStore from "../../store/auth";
|
|
@@ -17,6 +19,7 @@ import emitter from "../../utils/events";
|
|
|
17
19
|
const notPushType = [MessageType.TypingMessage, MessageType.RevokeMessage];
|
|
18
20
|
export const useGlobalEvent = () => {
|
|
19
21
|
const { user } = useChatContext();
|
|
22
|
+
const userRef = useLatest(user);
|
|
20
23
|
const queryClient = useQueryClient();
|
|
21
24
|
const { updateConnectStatus, updateSyncStatus, getSelfUserInfo } = useChatContext();
|
|
22
25
|
const updateConversationList = useConversationStore((state) => state.updateConversationList);
|
|
@@ -42,13 +45,7 @@ export const useGlobalEvent = () => {
|
|
|
42
45
|
]);
|
|
43
46
|
};
|
|
44
47
|
const revokedMessageHandler = ({ data }) => {
|
|
45
|
-
|
|
46
|
-
clientMsgID: data.clientMsgID,
|
|
47
|
-
contentType: MessageType.RevokeMessage,
|
|
48
|
-
notificationElem: {
|
|
49
|
-
detail: JSON.stringify(data),
|
|
50
|
-
},
|
|
51
|
-
});
|
|
48
|
+
applyRevokedMessage(data.clientMsgID);
|
|
52
49
|
};
|
|
53
50
|
const messagePinnedHandler = ({ data }) => {
|
|
54
51
|
updateOneMessage({
|
|
@@ -64,11 +61,12 @@ export const useGlobalEvent = () => {
|
|
|
64
61
|
}
|
|
65
62
|
};
|
|
66
63
|
const inCurrentConversation = (newServerMsg) => {
|
|
64
|
+
var _a;
|
|
67
65
|
const selectedSourceId = useConversationStore.getState().selectedSourceId;
|
|
68
66
|
switch (newServerMsg.sessionType) {
|
|
69
67
|
case SessionType.Single:
|
|
70
68
|
return (newServerMsg.sendID === selectedSourceId ||
|
|
71
|
-
((
|
|
69
|
+
!!(((_a = userRef.current) === null || _a === void 0 ? void 0 : _a.userID) && newServerMsg.recvID === selectedSourceId));
|
|
72
70
|
case SessionType.Group:
|
|
73
71
|
case SessionType.WorkingGroup:
|
|
74
72
|
return newServerMsg.groupID === selectedSourceId;
|
|
@@ -79,7 +77,7 @@ export const useGlobalEvent = () => {
|
|
|
79
77
|
}
|
|
80
78
|
};
|
|
81
79
|
const handleNewMessage = (newServerMsg) => {
|
|
82
|
-
var _a, _b;
|
|
80
|
+
var _a, _b, _c;
|
|
83
81
|
let customData = null;
|
|
84
82
|
if (newServerMsg.contentType === MessageType.CustomMessage) {
|
|
85
83
|
const rawCustomData = (_b = (_a = newServerMsg.customElem) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.trim();
|
|
@@ -102,7 +100,7 @@ export const useGlobalEvent = () => {
|
|
|
102
100
|
if (!notPushType.includes(newServerMsg.contentType)) {
|
|
103
101
|
pushNewMessage(newServerMsg);
|
|
104
102
|
}
|
|
105
|
-
if (newServerMsg.sendID !== (
|
|
103
|
+
if (newServerMsg.sendID !== ((_c = userRef.current) === null || _c === void 0 ? void 0 : _c.userID)) {
|
|
106
104
|
queryClient.invalidateQueries({
|
|
107
105
|
queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
|
|
108
106
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MessageItem, MessageType } from "@openim/wasm-client-sdk";
|
|
2
2
|
export declare const visibleTypeMessage: MessageType[];
|
|
3
|
+
export declare const isMessageHiddenForViewer: (message: MessageItem, isCrm: boolean) => boolean;
|
|
3
4
|
export declare const useMessage: (conversationId?: string, searchClientMsgID?: string, enabled?: boolean, useAppHistory?: boolean) => {
|
|
4
5
|
loadState: {
|
|
5
6
|
initLoading: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useMessage.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,WAAW,EACX,WAAW,EAEZ,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"useMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useMessage.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,WAAW,EACX,WAAW,EAEZ,MAAM,yBAAyB,CAAC;AAYjC,eAAO,MAAM,kBAAkB,eAgB9B,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS,WAAW,EACpB,OAAO,OAAO,KACb,OAWF,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,iBAAiB,MAAM,EACvB,oBAAoB,MAAM,EAC1B,iBAAc,EACd,uBAAqB;;;;;qBAeA,WAAW,EAAE;;;;;;qBAAb,WAAW,EAAE;;;;;;CAiSnC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,SACpB,CAAC;AAChC,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,SACpB,CAAC;AAClC,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,SACf,CAAC;AAEtC,eAAO,MAAM,kBAAkB,GAC7B,aAAa,WAAW,EAAE,EAC1B,SAAS,WAAW,EACpB,WAAW,MAAM,GAAG,MAAM,KACzB,WAAW,GAAG,SAkBhB,CAAC"}
|
|
@@ -8,6 +8,8 @@ import isEmpty from "lodash/isEmpty";
|
|
|
8
8
|
import { useChatContext } from "../../context/ChatContext";
|
|
9
9
|
import useAuthStore from "../../store/auth";
|
|
10
10
|
import { ConnectStatus, SyncStatus } from "../../types/chat";
|
|
11
|
+
import { isSystemLogMessageType } from "../../utils/messageLog";
|
|
12
|
+
import { isRenderableCustomMessage } from "../../utils/customMessage";
|
|
11
13
|
export const visibleTypeMessage = [
|
|
12
14
|
MessageType.TextMessage,
|
|
13
15
|
MessageType.PictureMessage,
|
|
@@ -25,6 +27,16 @@ export const visibleTypeMessage = [
|
|
|
25
27
|
MessageType.RevokeMessage,
|
|
26
28
|
MessageType.LogTextMessage,
|
|
27
29
|
];
|
|
30
|
+
export const isMessageHiddenForViewer = (message, isCrm) => {
|
|
31
|
+
if (!visibleTypeMessage.includes(message === null || message === void 0 ? void 0 : message.contentType))
|
|
32
|
+
return true;
|
|
33
|
+
if (isCrm)
|
|
34
|
+
return false;
|
|
35
|
+
const isCustomMessage = MessageType.CustomMessage === (message === null || message === void 0 ? void 0 : message.contentType);
|
|
36
|
+
return (Boolean(message === null || message === void 0 ? void 0 : message.isInternal) ||
|
|
37
|
+
isSystemLogMessageType(message === null || message === void 0 ? void 0 : message.contentType) ||
|
|
38
|
+
(isCustomMessage && !isRenderableCustomMessage(message)));
|
|
39
|
+
};
|
|
28
40
|
export const useMessage = (conversationId, searchClientMsgID, enabled = true, useAppHistory = false) => {
|
|
29
41
|
const { connectStatus, syncStatus } = useChatContext();
|
|
30
42
|
const userID = useAuthStore((state) => state.userID);
|
|
@@ -176,7 +188,10 @@ export const useMessage = (conversationId, searchClientMsgID, enabled = true, us
|
|
|
176
188
|
return;
|
|
177
189
|
}
|
|
178
190
|
setLoadState((preState) => {
|
|
179
|
-
|
|
191
|
+
// sendTime is assigned once at creation (optimistic or server) and
|
|
192
|
+
// never changes afterwards, so sorting by it keeps messages in the
|
|
193
|
+
// right order regardless of network delay or how late seq comes back.
|
|
194
|
+
const messageList = [message, ...preState.messageList].sort((a, b) => (b.sendTime || 0) - (a.sendTime || 0));
|
|
180
195
|
return Object.assign(Object.assign({}, preState), { messageList });
|
|
181
196
|
});
|
|
182
197
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRevokeMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useRevokeMessage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useRevokeMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useRevokeMessage.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,mBAAmB,GAC9B,aAAa,MAAM,EACnB,iBAAiB,MAAM,SAoBxB,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;CAkB5B,CAAC"}
|
|
@@ -1,11 +1,33 @@
|
|
|
1
|
+
import { MessageType } from "@openim/wasm-client-sdk";
|
|
1
2
|
import { DChatSDK } from "../../constants/sdk";
|
|
2
3
|
import { useRequest } from "ahooks";
|
|
4
|
+
import { updateOneMessage } from "../../hooks/message/useMessage";
|
|
5
|
+
import { fetchPinnedMessages } from "../../hooks/message/usePinnedMessages";
|
|
6
|
+
import useConversationStore from "../../store/conversation";
|
|
7
|
+
// Shared by the actor's own revoke call (conversationID known upfront) and by
|
|
8
|
+
// the OnNewRecvMessageRevoked socket handler (conversationID unknown, so we
|
|
9
|
+
// infer it from whichever conversation currently has this message pinned).
|
|
10
|
+
export const applyRevokedMessage = (clientMsgID, conversationID) => {
|
|
11
|
+
const revokedPatch = {
|
|
12
|
+
clientMsgID,
|
|
13
|
+
contentType: MessageType.RevokeMessage,
|
|
14
|
+
};
|
|
15
|
+
updateOneMessage(revokedPatch);
|
|
16
|
+
useConversationStore.getState().updatePinnedMessage(revokedPatch);
|
|
17
|
+
const { selectedConversationId, conversationData, pinnedMessageList } = useConversationStore.getState();
|
|
18
|
+
const targetConversationId = conversationID || selectedConversationId || (conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID);
|
|
19
|
+
const isRevokedMessagePinned = pinnedMessageList.some((pinnedMessage) => pinnedMessage.clientMsgID === clientMsgID);
|
|
20
|
+
if (targetConversationId && isRevokedMessagePinned) {
|
|
21
|
+
void fetchPinnedMessages(targetConversationId);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
3
24
|
export const useRevokeMessage = () => {
|
|
4
25
|
const { loading, runAsync: revokeMessage } = useRequest(async (conversationID, clientMsgID) => {
|
|
5
26
|
await DChatSDK.revokeMessage({
|
|
6
27
|
conversationID,
|
|
7
28
|
clientMsgID,
|
|
8
29
|
});
|
|
30
|
+
applyRevokedMessage(clientMsgID, conversationID);
|
|
9
31
|
}, {
|
|
10
32
|
manual: true,
|
|
11
33
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type UseSendMessageOptions } from "../../hooks/message/useSendMessage";
|
|
2
|
+
export declare const useSendCustomMessage: (options?: UseSendMessageOptions) => {
|
|
3
|
+
sendCustomMessage: (payload: import("../..").CustomMessagePayload, sendOptions?: {
|
|
4
|
+
currentSession?: import("../../types/dto").ISessionResponse;
|
|
5
|
+
}) => Promise<boolean>;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=useSendCustomMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSendCustomMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useSendCustomMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,gCAAgC,CAAC;AAExC,eAAO,MAAM,oBAAoB,GAAI,UAAU,qBAAqB;;sBAK84a,CAAC;;CADl9a,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { MergerMsgParams, MessageItem } from "@openim/wasm-client-sdk";
|
|
1
|
+
import { CustomMsgParams, MergerMsgParams, MessageItem } from "@openim/wasm-client-sdk";
|
|
2
|
+
import { type CustomMessagePayload } from "../../types/customMessage";
|
|
2
3
|
import { BotFlowMeta, ExtendMessageInfo, FileMsgParamsByFile, ImageMsgParamsByFile, UrlMetadataInfo, VideoMsgParamsByFile } from "../../types/chat";
|
|
3
4
|
import { UploadFile } from "antd";
|
|
4
5
|
import { ISessionResponse } from "../../types/dto";
|
|
@@ -12,6 +13,8 @@ export declare const createMergerMessage: (mergerMsgParams: MergerMsgParams) =>
|
|
|
12
13
|
export declare const createVideoMessageByFile: (file: VideoMsgParamsByFile) => Promise<MessageItem | null>;
|
|
13
14
|
export declare const createFileMessageByFile: (file: FileMsgParamsByFile) => Promise<MessageItem | null>;
|
|
14
15
|
export declare const createUrlTextMessage: (text: string, urls: string[]) => Promise<MessageItem | null>;
|
|
16
|
+
export declare const createCustomMessageByParams: (params: CustomMsgParams) => Promise<MessageItem | null>;
|
|
17
|
+
export declare const createCustomMessage: (payload: CustomMessagePayload) => Promise<MessageItem | null>;
|
|
15
18
|
export declare const createQuoteMessage: (text: string, quotedMessage: MessageItem) => Promise<MessageItem | null>;
|
|
16
19
|
export type SendMessageScrollEvent = "CHAT_LIST_SCROLL_TO_BOTTOM" | "CONVERSATION_CHAT_SCROLL_TO_BOTTOM_IF_AT_BOTTOM";
|
|
17
20
|
export interface OfflinePushMeta {
|
|
@@ -26,7 +29,7 @@ export interface UseSendMessageOptions {
|
|
|
26
29
|
}) => OfflinePushMeta;
|
|
27
30
|
}
|
|
28
31
|
export declare const useSendMessage: (options?: UseSendMessageOptions) => {
|
|
29
|
-
sendMergeMessage: ({ richText, plainText, files, currentSession, isInternal, urlMetadata, flow, }: {
|
|
32
|
+
sendMergeMessage: ({ richText, plainText, files, currentSession, isInternal, urlMetadata, flow, customMessage, }: {
|
|
30
33
|
richText: string;
|
|
31
34
|
plainText: string;
|
|
32
35
|
files?: UploadFile[];
|
|
@@ -34,6 +37,10 @@ export declare const useSendMessage: (options?: UseSendMessageOptions) => {
|
|
|
34
37
|
isInternal: boolean;
|
|
35
38
|
urlMetadata?: UrlMetadataInfo;
|
|
36
39
|
flow?: BotFlowMeta;
|
|
40
|
+
customMessage?: CustomMessagePayload;
|
|
41
|
+
}) => Promise<boolean>;
|
|
42
|
+
sendCustomMessage: (payload: CustomMessagePayload, sendOptions?: {
|
|
43
|
+
currentSession?: ISessionResponse;
|
|
37
44
|
}) => Promise<boolean>;
|
|
38
45
|
resendMessage: (failedMessage: MessageItem) => Promise<void>;
|
|
39
46
|
};
|