@droppii-org/chat-sdk 0.8.1 → 0.8.2

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 (165) hide show
  1. package/dist/components/canned-response/cannedTrigger.d.ts +2 -0
  2. package/dist/components/canned-response/cannedTrigger.d.ts.map +1 -0
  3. package/dist/components/canned-response/cannedTrigger.js +3 -0
  4. package/dist/components/canned-response/insertCannedContent.js +2 -2
  5. package/dist/components/conversation/ConversationByGroupItem.js +1 -1
  6. package/dist/components/conversation/ConversationBySessionItem.js +4 -4
  7. package/dist/components/conversation/internalNotePreview.d.ts +1 -1
  8. package/dist/components/conversation/internalNotePreview.d.ts.map +1 -1
  9. package/dist/components/conversation/internalNotePreview.js +22 -3
  10. package/dist/components/conversation/rowTime.d.ts +2 -2
  11. package/dist/components/conversation/rowTime.d.ts.map +1 -1
  12. package/dist/components/conversation/rowTime.js +2 -4
  13. package/dist/components/conversation-detail/ConversationDetailInput.d.ts.map +1 -1
  14. package/dist/components/conversation-detail/ConversationDetailInput.js +8 -3
  15. package/dist/components/conversation-detail/ConversationMessageList.d.ts.map +1 -1
  16. package/dist/components/conversation-detail/ConversationMessageList.js +6 -3
  17. package/dist/components/conversation-detail/bot/BotMenuSheet.d.ts.map +1 -1
  18. package/dist/components/conversation-detail/bot/BotMenuSheet.js +1 -1
  19. package/dist/components/conversation-inbox/ConversationInboxList.d.ts.map +1 -1
  20. package/dist/components/conversation-inbox/ConversationInboxList.js +4 -0
  21. package/dist/components/conversation-inbox/InboxBootStatus.d.ts.map +1 -1
  22. package/dist/components/conversation-inbox/InboxBootStatus.js +10 -2
  23. package/dist/components/group/CreateGroupForm.d.ts.map +1 -1
  24. package/dist/components/group/CreateGroupForm.js +2 -1
  25. package/dist/components/group/CreateGroupFormCrmView.d.ts.map +1 -1
  26. package/dist/components/group/CreateGroupFormCrmView.js +1 -1
  27. package/dist/components/group/GroupMemberPickerCrm.d.ts.map +1 -1
  28. package/dist/components/group/GroupMemberPickerCrm.js +1 -1
  29. package/dist/components/media-collection/FileCollection.d.ts.map +1 -1
  30. package/dist/components/media-collection/FileCollection.js +2 -1
  31. package/dist/components/media-collection/ImageCollection.d.ts.map +1 -1
  32. package/dist/components/media-collection/ImageCollection.js +2 -1
  33. package/dist/components/media-collection/LinkCollection.d.ts.map +1 -1
  34. package/dist/components/media-collection/LinkCollection.js +14 -26
  35. package/dist/components/media-collection/VideoCollection.d.ts.map +1 -1
  36. package/dist/components/media-collection/VideoCollection.js +2 -1
  37. package/dist/components/media-resources/ResourceScrollContainer.d.ts.map +1 -1
  38. package/dist/components/media-resources/ResourceScrollContainer.js +34 -2
  39. package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
  40. package/dist/components/message/GroupMembersDrawer.js +2 -3
  41. package/dist/components/message/MessageList.d.ts.map +1 -1
  42. package/dist/components/message/MessageList.js +15 -4
  43. package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
  44. package/dist/components/message/footer/ActionBar.js +10 -44
  45. package/dist/components/message/footer/CannedResponsePlugin.d.ts.map +1 -1
  46. package/dist/components/message/footer/CannedResponsePlugin.js +3 -2
  47. package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
  48. package/dist/components/message/footer/EnterHandler.js +10 -47
  49. package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
  50. package/dist/components/message/footer/FilePreview.js +2 -1
  51. package/dist/components/message/footer/LinkInputPreview.d.ts +1 -1
  52. package/dist/components/message/footer/LinkInputPreview.d.ts.map +1 -1
  53. package/dist/components/message/footer/LinkInputPreview.js +8 -1
  54. package/dist/components/message/footer/MediaUploadButtons.d.ts.map +1 -1
  55. package/dist/components/message/footer/MediaUploadButtons.js +4 -7
  56. package/dist/components/message/footer/index.d.ts.map +1 -1
  57. package/dist/components/message/footer/index.js +57 -16
  58. package/dist/components/message/footer/mention/useMentionOptions.d.ts.map +1 -1
  59. package/dist/components/message/footer/mention/useMentionOptions.js +2 -6
  60. package/dist/components/message/footer/resetEditorAfterSend.d.ts +7 -0
  61. package/dist/components/message/footer/resetEditorAfterSend.d.ts.map +1 -0
  62. package/dist/components/message/footer/resetEditorAfterSend.js +62 -0
  63. package/dist/components/message/groupMemberMenuCrm.d.ts +4 -4
  64. package/dist/components/message/groupMemberMenuCrm.d.ts.map +1 -1
  65. package/dist/components/message/groupMemberMenuCrm.js +73 -60
  66. package/dist/components/message/item/SystemLogMessage.d.ts.map +1 -1
  67. package/dist/components/message/item/SystemLogMessage.js +5 -2
  68. package/dist/components/search-conversation/SearchConversationAsGroups.js +1 -1
  69. package/dist/components/search-conversation/SearchConversationAsMessages.js +1 -1
  70. package/dist/components/search-conversation/SearchConversationMyInbox.js +1 -1
  71. package/dist/components/thread/GroupInfoBodyCrm.d.ts.map +1 -1
  72. package/dist/components/thread/GroupInfoBodyCrm.js +2 -2
  73. package/dist/components/thread/GroupThreadInfo.d.ts.map +1 -1
  74. package/dist/components/thread/GroupThreadInfo.js +2 -6
  75. package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
  76. package/dist/components/thread/ManualAssignPopover.js +6 -8
  77. package/dist/components/thread/SessionDetailCard.d.ts.map +1 -1
  78. package/dist/components/thread/SessionDetailCard.js +3 -3
  79. package/dist/components/thread/SessionSection.d.ts.map +1 -1
  80. package/dist/components/thread/SessionSection.js +3 -9
  81. package/dist/components/thread/SessionTagPicker.d.ts +3 -1
  82. package/dist/components/thread/SessionTagPicker.d.ts.map +1 -1
  83. package/dist/components/thread/SessionTagPicker.js +2 -2
  84. package/dist/components/thread/sessionDateFormat.d.ts +2 -0
  85. package/dist/components/thread/sessionDateFormat.d.ts.map +1 -1
  86. package/dist/components/thread/sessionDateFormat.js +6 -0
  87. package/dist/constants/dateFormat.d.ts +2 -0
  88. package/dist/constants/dateFormat.d.ts.map +1 -0
  89. package/dist/constants/dateFormat.js +2 -0
  90. package/dist/hooks/common/useFetchUrlMetadata.d.ts +1 -0
  91. package/dist/hooks/common/useFetchUrlMetadata.d.ts.map +1 -1
  92. package/dist/hooks/conversation/useBotFlow.d.ts.map +1 -1
  93. package/dist/hooks/conversation/useBotFlow.js +64 -12
  94. package/dist/hooks/conversation/useCloseBotSession.d.ts +2 -0
  95. package/dist/hooks/conversation/useCloseBotSession.d.ts.map +1 -1
  96. package/dist/hooks/conversation/useCloseBotSession.js +17 -1
  97. package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
  98. package/dist/hooks/global/useGlobalEvent.js +148 -16
  99. package/dist/hooks/global/useLoginHealth.d.ts +3 -0
  100. package/dist/hooks/global/useLoginHealth.d.ts.map +1 -0
  101. package/dist/hooks/global/useLoginHealth.js +55 -0
  102. package/dist/hooks/group/useCreateGroup.d.ts.map +1 -1
  103. package/dist/hooks/group/useCreateGroup.js +75 -6
  104. package/dist/hooks/init/useChatBootPhase.d.ts +2 -0
  105. package/dist/hooks/init/useChatBootPhase.d.ts.map +1 -1
  106. package/dist/hooks/init/useChatBootPhase.js +11 -6
  107. package/dist/hooks/message/useMessage.d.ts.map +1 -1
  108. package/dist/hooks/message/useMessage.js +97 -28
  109. package/dist/hooks/message/usePinnedMessages.d.ts.map +1 -1
  110. package/dist/hooks/message/usePinnedMessages.js +13 -2
  111. package/dist/hooks/message/useRevokeMessage.d.ts.map +1 -1
  112. package/dist/hooks/message/useRevokeMessage.js +25 -0
  113. package/dist/hooks/message/useSendMessage.d.ts +15 -12
  114. package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
  115. package/dist/hooks/message/useSendMessage.js +199 -133
  116. package/dist/hooks/search/useSearchMessage.d.ts.map +1 -1
  117. package/dist/hooks/search/useSearchMessage.js +57 -3
  118. package/dist/hooks/session/useConversationSessionState.d.ts.map +1 -1
  119. package/dist/hooks/session/useConversationSessionState.js +4 -1
  120. package/dist/hooks/session/useSessionLatestPreview.d.ts.map +1 -1
  121. package/dist/hooks/session/useSessionLatestPreview.js +34 -4
  122. package/dist/hooks/user/useAuth.d.ts +1 -1
  123. package/dist/hooks/user/useAuth.d.ts.map +1 -1
  124. package/dist/hooks/user/useAuth.js +31 -15
  125. package/dist/index.d.ts +1 -0
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +1 -0
  128. package/dist/locales/vi/boot.json +5 -1
  129. package/dist/locales/vi/common.json +34 -15
  130. package/dist/locales/vi/conversation-inbox.json +2 -1
  131. package/dist/screens/conversation-detail/index.d.ts.map +1 -1
  132. package/dist/screens/conversation-detail/index.js +6 -0
  133. package/dist/screens/desk-message/DeskBootCard.d.ts.map +1 -1
  134. package/dist/screens/desk-message/DeskBootCard.js +6 -4
  135. package/dist/store/boot.d.ts +5 -0
  136. package/dist/store/boot.d.ts.map +1 -1
  137. package/dist/store/boot.js +11 -1
  138. package/dist/store/conversation.d.ts.map +1 -1
  139. package/dist/store/conversation.js +5 -1
  140. package/dist/store/type.d.ts +3 -1
  141. package/dist/store/type.d.ts.map +1 -1
  142. package/dist/styles/global.css +1 -1
  143. package/dist/types/chat.d.ts +1 -1
  144. package/dist/types/chat.d.ts.map +1 -1
  145. package/dist/utils/common.d.ts.map +1 -1
  146. package/dist/utils/common.js +4 -1
  147. package/dist/utils/fileValidation.d.ts +7 -0
  148. package/dist/utils/fileValidation.d.ts.map +1 -1
  149. package/dist/utils/fileValidation.js +37 -13
  150. package/dist/utils/latestMessagePreviewable.d.ts +2 -0
  151. package/dist/utils/latestMessagePreviewable.d.ts.map +1 -0
  152. package/dist/utils/latestMessagePreviewable.js +18 -0
  153. package/dist/utils/mentionMembers.d.ts +3 -0
  154. package/dist/utils/mentionMembers.d.ts.map +1 -0
  155. package/dist/utils/mentionMembers.js +29 -0
  156. package/dist/utils/messageLog.d.ts +2 -2
  157. package/dist/utils/messageLog.d.ts.map +1 -1
  158. package/dist/utils/messageLog.js +129 -40
  159. package/dist/utils/notifiableMessage.d.ts +7 -0
  160. package/dist/utils/notifiableMessage.d.ts.map +1 -0
  161. package/dist/utils/notifiableMessage.js +26 -0
  162. package/dist/utils/withSdkTimeout.d.ts +11 -0
  163. package/dist/utils/withSdkTimeout.d.ts.map +1 -0
  164. package/dist/utils/withSdkTimeout.js +30 -0
  165. package/package.json +1 -1
@@ -7,6 +7,7 @@ import { useQueryClient } from "@tanstack/react-query";
7
7
  import { useTranslation } from "react-i18next";
8
8
  import { pushNewMessage, removeOneMessage, updateOneMessage, } from "./useMessage";
9
9
  import { emit } from "../../utils/events";
10
+ import { message as toast } from "antd";
10
11
  import useConversationStore from "../../store/conversation";
11
12
  import useAuthStore from "../../store/auth";
12
13
  import { apiInstance } from "../../services/api";
@@ -19,6 +20,8 @@ import { invalidateSessionQueries } from "../../utils/queryHelpers";
19
20
  import { resolveConversationBotId } from "../../utils/conversation";
20
21
  import { QUERY_KEYS } from "../../services/query";
21
22
  import { enqueue } from "../../utils/sendQueue";
23
+ import { SDK_CALL_TIMEOUT_MS, SdkCallError, SdkTimeoutError, withSdkTimeout, } from "../../utils/withSdkTimeout";
24
+ import { keepCurrentGroupMembersOnly } from "../../utils/mentionMembers";
22
25
  const messageFileStore = new Map();
23
26
  const MEDIA_CONTENT_TYPES = new Set([
24
27
  MessageType.PictureMessage,
@@ -27,106 +30,70 @@ const MEDIA_CONTENT_TYPES = new Set([
27
30
  ]);
28
31
  export const isMediaResendable = (message) => !MEDIA_CONTENT_TYPES.has(message.contentType) ||
29
32
  messageFileStore.has(message.clientMsgID);
30
- export const createTextMessage = async (text) => {
31
- const textMessage = await DChatSDK.createTextMessage(text, new Date().getTime().toString())
32
- .then(({ data }) => {
33
- return data;
34
- })
35
- .catch(({ errCode, errMsg }) => {
36
- console.error("createTextMessage", errCode, errMsg);
37
- return null;
33
+ // Messages whose sendMessage call is still unsettled, including ones the UI already
34
+ // gave up on after a timeout. Resending those would create a duplicate.
35
+ // The value is when the UI gave up waiting (null while it still waits). A call stuck for
36
+ // longer than the ceiling past that point is treated as lost so the user can resend.
37
+ const PENDING_SEND_CEILING_MS = 120000;
38
+ const pendingSends = new Map();
39
+ const findCachedSession = (queryClient, sessionId) => {
40
+ var _a;
41
+ const cached = queryClient.getQueriesData({
42
+ queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
38
43
  });
39
- return textMessage;
44
+ for (const [, data] of cached) {
45
+ const found = (_a = data === null || data === void 0 ? void 0 : data.pages) === null || _a === void 0 ? void 0 : _a.flat().find((session) => session.id === sessionId);
46
+ if (found)
47
+ return found;
48
+ }
49
+ return undefined;
40
50
  };
41
- export const createImageMessageByFile = async (file) => {
42
- const imageMessage = await DChatSDK.createImageMessageByFile(file, new Date().getTime().toString())
43
- .then(({ data }) => {
51
+ export const isSendPending = (clientMsgID) => {
52
+ if (!pendingSends.has(clientMsgID))
53
+ return false;
54
+ const gaveUpAt = pendingSends.get(clientMsgID);
55
+ return gaveUpAt == null || Date.now() - gaveUpAt < PENDING_SEND_CEILING_MS;
56
+ };
57
+ // Message builders fail loudly: a hung or rejected core call used to come back as
58
+ // null, which looked like "nothing to send" and cleared the composer.
59
+ const sendCall = async (label, call) => {
60
+ try {
61
+ const { data } = await withSdkTimeout(call, label);
44
62
  return data;
45
- })
46
- .catch(({ errCode, errMsg }) => {
47
- console.error("createImageMessageByFile", errCode, errMsg);
48
- return null;
49
- });
50
- return imageMessage;
63
+ }
64
+ catch (error) {
65
+ console.error(label, error);
66
+ throw error;
67
+ }
68
+ };
69
+ export const createTextMessage = async (text) => {
70
+ return sendCall("createTextMessage", DChatSDK.createTextMessage(text, new Date().getTime().toString()));
71
+ };
72
+ export const createImageMessageByFile = async (file) => {
73
+ return sendCall("createImageMessageByFile", DChatSDK.createImageMessageByFile(file, new Date().getTime().toString()));
51
74
  };
52
75
  export const createMergerMessage = async (mergerMsgParams) => {
53
- const mergerMessage = await DChatSDK.createMergerMessage(mergerMsgParams, new Date().getTime().toString())
54
- .then(({ data }) => {
55
- return data;
56
- })
57
- .catch(({ errCode, errMsg }) => {
58
- console.error("createMergerMessage", errCode, errMsg);
59
- return null;
60
- });
61
- return mergerMessage;
76
+ return sendCall("createMergerMessage", DChatSDK.createMergerMessage(mergerMsgParams, new Date().getTime().toString()));
62
77
  };
63
78
  export const createVideoMessageByFile = async (file) => {
64
- const videoMessage = await DChatSDK.createVideoMessageByFile(file, new Date().getTime().toString())
65
- .then(({ data }) => {
66
- return data;
67
- })
68
- .catch(({ errCode, errMsg }) => {
69
- console.error("createVideoMessageByFile", errCode, errMsg);
70
- return null;
71
- });
72
- return videoMessage;
79
+ return sendCall("createVideoMessageByFile", DChatSDK.createVideoMessageByFile(file, new Date().getTime().toString()));
73
80
  };
74
81
  export const createFileMessageByFile = async (file) => {
75
- const fileMessage = await DChatSDK.createFileMessageByFile(file, new Date().getTime().toString())
76
- .then(({ data }) => {
77
- return data;
78
- })
79
- .catch(({ errCode, errMsg }) => {
80
- console.error("createFileMessageByFile", errCode, errMsg);
81
- return null;
82
- });
83
- return fileMessage;
82
+ return sendCall("createFileMessageByFile", DChatSDK.createFileMessageByFile(file, new Date().getTime().toString()));
84
83
  };
85
84
  // OpenIM SDK convention for "tag all members" in AtMsgParams.atUserIDList.
86
85
  export const AT_ALL_TAG = "AtAllTag";
87
86
  export const createAtTextMessage = async (params) => {
88
- const atTextMessage = await DChatSDK.createTextAtMessage(params, new Date().getTime().toString())
89
- .then(({ data }) => {
90
- return data;
91
- })
92
- .catch(({ errCode, errMsg }) => {
93
- console.error("createTextAtMessage", errCode, errMsg);
94
- return null;
95
- });
96
- return atTextMessage;
87
+ return sendCall("createTextAtMessage", DChatSDK.createTextAtMessage(params, new Date().getTime().toString()));
97
88
  };
98
89
  export const createUrlTextMessage = async (text, urls) => {
99
- const textMessage = await DChatSDK.createUrlTextMessage(text, JSON.stringify(urls), new Date().getTime().toString())
100
- .then(({ data }) => {
101
- return data;
102
- })
103
- .catch(({ errCode, errMsg }) => {
104
- console.error("createUrlTextMessage", errCode, errMsg);
105
- return null;
106
- });
107
- return textMessage;
90
+ return sendCall("createUrlTextMessage", DChatSDK.createUrlTextMessage(text, JSON.stringify(urls), new Date().getTime().toString()));
108
91
  };
109
92
  export const createStickerMessage = async (stickerUrl) => {
110
- const stickerMessage = await DChatSDK.createStickerMessage(stickerUrl, uuidv4())
111
- .then(({ data }) => {
112
- return data;
113
- })
114
- .catch(({ errCode, errMsg }) => {
115
- console.error("createStickerMessage", errCode, errMsg);
116
- return null;
117
- });
118
- return stickerMessage;
93
+ return sendCall("createStickerMessage", DChatSDK.createStickerMessage(stickerUrl, uuidv4()));
119
94
  };
120
95
  export const createCustomMessageByParams = async (params) => {
121
- const customMessage = await DChatSDK.createCustomMessage(params, new Date().getTime().toString())
122
- .then(({ data }) => {
123
- return data;
124
- })
125
- .catch(({ errCode, errMsg }) => {
126
- console.error("createCustomMessage", errCode, errMsg);
127
- return null;
128
- });
129
- return customMessage;
96
+ return sendCall("createCustomMessage", DChatSDK.createCustomMessage(params, new Date().getTime().toString()));
130
97
  };
131
98
  export const createCustomMessage = async (payload) => {
132
99
  return createCustomMessageByParams({
@@ -136,19 +103,11 @@ export const createCustomMessage = async (payload) => {
136
103
  });
137
104
  };
138
105
  export const createQuoteMessage = async (text, quotedMessage, urls) => {
139
- const textMessage = await DChatSDK.createQuoteMessage({
106
+ return sendCall("createQuoteMessage", DChatSDK.createQuoteMessage({
140
107
  text,
141
108
  message: JSON.stringify(quotedMessage),
142
109
  urls,
143
- })
144
- .then(({ data }) => {
145
- return data;
146
- })
147
- .catch(({ errCode, errMsg }) => {
148
- console.error("createQuoteMessage", errCode, errMsg);
149
- return null;
150
- });
151
- return textMessage;
110
+ }));
152
111
  };
153
112
  // Rebuilds a failed message under a new clientMsgID, re-attaching its stored files.
154
113
  const recreateFailedMessage = async (failedMessage) => {
@@ -249,6 +208,13 @@ const settleOrTimeout = (promise, ms) => new Promise((resolve) => {
249
208
  resolve();
250
209
  });
251
210
  });
211
+ // Text goes out in moments; only a stored file can legitimately take longer.
212
+ const sendDispatchTimeoutMs = (message) => {
213
+ var _a, _b;
214
+ const items = (_b = (_a = message.mergeElem) === null || _a === void 0 ? void 0 : _a.multiMessage) !== null && _b !== void 0 ? _b : [message];
215
+ const hasFiles = items.some((item) => storedFileBytes(item.clientMsgID) > 0);
216
+ return hasFiles ? sendHoldLimitMs(message) : SDK_CALL_TIMEOUT_MS;
217
+ };
252
218
  let unsentCount = 0;
253
219
  const warnUnsent = (event) => {
254
220
  event.preventDefault();
@@ -274,7 +240,19 @@ export const useSendMessage = (options) => {
274
240
  const userId = useAuthStore((state) => state.userID);
275
241
  const { userID: recvID, groupID } = conversationData || {};
276
242
  const scrollEvent = (_a = options === null || options === void 0 ? void 0 : options.scrollEvent) !== null && _a !== void 0 ? _a : "CHAT_LIST_SCROLL_TO_BOTTOM";
277
- const syncSessionAfterPublicMessage = useCallback(async (currentSession) => {
243
+ const syncSessionAfterPublicMessage = useCallback(async (sessionAtSend, isLateSuccess = false) => {
244
+ let currentSession = sessionAtSend;
245
+ if (isLateSuccess && (sessionAtSend === null || sessionAtSend === void 0 ? void 0 : sessionAtSend.id)) {
246
+ // Minutes may have passed since the send; the session can be closed or reassigned by now.
247
+ const latest = findCachedSession(queryClient, sessionAtSend.id);
248
+ if (latest &&
249
+ (latest.isClosed ||
250
+ latest.status === SessionStatus.COMPLETED ||
251
+ latest.supporterId !== sessionAtSend.supporterId)) {
252
+ return;
253
+ }
254
+ currentSession = latest !== null && latest !== void 0 ? latest : sessionAtSend;
255
+ }
278
256
  if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.id)) {
279
257
  return;
280
258
  }
@@ -300,8 +278,8 @@ export const useSendMessage = (options) => {
300
278
  console.error("syncSessionAfterPublicMessage", error);
301
279
  }
302
280
  }, [queryClient]);
303
- const dispatchMessage = useCallback(async (message) => {
304
- var _a, _b, _c, _d, _e, _f;
281
+ const dispatchMessage = useCallback(async (message, onLateSent) => {
282
+ var _a, _b, _c, _d, _e;
305
283
  const plainText = ((_a = message === null || message === void 0 ? void 0 : message.textElem) === null || _a === void 0 ? void 0 : _a.content) ||
306
284
  ((_b = message === null || message === void 0 ? void 0 : message.quoteElem) === null || _b === void 0 ? void 0 : _b.text) ||
307
285
  ((_c = message === null || message === void 0 ? void 0 : message.urlTextElem) === null || _c === void 0 ? void 0 : _c.content) ||
@@ -317,7 +295,7 @@ export const useSendMessage = (options) => {
317
295
  icon: (conversationData === null || conversationData === void 0 ? void 0 : conversationData.faceURL) || "",
318
296
  conversationId: (conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID) || "",
319
297
  };
320
- const { data: successMessage } = await DChatSDK.sendMessage({
298
+ const dispatched = DChatSDK.sendMessage({
321
299
  recvID: recvID || "",
322
300
  groupID: groupID || "",
323
301
  message,
@@ -339,8 +317,39 @@ export const useSendMessage = (options) => {
339
317
  iOSBadgeCount: true,
340
318
  },
341
319
  });
342
- updateOneMessage(Object.assign(Object.assign({}, successMessage), { ex: successMessage.ex || message.ex || "{}", isInternal: (_f = successMessage.isInternal) !== null && _f !== void 0 ? _f : message.isInternal }));
343
- messageFileStore.delete(message.clientMsgID);
320
+ pendingSends.set(message.clientMsgID, null);
321
+ let isSettled = false;
322
+ const release = () => {
323
+ isSettled = true;
324
+ pendingSends.delete(message.clientMsgID);
325
+ };
326
+ dispatched.then(release, release);
327
+ const applySent = (successMessage) => {
328
+ var _a;
329
+ updateOneMessage(Object.assign(Object.assign({}, successMessage), { ex: successMessage.ex || message.ex || "{}", isInternal: (_a = successMessage.isInternal) !== null && _a !== void 0 ? _a : message.isInternal }));
330
+ messageFileStore.delete(message.clientMsgID);
331
+ };
332
+ try {
333
+ const { data } = await withSdkTimeout(dispatched, "sendMessage", sendDispatchTimeoutMs(message));
334
+ applySent(data);
335
+ }
336
+ catch (error) {
337
+ // The call may still land after we stop waiting: the bubble then ends Sent
338
+ // instead of staying Failed next to a message the server already has.
339
+ if (error instanceof SdkTimeoutError) {
340
+ // A call that settled while the timeout fired has nothing left to block a resend.
341
+ const gaveUpAt = Date.now();
342
+ if (!isSettled)
343
+ pendingSends.set(message.clientMsgID, gaveUpAt);
344
+ dispatched.then(({ data }) => {
345
+ applySent(data);
346
+ // Past the ceiling the send is treated as lost, so it must not move the session.
347
+ if (Date.now() - gaveUpAt < PENDING_SEND_CEILING_MS)
348
+ onLateSent === null || onLateSent === void 0 ? void 0 : onLateSent();
349
+ }, () => { });
350
+ }
351
+ throw error;
352
+ }
344
353
  }, [
345
354
  groupID,
346
355
  recvID,
@@ -354,14 +363,23 @@ export const useSendMessage = (options) => {
354
363
  const sendQueueKey = (conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID) || "";
355
364
  // Bubbles show in call order and reach the server one at a time in that same order,
356
365
  // so a text sent right after a large video cannot overtake the video's upload.
357
- const queueSend = useCallback((build, currentSession) => {
366
+ const queueSend = useCallback((build, currentSession, onBuilt) => {
358
367
  const shown = enqueue(`show:${sendQueueKey}`, async () => {
359
- const messages = await build();
360
- if (!(messages === null || messages === void 0 ? void 0 : messages.length))
361
- return null;
362
- messages.forEach((message) => pushNewMessage(message));
363
- emit(scrollEvent);
364
- return messages;
368
+ try {
369
+ const messages = await build();
370
+ if (!(messages === null || messages === void 0 ? void 0 : messages.length)) {
371
+ onBuilt === null || onBuilt === void 0 ? void 0 : onBuilt(false);
372
+ return null;
373
+ }
374
+ messages.forEach((message) => pushNewMessage(message));
375
+ emit(scrollEvent);
376
+ onBuilt === null || onBuilt === void 0 ? void 0 : onBuilt(true);
377
+ return messages;
378
+ }
379
+ catch (error) {
380
+ onBuilt === null || onBuilt === void 0 ? void 0 : onBuilt(false);
381
+ throw error;
382
+ }
365
383
  });
366
384
  const outcomes = [];
367
385
  let isSessionSynced = false;
@@ -372,11 +390,14 @@ export const useSendMessage = (options) => {
372
390
  });
373
391
  for (const message of messages !== null && messages !== void 0 ? messages : []) {
374
392
  const holdLimitMs = sendHoldLimitMs(message);
375
- const outcome = dispatchMessage(message).then(() => {
376
- if (!message.isInternal && !isSessionSynced) {
377
- isSessionSynced = true;
378
- void syncSessionAfterPublicMessage(currentSession);
379
- }
393
+ const syncSessionOnce = (isLateSuccess = false) => {
394
+ if (message.isInternal || isSessionSynced)
395
+ return;
396
+ isSessionSynced = true;
397
+ void syncSessionAfterPublicMessage(currentSession, isLateSuccess);
398
+ };
399
+ const outcome = dispatchMessage(message, () => syncSessionOnce(true)).then(() => {
400
+ syncSessionOnce();
380
401
  return true;
381
402
  }, (error) => {
382
403
  console.error("sendMessage", error);
@@ -391,21 +412,36 @@ export const useSendMessage = (options) => {
391
412
  .then(() => Promise.all(outcomes))
392
413
  .then((results) => results.length > 0 && results.every(Boolean)));
393
414
  }, [sendQueueKey, dispatchMessage, scrollEvent, syncSessionAfterPublicMessage]);
394
- const resendMessage = useCallback((failedMessage) => queueSend(async () => {
395
- const newPayload = await recreateFailedMessage(failedMessage);
396
- if (!newPayload) {
397
- updateOneMessage(Object.assign(Object.assign({}, failedMessage), { status: MessageStatus.Failed }));
398
- return null;
415
+ const resendMessage = useCallback((failedMessage) => {
416
+ if (isSendPending(failedMessage.clientMsgID)) {
417
+ toast.warning(t("message_send_pending"));
418
+ return Promise.resolve(false);
399
419
  }
400
- await DChatSDK.deleteMessageFromLocalStorage({
401
- conversationID: sendQueueKey,
402
- clientMsgID: failedMessage.clientMsgID,
420
+ return queueSend(async () => {
421
+ let newPayload;
422
+ try {
423
+ newPayload = await recreateFailedMessage(failedMessage);
424
+ }
425
+ catch (error) {
426
+ console.error("resendMessage", error);
427
+ toast.error(t("message_send_failed_no_retry"));
428
+ updateOneMessage(Object.assign(Object.assign({}, failedMessage), { status: MessageStatus.Failed }));
429
+ return null;
430
+ }
431
+ if (!newPayload) {
432
+ updateOneMessage(Object.assign(Object.assign({}, failedMessage), { status: MessageStatus.Failed }));
433
+ return null;
434
+ }
435
+ await DChatSDK.deleteMessageFromLocalStorage({
436
+ conversationID: sendQueueKey,
437
+ clientMsgID: failedMessage.clientMsgID,
438
+ });
439
+ removeOneMessage(failedMessage.clientMsgID);
440
+ return [
441
+ Object.assign(Object.assign({}, newPayload), { ex: failedMessage.ex, isInternal: failedMessage.isInternal }),
442
+ ];
403
443
  });
404
- removeOneMessage(failedMessage.clientMsgID);
405
- return [
406
- Object.assign(Object.assign({}, newPayload), { ex: failedMessage.ex, isInternal: failedMessage.isInternal }),
407
- ];
408
- }), [queueSend, sendQueueKey]);
444
+ }, [queueSend, sendQueueKey, t]);
409
445
  const sendCustomMessage = useCallback(async (payload, sendOptions) => {
410
446
  if (!conversationData || (!recvID && !groupID))
411
447
  return false;
@@ -448,14 +484,31 @@ export const useSendMessage = (options) => {
448
484
  }
449
485
  return isSent;
450
486
  }, [conversationData, recvID, groupID, queueSend, queryClient]);
451
- const sendMergeMessage = useCallback(async ({ richText, plainText, files = [], currentSession, isInternal, urlMetadata, flow, customMessage, mentions, }) => {
452
- if (!conversationData || (!recvID && !groupID))
487
+ const sendMergeMessage = useCallback(async ({ richText, plainText, files = [], currentSession, isInternal, urlMetadata, flow, customMessage, mentions, onBuilt, }) => {
488
+ if (!conversationData || (!recvID && !groupID)) {
489
+ onBuilt === null || onBuilt === void 0 ? void 0 : onBuilt(false);
453
490
  return false;
491
+ }
454
492
  const hasText = !!plainText && plainText.trim() !== "";
455
493
  // Clear the reply bar now rather than when earlier queued sends finish building.
456
494
  const quoted = (quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.clientMsgID) ? quotedMessage : undefined;
457
- if (hasText && quotedMessage)
495
+ const isQuoteCleared = hasText && !!quotedMessage;
496
+ if (isQuoteCleared)
458
497
  setQuotedMessage(null);
498
+ const sentConversationId = conversationData.conversationID;
499
+ // A failed build puts the reply bar back, unless the user already moved on to
500
+ // another thread or picked a new quote.
501
+ const reportBuilt = (shown) => {
502
+ var _a;
503
+ if (!shown && isQuoteCleared) {
504
+ const state = useConversationStore.getState();
505
+ if (!state.quotedMessage &&
506
+ ((_a = state.conversationData) === null || _a === void 0 ? void 0 : _a.conversationID) === sentConversationId) {
507
+ setQuotedMessage(quotedMessage);
508
+ }
509
+ }
510
+ onBuilt === null || onBuilt === void 0 ? void 0 : onBuilt(shown);
511
+ };
459
512
  // Every bubble (image or album → videos → files → text) is built first and shown
460
513
  // together, the same order the mobile app uses.
461
514
  const buildMessages = async () => {
@@ -497,6 +550,9 @@ export const useSendMessage = (options) => {
497
550
  imageMessages.push(imageMessage);
498
551
  }
499
552
  catch (err) {
553
+ // A failed SDK call aborts the whole send so nothing is dropped silently.
554
+ if (err instanceof SdkCallError)
555
+ throw err;
500
556
  console.error("Lỗi xử lý ảnh:", err);
501
557
  }
502
558
  }
@@ -548,6 +604,9 @@ export const useSendMessage = (options) => {
548
604
  messageList.push(videoMessage);
549
605
  }
550
606
  catch (err) {
607
+ // A failed SDK call aborts the whole send so nothing is dropped silently.
608
+ if (err instanceof SdkCallError)
609
+ throw err;
551
610
  console.error("Lỗi xử lý video:", err);
552
611
  }
553
612
  }
@@ -575,22 +634,29 @@ export const useSendMessage = (options) => {
575
634
  messageList.push(fileMessage);
576
635
  }
577
636
  catch (err) {
637
+ // A failed SDK call aborts the whole send so nothing is dropped silently.
638
+ if (err instanceof SdkCallError)
639
+ throw err;
578
640
  console.error("Lỗi xử lý tin nhắn:", err);
579
641
  }
580
642
  }
581
- const hasMentions = !!mentions && (mentions.atUserIDList.length > 0 || mentions.isAtAll);
643
+ const currentMentions = mentions
644
+ ? await keepCurrentGroupMembersOnly(groupID, mentions)
645
+ : undefined;
646
+ const hasMentions = !!currentMentions &&
647
+ (currentMentions.atUserIDList.length > 0 || currentMentions.isAtAll);
582
648
  if (hasText) {
583
649
  const urls = extractLinkUrls(plainText);
584
650
  let textMessage = null;
585
- if (hasMentions && mentions) {
651
+ if (hasMentions && currentMentions) {
586
652
  // OpenIM SDK convention: "tag all" is signaled by the sentinel
587
653
  // "AtAllTag" inside atUserIDList, not a separate flag/param.
588
654
  textMessage = await createAtTextMessage({
589
655
  text: plainText,
590
- atUserIDList: mentions.isAtAll
591
- ? [AT_ALL_TAG, ...mentions.atUserIDList]
592
- : mentions.atUserIDList,
593
- atUsersInfo: mentions.atUsersInfo,
656
+ atUserIDList: currentMentions.isAtAll
657
+ ? [AT_ALL_TAG, ...currentMentions.atUserIDList]
658
+ : currentMentions.atUserIDList,
659
+ atUsersInfo: currentMentions.atUsersInfo,
594
660
  message: quoted,
595
661
  urls: urls || undefined,
596
662
  });
@@ -625,13 +691,13 @@ export const useSendMessage = (options) => {
625
691
  currentSession,
626
692
  flow: isTextLikeMessage ? flow : undefined,
627
693
  mentionOffsets: (message === null || message === void 0 ? void 0 : message.contentType) === MessageType.AtTextMessage
628
- ? mentions === null || mentions === void 0 ? void 0 : mentions.mentionOffsets
694
+ ? currentMentions === null || currentMentions === void 0 ? void 0 : currentMentions.mentionOffsets
629
695
  : undefined,
630
696
  });
631
697
  return Object.assign(Object.assign({}, message), { ex: JSON.stringify(extendMessageInfo) || "{}", isInternal });
632
698
  });
633
699
  };
634
- return queueSend(buildMessages, currentSession);
700
+ return queueSend(buildMessages, currentSession, reportBuilt);
635
701
  }, [
636
702
  conversationData,
637
703
  recvID,
@@ -1 +1 @@
1
- {"version":3,"file":"useSearchMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/search/useSearchMessage.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAOrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,UAAU,uBAAuB;IAC/B,OAAO,EAAE,IAAI,CACX,oBAAoB,EACpB,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,GAAG,KAAK,CAC7D,CAAC;IACF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC;IAC/E,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,gBAAgB,GAAI,gCAI9B,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0FzB,CAAC"}
1
+ {"version":3,"file":"useSearchMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/search/useSearchMessage.ts"],"names":[],"mappings":"AAIA,OAAO,EAIL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AASrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,UAAU,uBAAuB;IAC/B,OAAO,EAAE,IAAI,CACX,oBAAoB,EACpB,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,GAAG,KAAK,CAC7D,CAAC;IACF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC;IAC/E,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,gBAAgB,GAAI,gCAI9B,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgHzB,CAAC"}
@@ -13,6 +13,8 @@ import { useInfiniteQuery } from "@tanstack/react-query";
13
13
  import { QUERY_KEYS } from "../../services/query";
14
14
  import { apiInstance } from "../../services/api";
15
15
  import { ENDPOINTS } from "../../services/routes";
16
+ import { ChatType } from "../../types/conversation";
17
+ import { APP_MESSAGE_SEARCH_CONTENT_TYPES } from "./useAppMessageSearch";
16
18
  import { useMemo } from "react";
17
19
  import dayjs from "dayjs";
18
20
  import useAuthStore from "../../store/auth";
@@ -21,10 +23,24 @@ import { isGroupSession } from "../../utils/imCommon";
21
23
  import { PAGE_SIZE } from "../../constants";
22
24
  export const useSearchMessage = ({ payload, options, enabled = true, }) => {
23
25
  const isPdpPortal = (options === null || options === void 0 ? void 0 : options.scope) === "pdp-portal";
26
+ const isCrm = useAuthStore((state) => state.isCrm);
27
+ // Non-CRM hosts (Obefe) have no access to the CRM search endpoint.
28
+ const useAppEndpoints = !isCrm && !isPdpPortal;
29
+ // The app endpoints are scoped to the open thread, so cached pages must not cross threads.
30
+ const conversationId = useConversationStore((state) => { var _a; return (_a = state.conversationData) === null || _a === void 0 ? void 0 : _a.conversationID; });
24
31
  const _a = useInfiniteQuery({
25
32
  initialPageParam: 1,
26
- queryKey: [QUERY_KEYS.SEARCH_MESSAGE, payload, options],
33
+ queryKey: [
34
+ QUERY_KEYS.SEARCH_MESSAGE,
35
+ payload,
36
+ options,
37
+ useAppEndpoints,
38
+ ...(useAppEndpoints ? [conversationId] : []),
39
+ ],
27
40
  queryFn: async ({ pageParam = 1 }) => {
41
+ if (useAppEndpoints) {
42
+ return fetchAppPage(payload, options === null || options === void 0 ? void 0 : options.pageSize, pageParam);
43
+ }
28
44
  const params = Object.assign(Object.assign({ pageSize: (options === null || options === void 0 ? void 0 : options.pageSize) || PAGE_SIZE.small }, payload), { page: pageParam, applicationType: useAuthStore.getState().applicationType });
29
45
  const res = await apiInstance.post(isPdpPortal
30
46
  ? ENDPOINTS.chatService.searchPdpPortalMessages
@@ -42,6 +58,8 @@ export const useSearchMessage = ({ payload, options, enabled = true, }) => {
42
58
  return dataLength < pageSize ? undefined : currentPage + 1;
43
59
  },
44
60
  enabled: enabled && hasValidFilter(payload),
61
+ // A 4xx would otherwise retry and keep the spinner up.
62
+ retry: useAppEndpoints ? false : undefined,
45
63
  }), { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = _a, rest = __rest(_a, ["data", "fetchNextPage", "hasNextPage", "isFetchingNextPage", "isLoading"]);
46
64
  const { groupedData, dataFlatten } = useMemo(() => {
47
65
  var _a, _b;
@@ -50,7 +68,11 @@ export const useSearchMessage = ({ payload, options, enabled = true, }) => {
50
68
  groupedData: {},
51
69
  dataFlatten: [],
52
70
  };
53
- const rawItems = ((_b = (_a = data === null || data === void 0 ? void 0 : data.pages) === null || _a === void 0 ? void 0 : _a.flatMap) === null || _b === void 0 ? void 0 : _b.call(_a, (page) => page.data)) || [];
71
+ const pagedItems = ((_b = (_a = data === null || data === void 0 ? void 0 : data.pages) === null || _a === void 0 ? void 0 : _a.flatMap) === null || _b === void 0 ? void 0 : _b.call(_a, (page) => page.data)) || [];
72
+ // The app endpoints return revoked messages; the legacy UI can't render them.
73
+ const rawItems = useAppEndpoints
74
+ ? pagedItems.filter((item) => !item.isRevoked)
75
+ : pagedItems;
54
76
  // BE search isn't scoped to live membership — filter defensively
55
77
  // against conversationList, which leftGroupHandler keeps in sync.
56
78
  const joinedGroupIDs = new Set(useConversationStore
@@ -73,7 +95,7 @@ export const useSearchMessage = ({ payload, options, enabled = true, }) => {
73
95
  groupedData: mGroupeddata,
74
96
  dataFlatten: allItems,
75
97
  };
76
- }, [data, isPdpPortal]);
98
+ }, [data, isPdpPortal, useAppEndpoints]);
77
99
  return Object.assign({ data,
78
100
  fetchNextPage,
79
101
  hasNextPage,
@@ -86,3 +108,35 @@ const hasValidFilter = (filter) => {
86
108
  const { searchTerm, recvID } = filter;
87
109
  return Boolean(searchTerm === null || searchTerm === void 0 ? void 0 : searchTerm.trim()) || Boolean(recvID === null || recvID === void 0 ? void 0 : recvID.trim());
88
110
  };
111
+ /** App (non-CRM) endpoints: a term searches text messages, no term lists media by type. */
112
+ const fetchAppPage = async (payload, pageSize, page) => {
113
+ var _a, _b, _c;
114
+ const size = pageSize || PAGE_SIZE.small;
115
+ const { applicationType } = useAuthStore.getState();
116
+ const conversationData = useConversationStore.getState().conversationData;
117
+ const term = (_a = payload.searchTerm) === null || _a === void 0 ? void 0 : _a.trim();
118
+ if (term) {
119
+ const res = await apiInstance.post(ENDPOINTS.chatService.searchAppMessages, Object.assign(Object.assign({}, ((conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID)
120
+ ? { conversationId: conversationData.conversationID }
121
+ : {})), { searchTerm: term, contentTypes: APP_MESSAGE_SEARCH_CONTENT_TYPES, page, pageSize: size, applicationType }));
122
+ return {
123
+ pageable: res.data.pageable,
124
+ data: ((_b = res.data.data) !== null && _b !== void 0 ? _b : []).map((item) => ({
125
+ chatLog: item.chatLog,
126
+ isRevoked: Boolean(item.chatLog.isRevoked),
127
+ })),
128
+ };
129
+ }
130
+ const params = {
131
+ recvID: (_c = payload.recvID) !== null && _c !== void 0 ? _c : "",
132
+ contentType: payload.contentType,
133
+ chatType: isGroupSession(conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationType)
134
+ ? ChatType.GROUP
135
+ : ChatType.SINGLE,
136
+ page,
137
+ pageSize: size,
138
+ applicationType,
139
+ };
140
+ const res = await apiInstance.post(ENDPOINTS.chatService.getMessageResources, params);
141
+ return res.data;
142
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"useConversationSessionState.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useConversationSessionState.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAI3D,UAAU,iCAAiC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,2BAA2B,GAAI,wCAIzC,iCAAiC;;;;;;CA6BnC,CAAC"}
1
+ {"version":3,"file":"useConversationSessionState.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useConversationSessionState.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAK3D,UAAU,iCAAiC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,2BAA2B,GAAI,wCAIzC,iCAAiC;;;;;;CA+BnC,CAAC"}
@@ -1,16 +1,19 @@
1
1
  "use client";
2
2
  import { useGetListSessionByConversation } from "./useGetListSessionByConversation";
3
3
  import { PeerType } from "../../types/conversation";
4
+ import useAuthStore from "../../store/auth";
4
5
  export const useConversationSessionState = ({ conversationId, peerType, groupId, }) => {
5
6
  var _a;
6
7
  // Strict check, not isGroupConversation's loose conversationType fallback
7
8
  // — that wrongly disabled the session-list fetch and ran group-permission
8
9
  // checks against a support/bot thread's non-member-managed groupID.
9
10
  const isConfirmedGroup = peerType === PeerType.GROUP;
11
+ // The sessions API is CRM-only; other hosts (Obefe) get a 4xx from it.
12
+ const isCrm = useAuthStore((state) => state.isCrm);
10
13
  const currentGroupId = isConfirmedGroup ? groupId : undefined;
11
14
  const { data: conversationSessions, refetch: refetchConversationSessions, } = useGetListSessionByConversation({
12
15
  conversationId,
13
- enabled: !isConfirmedGroup,
16
+ enabled: !isConfirmedGroup && isCrm,
14
17
  });
15
18
  const latestConversationSession = conversationSessions === null || conversationSessions === void 0 ? void 0 : conversationSessions[0];
16
19
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"useSessionLatestPreview.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useSessionLatestPreview.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAyB,MAAM,8BAA8B,CAAC;AASvF,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAKD,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAkBD,eAAO,MAAM,uBAAuB,GAClC,UAAU,yBAAyB,EAAE;;;CA8EtC,CAAC"}
1
+ {"version":3,"file":"useSessionLatestPreview.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useSessionLatestPreview.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAyB,MAAM,8BAA8B,CAAC;AAYvF,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAKD,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA6BD,eAAO,MAAM,uBAAuB,GAClC,UAAU,yBAAyB,EAAE;;;CA4FtC,CAAC"}