@droppii-org/chat-sdk 0.4.11 → 0.4.13
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/ConversationDetailInput.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationDetailInput.js +35 -1
- package/dist/components/message/footer/index.d.ts.map +1 -1
- package/dist/components/message/footer/index.js +35 -2
- package/dist/components/message/item/MessageBubble.d.ts.map +1 -1
- package/dist/components/message/item/MessageBubble.js +4 -4
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +9 -3
- package/dist/context/ChatContext.d.ts.map +1 -1
- package/dist/context/ChatContext.js +2 -0
- package/dist/locales/vi/conversation-inbox.json +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationDetailInput.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/ConversationDetailInput.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConversationDetailInput.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/ConversationDetailInput.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAkB/D,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,QAAA,MAAM,uBAAuB,GAAI,4EAM9B,4BAA4B,4CA8qB9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
|
|
@@ -4,8 +4,10 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
|
4
4
|
import { useTranslation } from "react-i18next";
|
|
5
5
|
import { useBoolean } from "ahooks";
|
|
6
6
|
import clsx from "clsx";
|
|
7
|
+
import { Button, message as toastMessage } from "antd";
|
|
7
8
|
import { Icon } from "../../components/icon";
|
|
8
9
|
import { useSendMessage } from "../../hooks/message/useSendMessage";
|
|
10
|
+
import { useJoinPublicGroup } from "../../hooks/group/useJoinPublicGroup";
|
|
9
11
|
import useAuthStore from "../../store/auth";
|
|
10
12
|
import useConversationStore from "../../store/conversation";
|
|
11
13
|
import useMessageDraftStore from "../../store/messageDraft";
|
|
@@ -36,6 +38,38 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
|
|
|
36
38
|
const conversationId = selectedConversationId || (conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID) || "";
|
|
37
39
|
const isConversationReady = !!conversationData && (!!conversationData.userID || !!conversationData.groupID);
|
|
38
40
|
const isViewOnlyMember = useConversationStore((state) => state.isViewOnlyMember);
|
|
41
|
+
const setIsViewOnlyMember = useConversationStore((state) => state.setIsViewOnlyMember);
|
|
42
|
+
const getCurrentMemberInGroupByReq = useConversationStore((state) => state.getCurrentMemberInGroupByReq);
|
|
43
|
+
const getSelfGroupPermissionByReq = useConversationStore((state) => state.getSelfGroupPermissionByReq);
|
|
44
|
+
const { mutate: joinPublicGroup, isPending: isJoiningPublicGroup } = useJoinPublicGroup();
|
|
45
|
+
const handleJoinPublicGroup = useCallback(() => {
|
|
46
|
+
const groupID = conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID;
|
|
47
|
+
if (!groupID)
|
|
48
|
+
return;
|
|
49
|
+
joinPublicGroup({ groupID }, {
|
|
50
|
+
onSuccess: async () => {
|
|
51
|
+
toastMessage.success(tCommon("join_group_success"));
|
|
52
|
+
// updateCurrentConversation's revalidation only runs on a
|
|
53
|
+
// conversationID change — this is the same conversation the user
|
|
54
|
+
// was already viewing, so refresh membership/permissions directly
|
|
55
|
+
// instead, and flip isViewOnlyMember off immediately rather than
|
|
56
|
+
// waiting on a WS event that may not fire right away.
|
|
57
|
+
setIsViewOnlyMember(false);
|
|
58
|
+
await Promise.allSettled([
|
|
59
|
+
getCurrentMemberInGroupByReq(groupID),
|
|
60
|
+
getSelfGroupPermissionByReq(groupID),
|
|
61
|
+
]);
|
|
62
|
+
},
|
|
63
|
+
onError: () => toastMessage.error(tCommon("join_group_failed")),
|
|
64
|
+
});
|
|
65
|
+
}, [
|
|
66
|
+
conversationData,
|
|
67
|
+
getCurrentMemberInGroupByReq,
|
|
68
|
+
getSelfGroupPermissionByReq,
|
|
69
|
+
joinPublicGroup,
|
|
70
|
+
setIsViewOnlyMember,
|
|
71
|
+
tCommon,
|
|
72
|
+
]);
|
|
39
73
|
const sendMessageOptions = useMemo(() => ({
|
|
40
74
|
scrollEvent: "CONVERSATION_CHAT_SCROLL_TO_BOTTOM_IF_AT_BOTTOM",
|
|
41
75
|
}), []);
|
|
@@ -408,7 +442,7 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
|
|
|
408
442
|
void handleSend();
|
|
409
443
|
};
|
|
410
444
|
if (isViewOnlyMember) {
|
|
411
|
-
return (
|
|
445
|
+
return (_jsxs("div", { "data-testid": "conversation-detail-input-view-only", className: "flex w-full shrink-0 items-center justify-between gap-3 bg-chat-bubble-neutral/[0.05] px-4 py-3", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("thread_detail.view_only_notice") }), _jsx(Button, { type: "primary", size: "small", loading: isJoiningPublicGroup, onClick: handleJoinPublicGroup, children: tCommon("join_group") })] }));
|
|
412
446
|
}
|
|
413
447
|
return (_jsxs("div", { ref: containerRef, "data-testid": "conversation-detail-input", "data-cp-name": "ConversationDetailInput", className: "flex w-full shrink-0 flex-col bg-chat-bubble-neutral/[0.05]", children: [_jsx("input", { ref: mediaInputRef, type: "file", accept: "image/jpeg,image/png,image/jpg,video/*", multiple: true, className: "hidden", onChange: handleMediaInputChange }), _jsx("input", { ref: documentInputRef, type: "file", accept: ".pdf,.doc,.docx", multiple: true, className: "hidden", onChange: handleDocumentInputChange }), _jsx(ReplyPreviewBar, {}), listUploadFiles.length > 0 && (_jsx(FilePreviewList, { files: listUploadFiles, onRemove: (file) => handleRemoveFile(file.uid), onVideoReady: () => setIsVideoLoading(false) })), showLinkPreview && previewUrl && (_jsx(LinkInputPreview, { url: previewUrl, onRemove: () => setPreviewDismissed(true) })), _jsxs("div", { className: "flex items-end gap-3 px-3 py-2", children: [_jsx("div", { className: "flex shrink-0 items-center", children: _jsx("button", { type: "button", onClick: handleToggleMoreOption, "aria-label": t("thread_detail.more_option.toggle"), "aria-expanded": isMoreOptionOpen, "data-testid": "conversation-detail-more-option-toggle", className: "flex py-3 items-center justify-center rounded-full", children: isMoreOptionOpen ? (_jsx(Icon, { icon: "close-circle-b", size: 24, className: "text-primary-400" })) : (_jsx(Icon, { icon: "plus-circle-o", size: 24, className: "text-gray-900" })) }) }), _jsx("div", { className: clsx("flex min-w-0 flex-1 overflow-hidden rounded-xl border bg-white transition-shadow", isFocused
|
|
414
448
|
? "border-primary-200 shadow-primary-focus"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAGL,wBAAwB,EAEzB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAGL,wBAAwB,EAEzB,MAAM,cAAc,CAAC;AAUtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoB/C,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AASD,eAAO,MAAM,oBAAoB,mDAc/B,CAAC;AAEH,eAAO,MAAM,uBAAuB,gCAAyC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,GAAI,4CAG5B,kBAAkB,4CAgYpB,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -10,7 +10,8 @@ import EnterHandler from "./EnterHandler";
|
|
|
10
10
|
import ActionBar from "./ActionBar";
|
|
11
11
|
import { AccountType, } from "../../../types/chat";
|
|
12
12
|
import { useSendMessage } from "../../../hooks/message/useSendMessage";
|
|
13
|
-
import {
|
|
13
|
+
import { useJoinPublicGroup } from "../../../hooks/group/useJoinPublicGroup";
|
|
14
|
+
import { Button, Modal, Popover, message as toastMessage } from "antd";
|
|
14
15
|
import FilePreview from "./FilePreview";
|
|
15
16
|
import LinkInputPreview from "./LinkInputPreview";
|
|
16
17
|
import ComposerTextSyncPlugin from "./ComposerTextSyncPlugin";
|
|
@@ -72,6 +73,38 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
72
73
|
const quotedMessage = useConversationStore((state) => state.quotedMessage);
|
|
73
74
|
const conversationData = useConversationStore((state) => state.conversationData);
|
|
74
75
|
const isViewOnlyMember = useConversationStore((state) => state.isViewOnlyMember);
|
|
76
|
+
const setIsViewOnlyMember = useConversationStore((state) => state.setIsViewOnlyMember);
|
|
77
|
+
const getCurrentMemberInGroupByReq = useConversationStore((state) => state.getCurrentMemberInGroupByReq);
|
|
78
|
+
const getSelfGroupPermissionByReq = useConversationStore((state) => state.getSelfGroupPermissionByReq);
|
|
79
|
+
const { mutate: joinPublicGroup, isPending: isJoiningPublicGroup } = useJoinPublicGroup();
|
|
80
|
+
const handleJoinPublicGroup = useCallback(() => {
|
|
81
|
+
const groupID = conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID;
|
|
82
|
+
if (!groupID)
|
|
83
|
+
return;
|
|
84
|
+
joinPublicGroup({ groupID }, {
|
|
85
|
+
onSuccess: async () => {
|
|
86
|
+
toastMessage.success(t("join_group_success"));
|
|
87
|
+
// updateCurrentConversation's revalidation only runs on a
|
|
88
|
+
// conversationID change — this is the same conversation the user
|
|
89
|
+
// was already viewing, so refresh membership/permissions directly
|
|
90
|
+
// instead, and flip isViewOnlyMember off immediately rather than
|
|
91
|
+
// waiting on a WS event that may not fire right away.
|
|
92
|
+
setIsViewOnlyMember(false);
|
|
93
|
+
await Promise.allSettled([
|
|
94
|
+
getCurrentMemberInGroupByReq(groupID),
|
|
95
|
+
getSelfGroupPermissionByReq(groupID),
|
|
96
|
+
]);
|
|
97
|
+
},
|
|
98
|
+
onError: () => toastMessage.error(t("join_group_failed")),
|
|
99
|
+
});
|
|
100
|
+
}, [
|
|
101
|
+
conversationData,
|
|
102
|
+
getCurrentMemberInGroupByReq,
|
|
103
|
+
getSelfGroupPermissionByReq,
|
|
104
|
+
joinPublicGroup,
|
|
105
|
+
setIsViewOnlyMember,
|
|
106
|
+
t,
|
|
107
|
+
]);
|
|
75
108
|
// Internal notes are a CX-support concept (team-only remarks not sent to
|
|
76
109
|
// the customer) — meaningless inside a real member-managed group, where
|
|
77
110
|
// everyone in the thread already is the "team".
|
|
@@ -216,7 +249,7 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
216
249
|
closeCanned();
|
|
217
250
|
};
|
|
218
251
|
if (isViewOnlyMember) {
|
|
219
|
-
return (
|
|
252
|
+
return (_jsxs("div", { "data-testid": "message-footer-view-only", className: "flex w-full items-center justify-between gap-3 border-t border-gray-25 bg-white px-4 py-3", children: [_jsx("span", { className: "text-sm text-gray-500", children: tConversationInbox("thread_detail.view_only_notice") }), _jsx(Button, { type: "primary", size: "small", loading: isJoiningPublicGroup, onClick: handleJoinPublicGroup, children: t("join_group") })] }));
|
|
220
253
|
}
|
|
221
254
|
return (_jsxs(MessageFooterContext.Provider, { value: {
|
|
222
255
|
onSendMessage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/MessageBubble.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,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;IACnB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AA6CD,QAAA,MAAM,aAAa,GAAI,uIAYpB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/MessageBubble.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,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;IACnB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AA6CD,QAAA,MAAM,aAAa,GAAI,uIAYpB,kBAAkB,4CAsEpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -22,9 +22,9 @@ const MessageBubble = ({ isMine, content, senderName, showSenderName, showTip =
|
|
|
22
22
|
: isMine
|
|
23
23
|
? "bg-chat-bubble-mine/10"
|
|
24
24
|
: "bg-chat-bubble-neutral/10"));
|
|
25
|
-
return (_jsxs("div", { className: "relative flex min-w-0 max-w-full items-end", "data-testid": "message-bubble", "data-cp-name": "MessageBubble", onClick: () => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
return (_jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-1", children: [showSenderName && senderName && (_jsx("span", { "data-testid": "message-sender-name", className: "px-1 text-[12px] font-medium leading-[160%] tracking-[0.12px] text-gray-400", children: senderName })), _jsxs("div", { className: "relative flex min-w-0 max-w-full items-end", "data-testid": "message-bubble", "data-cp-name": "MessageBubble", onClick: () => {
|
|
26
|
+
if (timeLabel)
|
|
27
|
+
onToggleTimeReveal === null || onToggleTimeReveal === void 0 ? void 0 : onToggleTimeReveal();
|
|
28
|
+
}, children: [!isMine && showTail && (_jsx(MessageBubbleTail, { isMine: isMine, isInternal: isInternal })), _jsx("div", { className: bubbleClass, id: id, children: _jsx("div", { className: clsx("flex flex-col gap-2", !isTransparent && "px-1"), 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 }))] })] }));
|
|
29
29
|
};
|
|
30
30
|
export default MessageBubble;
|
|
@@ -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;AAyCtC,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;CACpD;
|
|
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;AAyCtC,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;CACpD;AAkCD,QAAA,MAAM,WAAW,GAAI,uOAelB,gBAAgB,mDA+UlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -25,9 +25,14 @@ import { isGroupNotificationMessageType, isSessionEventMessage, isSystemLogMessa
|
|
|
25
25
|
import { buildMessageToolboxMenuItems, getCopyableMessageText, isCopyableMessageType, isPinnableMessageType, MessageToolboxActionKey, MESSAGE_TOOLBOX_OVERLAY_CLASSNAME, useMessageToolboxVisibility, } from "../../../components/message/toolbox";
|
|
26
26
|
const MESSAGE_AVATAR_SIZE = 24;
|
|
27
27
|
const DIVIDER_GAP_MINUTES = 30;
|
|
28
|
+
const DIVIDER_GAP_MS = DIVIDER_GAP_MINUTES * 60 * 1000;
|
|
28
29
|
const GROUPING_GAP_MINUTES = 5;
|
|
29
30
|
const GROUPING_GAP_MS = GROUPING_GAP_MINUTES * 60 * 1000;
|
|
30
31
|
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; };
|
|
32
|
+
// Shared by showTimeBreak (day divider) and prevSameUser/nextSameUser (group
|
|
33
|
+
// break) so both features agree on the same calendar-day boundary — a group
|
|
34
|
+
// must never span a divider, regardless of how small the time gap is.
|
|
35
|
+
const isSameCalendarDay = (sendTimeA, sendTimeB) => dayjs(sendTimeA).isSame(sendTimeB, "day");
|
|
31
36
|
const MessageAvatar = ({ avatarUrl, senderNickname, }) => {
|
|
32
37
|
var _a;
|
|
33
38
|
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" }));
|
|
@@ -154,6 +159,7 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
154
159
|
!!previousMessage &&
|
|
155
160
|
!isOrderMessage(previousMessage) &&
|
|
156
161
|
previousMessage.sendID === (message === null || message === void 0 ? void 0 : message.sendID) &&
|
|
162
|
+
isSameCalendarDay(message.sendTime, previousMessage.sendTime) &&
|
|
157
163
|
Math.abs(dayjs(message.sendTime).diff(previousMessage.sendTime, "millisecond")) <=
|
|
158
164
|
GROUPING_GAP_MS;
|
|
159
165
|
const nextSameUser = !isOrder &&
|
|
@@ -161,12 +167,12 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
|
|
|
161
167
|
!!nextMessage &&
|
|
162
168
|
!isOrderMessage(nextMessage) &&
|
|
163
169
|
nextMessage.sendID === (message === null || message === void 0 ? void 0 : message.sendID) &&
|
|
170
|
+
isSameCalendarDay(nextMessage.sendTime, message.sendTime) &&
|
|
164
171
|
Math.abs(dayjs(nextMessage.sendTime).diff(message.sendTime, "millisecond")) <=
|
|
165
172
|
GROUPING_GAP_MS;
|
|
166
173
|
const showTimeBreak = !previousMessage ||
|
|
167
|
-
!
|
|
168
|
-
Math.abs(dayjs(message.sendTime).diff(previousMessage.sendTime, "
|
|
169
|
-
DIVIDER_GAP_MINUTES;
|
|
174
|
+
!isSameCalendarDay(message.sendTime, previousMessage.sendTime) ||
|
|
175
|
+
Math.abs(dayjs(message.sendTime).diff(previousMessage.sendTime, "millisecond")) > DIVIDER_GAP_MS;
|
|
170
176
|
const showPeerInfo = isGroupChat || showSenderInfo;
|
|
171
177
|
const showAvatar = showPeerInfo && !isMine && !nextSameUser;
|
|
172
178
|
const showSenderName = showPeerInfo && !isMine && !prevSameUser;
|
|
@@ -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,gFAM1B,iBAAiB,
|
|
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,gFAM1B,iBAAiB,4CA0GnB,CAAC"}
|
|
@@ -73,6 +73,8 @@ export const ChatProvider = ({ children, config, renderCustomMessage, onNavigate
|
|
|
73
73
|
wsAddress: config.wsAddr,
|
|
74
74
|
applicationType: config.applicationType,
|
|
75
75
|
isCrm: config.isCrm,
|
|
76
|
+
onTokenRefresh: config.onTokenRefresh,
|
|
77
|
+
onAuthError: config.onAuthError,
|
|
76
78
|
});
|
|
77
79
|
setUser({
|
|
78
80
|
userID: config.userID,
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"profile_hint": "Nhấn để xem thông tin",
|
|
73
73
|
"options_title": "Tuỳ chọn",
|
|
74
74
|
"input_placeholder": "Nhập tin nhắn...",
|
|
75
|
-
"view_only_notice": "Bạn
|
|
75
|
+
"view_only_notice": "Bạn cần tham gia nhóm để gửi tin nhắn",
|
|
76
76
|
"resolve_failed": "Không thể mở cuộc trò chuyện",
|
|
77
77
|
"more_option": {
|
|
78
78
|
"toggle": "Tùy chọn khác",
|