@droppii-org/chat-sdk 0.0.34 → 0.0.35

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.
@@ -10,8 +10,8 @@ import { formatTimestamp, parseLatestMessage } from "../../utils/common";
10
10
  const ConversationBySessionItem = ({ sessionItem, }) => {
11
11
  const { t } = useTranslation();
12
12
  const { user } = useChatContext();
13
- const conversation = useConversationStore((state) => state.conversationList.find((conv) => conv.conversationID === sessionItem.conversationId));
14
- const isSelected = useConversationStore((state) => state.selectedConversationId === sessionItem.conversationId);
13
+ const isSelected = useConversationStore((state) => { var _a; return state.selectedConversationId === ((_a = sessionItem === null || sessionItem === void 0 ? void 0 : sessionItem.conversation) === null || _a === void 0 ? void 0 : _a.conversationID); });
14
+ const conversation = sessionItem === null || sessionItem === void 0 ? void 0 : sessionItem.conversation;
15
15
  const router = useRouter();
16
16
  const pathname = usePathname();
17
17
  const searchParams = useSearchParams();
@@ -27,6 +27,8 @@ const ConversationBySessionItem = ({ sessionItem, }) => {
27
27
  const { avatar, displayName = "" } = useConversationDisplayData(conversation || null);
28
28
  if (!conversation)
29
29
  return null;
30
- return (_jsxs("div", { onClick: () => handleConversationClick(conversation), className: `relative p-3 border-b border-gray-100 hover:bg-gray-100 cursor-pointer transition-colors ${isSelected ? "bg-blue-50" : "bg-white"}`, children: [isSelected && (_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-1 bg-blue-500" })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "relative flex-shrink-0", children: _jsx(Badge, { dot: true, status: "success", offset: [-2, 36], children: _jsx(Avatar, { size: 48, src: avatar, alt: displayName, children: displayName.charAt(0).toUpperCase() }) }) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-semibold text-gray-900 text-sm truncate", children: displayName }), _jsx("p", { className: "text-xs text-gray-500 truncate mt-0.5", children: parseLatestMessage(conversation.latestMsg, user === null || user === void 0 ? void 0 : user.userID) })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [_jsx("span", { className: "text-xs text-gray-400", children: formatTimestamp(conversation.latestMsgSendTime) }), _jsx("div", { className: "flex items-center gap-1", children: conversation.unreadCount > 0 && (_jsx(Badge, { count: conversation.unreadCount })) })] })] }) })] })] }, conversation.conversationID));
30
+ return (_jsxs("div", { onClick: () => handleConversationClick(conversation), className: `relative p-3 border-b border-gray-100 hover:bg-gray-100 cursor-pointer transition-colors ${isSelected ? "bg-blue-50" : "bg-white"}`, children: [isSelected && (_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-1 bg-blue-500" })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "relative flex-shrink-0", children: _jsx(Badge, { dot: true, status: "success", offset: [-2, 36], children: _jsx(Avatar, { size: 48, src: avatar, alt: displayName, children: displayName.charAt(0).toUpperCase() }) }) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-semibold text-gray-900 text-sm truncate", children: displayName }), _jsx("p", { className: "text-xs text-gray-500 truncate mt-0.5", children: parseLatestMessage(conversation.latestMsg, user === null || user === void 0 ? void 0 : user.userID) })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [_jsx("span", { className: "text-xs text-gray-400", children: formatTimestamp(conversation.latestMsgSendTime, {
31
+ hasTime: false,
32
+ }) }), _jsx("div", { className: "flex items-center gap-1", children: conversation.unreadCount > 0 && (_jsx(Badge, { count: conversation.unreadCount })) })] })] }) })] })] }, conversation.conversationID));
31
33
  };
32
34
  export default ConversationBySessionItem;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AAoBA,UAAU,gBAAgB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA0J3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AAsBA,UAAU,gBAAgB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA0K3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -16,16 +16,30 @@ import useConversationStore from "../../store/conversation";
16
16
  import { isNumber } from "lodash";
17
17
  import { useDebounceFn } from "ahooks";
18
18
  import { MSG_ITEM_CONTENT_PREFIX, MSG_ITEM_PREFIX } from "../../constants";
19
+ import { markConversationMessageAsRead } from "../../hooks/conversation/useConversation";
20
+ import { useChatContext } from "../../context/ChatContext";
19
21
  dayjs.extend(isToday);
20
22
  const BOTTOM_THRESHOLD = -5;
21
23
  const MessageList = (props) => {
22
24
  var _a;
23
25
  const { t } = useTranslation();
26
+ const { user } = useChatContext();
24
27
  const { onClose, conversationId, searchClientMsgID } = props;
25
28
  const scrollRef = useRef(null);
26
- const { getMoreOldMessages, moreOldLoading, loadState, getMoreNewMessages, moreNewLoading, } = useMessage(conversationId, searchClientMsgID);
29
+ const { getMoreOldMessages, moreOldLoading, loadState, getMoreNewMessages, moreNewLoading, latestLoadState, } = useMessage(conversationId, searchClientMsgID);
27
30
  const conversationData = useConversationStore((state) => state.conversationData);
31
+ const handleMarkConversationMessageAsRead = () => {
32
+ var _a, _b, _c;
33
+ const lastMessage = (_b = (_a = latestLoadState === null || latestLoadState === void 0 ? void 0 : latestLoadState.current) === null || _a === void 0 ? void 0 : _a.messageList) === null || _b === void 0 ? void 0 : _b[0];
34
+ if (!((_c = latestLoadState === null || latestLoadState === void 0 ? void 0 : latestLoadState.current) === null || _c === void 0 ? void 0 : _c.hasMoreNew) &&
35
+ !moreNewLoading &&
36
+ (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.isRead) === false &&
37
+ (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.sendID) !== (user === null || user === void 0 ? void 0 : user.userID)) {
38
+ markConversationMessageAsRead(conversationId);
39
+ }
40
+ };
28
41
  const scrollToBottom = () => {
42
+ handleMarkConversationMessageAsRead();
29
43
  setTimeout(() => {
30
44
  var _a, _b, _c, _d;
31
45
  if (isNumber((_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.scrollTop) &&
@@ -80,7 +94,6 @@ const MessageList = (props) => {
80
94
  if (!conversationData) {
81
95
  return (_jsx("div", { className: "flex flex-1 items-center justify-center h-full", children: _jsx(Empty, { description: t("no_conversation_data") }) }));
82
96
  }
83
- console.log("moreNewLoading", moreNewLoading);
84
97
  return (_jsxs("div", { className: "flex flex-col flex-1 relative h-full", style: {
85
98
  backgroundImage: `url(${images.conversationBg})`,
86
99
  backgroundSize: "cover",
@@ -94,6 +107,7 @@ const MessageList = (props) => {
94
107
  }, children: _jsx(InfiniteScroll, { dataLength: ((_a = loadState.messageList) === null || _a === void 0 ? void 0 : _a.length) || 0, next: loadMoreOldMessage, style: { display: "flex", flexDirection: "column-reverse" }, inverse: true, hasMore: loadState.hasMoreOld, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableMessagesDiv", onScroll: (e) => {
95
108
  const target = e.target;
96
109
  if (target.scrollTop > BOTTOM_THRESHOLD) {
110
+ handleMarkConversationMessageAsRead();
97
111
  loadMoreNewMessage();
98
112
  }
99
113
  }, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array }, message.clientMsgID))) }) }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), _jsx(MessageFooter, {})] }));
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,IAAI,eAAe,EAE/B,MAAM,yBAAyB,CAAC;AAajC,UAAU,gBAAgB;IACxB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAID,QAAA,MAAM,WAAW,GAAI,0BAA0B,gBAAgB,mDAmH9D,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/index.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,WAAW,IAAI,eAAe,EAE/B,MAAM,yBAAyB,CAAC;AAYjC,UAAU,gBAAgB;IACxB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAID,QAAA,MAAM,WAAW,GAAI,0BAA0B,gBAAgB,mDAgH9D,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import dayjs from "dayjs";
3
3
  import clsx from "clsx";
4
4
  import { Avatar } from "antd";
5
- import isToday from "dayjs/plugin/isToday";
6
5
  import { useChatContext } from "../../../context/ChatContext";
7
6
  import { MessageType, } from "@openim/wasm-client-sdk";
8
7
  import TextMessageItem from "./TextMessage";
@@ -11,12 +10,11 @@ import FileMessageItem from "./FileMessage";
11
10
  import VideoMessageItem from "./VideoMessage";
12
11
  import { getVisibleNeighbor, visibleTypeMessage, } from "../../../hooks/message/useMessage";
13
12
  import { MSG_ITEM_CONTENT_PREFIX, MSG_ITEM_PREFIX } from "../../../constants";
14
- dayjs.extend(isToday);
13
+ import { formatTimestamp } from "../../../utils/common";
15
14
  const BREAK_TIME = 5;
16
15
  const MessageItem = ({ message, allMessages }) => {
17
16
  var _a, _b, _c, _d;
18
17
  const { user } = useChatContext();
19
- const isToday = dayjs(message === null || message === void 0 ? void 0 : message.sendTime).isToday();
20
18
  const isVisibleGroup = visibleTypeMessage.includes(message === null || message === void 0 ? void 0 : message.contentType);
21
19
  const renderMessageByType = (message) => {
22
20
  switch (message === null || message === void 0 ? void 0 : message.contentType) {
@@ -47,7 +45,7 @@ const MessageItem = ({ message, allMessages }) => {
47
45
  const showTimeBreak = prevTimeBreak;
48
46
  const isFirstInGroup = prevTimeBreak || !prevSameUser;
49
47
  const isLastInGroup = nextTimeBreak || !nextSameUser;
50
- return (_jsxs("div", { className: "flex flex-col gap-2 py-1 px-3 sm:p x-4", id: `${MSG_ITEM_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, children: [showTimeBreak && (_jsx("div", { className: "flex justify-center", children: _jsx("span", { className: "text-xs text-gray-600 text-center bg-neutral-100 px-2 py-1 rounded-full", children: dayjs(message === null || message === void 0 ? void 0 : message.sendTime).format(isToday ? "HH:mm" : "HH:mm, DD MMMM") }) })), _jsx("div", { className: clsx("flex", isMine ? "justify-end" : "justify-start"), children: _jsxs("div", { className: clsx("flex flex-1 items-end gap-2", isMine ? "justify-end" : "justify-start"), children: [!isMine && (_jsx("div", { className: "flex items-center justify-center w-[32px] h-[32px]", children: isLastInGroup && (_jsx(Avatar, { children: ((_b = (_a = message === null || message === void 0 ? void 0 : message.senderNickname) === null || _a === void 0 ? void 0 : _a.charAt) === null || _b === void 0 ? void 0 : _b.call(_a, 0)) || "A" })) })), _jsxs("div", { className: clsx("flex flex-col flex-[0.8]", isMine ? "items-end" : "items-start"), children: [isFirstInGroup && !isMine && (_jsx("span", { className: "text-xs text-gray-500 mb-1 px-3", children: message === null || message === void 0 ? void 0 : message.senderNickname })), _jsxs("div", { className: clsx("px-3 py-2 rounded-2xl max-w-full break-words flex flex-col flex-1 text-gray-900 gap-1", isMine ? "bg-blue-100" : "bg-white"), id: `${MSG_ITEM_CONTENT_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, children: [(message === null || message === void 0 ? void 0 : message.contentType) === MessageType.MergeMessage ? (_jsxs("div", { children: [(_d = (_c = message === null || message === void 0 ? void 0 : message.mergeElem) === null || _c === void 0 ? void 0 : _c.multiMessage) === null || _d === void 0 ? void 0 : _d.map((item) => {
48
+ return (_jsxs("div", { className: "flex flex-col gap-2 py-1 px-3 sm:p x-4", id: `${MSG_ITEM_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, children: [showTimeBreak && (_jsx("div", { className: "flex justify-center", children: _jsx("span", { className: "text-xs text-gray-600 text-center bg-neutral-100 px-2 py-1 rounded-full", children: formatTimestamp(message.sendTime) }) })), _jsx("div", { className: clsx("flex", isMine ? "justify-end" : "justify-start"), children: _jsxs("div", { className: clsx("flex flex-1 items-end gap-2", isMine ? "justify-end" : "justify-start"), children: [!isMine && (_jsx("div", { className: "flex items-center justify-center w-[32px] h-[32px]", children: isLastInGroup && (_jsx(Avatar, { children: ((_b = (_a = message === null || message === void 0 ? void 0 : message.senderNickname) === null || _a === void 0 ? void 0 : _a.charAt) === null || _b === void 0 ? void 0 : _b.call(_a, 0)) || "A" })) })), _jsxs("div", { className: clsx("flex flex-col flex-[0.8]", isMine ? "items-end" : "items-start"), children: [isFirstInGroup && !isMine && (_jsx("span", { className: "text-xs text-gray-500 mb-1 px-3", children: message === null || message === void 0 ? void 0 : message.senderNickname })), _jsxs("div", { className: clsx("px-3 py-2 rounded-2xl max-w-full break-words flex flex-col flex-1 text-gray-900 gap-1", isMine ? "bg-blue-100" : "bg-white"), id: `${MSG_ITEM_CONTENT_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, children: [(message === null || message === void 0 ? void 0 : message.contentType) === MessageType.MergeMessage ? (_jsxs("div", { children: [(_d = (_c = message === null || message === void 0 ? void 0 : message.mergeElem) === null || _c === void 0 ? void 0 : _c.multiMessage) === null || _d === void 0 ? void 0 : _d.map((item) => {
51
49
  return renderMessageByType(item);
52
50
  }), (message === null || message === void 0 ? void 0 : message.textElem) && _jsx(TextMessageItem, { message: message })] })) : (renderMessageByType(message)), _jsx("span", { className: clsx("text-xs text-gray-500 text-right text-gray-500"), children: dayjs(message === null || message === void 0 ? void 0 : message.sendTime).format("HH:mm") })] })] })] }) }, message === null || message === void 0 ? void 0 : message.clientMsgID)] }, message === null || message === void 0 ? void 0 : message.clientMsgID));
53
51
  };
@@ -27,6 +27,6 @@ const SearchConversationAll = ({ searchTerm = "", setActiveKey, }) => {
27
27
  if (isLoadingMessage || isLoadingSession) {
28
28
  return (_jsx("div", { className: "h-full overflow-auto flex items-center justify-center", children: _jsx(Spin, {}) }));
29
29
  }
30
- return (_jsxs("div", { className: "h-full overflow-auto", children: [sessions.length > 0 && (_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between px-3", children: [_jsx("span", { className: "text-xs font-medium uppercase flex-1 text-gray-600", children: t("users") }), hasNextPageMessage && (_jsx(Button, { type: "link", icon: _jsx(Icon, { icon: "angle-right-o", size: 18, className: "!align-[-4px]" }), iconPosition: "end", className: "p-0 gap-1", onClick: () => setActiveKey === null || setActiveKey === void 0 ? void 0 : setActiveKey(SearchConversationTabKey.Users), children: t("see_more") }))] }), _jsx("div", { children: sessions.map((session) => (_jsx(SearchItemAsUser, { session: session, searchTerm: searchTerm }))) })] })), messages.length > 0 && (_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between px-3", children: [_jsx("span", { className: "text-xs font-medium uppercase flex-1 text-gray-600", children: t("messages") }), hasNextPageSession && (_jsx(Button, { type: "link", icon: _jsx(Icon, { icon: "angle-right-o", size: 18, className: "!align-[-4px]" }), iconPosition: "end", className: "p-0 gap-1", onClick: () => setActiveKey === null || setActiveKey === void 0 ? void 0 : setActiveKey(SearchConversationTabKey.Messages), children: t("see_more") }))] }), _jsx("div", { children: messages.map((message) => (_jsx(SearchItemAsMessage, { message: message.chatLog, searchTerm: searchTerm }))) })] }))] }));
30
+ return (_jsxs("div", { className: "h-full overflow-auto", children: [sessions.length > 0 && (_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between px-3", children: [_jsx("span", { className: "text-xs font-medium uppercase flex-1 text-gray-600", children: t("users") }), hasNextPageSession && (_jsx(Button, { type: "link", icon: _jsx(Icon, { icon: "angle-right-o", size: 18, className: "!align-[-4px]" }), iconPosition: "end", className: "p-0 gap-1", onClick: () => setActiveKey === null || setActiveKey === void 0 ? void 0 : setActiveKey(SearchConversationTabKey.Users), children: t("see_more") }))] }), _jsx("div", { children: sessions.map((session) => (_jsx(SearchItemAsUser, { session: session, searchTerm: searchTerm }))) })] })), messages.length > 0 && (_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between px-3", children: [_jsx("span", { className: "text-xs font-medium uppercase flex-1 text-gray-600", children: t("messages") }), hasNextPageMessage && (_jsx(Button, { type: "link", icon: _jsx(Icon, { icon: "angle-right-o", size: 18, className: "!align-[-4px]" }), iconPosition: "end", className: "p-0 gap-1", onClick: () => setActiveKey === null || setActiveKey === void 0 ? void 0 : setActiveKey(SearchConversationTabKey.Messages), children: t("see_more") }))] }), _jsx("div", { children: messages.map((message) => (_jsx(SearchItemAsMessage, { message: message.chatLog, searchTerm: searchTerm }))) })] }))] }));
31
31
  };
32
32
  export default SearchConversationAll;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/searchConversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AASnE,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CAsE3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/searchConversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AASnE,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CAwE3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -42,7 +42,9 @@ const SearchItemAsMessage = (props) => {
42
42
  msgContent = message === null || message === void 0 ? void 0 : message.content;
43
43
  }
44
44
  }
45
- return (_jsxs("div", { className: "py-3 px-2 flex items-center gap-3 hover:bg-gray-100 hover:rounded-sm cursor-pointer border-b mx-1", onClick: onPressItem, children: [_jsx("div", { children: _jsx(Avatar, { size: "large", src: message.senderFaceUrl, alt: message.senderNickname, children: message.senderNickname.charAt(0).toUpperCase() }) }), _jsxs("div", { className: "flex flex-col flex-1 min-w-0 gap-1", children: [_jsxs("div", { className: "flex flex-1 items-center justify-between", children: [_jsx("span", { className: "text-sm flex-1 font-semibold truncate", children: message.senderNickname }), _jsx("span", { className: "text-xs text-gray-500", children: formatTimestamp(message.sendTime) })] }), _jsx("div", { className: "flex flex-col flex-1 min-w-0", children: _jsx("span", { className: "text-xs flex-1 text-gray-500 truncate", dangerouslySetInnerHTML: {
45
+ return (_jsxs("div", { className: "py-3 px-2 flex items-center gap-3 hover:bg-gray-100 hover:rounded-sm cursor-pointer border-b mx-1", onClick: onPressItem, children: [_jsx("div", { children: _jsx(Avatar, { size: "large", src: message.senderFaceUrl, alt: message.senderNickname, children: message.senderNickname.charAt(0).toUpperCase() }) }), _jsxs("div", { className: "flex flex-col flex-1 min-w-0 gap-1", children: [_jsxs("div", { className: "flex flex-1 items-center justify-between", children: [_jsx("span", { className: "text-sm flex-1 font-semibold truncate", children: message.senderNickname }), _jsx("span", { className: "text-xs text-gray-500", children: formatTimestamp(message.sendTime, {
46
+ hasTime: false,
47
+ }) })] }), _jsx("div", { className: "flex flex-col flex-1 min-w-0", children: _jsx("span", { className: "text-xs flex-1 text-gray-500 truncate", dangerouslySetInnerHTML: {
46
48
  __html: highlightSearch(msgContent, searchTerm),
47
49
  } }) })] })] }, message.clientMsgID));
48
50
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DeskAssignedSession.d.ts","sourceRoot":"","sources":["../../../src/components/session/DeskAssignedSession.tsx"],"names":[],"mappings":"AAeA,QAAA,MAAM,mBAAmB,+CAkNxB,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"DeskAssignedSession.d.ts","sourceRoot":"","sources":["../../../src/components/session/DeskAssignedSession.tsx"],"names":[],"mappings":"AAeA,QAAA,MAAM,mBAAmB,+CAwNxB,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -16,7 +16,7 @@ const DeskAssignedSession = () => {
16
16
  const setFilterSummary = useSessionStore((state) => state.setFilterSummary);
17
17
  const { data: sessionSummary } = useGetSessionSummary();
18
18
  const menuItems = useMemo(() => {
19
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
19
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
20
20
  return [
21
21
  {
22
22
  label: t("active_sessions"),
@@ -45,7 +45,7 @@ const DeskAssignedSession = () => {
45
45
  tag: TAG_ENUM.SLOW_PROCESSING,
46
46
  });
47
47
  },
48
- extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_d = (_c = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.sessionStatuses) === null || _c === void 0 ? void 0 : _c.find((s) => s.type === TAG_ENUM.SLOW_PROCESSING)) === null || _d === void 0 ? void 0 : _d.count) || "" })),
48
+ extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_d = (_c = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.tagCounts) === null || _c === void 0 ? void 0 : _c.find((s) => s.type === TAG_ENUM.SLOW_PROCESSING)) === null || _d === void 0 ? void 0 : _d.count) || "" })),
49
49
  },
50
50
  {
51
51
  label: t("waiting_process"),
@@ -69,7 +69,7 @@ const DeskAssignedSession = () => {
69
69
  tag: TAG_ENUM.AWAITING_REPLY,
70
70
  });
71
71
  },
72
- extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_h = (_g = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.sessionStatuses) === null || _g === void 0 ? void 0 : _g.find((s) => s.type === TAG_ENUM.AWAITING_REPLY)) === null || _h === void 0 ? void 0 : _h.count) || "" })),
72
+ extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_h = (_g = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.tagCounts) === null || _g === void 0 ? void 0 : _g.find((s) => s.type === TAG_ENUM.AWAITING_REPLY)) === null || _h === void 0 ? void 0 : _h.count) || "" })),
73
73
  },
74
74
  {
75
75
  label: t("in_process"),
@@ -93,14 +93,13 @@ const DeskAssignedSession = () => {
93
93
  tag: TAG_ENUM.TEMPORARILY_PAUSED,
94
94
  });
95
95
  },
96
- extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_m = (_l = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.sessionStatuses) === null || _l === void 0 ? void 0 : _l.find((s) => s.type === TAG_ENUM.TEMPORARILY_PAUSED)) === null || _m === void 0 ? void 0 : _m.count) || "" })),
96
+ extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_m = (_l = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.tagCounts) === null || _l === void 0 ? void 0 : _l.find((s) => s.type === TAG_ENUM.TEMPORARILY_PAUSED)) === null || _m === void 0 ? void 0 : _m.count) || "" })),
97
97
  },
98
98
  ],
99
- expandIcon: undefined,
100
- extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_p = (_o = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.sessionStatuses) === null || _o === void 0 ? void 0 : _o.find((s) => s.type === SESSION_STATUS_ENUM.IN_PROCESS)) === null || _p === void 0 ? void 0 : _p.count) || "" })),
99
+ extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_p = (_o = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.sessionStatuses) === null || _o === void 0 ? void 0 : _o.find((s) => s.type === SESSION_STATUS_ENUM.IN_PROCESS)) === null || _p === void 0 ? void 0 : _p.count) || "100" })),
101
100
  },
102
101
  {
103
- label: t("closed_sessions"),
102
+ label: (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "ant-menu-title-content ant-menu-title-content-with-extra flex-1", children: t("closed_sessions") }), _jsx("span", { className: "text-xs text-gray-500", children: (sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.completedSessionCount) || "" })] })),
104
103
  key: "CLOSED_SESSIONS",
105
104
  icon: _jsx(Icon, { icon: "check-square-o", size: 20 }),
106
105
  onClick: () => {
@@ -109,10 +108,9 @@ const DeskAssignedSession = () => {
109
108
  tag: undefined,
110
109
  });
111
110
  },
112
- extra: (_jsx("span", { className: "text-xs text-gray-500", children: ((_r = (_q = sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.sessionStatuses) === null || _q === void 0 ? void 0 : _q.find((s) => s.type === SESSION_STATUS_ENUM.COMPLETED)) === null || _r === void 0 ? void 0 : _r.count) || "" })),
113
111
  },
114
112
  ];
115
113
  }, [sessionSummary]);
116
- return (_jsxs(Sider, { collapsible: true, collapsed: collapsed, onCollapse: toggle, width: 220, className: "bg-white h-full border-r border-gray-200", trigger: null, children: [_jsxs("div", { className: clsx("flex items-center p-4 border-b", collapsed ? "justify-center" : "justify-between"), children: [!collapsed && (_jsx("span", { className: "text-md font-semibold flex-1 truncate", children: "Droppii Staging" })), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: toggle, children: _jsx(Icon, { icon: collapsed ? "angle-right-o" : "angle-left-o", size: 22 }) })] }), _jsx(Menu, { defaultSelectedKeys: [SESSION_STATUS_ENUM.IN_PROCESS], defaultOpenKeys: ["ACTIVE_SESSIONS"], mode: "inline", items: menuItems, inlineIndent: 12 })] }));
114
+ return (_jsxs(Sider, { collapsible: true, collapsed: collapsed, onCollapse: toggle, width: 220, className: "bg-white h-full border-r border-gray-200", trigger: null, children: [_jsxs("div", { className: clsx("flex items-center p-4 border-b", collapsed ? "justify-center" : "justify-between"), children: [!collapsed && (_jsx("span", { className: "text-md font-semibold flex-1 truncate", children: "Droppii Staging" })), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: toggle, children: _jsx(Icon, { icon: collapsed ? "angle-right-o" : "angle-left-o", size: 22 }) })] }), _jsx(Menu, { defaultSelectedKeys: [SESSION_STATUS_ENUM.IN_PROCESS], defaultOpenKeys: ["ACTIVE_SESSIONS"], mode: "inline", items: menuItems, inlineIndent: 12, expandIcon: _jsx("span", { className: "text-xs text-gray-500", children: sessionSummary === null || sessionSummary === void 0 ? void 0 : sessionSummary.activeSessionCount }) })] }));
117
115
  };
118
116
  export default DeskAssignedSession;
@@ -1 +1 @@
1
- {"version":3,"file":"useGetSession.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useGetSession.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAA+B,MAAM,iBAAiB,CAAC;AAE5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAOpE,eAAO,MAAM,aAAa,GACxB,QAAQ,cAAc,EACtB,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4EhC,CAAC"}
1
+ {"version":3,"file":"useGetSession.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useGetSession.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAA+B,MAAM,iBAAiB,CAAC;AAE5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAOpE,eAAO,MAAM,aAAa,GACxB,QAAQ,cAAc,EACtB,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4FhC,CAAC"}
@@ -20,6 +20,7 @@ import { DChatSDK } from "../../constants/sdk";
20
20
  import useAuthStore from "../../store/auth";
21
21
  import { PAGE_SIZE } from "../../constants";
22
22
  export const useGetSession = (filter, options) => {
23
+ const conversationList = useConversationStore((state) => state.conversationList);
23
24
  const _a = useInfiniteQuery({
24
25
  initialPageParam: 1,
25
26
  queryKey: [QUERY_KEYS.GET_SESSION_BY_TAG_OR_STATUS, filter, options],
@@ -58,15 +59,22 @@ export const useGetSession = (filter, options) => {
58
59
  enabled: hasValidFilter(filter),
59
60
  }), { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = _a, rest = __rest(_a, ["data", "fetchNextPage", "hasNextPage", "isFetchingNextPage", "isLoading"]);
60
61
  const { dataFlatten } = useMemo(() => {
61
- if (!data)
62
- return {
63
- dataFlatten: [],
64
- };
62
+ if (!data) {
63
+ return { dataFlatten: [] };
64
+ }
65
65
  const allItems = data.pages.flatMap((page) => page.data);
66
- return {
67
- dataFlatten: allItems,
68
- };
69
- }, [data]);
66
+ // Map session theo conversationId
67
+ const sessionMap = new Map(allItems.map((s) => [s.conversationId, s]));
68
+ const merged = conversationList
69
+ .map((conv) => {
70
+ const session = sessionMap.get(conv.conversationID);
71
+ if (!session)
72
+ return null;
73
+ return Object.assign(Object.assign({}, session), { conversation: conv });
74
+ })
75
+ .filter((x) => Boolean(x));
76
+ return { dataFlatten: merged };
77
+ }, [data, conversationList]);
70
78
  return Object.assign({ data,
71
79
  fetchNextPage,
72
80
  hasNextPage,
@@ -1,5 +1,9 @@
1
1
  export declare function renderFileSize(bytes: number): string;
2
2
  export declare const parseLatestMessage: (latestMsg: string, currentUserId?: string) => string;
3
- export declare const formatTimestamp: (timestamp: number) => string;
4
3
  export declare const highlightSearch: (text: string, keyword: string, maxLength?: number) => string;
4
+ interface FormatOptions {
5
+ hasTime?: boolean;
6
+ }
7
+ export declare function formatTimestamp(timestamp: number, options?: FormatOptions): string;
8
+ export {};
5
9
  //# sourceMappingURL=common.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAapD;AAED,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,EACjB,gBAAgB,MAAM,WAgCvB,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,WAAW,MAAM,KAAG,MA4BnD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,kBAAc,WA2Cf,CAAC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAapD;AAED,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,EACjB,gBAAgB,MAAM,WAgCvB,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,kBAAc,WA2Cf,CAAC;AAEF,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAiBR"}
@@ -1,4 +1,5 @@
1
1
  import { MessageType } from "@openim/wasm-client-sdk";
2
+ import dayjs from "dayjs";
2
3
  export function renderFileSize(bytes) {
3
4
  if (!bytes || bytes <= 0)
4
5
  return "0 B";
@@ -44,37 +45,6 @@ export const parseLatestMessage = (latestMsg, currentUserId) => {
44
45
  return "";
45
46
  }
46
47
  };
47
- export const formatTimestamp = (timestamp) => {
48
- if (!timestamp)
49
- return "";
50
- const date = new Date(timestamp);
51
- const now = new Date();
52
- const diffInMs = now.getTime() - date.getTime();
53
- const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24));
54
- if (diffInDays === 0) {
55
- // Today - show time
56
- return date.toLocaleTimeString("vi-VN", {
57
- hour: "2-digit",
58
- minute: "2-digit",
59
- hour12: false,
60
- });
61
- }
62
- else if (diffInDays === 1) {
63
- // Yesterday
64
- return "Hôm qua";
65
- }
66
- else if (diffInDays < 7) {
67
- // This week - show day name
68
- return date.toLocaleDateString("vi-VN", { weekday: "long" });
69
- }
70
- else {
71
- // Older - show date
72
- return date.toLocaleDateString("vi-VN", {
73
- day: "2-digit",
74
- month: "2-digit",
75
- });
76
- }
77
- };
78
48
  export const highlightSearch = (text, keyword, maxLength = 30) => {
79
49
  if (!keyword)
80
50
  return text;
@@ -108,3 +78,18 @@ export const highlightSearch = (text, keyword, maxLength = 30) => {
108
78
  const displayedAfter = after.length > right ? after.slice(0, right) + "…" : after;
109
79
  return `${displayedBefore}<mark>${match}</mark>${displayedAfter}`;
110
80
  };
81
+ export function formatTimestamp(timestamp, options) {
82
+ const { hasTime = true } = options || {};
83
+ const date = dayjs(timestamp);
84
+ const now = dayjs();
85
+ if (date.isSame(now, "day")) {
86
+ // hôm nay
87
+ return date.format("HH:mm");
88
+ }
89
+ if (date.isSame(now, "year")) {
90
+ // cùng năm
91
+ return hasTime ? date.format(`HH:mm DD/MM`) : date.format("DD/MM");
92
+ }
93
+ // khác năm
94
+ return hasTime ? date.format(`HH:mm DD/MM YYYY`) : date.format("DD/MM YYYY");
95
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droppii-org/chat-sdk",
3
- "version": "0.0.34",
3
+ "version": "0.0.35",
4
4
  "description": "Droppii React Chat SDK",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",