@droppii-org/chat-sdk 0.1.5 → 0.1.7

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 (101) hide show
  1. package/dist/components/cannedResponse/CannedResponseBody.d.ts.map +1 -1
  2. package/dist/components/cannedResponse/CannedResponseBody.js +54 -3
  3. package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
  4. package/dist/components/conversation/ConversationBySessionItem.js +7 -2
  5. package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
  6. package/dist/components/conversation/DeskConversationList.js +22 -17
  7. package/dist/components/message/MessageHeader.d.ts +2 -2
  8. package/dist/components/message/MessageHeader.d.ts.map +1 -1
  9. package/dist/components/message/MessageHeader.js +5 -2
  10. package/dist/components/message/MessageList.d.ts.map +1 -1
  11. package/dist/components/message/MessageList.js +31 -22
  12. package/dist/components/message/SelectSession.d.ts.map +1 -1
  13. package/dist/components/message/SelectSession.js +7 -9
  14. package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
  15. package/dist/components/message/footer/ActionBar.js +3 -2
  16. package/dist/components/message/footer/CannedResponsePlugin.d.ts.map +1 -1
  17. package/dist/components/message/footer/CannedResponsePlugin.js +37 -1
  18. package/dist/components/message/footer/ComposerEditor.d.ts +7 -0
  19. package/dist/components/message/footer/ComposerEditor.d.ts.map +1 -0
  20. package/dist/components/message/footer/ComposerEditor.js +13 -0
  21. package/dist/components/message/footer/ComposerTabs.d.ts +9 -0
  22. package/dist/components/message/footer/ComposerTabs.d.ts.map +1 -0
  23. package/dist/components/message/footer/ComposerTabs.js +37 -0
  24. package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
  25. package/dist/components/message/footer/EnterHandler.js +10 -1
  26. package/dist/components/message/footer/index.d.ts +2 -2
  27. package/dist/components/message/footer/index.d.ts.map +1 -1
  28. package/dist/components/message/footer/index.js +45 -9
  29. package/dist/components/message/item/QuoteMessage.d.ts.map +1 -1
  30. package/dist/components/message/item/QuoteMessage.js +44 -35
  31. package/dist/components/message/item/index.d.ts.map +1 -1
  32. package/dist/components/message/item/index.js +11 -1
  33. package/dist/components/session/DeskAssignedSession.d.ts.map +1 -1
  34. package/dist/components/session/DeskAssignedSession.js +14 -109
  35. package/dist/components/session/DeskTeamInbox.d.ts +3 -0
  36. package/dist/components/session/DeskTeamInbox.d.ts.map +1 -0
  37. package/dist/components/session/DeskTeamInbox.js +56 -0
  38. package/dist/components/session/SessionFilterMenu.d.ts +13 -0
  39. package/dist/components/session/SessionFilterMenu.d.ts.map +1 -0
  40. package/dist/components/session/SessionFilterMenu.js +27 -0
  41. package/dist/components/session/sessionMenuItems.d.ts +26 -0
  42. package/dist/components/session/sessionMenuItems.d.ts.map +1 -0
  43. package/dist/components/session/sessionMenuItems.js +108 -0
  44. package/dist/hooks/conversation/useConversationPreview.d.ts +12 -0
  45. package/dist/hooks/conversation/useConversationPreview.d.ts.map +1 -0
  46. package/dist/hooks/conversation/useConversationPreview.js +22 -0
  47. package/dist/hooks/message/useConversationMessages.d.ts +27 -0
  48. package/dist/hooks/message/useConversationMessages.d.ts.map +1 -0
  49. package/dist/hooks/message/useConversationMessages.js +29 -0
  50. package/dist/hooks/message/useMessage.d.ts.map +1 -1
  51. package/dist/hooks/message/usePullSessionMessages.d.ts +9 -0
  52. package/dist/hooks/message/usePullSessionMessages.d.ts.map +1 -0
  53. package/dist/hooks/message/usePullSessionMessages.js +27 -0
  54. package/dist/hooks/message/useSendMessage.d.ts +8 -6
  55. package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
  56. package/dist/hooks/message/useSendMessage.js +8 -8
  57. package/dist/hooks/session/useConversationSessionState.d.ts +21 -0
  58. package/dist/hooks/session/useConversationSessionState.d.ts.map +1 -0
  59. package/dist/hooks/session/useConversationSessionState.js +41 -0
  60. package/dist/hooks/session/useGetSession.d.ts.map +1 -1
  61. package/dist/hooks/session/useGetSession.js +138 -52
  62. package/dist/hooks/session/useGetTeamSessionSummary.d.ts +3 -0
  63. package/dist/hooks/session/useGetTeamSessionSummary.d.ts.map +1 -0
  64. package/dist/hooks/session/useGetTeamSessionSummary.js +12 -0
  65. package/dist/hooks/session/useIsJoinedGroup.d.ts +5 -0
  66. package/dist/hooks/session/useIsJoinedGroup.d.ts.map +1 -0
  67. package/dist/hooks/session/useIsJoinedGroup.js +24 -0
  68. package/dist/hooks/session/useJoinGroupFlow.d.ts +12 -0
  69. package/dist/hooks/session/useJoinGroupFlow.d.ts.map +1 -0
  70. package/dist/hooks/session/useJoinGroupFlow.js +59 -0
  71. package/dist/hooks/session/useJoinSession.d.ts +3 -0
  72. package/dist/hooks/session/useJoinSession.d.ts.map +1 -0
  73. package/dist/hooks/session/useJoinSession.js +38 -0
  74. package/dist/hooks/user/useCurrentUserAccountType.d.ts +3 -0
  75. package/dist/hooks/user/useCurrentUserAccountType.d.ts.map +1 -0
  76. package/dist/hooks/user/useCurrentUserAccountType.js +30 -0
  77. package/dist/locales/vi/common.json +12 -2
  78. package/dist/services/query.d.ts +5 -0
  79. package/dist/services/query.d.ts.map +1 -1
  80. package/dist/services/query.js +5 -0
  81. package/dist/services/routes.d.ts +5 -0
  82. package/dist/services/routes.d.ts.map +1 -1
  83. package/dist/services/routes.js +5 -0
  84. package/dist/store/conversation.d.ts.map +1 -1
  85. package/dist/store/conversation.js +41 -12
  86. package/dist/store/session.js +1 -1
  87. package/dist/styles/global.css +1 -1
  88. package/dist/tsconfig.tsbuildinfo +1 -1
  89. package/dist/types/chat.d.ts +18 -1
  90. package/dist/types/chat.d.ts.map +1 -1
  91. package/dist/types/chat.js +9 -0
  92. package/dist/types/dto.d.ts +87 -0
  93. package/dist/types/dto.d.ts.map +1 -1
  94. package/dist/utils/events.d.ts +1 -0
  95. package/dist/utils/events.d.ts.map +1 -1
  96. package/dist/utils/messageTransform.d.ts +5 -0
  97. package/dist/utils/messageTransform.d.ts.map +1 -0
  98. package/dist/utils/messageTransform.js +106 -0
  99. package/dist/utils/queryHelpers.d.ts.map +1 -1
  100. package/dist/utils/queryHelpers.js +2 -0
  101. package/package.json +1 -1
@@ -11,72 +11,165 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  return t;
12
12
  };
13
13
  import { useInfiniteQuery } from "@tanstack/react-query";
14
+ import { useMemo } from "react";
14
15
  import { apiInstance } from "../../services/api";
15
16
  import { ENDPOINTS } from "../../services/routes";
16
17
  import { QUERY_KEYS } from "../../services/query";
17
- import { useMemo } from "react";
18
18
  import useConversationStore from "../../store/conversation";
19
- import { DChatSDK } from "../../constants/sdk";
20
19
  import useAuthStore from "../../store/auth";
21
- import { PAGE_SIZE } from "../../constants";
22
- export const useGetSession = ({ filter, options = {
23
- pageSize: undefined,
24
- isEnabled: true,
25
- }, }) => {
20
+ import { DChatSDK } from "../../constants/sdk";
21
+ const SESSION_PAGE_SIZE = 20;
22
+ const hasValidFilter = (filter) => {
23
+ return Object.values(filter).some((v) => {
24
+ if (typeof v === "string")
25
+ return v.trim() !== "";
26
+ return v !== undefined && v !== null;
27
+ });
28
+ };
29
+ const buildSessionConfig = (filter, pageSize) => {
30
+ const applicationType = useAuthStore.getState().applicationType;
31
+ if (filter.teamId) {
32
+ return {
33
+ queryKey: QUERY_KEYS.GET_TEAM_SESSIONS,
34
+ endpoint: ENDPOINTS.chatService.getTeamSessionsByQuery,
35
+ buildParams: (page) => ({
36
+ teamId: filter.teamId,
37
+ applicationType,
38
+ page,
39
+ pageSize,
40
+ status: filter.status,
41
+ tag: filter.tag,
42
+ }),
43
+ };
44
+ }
45
+ return {
46
+ queryKey: QUERY_KEYS.GET_SESSION_BY_TAG_OR_STATUS,
47
+ endpoint: ENDPOINTS.chatService.getSessionsByTagOrStatus,
48
+ buildParams: (page) => ({
49
+ applicationType,
50
+ tag: filter.tag,
51
+ status: filter.status,
52
+ page,
53
+ pageSize,
54
+ searchTerm: filter.searchTerm,
55
+ conversationIds: filter.conversationIds,
56
+ }),
57
+ };
58
+ };
59
+ const mapImDetailToConversation = (item) => ({
60
+ conversationID: item.conversationID,
61
+ conversationType: item.conversationType,
62
+ userID: item.userID,
63
+ groupID: item.groupID,
64
+ showName: "",
65
+ faceURL: "",
66
+ recvMsgOpt: item.recvMsgOpt,
67
+ unreadCount: 0,
68
+ groupAtType: item.groupAtType,
69
+ latestMsg: "",
70
+ latestMsgSendTime: 0,
71
+ draftText: "",
72
+ draftTextTime: 0,
73
+ burnDuration: item.burnDuration,
74
+ msgDestructTime: item.msgDestructTime,
75
+ isPinned: item.isPinned,
76
+ isNotInGroup: true,
77
+ isPrivateChat: item.isPrivateChat,
78
+ isMsgDestruct: item.isMsgDestruct,
79
+ attachedInfo: item.attachedInfo,
80
+ ex: item.ex,
81
+ });
82
+ const fetchConversationsImDetail = async (conversations) => {
83
+ var _a, _b;
84
+ if (!conversations.length)
85
+ return [];
86
+ const payload = {
87
+ applicationType: useAuthStore.getState().applicationType,
88
+ conversations,
89
+ };
90
+ const res = await apiInstance.post(ENDPOINTS.chatService.getConversationsImDetail, payload);
91
+ return ((_b = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : []).map(mapImDetailToConversation);
92
+ };
93
+ const fetchSdkConversations = async (sessions) => {
94
+ var _a;
95
+ if (!sessions.length)
96
+ return [];
97
+ try {
98
+ const res = await DChatSDK.getMultipleConversation(sessions.map((session) => session.conversationId));
99
+ return (_a = res === null || res === void 0 ? void 0 : res.data) !== null && _a !== void 0 ? _a : [];
100
+ }
101
+ catch (error) {
102
+ console.error("getMultipleConversation", error);
103
+ return [];
104
+ }
105
+ };
106
+ const findMissingSessionsFromSdk = (sessions, sdkConversations) => sessions.filter((session) => !sdkConversations.some((conversation) => conversation.conversationID === session.conversationId));
107
+ const syncSessionConversationsToStore = async (sessions) => {
108
+ const currentList = useConversationStore.getState().conversationList;
109
+ const newSessions = sessions.filter((session) => !currentList.some((conversation) => conversation.conversationID === session.conversationId));
110
+ if (!newSessions.length)
111
+ return;
112
+ const sdkConversations = await fetchSdkConversations(newSessions);
113
+ const missingSessions = findMissingSessionsFromSdk(newSessions, sdkConversations);
114
+ const conversationsToUpdate = [...sdkConversations];
115
+ if (missingSessions.length) {
116
+ try {
117
+ const fallbackConversations = await fetchConversationsImDetail(missingSessions.map((session) => ({
118
+ ownerUserID: session.ownerId,
119
+ conversationID: session.conversationId,
120
+ })));
121
+ conversationsToUpdate.push(...fallbackConversations);
122
+ }
123
+ catch (error) {
124
+ console.error("syncSessionConversationsToStore", error);
125
+ }
126
+ }
127
+ if (conversationsToUpdate.length) {
128
+ useConversationStore
129
+ .getState()
130
+ .updateConversationList(conversationsToUpdate, "filter");
131
+ }
132
+ };
133
+ export const useGetSession = ({ filter, options = { pageSize: undefined, isEnabled: true }, }) => {
134
+ var _a, _b;
135
+ const pageSize = (_a = options === null || options === void 0 ? void 0 : options.pageSize) !== null && _a !== void 0 ? _a : SESSION_PAGE_SIZE;
136
+ const isEnabled = (_b = options === null || options === void 0 ? void 0 : options.isEnabled) !== null && _b !== void 0 ? _b : true;
26
137
  const conversationList = useConversationStore((state) => state.conversationList);
27
- const _a = useInfiniteQuery({
138
+ const config = useMemo(() => buildSessionConfig(filter, pageSize), [filter, pageSize]);
139
+ const _c = useInfiniteQuery({
28
140
  initialPageParam: 1,
29
- queryKey: [QUERY_KEYS.GET_SESSION_BY_TAG_OR_STATUS, filter, options],
141
+ queryKey: [config.queryKey, filter, pageSize],
30
142
  queryFn: async ({ pageParam = 1 }) => {
31
- var _a, _b, _c;
32
- const params = {
33
- applicationType: useAuthStore.getState().applicationType,
34
- tag: filter.tag,
35
- status: filter.status,
36
- page: pageParam,
37
- pageSize: (options === null || options === void 0 ? void 0 : options.pageSize) || PAGE_SIZE,
38
- searchTerm: filter.searchTerm,
39
- conversationIds: filter.conversationIds,
40
- };
41
- const res = await apiInstance.post(ENDPOINTS.chatService.getSessionsByTagOrStatus, params);
42
- //FIND NEW CONVERSATIONS
43
- const conversationList = useConversationStore.getState().conversationList;
44
- const newConversations = ((_c = (_b = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.filter) === null || _c === void 0 ? void 0 : _c.call(_b, (session) => {
45
- return !conversationList.some((conversation) => conversation.conversationID === session.conversationId);
46
- })) || [];
47
- if (newConversations === null || newConversations === void 0 ? void 0 : newConversations.length) {
48
- DChatSDK.getMultipleConversation(newConversations.map((session) => session.conversationId)).then((res) => {
49
- useConversationStore
50
- .getState()
51
- .updateConversationList(res.data, "filter");
143
+ var _a, _b;
144
+ const params = config.buildParams(pageParam);
145
+ const res = await apiInstance.post(config.endpoint, params);
146
+ if ((_b = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.length) {
147
+ void syncSessionConversationsToStore(res.data.data).catch((error) => {
148
+ console.error("syncSessionConversationsToStore", error);
52
149
  });
53
150
  }
54
151
  return res.data;
55
152
  },
56
153
  getNextPageParam: (lastPage) => {
57
154
  var _a, _b;
58
- const pageSize = (options === null || options === void 0 ? void 0 : options.pageSize) || PAGE_SIZE;
59
155
  const dataLength = ((_a = lastPage === null || lastPage === void 0 ? void 0 : lastPage.data) === null || _a === void 0 ? void 0 : _a.length) || 0;
60
156
  const currentPage = ((_b = lastPage === null || lastPage === void 0 ? void 0 : lastPage.pageable) === null || _b === void 0 ? void 0 : _b.pageNumber) || 1;
61
157
  return dataLength < pageSize ? undefined : currentPage + 1;
62
158
  },
63
- enabled: (options === null || options === void 0 ? void 0 : options.isEnabled) && hasValidFilter(filter),
64
- }), { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = _a, rest = __rest(_a, ["data", "fetchNextPage", "hasNextPage", "isFetchingNextPage", "isLoading"]);
65
- const { dataFlatten } = useMemo(() => {
66
- var _a, _b, _c;
67
- if (!data) {
68
- return { dataFlatten: [] };
69
- }
159
+ enabled: isEnabled && hasValidFilter(filter),
160
+ }), { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = _c, rest = __rest(_c, ["data", "fetchNextPage", "hasNextPage", "isFetchingNextPage", "isLoading"]);
161
+ const dataFlatten = useMemo(() => {
162
+ var _a;
163
+ if (!data)
164
+ return [];
70
165
  const allItems = data.pages.flatMap((page) => page.data);
71
- // Map session theo conversationId
72
- const sessionMap = new Map(allItems.map((s) => [s.conversationId, s]));
73
- const merged = ((_c = (_b = (_a = conversationList === null || conversationList === void 0 ? void 0 : conversationList.map) === null || _a === void 0 ? void 0 : _a.call(conversationList, (conv) => {
74
- const session = sessionMap.get(conv.conversationID);
166
+ const sessionMap = new Map(allItems.map((session) => [session.conversationId, session]));
167
+ return (((_a = conversationList === null || conversationList === void 0 ? void 0 : conversationList.map((conversation) => {
168
+ const session = sessionMap.get(conversation.conversationID);
75
169
  if (!session)
76
170
  return null;
77
- return Object.assign(Object.assign({}, session), { conversation: conv });
78
- })) === null || _b === void 0 ? void 0 : _b.filter) === null || _c === void 0 ? void 0 : _c.call(_b, (x) => Boolean(x))) || [];
79
- return { dataFlatten: merged };
171
+ return Object.assign(Object.assign({}, session), { conversation });
172
+ })) === null || _a === void 0 ? void 0 : _a.filter((item) => Boolean(item))) || []);
80
173
  }, [data, conversationList]);
81
174
  return Object.assign({ data,
82
175
  fetchNextPage,
@@ -85,10 +178,3 @@ export const useGetSession = ({ filter, options = {
85
178
  isLoading,
86
179
  dataFlatten }, rest);
87
180
  };
88
- function hasValidFilter(filter) {
89
- return Object.values(filter).some((v) => {
90
- if (typeof v === "string")
91
- return v.trim() !== "";
92
- return v !== undefined && v !== null;
93
- });
94
- }
@@ -0,0 +1,3 @@
1
+ import { ITeamSessionSummaryItem } from "../../types/dto";
2
+ export declare const useGetTeamSessionSummary: () => import("@tanstack/react-query").UseQueryResult<ITeamSessionSummaryItem[], Error>;
3
+ //# sourceMappingURL=useGetTeamSessionSummary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGetTeamSessionSummary.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useGetTeamSessionSummary.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAExE,eAAO,MAAM,wBAAwB,wFASjC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import { QUERY_KEYS } from "../../services/query";
3
+ import { apiInstance } from "../../services/api";
4
+ import { ENDPOINTS } from "../../services/routes";
5
+ export const useGetTeamSessionSummary = () => useQuery({
6
+ queryKey: [QUERY_KEYS.GET_TEAM_SESSION_SUMMARY],
7
+ queryFn: async () => {
8
+ var _a;
9
+ const res = await apiInstance.post(ENDPOINTS.chatService.getTeamSessionSummary, {});
10
+ return ((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data) || [];
11
+ },
12
+ });
@@ -0,0 +1,5 @@
1
+ export declare const useIsJoinedGroup: (groupId?: string) => {
2
+ isJoined: boolean | null;
3
+ refetch: () => Promise<void>;
4
+ };
5
+ //# sourceMappingURL=useIsJoinedGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsJoinedGroup.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useIsJoinedGroup.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM;;;CAsBhD,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { useCallback, useEffect, useState } from "react";
3
+ import { DChatSDK } from "../../constants/sdk";
4
+ export const useIsJoinedGroup = (groupId) => {
5
+ const [isJoined, setIsJoined] = useState(null);
6
+ const checkIsJoined = useCallback(async () => {
7
+ if (!groupId) {
8
+ setIsJoined(null);
9
+ return;
10
+ }
11
+ try {
12
+ const { data } = await DChatSDK.isJoinGroup(groupId);
13
+ setIsJoined(Boolean(data));
14
+ }
15
+ catch (error) {
16
+ console.error("isJoinGroup error", error);
17
+ setIsJoined(null);
18
+ }
19
+ }, [groupId]);
20
+ useEffect(() => {
21
+ checkIsJoined();
22
+ }, [checkIsJoined]);
23
+ return { isJoined, refetch: checkIsJoined };
24
+ };
@@ -0,0 +1,12 @@
1
+ interface UseJoinGroupFlowParams {
2
+ groupId?: string;
3
+ latestConversationSessionId?: string;
4
+ refetchIsJoined: () => Promise<unknown>;
5
+ refetchConversationSessions: () => Promise<unknown>;
6
+ }
7
+ export declare const useJoinGroupFlow: ({ groupId, latestConversationSessionId, refetchIsJoined, refetchConversationSessions, }: UseJoinGroupFlowParams) => {
8
+ handleJoinGroup: () => Promise<void>;
9
+ isJoining: boolean;
10
+ };
11
+ export {};
12
+ //# sourceMappingURL=useJoinGroupFlow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useJoinGroupFlow.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useJoinGroupFlow.ts"],"names":[],"mappings":"AAQA,UAAU,sBAAsB;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,2BAA2B,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACrD;AAED,eAAO,MAAM,gBAAgB,GAAI,yFAK9B,sBAAsB;;;CA6DxB,CAAC"}
@@ -0,0 +1,59 @@
1
+ "use client";
2
+ import { message } from "antd";
3
+ import { useCallback, useEffect, useRef } from "react";
4
+ import { useTranslation } from "react-i18next";
5
+ import useConversationStore from "../../store/conversation";
6
+ import { useJoinSession } from "./useJoinSession";
7
+ export const useJoinGroupFlow = ({ groupId, latestConversationSessionId, refetchIsJoined, refetchConversationSessions, }) => {
8
+ const { t } = useTranslation();
9
+ const joinSyncTimerRef = useRef(null);
10
+ const getCurrentGroupInfoByReq = useConversationStore((state) => state.getCurrentGroupInfoByReq);
11
+ const { mutateAsync: joinSession, isPending: isJoining } = useJoinSession();
12
+ const syncGroupStateAfterJoin = useCallback(async () => {
13
+ await refetchIsJoined();
14
+ await refetchConversationSessions();
15
+ if (!groupId)
16
+ return;
17
+ await getCurrentGroupInfoByReq(groupId);
18
+ if (joinSyncTimerRef.current) {
19
+ clearTimeout(joinSyncTimerRef.current);
20
+ }
21
+ joinSyncTimerRef.current = setTimeout(() => {
22
+ void getCurrentGroupInfoByReq(groupId);
23
+ }, 1500);
24
+ }, [
25
+ getCurrentGroupInfoByReq,
26
+ groupId,
27
+ refetchConversationSessions,
28
+ refetchIsJoined,
29
+ ]);
30
+ const handleJoinGroup = useCallback(async () => {
31
+ var _a, _b, _c, _d;
32
+ if (!latestConversationSessionId)
33
+ return;
34
+ try {
35
+ await joinSession(latestConversationSessionId);
36
+ message.success(t("join_group_success"));
37
+ }
38
+ catch (error) {
39
+ const isDuplicate = (_d = (_c = (_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) === null || _c === void 0 ? void 0 : _c.includes) === null || _d === void 0 ? void 0 : _d.call(_c, "Duplicate key");
40
+ if (!isDuplicate) {
41
+ message.error(t("join_group_failed"));
42
+ }
43
+ }
44
+ finally {
45
+ await syncGroupStateAfterJoin();
46
+ }
47
+ }, [joinSession, latestConversationSessionId, syncGroupStateAfterJoin, t]);
48
+ useEffect(() => {
49
+ return () => {
50
+ if (joinSyncTimerRef.current) {
51
+ clearTimeout(joinSyncTimerRef.current);
52
+ }
53
+ };
54
+ }, []);
55
+ return {
56
+ handleJoinGroup,
57
+ isJoining,
58
+ };
59
+ };
@@ -0,0 +1,3 @@
1
+ import { BaseResponse } from "../../types/dto";
2
+ export declare const useJoinSession: () => import("@tanstack/react-query").UseMutationResult<BaseResponse<boolean>, Error, string, unknown>;
3
+ //# sourceMappingURL=useJoinSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useJoinSession.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useJoinSession.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,eAAO,MAAM,cAAc,wGAqC1B,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
2
+ import { QUERY_KEYS } from "../../services/query";
3
+ import { apiInstance } from "../../services/api";
4
+ import { ENDPOINTS } from "../../services/routes";
5
+ import useAuthStore from "../../store/auth";
6
+ export const useJoinSession = () => {
7
+ const queryClient = useQueryClient();
8
+ return useMutation({
9
+ mutationKey: [QUERY_KEYS.JOIN_SESSION],
10
+ mutationFn: async (sessionId) => {
11
+ const res = await apiInstance.post(ENDPOINTS.chatService.joinSession(sessionId), null, {
12
+ params: {
13
+ applicationType: useAuthStore.getState().applicationType,
14
+ },
15
+ });
16
+ return res === null || res === void 0 ? void 0 : res.data;
17
+ },
18
+ onSuccess: async () => {
19
+ await Promise.all([
20
+ queryClient.invalidateQueries({
21
+ queryKey: [QUERY_KEYS.GET_SESSION_SUMMARY],
22
+ }),
23
+ queryClient.invalidateQueries({
24
+ queryKey: [QUERY_KEYS.GET_TEAM_SESSION_SUMMARY],
25
+ }),
26
+ queryClient.invalidateQueries({
27
+ queryKey: [QUERY_KEYS.GET_SESSION_BY_TAG_OR_STATUS],
28
+ }),
29
+ queryClient.invalidateQueries({
30
+ queryKey: [QUERY_KEYS.GET_TEAM_SESSIONS],
31
+ }),
32
+ queryClient.invalidateQueries({
33
+ queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
34
+ }),
35
+ ]);
36
+ },
37
+ });
38
+ };
@@ -0,0 +1,3 @@
1
+ import { AccountType } from "../../types/chat";
2
+ export declare const useCurrentUserAccountType: () => AccountType;
3
+ //# sourceMappingURL=useCurrentUserAccountType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCurrentUserAccountType.d.ts","sourceRoot":"","sources":["../../../src/hooks/user/useCurrentUserAccountType.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,WAAW,EAEZ,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,yBAAyB,mBA4BrC,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { useEffect, useMemo } from "react";
3
+ import { DChatSDK } from "../../constants/sdk";
4
+ import useUsersInfoStore from "../../store/usersInfo";
5
+ import useAuthStore from "../../store/auth";
6
+ import { AccountType, } from "../../types/chat";
7
+ export const useCurrentUserAccountType = () => {
8
+ const userID = useAuthStore((state) => state.userID);
9
+ const currentUser = useUsersInfoStore((state) => userID ? state.usersInfo[userID] : undefined);
10
+ useEffect(() => {
11
+ if (!userID || currentUser)
12
+ return;
13
+ DChatSDK.getUsersInfo([userID])
14
+ .then(({ data }) => {
15
+ useUsersInfoStore.getState().upsertUsers(data);
16
+ })
17
+ .catch((error) => {
18
+ console.error("Error fetching current user info:", error);
19
+ });
20
+ }, [currentUser, userID]);
21
+ return useMemo(() => {
22
+ var _a, _b, _c, _d;
23
+ try {
24
+ return ((_d = (_c = (_b = (_a = JSON.parse((currentUser === null || currentUser === void 0 ? void 0 : currentUser.ex) || "{}")) === null || _a === void 0 ? void 0 : _a.userInfo) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.accountType) !== null && _d !== void 0 ? _d : AccountType.Customer);
25
+ }
26
+ catch (_e) {
27
+ return AccountType.Customer;
28
+ }
29
+ }, [currentUser]);
30
+ };
@@ -24,6 +24,10 @@
24
24
  "see_more": "Xem thêm",
25
25
  "err_get_conversation": "Lỗi khi lấy thông tin cuộc trò chuyện",
26
26
  "enter_message": "Nhập tin nhắn",
27
+ "enter_internal_message": "Tin nhắn nội bộ chỉ hiển thị với bạn và các thành viên trong nhóm.",
28
+ "reply": "Reply",
29
+ "internal": "Internal",
30
+ "canned_response_hint": "Gõ # và nhấn Enter để chèn câu trả lời nhanh",
27
31
  "update_session_status_title": "Cập nhật status",
28
32
  "update_session_tag_title": "Cập nhật tag",
29
33
  "cancel": "Hủy",
@@ -98,5 +102,11 @@
98
102
  "canned_response_quick_search_placeholder": "Câu trả lời nhanh phù hợp với",
99
103
  "replied_yourself": "đã trả lời chính mình",
100
104
  "replied_you": "đã trả lời bạn",
101
- "replied": "đã trả lời"
102
- }
105
+ "replied": "đã trả lời",
106
+ "my_messages": "Tin nhắn của tôi",
107
+ "team_messages": "Tin nhắn nhóm",
108
+ "join_group_required": "Bạn phải là thành viên để gửi tin nhắn",
109
+ "join_group": "Tham gia",
110
+ "join_group_success": "Tham gia nhóm thành công",
111
+ "join_group_failed": "Tham gia nhóm thất bại"
112
+ }
@@ -14,8 +14,13 @@ export declare const QUERY_KEYS: {
14
14
  GET_LABEL_SESSION: string;
15
15
  GET_TEAM_SUPPORTERS: string;
16
16
  ASSIGN_SESSION: string;
17
+ GET_TEAM_SESSION_SUMMARY: string;
18
+ GET_TEAM_SESSIONS: string;
17
19
  GET_MY_TEAMS: string;
18
20
  GET_CANNED_CATEGORIES: string;
19
21
  GET_CANNED_RESPONSES: string;
22
+ JOIN_SESSION: string;
23
+ PULL_SESSION_MESSAGES: string;
24
+ GET_CONVERSATIONS_IM_DETAIL: string;
20
25
  };
21
26
  //# sourceMappingURL=query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/services/query.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;CAmBtB,CAAC"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/services/query.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;CAwBtB,CAAC"}
@@ -14,7 +14,12 @@ export const QUERY_KEYS = {
14
14
  GET_LABEL_SESSION: "GET_LABEL_SESSION",
15
15
  GET_TEAM_SUPPORTERS: "GET_TEAM_SUPPORTERS",
16
16
  ASSIGN_SESSION: "ASSIGN_SESSION",
17
+ GET_TEAM_SESSION_SUMMARY: "GET_TEAM_SESSION_SUMMARY",
18
+ GET_TEAM_SESSIONS: "GET_TEAM_SESSIONS",
17
19
  GET_MY_TEAMS: "GET_MY_TEAMS_PACKAGE",
18
20
  GET_CANNED_CATEGORIES: "GET_CANNED_CATEGORIES_PACKAGE",
19
21
  GET_CANNED_RESPONSES: "GET_CANNED_RESPONSES_PACKAGE",
22
+ JOIN_SESSION: "JOIN_SESSION",
23
+ PULL_SESSION_MESSAGES: "PULL_SESSION_MESSAGES",
24
+ GET_CONVERSATIONS_IM_DETAIL: "GET_CONVERSATIONS_IM_DETAIL",
20
25
  };
@@ -15,9 +15,14 @@ export declare const ENDPOINTS: {
15
15
  getLabelSession: string;
16
16
  getTeamSupporters: (teamId: string) => string;
17
17
  assignSession: (sessionId: string) => string;
18
+ getTeamSessionSummary: string;
19
+ getTeamSessionsByQuery: string;
18
20
  getMyTeams: string;
19
21
  getCannedCategories: string;
20
22
  getCannedResponses: string;
23
+ joinSession: (sessionId: string) => string;
24
+ pullSessionMessages: string;
25
+ getConversationsImDetail: string;
21
26
  };
22
27
  identityService: {
23
28
  getToken: string;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/services/routes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;;;mCAMS,MAAM;;0CAGC,MAAM,UAAU,MAAM;6BAEnC,MAAM;;oDAEiB,MAAM;uCAEnB,MAAM;kCAEX,MAAM;;oCAGJ,MAAM;mCAEP,MAAM;;;;;;;;;;;CAYpC,CAAC"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/services/routes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;;;mCAMS,MAAM;;0CAGC,MAAM,UAAU,MAAM;6BAEnC,MAAM;;oDAEiB,MAAM;uCAEnB,MAAM;kCAEX,MAAM;;oCAGJ,MAAM;mCAEP,MAAM;;;;;;iCAOR,MAAM;;;;;;;;;;CAWlC,CAAC"}
@@ -15,9 +15,14 @@ export const ENDPOINTS = {
15
15
  getLabelSession: "chat-service/v1/labels",
16
16
  getTeamSupporters: (teamId) => `chat-service/v1/crm/teams/${teamId}/supporters`,
17
17
  assignSession: (sessionId) => `chat-service/v1/crm/sessions/${sessionId}/assign`,
18
+ getTeamSessionSummary: "chat-service/v1/crm/sessions/teams/summary",
19
+ getTeamSessionsByQuery: "chat-service/v1/crm/sessions/team/query",
18
20
  getMyTeams: "/chat-service/v1/crm/teams/user/me",
19
21
  getCannedCategories: "/chat-service/v1/crm/canned-responses/categories",
20
22
  getCannedResponses: "chat-service/v1/crm/canned-responses/search",
23
+ joinSession: (sessionId) => `chat-service/v1/crm/sessions/${sessionId}/join`,
24
+ pullSessionMessages: "/chat-service/v1/messages/session/pull",
25
+ getConversationsImDetail: "/chat-service/v1/crm/conversations/im-detail",
21
26
  },
22
27
  identityService: {
23
28
  getToken: "/identity-service/v1/identity/get-token",
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/store/conversation.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAO3C,QAAA,MAAM,oBAAoB,gFA8JvB,CAAC;AAEJ,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/store/conversation.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAO3C,QAAA,MAAM,oBAAoB,gFA6LvB,CAAC;AAEJ,eAAe,oBAAoB,CAAC"}
@@ -7,13 +7,16 @@ import { markConversationMessageAsRead } from "../hooks/conversation/useConversa
7
7
  const CONVERSATION_SPLIT_COUNT = 500;
8
8
  const useConversationStore = create((set, get) => ({
9
9
  conversationData: null,
10
- setConversationData: (data, dataSearchClientMsgID) => set({
11
- conversationData: data,
12
- selectedSourceId: (data === null || data === void 0 ? void 0 : data.conversationType) === SessionType.Group
13
- ? data === null || data === void 0 ? void 0 : data.groupID
14
- : data === null || data === void 0 ? void 0 : data.userID,
15
- searchClientMsgID: dataSearchClientMsgID,
16
- }),
10
+ setConversationData: (data, dataSearchClientMsgID) => {
11
+ void get().updateCurrentConversation(data);
12
+ set({
13
+ conversationData: data,
14
+ selectedSourceId: (data === null || data === void 0 ? void 0 : data.conversationType) === SessionType.Group
15
+ ? data === null || data === void 0 ? void 0 : data.groupID
16
+ : data === null || data === void 0 ? void 0 : data.userID,
17
+ searchClientMsgID: dataSearchClientMsgID,
18
+ });
19
+ },
17
20
  selectedConversationId: "",
18
21
  setSelectedConversationId: (threadId) => set({ selectedConversationId: threadId, quotedMessage: null }),
19
22
  selectedSourceId: "",
@@ -67,15 +70,29 @@ const useConversationStore = create((set, get) => ({
67
70
  },
68
71
  updateCurrentConversation: async (conversation) => {
69
72
  if (!conversation) {
70
- set({ currentConversation: undefined });
73
+ set({
74
+ currentConversation: undefined,
75
+ currentGroupInfo: undefined,
76
+ currentMemberInGroup: undefined,
77
+ });
71
78
  return;
72
79
  }
73
80
  const prevConversation = get().currentConversation;
74
81
  const toggleNewConversation = conversation.conversationID !== (prevConversation === null || prevConversation === void 0 ? void 0 : prevConversation.conversationID);
75
- if (toggleNewConversation &&
76
- isGroupSession(conversation.conversationType)) {
77
- get().getCurrentGroupInfoByReq(conversation.groupID);
78
- await get().getCurrentMemberInGroupByReq(conversation.groupID);
82
+ if (toggleNewConversation) {
83
+ if (isGroupSession(conversation.conversationType)) {
84
+ set({
85
+ currentMemberInGroup: undefined,
86
+ });
87
+ get().getCurrentGroupInfoByReq(conversation.groupID);
88
+ await get().getCurrentMemberInGroupByReq(conversation.groupID);
89
+ }
90
+ else {
91
+ set({
92
+ currentGroupInfo: undefined,
93
+ currentMemberInGroup: undefined,
94
+ });
95
+ }
79
96
  }
80
97
  set(() => ({ currentConversation: Object.assign({}, conversation) }));
81
98
  },
@@ -89,6 +106,12 @@ const useConversationStore = create((set, get) => ({
89
106
  console.error("Error fetching group info:", error);
90
107
  return;
91
108
  }
109
+ const currentConversationData = get().conversationData;
110
+ const shouldApplyGroupInfo = (currentConversationData === null || currentConversationData === void 0 ? void 0 : currentConversationData.groupID) === groupID &&
111
+ isGroupSession(currentConversationData === null || currentConversationData === void 0 ? void 0 : currentConversationData.conversationType);
112
+ if (!shouldApplyGroupInfo) {
113
+ return;
114
+ }
92
115
  set(() => ({ currentGroupInfo: Object.assign({}, groupInfo) }));
93
116
  },
94
117
  getCurrentMemberInGroupByReq: async (groupID) => {
@@ -106,6 +129,12 @@ const useConversationStore = create((set, get) => ({
106
129
  console.error("Error fetching group members:", error);
107
130
  return;
108
131
  }
132
+ const currentConversationData = get().conversationData;
133
+ const shouldApplyMemberInfo = (currentConversationData === null || currentConversationData === void 0 ? void 0 : currentConversationData.groupID) === groupID &&
134
+ isGroupSession(currentConversationData === null || currentConversationData === void 0 ? void 0 : currentConversationData.conversationType);
135
+ if (!shouldApplyMemberInfo) {
136
+ return;
137
+ }
109
138
  set(() => ({
110
139
  currentMemberInGroup: memberInfo ? Object.assign({}, memberInfo) : undefined,
111
140
  }));
@@ -1,6 +1,6 @@
1
1
  import { create } from "zustand";
2
2
  import { SessionStatus } from "../types/chat";
3
- const useSessionStore = create((set, get) => ({
3
+ const useSessionStore = create((set) => ({
4
4
  filterSummary: {
5
5
  status: SessionStatus.IN_PROCESS,
6
6
  tag: undefined,