@droppii-org/chat-sdk 0.6.55 → 0.6.56
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/message/item/QuoteMessage.d.ts.map +1 -1
- package/dist/components/message/item/QuoteMessage.js +23 -2
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +16 -3
- package/dist/components/message/reply/ReplyPreviewBar.d.ts.map +1 -1
- package/dist/components/message/reply/ReplyPreviewBar.js +9 -2
- package/dist/hooks/user/useUserUsername.d.ts +3 -0
- package/dist/hooks/user/useUserUsername.d.ts.map +1 -0
- package/dist/hooks/user/useUserUsername.js +49 -0
- package/package.json +1 -1
|
@@ -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;
|
|
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;AAS3D,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,mDA0EvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -4,6 +4,8 @@ import { useCallback, useMemo } from "react";
|
|
|
4
4
|
import useAuthStore from "../../../store/auth";
|
|
5
5
|
import useConversationStore from "../../../store/conversation";
|
|
6
6
|
import ReplyQuoteContent from "../../../components/message/reply/ReplyQuoteContent";
|
|
7
|
+
import { useUserUsername } from "../../../hooks/user/useUserUsername";
|
|
8
|
+
import { isSupportSessionAgentView } from "../../../utils/conversation";
|
|
7
9
|
const QuoteMessageItem = ({ message, onPressQuoteMessage, }) => {
|
|
8
10
|
var _a, _b;
|
|
9
11
|
const userID = useAuthStore((state) => state.userID);
|
|
@@ -19,7 +21,19 @@ const QuoteMessageItem = ({ message, onPressQuoteMessage, }) => {
|
|
|
19
21
|
return false;
|
|
20
22
|
}
|
|
21
23
|
}, [conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex]);
|
|
24
|
+
const quoteMessage = ((_a = message === null || message === void 0 ? void 0 : message.quoteElem) === null || _a === void 0 ? void 0 : _a.quoteMessage) || ((_b = message === null || message === void 0 ? void 0 : message.atTextElem) === null || _b === void 0 ? void 0 : _b.quoteMessage);
|
|
25
|
+
// Outside CRM, an agent identifies quoted senders by username; the session
|
|
26
|
+
// owner keeps seeing the thread's own name.
|
|
27
|
+
const isAgentView = !isCrm && isSupportSessionAgentView(conversationData, userID);
|
|
28
|
+
const quotedUsername = useUserUsername(isAgentView && (quoteMessage === null || quoteMessage === void 0 ? void 0 : quoteMessage.sendID) !== userID
|
|
29
|
+
? quoteMessage === null || quoteMessage === void 0 ? void 0 : quoteMessage.sendID
|
|
30
|
+
: undefined);
|
|
22
31
|
const getDisplayName = useCallback(({ name, id }) => {
|
|
32
|
+
if (isAgentView) {
|
|
33
|
+
if (id === userID)
|
|
34
|
+
return t("you");
|
|
35
|
+
return quotedUsername || name || "";
|
|
36
|
+
}
|
|
23
37
|
if (!name)
|
|
24
38
|
return "";
|
|
25
39
|
if (!isCrm && isChatSupport) {
|
|
@@ -28,8 +42,15 @@ const QuoteMessageItem = ({ message, onPressQuoteMessage, }) => {
|
|
|
28
42
|
if (id === userID)
|
|
29
43
|
return t("you");
|
|
30
44
|
return name;
|
|
31
|
-
}, [
|
|
32
|
-
|
|
45
|
+
}, [
|
|
46
|
+
isAgentView,
|
|
47
|
+
quotedUsername,
|
|
48
|
+
isCrm,
|
|
49
|
+
isChatSupport,
|
|
50
|
+
conversationData === null || conversationData === void 0 ? void 0 : conversationData.showName,
|
|
51
|
+
userID,
|
|
52
|
+
t,
|
|
53
|
+
]);
|
|
33
54
|
if (!quoteMessage)
|
|
34
55
|
return null;
|
|
35
56
|
const title = getDisplayName({
|
|
@@ -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;AA+CtC,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;IAC1B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;CAClC;AAkCD,QAAA,MAAM,WAAW,GAAI,kSAkBlB,gBAAgB,
|
|
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;AA+CtC,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;IAC1B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;CAClC;AAkCD,QAAA,MAAM,WAAW,GAAI,kSAkBlB,gBAAgB,mDAsZlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -135,22 +135,35 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
135
135
|
]);
|
|
136
136
|
const bubbleWrapperRef = useRef(null);
|
|
137
137
|
useLongPress(() => onContextMenuOpenChange === null || onContextMenuOpenChange === void 0 ? void 0 : onContextMenuOpenChange(true), enableLongPress ? bubbleWrapperRef : undefined, { delay: 500 });
|
|
138
|
+
// Agents outside CRM (e.g. PDP CS) also need to tell the owner apart from
|
|
139
|
+
// other supporters; only the session owner keeps the anonymous bot view.
|
|
140
|
+
const isSessionAgentView = isSupportSessionAgentView(conversationData, userID);
|
|
138
141
|
const showSenderInfo = useMemo(() => {
|
|
139
142
|
var _a, _b, _c;
|
|
143
|
+
if ((message === null || message === void 0 ? void 0 : message.sendID) === userID)
|
|
144
|
+
return false;
|
|
145
|
+
if (isSessionAgentView)
|
|
146
|
+
return true;
|
|
140
147
|
try {
|
|
141
148
|
const isChatSupport = (_c = (_b = (_a = JSON.parse((conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex) || "{}")) === null || _a === void 0 ? void 0 : _a.sessionInfo) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.botId;
|
|
142
|
-
return Boolean(isChatSupport && isCrm
|
|
149
|
+
return Boolean(isChatSupport && isCrm);
|
|
143
150
|
}
|
|
144
151
|
catch (_d) {
|
|
145
152
|
console.log("Failed to parse conversationData.ex");
|
|
146
153
|
return false;
|
|
147
154
|
}
|
|
148
|
-
}, [
|
|
155
|
+
}, [
|
|
156
|
+
conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex,
|
|
157
|
+
isCrm,
|
|
158
|
+
isSessionAgentView,
|
|
159
|
+
message === null || message === void 0 ? void 0 : message.sendID,
|
|
160
|
+
userID,
|
|
161
|
+
]);
|
|
149
162
|
const isInternalMessage = Boolean(message === null || message === void 0 ? void 0 : message.isInternal);
|
|
150
163
|
const isSystemLogMessage = isSystemLogMessageType(message === null || message === void 0 ? void 0 : message.contentType);
|
|
151
164
|
const isGroupNotificationMessage = isGroupNotificationMessageType(message === null || message === void 0 ? void 0 : message.contentType);
|
|
152
165
|
const isSessionEvent = isSessionEventMessage(message);
|
|
153
|
-
const showsSessionEvents = isCrm ||
|
|
166
|
+
const showsSessionEvents = isCrm || isSessionAgentView;
|
|
154
167
|
const isStickerMessage = (message === null || message === void 0 ? void 0 : message.contentType) === MessageType.StickerMessage;
|
|
155
168
|
const hasContextMenu = contextMenuItems.length > 0;
|
|
156
169
|
const isLatestMine = ((_a = allMessages.find((m) => m.sendID === userID)) === null || _a === void 0 ? void 0 : _a.clientMsgID) ===
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReplyPreviewBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/reply/ReplyPreviewBar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReplyPreviewBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/reply/ReplyPreviewBar.tsx"],"names":[],"mappings":"AAQA,eAAO,MAAM,eAAe,sDAmD3B,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -3,21 +3,28 @@ import { useTranslation } from "react-i18next";
|
|
|
3
3
|
import { Icon } from "../../../components/icon";
|
|
4
4
|
import useAuthStore from "../../../store/auth";
|
|
5
5
|
import useConversationStore from "../../../store/conversation";
|
|
6
|
+
import { useUserUsername } from "../../../hooks/user/useUserUsername";
|
|
7
|
+
import { isSupportSessionAgentView } from "../../../utils/conversation";
|
|
6
8
|
import { ReplyQuoteContent } from "./ReplyQuoteContent";
|
|
7
9
|
export const ReplyPreviewBar = () => {
|
|
8
10
|
const { t } = useTranslation();
|
|
9
11
|
const quotedMessage = useConversationStore((state) => state.quotedMessage);
|
|
10
12
|
const setQuotedMessage = useConversationStore((state) => state.setQuotedMessage);
|
|
13
|
+
const conversationData = useConversationStore((state) => state.conversationData);
|
|
11
14
|
const userID = useAuthStore((state) => state.userID);
|
|
15
|
+
const isCrm = useAuthStore((state) => state.isCrm);
|
|
16
|
+
const isMe = (quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.sendID) === userID;
|
|
17
|
+
// Matches the sent quote's title, which shows agents outside CRM the username.
|
|
18
|
+
const isAgentView = !isCrm && isSupportSessionAgentView(conversationData, userID);
|
|
19
|
+
const quotedUsername = useUserUsername(isAgentView && !isMe ? quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.sendID : undefined);
|
|
12
20
|
const handleClearQuotedMessage = () => {
|
|
13
21
|
setQuotedMessage(null);
|
|
14
22
|
};
|
|
15
23
|
if (!quotedMessage)
|
|
16
24
|
return null;
|
|
17
|
-
const isMe = quotedMessage.sendID === userID;
|
|
18
25
|
const senderName = isMe
|
|
19
26
|
? t("your_self")
|
|
20
|
-
: quotedMessage.senderNickname || "";
|
|
27
|
+
: quotedUsername || quotedMessage.senderNickname || "";
|
|
21
28
|
return (_jsxs("div", { "data-testid": "reply-preview-bar", "data-cp-name": "ReplyPreviewBar", className: "flex h-[59px] w-full shrink-0 items-center bg-gray-200/10 px-2 py-1", children: [_jsx(ReplyQuoteContent, { message: quotedMessage, title: t("reply_to", { name: senderName }) }), _jsx("button", { type: "button", onClick: handleClearQuotedMessage, "aria-label": t("cancel"), "data-testid": "reply-preview-bar-close", className: "flex h-4 w-4 shrink-0 items-center justify-center", children: _jsx(Icon, { icon: "close-o", size: 16, className: "text-gray-600" }) })] }));
|
|
22
29
|
};
|
|
23
30
|
export default ReplyPreviewBar;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUserUsername.d.ts","sourceRoot":"","sources":["../../../src/hooks/user/useUserUsername.ts"],"names":[],"mappings":"AA+BA,wEAAwE;AACxE,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,MAAM,GAAG,SAoB1D,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { DChatSDK } from "../../constants/sdk";
|
|
4
|
+
import { useChatContext } from "../../context/ChatContext";
|
|
5
|
+
import useUsersInfoStore from "../../store/usersInfo";
|
|
6
|
+
import { ConnectStatus } from "../../types/chat";
|
|
7
|
+
// Backoff for a failed/empty lookup, same as the header's owner lookup.
|
|
8
|
+
const RETRY_DELAYS_MS = [2000, 5000, 10000];
|
|
9
|
+
// Quotes of one sender mount together; only one lookup runs per user at a time.
|
|
10
|
+
const pendingUserIds = new Set();
|
|
11
|
+
const loadUserInfo = (userId, attempt = 0) => {
|
|
12
|
+
DChatSDK.getUsersInfo([userId])
|
|
13
|
+
.then(({ data }) => {
|
|
14
|
+
if (!(data === null || data === void 0 ? void 0 : data.length))
|
|
15
|
+
throw new Error("user not found");
|
|
16
|
+
useUsersInfoStore.getState().upsertUsers(data);
|
|
17
|
+
pendingUserIds.delete(userId);
|
|
18
|
+
})
|
|
19
|
+
.catch((error) => {
|
|
20
|
+
const delay = RETRY_DELAYS_MS[attempt];
|
|
21
|
+
if (delay === undefined) {
|
|
22
|
+
pendingUserIds.delete(userId);
|
|
23
|
+
console.error("Error fetching user info:", error);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
setTimeout(() => loadUserInfo(userId, attempt + 1), delay);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
/** Username from the user's public info `ex`; undefined until known. */
|
|
30
|
+
export const useUserUsername = (userId) => {
|
|
31
|
+
var _a, _b, _c;
|
|
32
|
+
const { connectStatus } = useChatContext();
|
|
33
|
+
const user = useUsersInfoStore((state) => userId ? state.usersInfo[userId] : undefined);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!userId || user || pendingUserIds.has(userId))
|
|
36
|
+
return;
|
|
37
|
+
if (connectStatus !== ConnectStatus.Connected)
|
|
38
|
+
return;
|
|
39
|
+
pendingUserIds.add(userId);
|
|
40
|
+
loadUserInfo(userId);
|
|
41
|
+
}, [userId, user, connectStatus]);
|
|
42
|
+
try {
|
|
43
|
+
const ex = JSON.parse((user === null || user === void 0 ? void 0 : user.ex) || "{}");
|
|
44
|
+
return ((_c = (_b = (_a = ex === null || ex === void 0 ? void 0 : ex.userInfo) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.username) === null || _c === void 0 ? void 0 : _c.trim()) || undefined;
|
|
45
|
+
}
|
|
46
|
+
catch (_d) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
};
|