@droppii-org/chat-sdk 0.1.18 → 0.1.20

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.
Files changed (108) hide show
  1. package/dist/components/conversation/ConversationBySessionItem.d.ts +3 -1
  2. package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
  3. package/dist/components/conversation/ConversationBySessionItem.js +4 -7
  4. package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
  5. package/dist/components/conversation/DeskConversationList.js +6 -2
  6. package/dist/components/message/GroupMembersDrawer.d.ts +4 -1
  7. package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
  8. package/dist/components/message/GroupMembersDrawer.js +39 -5
  9. package/dist/components/message/MessageHeader.d.ts +2 -1
  10. package/dist/components/message/MessageHeader.d.ts.map +1 -1
  11. package/dist/components/message/MessageHeader.js +3 -4
  12. package/dist/components/message/MessageList.d.ts.map +1 -1
  13. package/dist/components/message/MessageList.js +8 -20
  14. package/dist/components/message/UnassignedSessionFooter.d.ts +7 -0
  15. package/dist/components/message/UnassignedSessionFooter.d.ts.map +1 -0
  16. package/dist/components/message/UnassignedSessionFooter.js +26 -0
  17. package/dist/components/searchConversation/SearchAll.d.ts.map +1 -1
  18. package/dist/components/searchConversation/SearchAll.js +5 -3
  19. package/dist/components/searchConversation/SearchConversationAsMessages.d.ts.map +1 -1
  20. package/dist/components/searchConversation/SearchConversationAsMessages.js +1 -1
  21. package/dist/components/searchConversation/SearchConversationAsUsers.js +1 -1
  22. package/dist/components/searchConversation/SearchConversationMyInbox.d.ts +6 -0
  23. package/dist/components/searchConversation/SearchConversationMyInbox.d.ts.map +1 -0
  24. package/dist/components/searchConversation/SearchConversationMyInbox.js +24 -0
  25. package/dist/components/searchConversation/SearchMessageOnCurrentConversation.d.ts.map +1 -1
  26. package/dist/components/searchConversation/SearchMessageOnCurrentConversation.js +1 -1
  27. package/dist/components/searchConversation/index.d.ts +1 -0
  28. package/dist/components/searchConversation/index.d.ts.map +1 -1
  29. package/dist/components/searchConversation/index.js +8 -1
  30. package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts +1 -0
  31. package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts.map +1 -1
  32. package/dist/components/searchConversation/item/SearchItemAsMessage.js +4 -4
  33. package/dist/components/thread/ManualAssignPopover.d.ts +5 -2
  34. package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
  35. package/dist/components/thread/ManualAssignPopover.js +40 -21
  36. package/dist/components/thread/SessionSection.d.ts.map +1 -1
  37. package/dist/components/thread/SessionSection.js +4 -2
  38. package/dist/components/thread/ThreadInfo.d.ts.map +1 -1
  39. package/dist/components/thread/ThreadInfo.js +2 -1
  40. package/dist/constants/index.d.ts +6 -1
  41. package/dist/constants/index.d.ts.map +1 -1
  42. package/dist/constants/index.js +6 -1
  43. package/dist/hooks/cannedResponse/useFetchCannedResponse.js +2 -2
  44. package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
  45. package/dist/hooks/global/useGlobalEvent.js +11 -0
  46. package/dist/hooks/group/useGroupMembers.d.ts.map +1 -1
  47. package/dist/hooks/group/useGroupMembers.js +17 -0
  48. package/dist/hooks/message/useMessage.js +5 -5
  49. package/dist/hooks/message/usePullSessionMessages.d.ts +2 -0
  50. package/dist/hooks/message/usePullSessionMessages.d.ts.map +1 -1
  51. package/dist/hooks/message/usePullSessionMessages.js +18 -15
  52. package/dist/hooks/search/useSearchMessage.d.ts +2 -1
  53. package/dist/hooks/search/useSearchMessage.d.ts.map +1 -1
  54. package/dist/hooks/search/useSearchMessage.js +9 -9
  55. package/dist/hooks/session/useAssignSession.d.ts +4 -0
  56. package/dist/hooks/session/useAssignSession.d.ts.map +1 -1
  57. package/dist/hooks/session/useAssignSession.js +44 -11
  58. package/dist/hooks/session/useConversationSessionState.d.ts +1 -8
  59. package/dist/hooks/session/useConversationSessionState.d.ts.map +1 -1
  60. package/dist/hooks/session/useConversationSessionState.js +2 -25
  61. package/dist/hooks/session/useGetListSessionByConversation.d.ts.map +1 -1
  62. package/dist/hooks/session/useGetListSessionByConversation.js +2 -1
  63. package/dist/hooks/session/useGetSession.d.ts.map +1 -1
  64. package/dist/hooks/session/useGetSession.js +2 -2
  65. package/dist/hooks/session/useGetTeamSupporters.d.ts +2 -1
  66. package/dist/hooks/session/useGetTeamSupporters.d.ts.map +1 -1
  67. package/dist/hooks/session/useGetTeamSupporters.js +2 -2
  68. package/dist/hooks/session/useIsJoinedGroup.d.ts +1 -1
  69. package/dist/hooks/session/useIsJoinedGroup.d.ts.map +1 -1
  70. package/dist/hooks/session/useIsJoinedGroup.js +13 -19
  71. package/dist/hooks/session/useJoinGroupFlow.d.ts +8 -6
  72. package/dist/hooks/session/useJoinGroupFlow.d.ts.map +1 -1
  73. package/dist/hooks/session/useJoinGroupFlow.js +19 -57
  74. package/dist/hooks/session/useJoinSession.d.ts.map +1 -1
  75. package/dist/hooks/session/useJoinSession.js +3 -0
  76. package/dist/hooks/session/useLeaveConversation.d.ts +5 -0
  77. package/dist/hooks/session/useLeaveConversation.d.ts.map +1 -0
  78. package/dist/hooks/session/useLeaveConversation.js +35 -0
  79. package/dist/hooks/session/useSessionLatestPreview.d.ts +7 -0
  80. package/dist/hooks/session/useSessionLatestPreview.d.ts.map +1 -0
  81. package/dist/hooks/session/useSessionLatestPreview.js +82 -0
  82. package/dist/hooks/session/useSortedSessions.d.ts +4 -0
  83. package/dist/hooks/session/useSortedSessions.d.ts.map +1 -0
  84. package/dist/hooks/session/useSortedSessions.js +13 -0
  85. package/dist/hooks/session/useSyncGroupStateAfterJoin.d.ts +9 -0
  86. package/dist/hooks/session/useSyncGroupStateAfterJoin.d.ts.map +1 -0
  87. package/dist/hooks/session/useSyncGroupStateAfterJoin.js +23 -0
  88. package/dist/index.d.ts +1 -0
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +1 -0
  91. package/dist/locales/vi/common.json +13 -2
  92. package/dist/services/query.d.ts +3 -0
  93. package/dist/services/query.d.ts.map +1 -1
  94. package/dist/services/query.js +3 -0
  95. package/dist/services/routes.d.ts +2 -0
  96. package/dist/services/routes.d.ts.map +1 -1
  97. package/dist/services/routes.js +2 -0
  98. package/dist/store/conversation.d.ts.map +1 -1
  99. package/dist/store/conversation.js +5 -2
  100. package/dist/styles/global.css +1 -1
  101. package/dist/tsconfig.tsbuildinfo +1 -1
  102. package/dist/types/dto.d.ts +4 -0
  103. package/dist/types/dto.d.ts.map +1 -1
  104. package/dist/utils/events.d.ts +1 -0
  105. package/dist/utils/events.d.ts.map +1 -1
  106. package/dist/utils/messageTransform.d.ts.map +1 -1
  107. package/dist/utils/messageTransform.js +1 -1
  108. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
+ import type { LatestPreview } from "../../hooks/session/useSessionLatestPreview";
1
2
  import { ISessionByStatus } from "../../store/type";
2
3
  interface ConversationBySessionItemProps {
3
4
  sessionItem: ISessionByStatus;
5
+ latestPreview?: LatestPreview;
4
6
  }
5
- declare const ConversationBySessionItem: ({ sessionItem, }: ConversationBySessionItemProps) => import("react/jsx-runtime").JSX.Element | null;
7
+ declare const ConversationBySessionItem: ({ sessionItem, latestPreview, }: ConversationBySessionItemProps) => import("react/jsx-runtime").JSX.Element | null;
6
8
  export default ConversationBySessionItem;
7
9
  //# sourceMappingURL=ConversationBySessionItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AASpD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,kBAEhC,8BAA8B,mDAgGhC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
1
+ {"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAEjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAQpD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,iCAGhC,8BAA8B,mDAyFhC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
@@ -6,9 +6,8 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation";
6
6
  import { Avatar, Badge } from "antd";
7
7
  import { useChatContext } from "../../context/ChatContext";
8
8
  import { useConversationDisplayData } from "../../hooks/conversation/useConversation";
9
- import { useConversationPreview } from "../../hooks/conversation/useConversationPreview";
10
9
  import { formatTimestamp, parseLatestMessage } from "../../utils/common";
11
- const ConversationBySessionItem = ({ sessionItem, }) => {
10
+ const ConversationBySessionItem = ({ sessionItem, latestPreview, }) => {
12
11
  var _a;
13
12
  const { t } = useTranslation();
14
13
  const user = useChatContext().user;
@@ -31,13 +30,11 @@ const ConversationBySessionItem = ({ sessionItem, }) => {
31
30
  setSelectedConversationId(conversation.conversationID);
32
31
  };
33
32
  const { avatar, displayName = "" } = useConversationDisplayData(conversation || null);
34
- const { latestMsg, latestMsgSendTime } = useConversationPreview({
35
- conversation,
36
- ownerUserID: sessionItem.ownerId,
37
- });
33
+ const latestMsg = (latestPreview === null || latestPreview === void 0 ? void 0 : latestPreview.latestMsg) || "";
34
+ const latestMsgSendTime = (latestPreview === null || latestPreview === void 0 ? void 0 : latestPreview.latestMsgSendTime) || 0;
38
35
  if (!conversation)
39
36
  return null;
40
- 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, children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }) }) }), _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(latestMsg, user === null || user === void 0 ? void 0 : user.userID, t) })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [latestMsgSendTime > 0 && (_jsx("span", { className: "text-xs text-gray-400", children: formatTimestamp(latestMsgSendTime, {
37
+ 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(Avatar, { size: 48, src: avatar, children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }) }), _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(latestMsg, user === null || user === void 0 ? void 0 : user.userID, t) })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [latestMsgSendTime > 0 && (_jsx("span", { className: "text-xs text-gray-400", children: formatTimestamp(latestMsgSendTime, {
41
38
  hasTime: true,
42
39
  }) })), _jsx("div", { className: "flex items-center gap-1", children: conversation.unreadCount > 0 && (_jsx(Badge, { count: conversation.unreadCount })) })] })] }) })] })] }, conversation.conversationID));
43
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DeskConversationList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/DeskConversationList.tsx"],"names":[],"mappings":"AAoBA,QAAA,MAAM,oBAAoB,+CAoMzB,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"DeskConversationList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/DeskConversationList.tsx"],"names":[],"mappings":"AAsBA,QAAA,MAAM,oBAAoB,+CAgNzB,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -12,6 +12,8 @@ import useSessionStore from "../../store/session";
12
12
  import InfiniteScroll from "react-infinite-scroll-component";
13
13
  import ConversationBySessionItem from "./ConversationBySessionItem";
14
14
  import { useGetSession } from "../../hooks/session/useGetSession";
15
+ import { useSortedSessions } from "../../hooks/session/useSortedSessions";
16
+ import { useSessionLatestPreview } from "../../hooks/session/useSessionLatestPreview";
15
17
  import { useGetTeamSessionSummary } from "../../hooks/session/useGetTeamSessionSummary";
16
18
  import { DChatSDK } from "../../constants/sdk";
17
19
  import emitter from "../../utils/events";
@@ -29,7 +31,9 @@ const DeskConversationList = () => {
29
31
  const updateConversationList = useConversationStore((state) => state.updateConversationList);
30
32
  const filterSummary = useSessionStore((state) => state.filterSummary);
31
33
  const { data: teamSummaries } = useGetTeamSessionSummary();
32
- const { dataFlatten: sessions, hasNextPage, fetchNextPage, refetch } = useGetSession({ filter: filterSummary });
34
+ const { dataFlatten: rawSessions, hasNextPage, fetchNextPage, refetch, } = useGetSession({ filter: filterSummary });
35
+ const latestPreviewMap = useSessionLatestPreview(rawSessions);
36
+ const sessions = useSortedSessions(rawSessions, latestPreviewMap);
33
37
  const currentFilterKey = filterSummary.status || filterSummary.tag || "";
34
38
  const filterConfig = getFilterConfig(currentFilterKey);
35
39
  const pathName = filterSummary.teamId
@@ -91,7 +95,7 @@ const DeskConversationList = () => {
91
95
  height: "100%",
92
96
  overflow: showSearch ? "hidden" : "auto",
93
97
  position: "relative",
94
- }, children: [_jsx(InfiniteScroll, { dataLength: (sessions === null || sessions === void 0 ? void 0 : sessions.length) || 0, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableConversationsDiv", children: (sessions === null || sessions === void 0 ? void 0 : sessions.length) === 0 ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Empty, { image: _jsx(Icon, { icon: "chat-square-b", size: 80, className: "text-gray-300" }), description: t("no_conversation") }) })) : ((_b = sessions === null || sessions === void 0 ? void 0 : sessions.map) === null || _b === void 0 ? void 0 : _b.call(sessions, (session) => (_jsx(ConversationBySessionItem, { sessionItem: session }, session.conversationId)))) }), _jsx(Drawer, { open: showSearch, mask: false, closeIcon: false, styles: {
98
+ }, children: [_jsx(InfiniteScroll, { dataLength: (sessions === null || sessions === void 0 ? void 0 : sessions.length) || 0, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableConversationsDiv", children: (sessions === null || sessions === void 0 ? void 0 : sessions.length) === 0 ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Empty, { image: _jsx(Icon, { icon: "chat-square-b", size: 80, className: "text-gray-300" }), description: t("no_conversation") }) })) : ((_b = sessions === null || sessions === void 0 ? void 0 : sessions.map) === null || _b === void 0 ? void 0 : _b.call(sessions, (session) => (_jsx(ConversationBySessionItem, { sessionItem: session, latestPreview: latestPreviewMap.get(session.conversationId) }, session.conversationId)))) }), _jsx(Drawer, { open: showSearch, mask: false, closeIcon: false, styles: {
95
99
  body: {
96
100
  padding: 0,
97
101
  },
@@ -1,7 +1,10 @@
1
+ import { ISessionResponse } from "../../types/dto";
1
2
  interface GroupMembersDrawerProps {
2
3
  groupID?: string;
4
+ conversationId?: string;
5
+ currentSession?: ISessionResponse;
3
6
  disabled?: boolean;
4
7
  }
5
- declare const GroupMembersDrawer: ({ groupID, disabled, }: GroupMembersDrawerProps) => import("react/jsx-runtime").JSX.Element;
8
+ declare const GroupMembersDrawer: ({ groupID, conversationId, currentSession, disabled, }: GroupMembersDrawerProps) => import("react/jsx-runtime").JSX.Element;
6
9
  export default GroupMembersDrawer;
7
10
  //# sourceMappingURL=GroupMembersDrawer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AAUA,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsCD,QAAA,MAAM,kBAAkB,GAAI,wBAGzB,uBAAuB,4CAwLzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKnD,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsCD,QAAA,MAAM,kBAAkB,GAAI,wDAKzB,uBAAuB,4CA0OzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -1,11 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { GroupMemberRole } from "@openim/wasm-client-sdk";
3
- import { Avatar, Button, Drawer, Dropdown, Empty, Spin } from "antd";
3
+ import { Avatar, Button, Drawer, Dropdown, Empty, message, Modal, Spin } from "antd";
4
4
  import { useEffect, useMemo, useState } from "react";
5
5
  import { useTranslation } from "react-i18next";
6
+ import { usePathname, useRouter } from "next/navigation";
6
7
  import useAuthStore from "../../store/auth";
7
8
  import useConversationStore from "../../store/conversation";
8
9
  import { useGroupMembers } from "../../hooks/group/useGroupMembers";
10
+ import { useLeaveConversation } from "../../hooks/session/useLeaveConversation";
9
11
  import { Icon } from "../icon";
10
12
  const getMemberDisplayName = (member) => {
11
13
  return member.nickname || member.userID || "";
@@ -20,13 +22,17 @@ const getMemberRoleLabel = ({ member, customerUserID, t, }) => {
20
22
  }
21
23
  return t("group_member");
22
24
  };
23
- const GroupMembersDrawer = ({ groupID, disabled = false, }) => {
25
+ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled = false, }) => {
24
26
  var _a, _b;
25
27
  const { t } = useTranslation();
28
+ const router = useRouter();
29
+ const pathname = usePathname();
26
30
  const [isOpen, setIsOpen] = useState(false);
31
+ const [showLeaveConfirm, setShowLeaveConfirm] = useState(false);
27
32
  const authUserID = useAuthStore((state) => state.userID);
28
33
  const conversationData = useConversationStore((state) => state.conversationData);
29
- const { members, isLoading, error } = useGroupMembers(groupID);
34
+ const { members, isLoading, error, refetch } = useGroupMembers(groupID);
35
+ const { mutateAsync: leaveConversation, isPending: isLeaving } = useLeaveConversation();
30
36
  let customerUserID = "";
31
37
  try {
32
38
  const exConversationInfo = JSON.parse((conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex) || "{}");
@@ -63,11 +69,39 @@ const GroupMembersDrawer = ({ groupID, disabled = false, }) => {
63
69
  return;
64
70
  }
65
71
  setIsOpen(true);
72
+ void refetch();
66
73
  };
67
74
  const handleCloseDrawer = () => {
68
75
  setIsOpen(false);
69
76
  };
70
- const handleLeaveGroup = () => { };
77
+ const isCurrentUserAssigneeOfActiveSession = useMemo(() => {
78
+ if (!currentSession || currentSession.isClosed)
79
+ return false;
80
+ return currentSession.supporterId === authUserID;
81
+ }, [currentSession, authUserID]);
82
+ const handleLeaveGroup = () => {
83
+ if (isCurrentUserAssigneeOfActiveSession) {
84
+ message.error(t("leave_group_assignee_error"));
85
+ return;
86
+ }
87
+ setShowLeaveConfirm(true);
88
+ };
89
+ const handleConfirmLeave = async () => {
90
+ var _a, _b;
91
+ if (!conversationId || !groupID)
92
+ return;
93
+ try {
94
+ await leaveConversation({ conversationId });
95
+ message.success(t("leave_group_success"));
96
+ router.replace(pathname);
97
+ setShowLeaveConfirm(false);
98
+ setIsOpen(false);
99
+ }
100
+ catch (error) {
101
+ const errorMessage = ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || t("leave_group_failed");
102
+ message.error(errorMessage);
103
+ }
104
+ };
71
105
  useEffect(() => {
72
106
  setIsOpen(false);
73
107
  }, [groupID]);
@@ -99,6 +133,6 @@ const GroupMembersDrawer = ({ groupID, disabled = false, }) => {
99
133
  padding: 0,
100
134
  height: "100%",
101
135
  },
102
- }, getContainer: false, width: 360, children: _jsxs("div", { className: "flex flex-col h-full bg-white", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100", children: [_jsx("span", { className: "text-lg font-medium", children: t("members") }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: handleCloseDrawer, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: renderContent() })] }) })] }));
136
+ }, getContainer: false, width: 360, children: _jsxs("div", { className: "flex flex-col h-full bg-white", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100", children: [_jsx("span", { className: "text-lg font-medium", children: t("members") }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: handleCloseDrawer, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: renderContent() })] }) }), _jsx(Modal, { centered: true, open: showLeaveConfirm, onOk: handleConfirmLeave, onCancel: () => setShowLeaveConfirm(false), title: t("leave_group_confirm_title"), okText: t("leave_group"), cancelText: t("cancel"), okType: "danger", confirmLoading: isLeaving, getContainer: false, children: _jsx("p", { children: t("leave_group_confirm_message") }) })] }));
103
137
  };
104
138
  export default GroupMembersDrawer;
@@ -3,6 +3,7 @@ import { ISessionResponse } from "../../types/dto";
3
3
  interface MessageHeaderProps {
4
4
  onClose?: () => void;
5
5
  currentSession?: ISessionResponse;
6
+ isJoined?: boolean | null;
6
7
  }
7
8
  type SelectSessionValueType = SessionStatus | SessionTag;
8
9
  export interface SelectSessionOption {
@@ -12,6 +13,6 @@ export interface SelectSessionOption {
12
13
  tintColorClassnameBg: string;
13
14
  bgTintColorClassname: string;
14
15
  }
15
- declare const MessageHeader: ({ onClose, currentSession }: MessageHeaderProps) => import("react/jsx-runtime").JSX.Element;
16
+ declare const MessageHeader: ({ onClose, currentSession, isJoined, }: MessageHeaderProps) => import("react/jsx-runtime").JSX.Element;
16
17
  export default MessageHeader;
17
18
  //# sourceMappingURL=MessageHeader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOnD,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,KAAK,sBAAsB,GAAG,aAAa,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,sBAAsB,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,6BAA6B,kBAAkB,4CA0MrE,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMnD,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,KAAK,sBAAsB,GAAG,aAAa,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,sBAAsB,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,wCAIpB,kBAAkB,4CA6MpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -12,19 +12,18 @@ import SelectSession from "./SelectSession";
12
12
  import { useUpdateSession } from "../../hooks/session/useUpdateSession";
13
13
  import useAuthStore from "../../store/auth";
14
14
  import SearchDrawer from "../searchConversation/SearchDrawer";
15
- import { useIsJoinedGroup } from "../../hooks/session/useIsJoinedGroup";
16
15
  import { isGroupSession } from "../../utils/imCommon";
17
16
  import GroupMembersDrawer from "./GroupMembersDrawer";
18
- const MessageHeader = ({ onClose, currentSession }) => {
17
+ const MessageHeader = ({ onClose, currentSession, isJoined, }) => {
19
18
  var _a, _b;
20
19
  const { t } = useTranslation();
21
20
  const isCx = useAuthStore((state) => state.isCx);
21
+ const isCrm = useAuthStore((state) => state.isCrm);
22
22
  const conversationData = useConversationStore((state) => state.conversationData);
23
23
  const currentGroupInfo = useConversationStore((state) => state.currentGroupInfo);
24
24
  const { mutate: updateSession } = useUpdateSession();
25
25
  const { avatar, displayName } = useConversationDisplayData(conversationData);
26
26
  const shouldShowMemberCount = isGroupSession(conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationType);
27
- const { isJoined } = useIsJoinedGroup(conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID);
28
27
  const [currentSessionStatus, setCurrentSessionStatus] = useState(SessionStatus.UNASSIGNED);
29
28
  const [currentSessionTag, setCurrentSessionTag] = useState(SessionTag.NONE);
30
29
  const statusOptions = useMemo(() => {
@@ -128,6 +127,6 @@ const MessageHeader = ({ onClose, currentSession }) => {
128
127
  setCurrentSessionStatus(currentSession.status);
129
128
  }
130
129
  }, [currentSession]);
131
- return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), shouldShowMemberCount && (_jsx("p", { className: "text-xs text-gray-500 truncate", children: t("member_count", { count: (_b = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount) !== null && _b !== void 0 ? _b : 0 }) }))] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), shouldShowMemberCount && isJoined === true && (_jsx(GroupMembersDrawer, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID })), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
130
+ return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), shouldShowMemberCount && (_jsx("p", { className: "text-xs text-gray-500 truncate", children: t("member_count", { count: (_b = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount) !== null && _b !== void 0 ? _b : 0 }) }))] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), shouldShowMemberCount && isJoined === true && isCrm && (_jsx(GroupMembersDrawer, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID, conversationId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID, currentSession: currentSession })), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
132
131
  };
133
132
  export default MessageHeader;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AA2BA,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;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA4V3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AA4BA,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;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA6V3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -10,6 +10,7 @@ import MessageItem from "./item";
10
10
  import InfiniteScroll from "react-infinite-scroll-component";
11
11
  import MessageHeader from "./MessageHeader";
12
12
  import MessageFooter from "./footer";
13
+ import UnassignedSessionFooter from "./UnassignedSessionFooter";
13
14
  import { images } from "../../constants/images";
14
15
  import { useTranslation } from "react-i18next";
15
16
  import useConversationStore from "../../store/conversation";
@@ -21,7 +22,7 @@ import { useChatContext } from "../../context/ChatContext";
21
22
  import { useRevokeMessage } from "../../hooks/message/useRevokeMessage";
22
23
  import { useConversationSessionState } from "../../hooks/session/useConversationSessionState";
23
24
  import { useJoinGroupFlow } from "../../hooks/session/useJoinGroupFlow";
24
- import { ConnectStatus } from "../../types/chat";
25
+ import { ConnectStatus, SessionStatus } from "../../types/chat";
25
26
  dayjs.extend(isToday);
26
27
  const BOTTOM_THRESHOLD = -5;
27
28
  const MessageList = (props) => {
@@ -37,19 +38,15 @@ const MessageList = (props) => {
37
38
  const [selectedItem, setSelectedItem] = useState(null);
38
39
  const [showConfirmRevoke, { setTrue: openConfirmRevoke, setFalse: closeConfirmRevoke },] = useBoolean(false);
39
40
  const { revokeMessage, loading: isRevoking } = useRevokeMessage();
40
- const { isNotGroupMember, latestConversationSession, customerUserID, refetchConversationSessions, refetchIsJoined, } = useConversationSessionState({
41
+ const { groupId, latestConversationSession, customerUserID, refetchConversationSessions, } = useConversationSessionState({
41
42
  conversationId,
42
43
  conversationType: conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationType,
43
44
  groupId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID,
44
- userID: user === null || user === void 0 ? void 0 : user.userID,
45
45
  });
46
- const { handleJoinGroup, isJoining } = useJoinGroupFlow({
47
- groupId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID,
48
- latestConversationSessionId: latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.id,
49
- refetchConversationSessions,
50
- refetchIsJoined,
46
+ const { isJoined, isCheckingMembership, shouldRestrictToLastSession, joinGroup, isJoining, } = useJoinGroupFlow({
47
+ groupId,
48
+ sessionId: latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.id,
51
49
  });
52
- const shouldRestrictToLastSession = isNotGroupMember || isJoining;
53
50
  const { getMoreOldMessages, moreOldLoading, loadState, getMoreNewMessages, moreNewLoading, latestLoadState, } = useConversationMessages({
54
51
  conversationId,
55
52
  searchClientMsgID,
@@ -158,15 +155,6 @@ const MessageList = (props) => {
158
155
  emitter.off("UPDATE_SESSION", handler);
159
156
  };
160
157
  }, [conversationId, refetchConversationSessions]);
161
- useEffect(() => {
162
- if (!loadState.hasMoreNew && !loadState.initLoading) {
163
- handleMarkConversationMessageAsRead();
164
- }
165
- }, [
166
- loadState.hasMoreNew,
167
- loadState.initLoading,
168
- handleMarkConversationMessageAsRead,
169
- ]);
170
158
  useEffect(() => {
171
159
  if (!loadState.hasMoreNew &&
172
160
  !loadState.initLoading &&
@@ -197,7 +185,7 @@ const MessageList = (props) => {
197
185
  backgroundSize: "cover",
198
186
  backgroundPosition: "center",
199
187
  overflowX: "hidden",
200
- }, children: [_jsx(MessageHeader, { onClose: onClose, currentSession: latestConversationSession }), _jsx("div", { id: "scrollableMessagesDiv", ref: scrollRef, style: {
188
+ }, children: [_jsx(MessageHeader, { onClose: onClose, currentSession: latestConversationSession, isJoined: isJoined }), _jsx("div", { id: "scrollableMessagesDiv", ref: scrollRef, style: {
201
189
  height: "100%",
202
190
  overflowY: "auto",
203
191
  overflowX: "hidden",
@@ -215,6 +203,6 @@ const MessageList = (props) => {
215
203
  handleMarkConversationMessageAsRead();
216
204
  loadMoreNewMessage();
217
205
  }
218
- }, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array, contextMenuOpen: openMenuId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenMenuId(open ? message.clientMsgID : null), onRevokeMessage: handleOpenRevoke, onQuoteMessage: setQuotedMessage, onPressQuoteMessage: onPressQuoteMessage }, message.clientMsgID))) }) }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), shouldRestrictToLastSession ? (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-sm text-gray-500", children: t("join_group_required") }), _jsx(Button, { type: "primary", onClick: handleJoinGroup, loading: isJoining, children: t("join_group") })] })) : (_jsx(MessageFooter, { currentSession: latestConversationSession, openCreateCannedModal: openCreateCannedModal })), _jsx(Modal, { centered: true, open: showConfirmRevoke, onOk: onRevokeMessage, onCancel: handleCloseRevoke, title: t("revoke_message_confirm_title"), okText: t("revoke"), cancelText: t("cancel"), okType: "danger", confirmLoading: isRevoking, getContainer: false, forceRender: true, children: _jsx("p", { children: t("revoke_message_confirm_message") }) })] }));
206
+ }, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array, contextMenuOpen: openMenuId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenMenuId(open ? message.clientMsgID : null), onRevokeMessage: handleOpenRevoke, onQuoteMessage: setQuotedMessage, onPressQuoteMessage: onPressQuoteMessage }, message.clientMsgID))) }) }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), isCheckingMembership ? (_jsx("div", { className: "border-t bg-white py-4 flex items-center justify-center", children: _jsx(Spin, {}) })) : (latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.status) === SessionStatus.UNASSIGNED ? (_jsx(UnassignedSessionFooter, { sessionId: latestConversationSession.id, teamId: latestConversationSession.teamId })) : shouldRestrictToLastSession ? (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-sm text-gray-500", children: t("join_group_required") }), _jsx(Button, { type: "primary", onClick: joinGroup, loading: isJoining, children: t("join_group") })] })) : (_jsx(MessageFooter, { currentSession: latestConversationSession, openCreateCannedModal: openCreateCannedModal })), _jsx(Modal, { centered: true, open: showConfirmRevoke, onOk: onRevokeMessage, onCancel: handleCloseRevoke, title: t("revoke_message_confirm_title"), okText: t("revoke"), cancelText: t("cancel"), okType: "danger", confirmLoading: isRevoking, getContainer: false, forceRender: true, children: _jsx("p", { children: t("revoke_message_confirm_message") }) })] }));
219
207
  };
220
208
  export default MessageList;
@@ -0,0 +1,7 @@
1
+ interface UnassignedSessionFooterProps {
2
+ sessionId: string;
3
+ teamId?: string;
4
+ }
5
+ declare const UnassignedSessionFooter: ({ sessionId, teamId, }: UnassignedSessionFooterProps) => import("react/jsx-runtime").JSX.Element | null;
6
+ export default UnassignedSessionFooter;
7
+ //# sourceMappingURL=UnassignedSessionFooter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnassignedSessionFooter.d.ts","sourceRoot":"","sources":["../../../src/components/message/UnassignedSessionFooter.tsx"],"names":[],"mappings":"AASA,UAAU,4BAA4B;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,QAAA,MAAM,uBAAuB,GAAI,wBAG9B,4BAA4B,mDA2C9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button, message as antdMessage } from "antd";
4
+ import { useTranslation } from "react-i18next";
5
+ import { useAssignSession } from "../../hooks/session/useAssignSession";
6
+ import useAuthStore from "../../store/auth";
7
+ import ManualAssignPopover from "../thread/ManualAssignPopover";
8
+ import { Icon } from "../icon";
9
+ const UnassignedSessionFooter = ({ sessionId, teamId, }) => {
10
+ const { t } = useTranslation();
11
+ const userID = useAuthStore((state) => state.userID);
12
+ const isCrm = useAuthStore((state) => state.isCrm);
13
+ const { mutateAsync: assignSession, isPending: isAssigning } = useAssignSession();
14
+ if (!isCrm)
15
+ return null;
16
+ const handleAssignToMe = async () => {
17
+ try {
18
+ await assignSession({ sessionId, supporterId: userID });
19
+ }
20
+ catch (_a) {
21
+ antdMessage.error(t("manual_assign_failed"));
22
+ }
23
+ };
24
+ return (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-amber-500", children: [_jsx(Icon, { icon: "user-del-o", size: 16 }), _jsx("p", { className: "text-sm text-gray-500", children: t("unassigned_thread_notice") })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { type: "primary", onClick: handleAssignToMe, loading: isAssigning, disabled: isAssigning, children: t("assign_to_me") }), _jsx(ManualAssignPopover, { sessionId: sessionId, teamId: teamId, excludeCurrentUser: true, children: _jsx(Button, { disabled: isAssigning, children: t("assign_to_others") }) })] })] }));
25
+ };
26
+ export default UnassignedSessionFooter;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchAll.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchAll.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,wBAAwB,EAAE,MAAM,GAAG,CAAC;AAE7C,UAAU,0BAA0B;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,GAAG,EAAE,wBAAwB,KAAK,IAAI,CAAC;CACvD;AACD,QAAA,MAAM,qBAAqB,GAAI,+BAG5B,0BAA0B,4CAkH5B,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"SearchAll.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchAll.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,wBAAwB,EAAE,MAAM,GAAG,CAAC;AAG7C,UAAU,0BAA0B;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,GAAG,EAAE,wBAAwB,KAAK,IAAI,CAAC;CACvD;AACD,QAAA,MAAM,qBAAqB,GAAI,+BAG5B,0BAA0B,4CA6G5B,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button, Empty, Spin } from "antd";
3
+ import clsx from "clsx";
3
4
  import { useTranslation } from "react-i18next";
4
5
  import { useSearchMessage } from "../../hooks/search/useSearchMessage";
5
6
  import { MessageType } from "@openim/wasm-client-sdk";
@@ -8,6 +9,7 @@ import SearchItemAsMessage from "./item/SearchItemAsMessage";
8
9
  import { useGetSession } from "../../hooks/session/useGetSession";
9
10
  import SearchItemAsUser from "./item/SearchItemAsUser";
10
11
  import { SearchConversationTabKey } from ".";
12
+ import { PAGE_SIZE } from "../../constants";
11
13
  const SearchConversationAll = ({ searchTerm = "", setActiveKey, }) => {
12
14
  const { t } = useTranslation();
13
15
  const { dataFlatten: messages, isLoading: isLoadingMessage, hasNextPage: hasNextPageMessage, } = useSearchMessage({
@@ -15,13 +17,13 @@ const SearchConversationAll = ({ searchTerm = "", setActiveKey, }) => {
15
17
  searchTerm: searchTerm.trim(),
16
18
  contentType: MessageType.TextMessage,
17
19
  },
18
- options: { pageSize: 5 },
20
+ options: { pageSize: PAGE_SIZE.xs },
19
21
  });
20
22
  const { dataFlatten: sessions, isLoading: isLoadingSession, hasNextPage: hasNextPageSession, } = useGetSession({
21
23
  filter: {
22
24
  searchTerm: searchTerm.trim(),
23
25
  },
24
- options: { pageSize: 5 },
26
+ options: { pageSize: PAGE_SIZE.xs },
25
27
  });
26
28
  if (searchTerm.trim() === "" ||
27
29
  (messages.length === 0 && sessions.length === 0)) {
@@ -30,6 +32,6 @@ const SearchConversationAll = ({ searchTerm = "", setActiveKey, }) => {
30
32
  if (isLoadingMessage || isLoadingSession) {
31
33
  return (_jsx("div", { className: "h-full overflow-auto flex items-center justify-center", children: _jsx(Spin, {}) }));
32
34
  }
33
- 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 }))) })] }))] }));
35
+ 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 min-h-[32px]", children: [_jsx("span", { className: "text-xs font-medium uppercase flex-1 text-gray-600", children: t("users") }), _jsx(Button, { type: "link", icon: _jsx(Icon, { icon: "angle-right-o", size: 18, className: "!align-[-4px]" }), iconPosition: "end", className: clsx("p-0 gap-1", !hasNextPageSession && "invisible"), 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 min-h-[32px]", children: [_jsx("span", { className: "text-xs font-medium uppercase flex-1 text-gray-600", children: t("messages") }), _jsx(Button, { type: "link", icon: _jsx(Icon, { icon: "angle-right-o", size: 18, className: "!align-[-4px]" }), iconPosition: "end", className: clsx("p-0 gap-1", !hasNextPageMessage && "invisible"), 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, displayTag: message.displayTag }))) })] }))] }));
34
36
  };
35
37
  export default SearchConversationAll;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchConversationAsMessages.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchConversationAsMessages.tsx"],"names":[],"mappings":"AAOA,UAAU,iCAAiC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AACD,QAAA,MAAM,4BAA4B,GAChC,OAAO,iCAAiC,4CAuCzC,CAAC;AAEF,eAAe,4BAA4B,CAAC"}
1
+ {"version":3,"file":"SearchConversationAsMessages.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchConversationAsMessages.tsx"],"names":[],"mappings":"AAOA,UAAU,iCAAiC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AACD,QAAA,MAAM,4BAA4B,GAChC,OAAO,iCAAiC,4CA2CzC,CAAC;AAEF,eAAe,4BAA4B,CAAC"}
@@ -18,6 +18,6 @@ const SearchConversationAsMessages = (props) => {
18
18
  return _jsx(Empty, { description: t("no_conversation") });
19
19
  if (isLoading)
20
20
  return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
21
- return (_jsx("div", { id: "scrollableVideoDiv", className: "h-full overflow-auto", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableVideoDiv", children: dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm }))) }) }));
21
+ return (_jsx("div", { id: "scrollableSearchMessagesTab", className: "h-full overflow-auto", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableSearchMessagesTab", children: dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm, displayTag: item.displayTag }))) }) }));
22
22
  };
23
23
  export default SearchConversationAsMessages;
@@ -16,6 +16,6 @@ const SearchConversationAsUsers = (props) => {
16
16
  return _jsx(Empty, { description: t("no_conversation") });
17
17
  if (isLoading)
18
18
  return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
19
- return (_jsx("div", { id: "scrollableVideoDiv", className: "h-full overflow-auto", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableVideoDiv", children: dataFlatten.map((item) => (_jsx(SearchItemAsUser, { session: item, searchTerm: searchTerm }))) }) }));
19
+ return (_jsx("div", { id: "scrollableSearchUsersTab", className: "h-full overflow-auto", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableSearchUsersTab", children: dataFlatten.map((item) => (_jsx(SearchItemAsUser, { session: item, searchTerm: searchTerm }))) }) }));
20
20
  };
21
21
  export default SearchConversationAsUsers;
@@ -0,0 +1,6 @@
1
+ interface SearchConversationMyInboxProps {
2
+ searchTerm: string;
3
+ }
4
+ declare const SearchConversationMyInbox: ({ searchTerm, }: SearchConversationMyInboxProps) => import("react/jsx-runtime").JSX.Element;
5
+ export default SearchConversationMyInbox;
6
+ //# sourceMappingURL=SearchConversationMyInbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchConversationMyInbox.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchConversationMyInbox.tsx"],"names":[],"mappings":"AAQA,UAAU,8BAA8B;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,yBAAyB,GAAI,iBAEhC,8BAA8B,4CA2ChC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Empty, Spin } from "antd";
3
+ import { useTranslation } from "react-i18next";
4
+ import { useSearchMessage } from "../../hooks/search/useSearchMessage";
5
+ import { MessageType } from "@openim/wasm-client-sdk";
6
+ import SearchItemAsMessage from "./item/SearchItemAsMessage";
7
+ const MY_INBOX_TAG = "MY_INBOX";
8
+ const SearchConversationMyInbox = ({ searchTerm = "", }) => {
9
+ const { t } = useTranslation();
10
+ const { dataFlatten, hasNextPage, fetchNextPage, isLoading, isFetchingNextPage } = useSearchMessage({
11
+ payload: {
12
+ searchTerm: searchTerm.trim(),
13
+ contentType: MessageType.TextMessage,
14
+ tag: MY_INBOX_TAG,
15
+ },
16
+ options: { untilEmptyPage: true },
17
+ });
18
+ if ((dataFlatten.length === 0 && !isLoading) || searchTerm.trim() === "")
19
+ return _jsx(Empty, { description: t("no_conversation") });
20
+ if (isLoading)
21
+ return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
22
+ return (_jsxs("div", { className: "overflow-auto", children: [dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm, displayTag: item.displayTag }, item.chatLog.clientMsgID))), _jsx("div", { className: "flex justify-center py-2", children: _jsx(Button, { type: "link", loading: isFetchingNextPage, onClick: () => fetchNextPage(), children: t("see_more") }) })] }));
23
+ };
24
+ export default SearchConversationMyInbox;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchMessageOnCurrentConversation.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchMessageOnCurrentConversation.tsx"],"names":[],"mappings":"AAQA,UAAU,uCAAuC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AACD,QAAA,MAAM,kCAAkC,GACtC,OAAO,uCAAuC,4CAoD/C,CAAC;AAEF,eAAe,kCAAkC,CAAC"}
1
+ {"version":3,"file":"SearchMessageOnCurrentConversation.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/SearchMessageOnCurrentConversation.tsx"],"names":[],"mappings":"AAQA,UAAU,uCAAuC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AACD,QAAA,MAAM,kCAAkC,GACtC,OAAO,uCAAuC,4CAuD/C,CAAC;AAEF,eAAe,kCAAkC,CAAC"}
@@ -23,6 +23,6 @@ const SearchMessageOnCurrentConversation = (props) => {
23
23
  return _jsx(Empty, { description: t("no_result") });
24
24
  if (isLoading)
25
25
  return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
26
- return (_jsx("div", { id: "scrollableVideoDiv", className: "h-full overflow-auto", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableVideoDiv", children: dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm, onClick: props === null || props === void 0 ? void 0 : props.onClose }))) }) }));
26
+ return (_jsx("div", { id: "scrollableCurrentConversationSearchMessages", className: "h-full overflow-auto", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableCurrentConversationSearchMessages", children: dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm, onClick: props === null || props === void 0 ? void 0 : props.onClose }))) }) }));
27
27
  };
28
28
  export default SearchMessageOnCurrentConversation;
@@ -1,5 +1,6 @@
1
1
  export declare enum SearchConversationTabKey {
2
2
  All = "all",
3
+ MyInbox = "myInbox",
3
4
  Users = "users",
4
5
  Messages = "messages"
5
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/index.tsx"],"names":[],"mappings":"AASA,oBAAY,wBAAwB;IAClC,GAAG,QAAQ;IACX,KAAK,UAAU;IACf,QAAQ,aAAa;CACtB;AAED,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AACD,QAAA,MAAM,kBAAkB,GAAI,gBAAgB,uBAAuB,4CA0ClE,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/searchConversation/index.tsx"],"names":[],"mappings":"AAUA,oBAAY,wBAAwB;IAClC,GAAG,QAAQ;IACX,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,QAAQ,aAAa;CACtB;AAED,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AACD,QAAA,MAAM,kBAAkB,GAAI,gBAAgB,uBAAuB,4CAgDlE,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -4,11 +4,13 @@ import { Tabs } from "antd";
4
4
  import { useMemo, useState } from "react";
5
5
  import { useTranslation } from "react-i18next";
6
6
  import SearchConversationAll from "./SearchAll";
7
+ import SearchConversationMyInbox from "./SearchConversationMyInbox";
7
8
  import SearchConversationAsUsers from "./SearchConversationAsUsers";
8
9
  import SearchConversationAsMessages from "./SearchConversationAsMessages";
9
10
  export var SearchConversationTabKey;
10
11
  (function (SearchConversationTabKey) {
11
12
  SearchConversationTabKey["All"] = "all";
13
+ SearchConversationTabKey["MyInbox"] = "myInbox";
12
14
  SearchConversationTabKey["Users"] = "users";
13
15
  SearchConversationTabKey["Messages"] = "messages";
14
16
  })(SearchConversationTabKey || (SearchConversationTabKey = {}));
@@ -22,6 +24,11 @@ const SearchConversation = ({ searchTerm }) => {
22
24
  label: t("all"),
23
25
  children: (_jsx(SearchConversationAll, { searchTerm: searchTerm, setActiveKey: setActiveKey })),
24
26
  },
27
+ {
28
+ key: SearchConversationTabKey.MyInbox,
29
+ label: t("my_inbox_tab"),
30
+ children: _jsx(SearchConversationMyInbox, { searchTerm: searchTerm }),
31
+ },
25
32
  {
26
33
  key: SearchConversationTabKey.Users,
27
34
  label: t("users"),
@@ -34,6 +41,6 @@ const SearchConversation = ({ searchTerm }) => {
34
41
  },
35
42
  ];
36
43
  }, [t, searchTerm]);
37
- return (_jsx("div", { className: "h-full", children: _jsx(Tabs, { defaultActiveKey: SearchConversationTabKey.All, items: items, className: "h-full", activeKey: activeKey, onChange: (key) => setActiveKey(key) }) }));
44
+ return (_jsx("div", { className: "h-full", children: _jsx(Tabs, { defaultActiveKey: SearchConversationTabKey.All, items: items, className: "h-full", activeKey: activeKey, onChange: (key) => setActiveKey(key), destroyOnHidden: true }) }));
38
45
  };
39
46
  export default SearchConversation;
@@ -4,6 +4,7 @@ interface SearchItemAsMessageProps {
4
4
  isRevoked?: boolean;
5
5
  };
6
6
  searchTerm: string;
7
+ displayTag?: string;
7
8
  onClick?: () => void;
8
9
  }
9
10
  declare const SearchItemAsMessage: (props: SearchItemAsMessageProps) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/searchConversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAA4B,MAAM,yBAAyB,CAAC;AAehF,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,GAAG;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CAkG3D,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,EAA4B,MAAM,yBAAyB,CAAC;AAehF,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,GAAG;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CAuG3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -13,7 +13,7 @@ import useAuthStore from "../../../store/auth";
13
13
  const SearchItemAsMessage = (props) => {
14
14
  var _a;
15
15
  const { t } = useTranslation();
16
- const { message, searchTerm = "", onClick } = props;
16
+ const { message, searchTerm = "", displayTag, onClick } = props;
17
17
  const { user } = useChatContext();
18
18
  const isCrm = useAuthStore((state) => state.isCrm);
19
19
  const conversationData = useConversationStore((state) => state.conversationData);
@@ -65,8 +65,8 @@ const SearchItemAsMessage = (props) => {
65
65
  ? message.senderNickname
66
66
  : conversationData === null || conversationData === void 0 ? void 0 : conversationData.showName }), _jsx("span", { className: "text-xs text-gray-500", children: formatTimestamp(message.sendTime, {
67
67
  hasTime: true,
68
- }) })] }), _jsx("div", { className: "flex flex-col flex-1 min-w-0", children: _jsx("span", { className: "text-xs flex-1 text-gray-500 truncate", dangerouslySetInnerHTML: {
69
- __html: sanitizeHtml(highlightSearch(msgContent, searchTerm)),
70
- } }) })] })] }, message.clientMsgID));
68
+ }) })] }), _jsxs("div", { className: "flex flex-col flex-1 min-w-0 gap-1", children: [_jsx("span", { className: "text-xs flex-1 text-gray-500 truncate", dangerouslySetInnerHTML: {
69
+ __html: sanitizeHtml(highlightSearch(msgContent, searchTerm)),
70
+ } }), displayTag && (_jsx("span", { className: "text-[10px] text-blue-600 bg-blue-50 px-1.5 py-0.5 rounded w-fit truncate", children: displayTag }))] })] })] }, message.clientMsgID));
71
71
  };
72
72
  export default SearchItemAsMessage;