@droppii-org/chat-sdk 0.6.26 → 0.6.28

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 (62) hide show
  1. package/dist/components/chat-bubble/ChatBubble.d.ts +3 -1
  2. package/dist/components/chat-bubble/ChatBubble.d.ts.map +1 -1
  3. package/dist/components/chat-bubble/ChatBubble.js +3 -3
  4. package/dist/components/conversation-detail/ConversationDetailHeader.js +1 -1
  5. package/dist/components/conversation-detail/ConversationDetailInput.d.ts.map +1 -1
  6. package/dist/components/conversation-detail/ConversationDetailInput.js +17 -13
  7. package/dist/components/conversation-detail/ConversationMessageList.d.ts +3 -1
  8. package/dist/components/conversation-detail/ConversationMessageList.d.ts.map +1 -1
  9. package/dist/components/conversation-detail/ConversationMessageList.js +2 -2
  10. package/dist/components/conversation-detail/ThreadProfilePanel.js +1 -1
  11. package/dist/components/conversation-inbox/ConversationInboxHeader.js +1 -1
  12. package/dist/components/conversation-inbox/contact-search/ContactSearchPanel.js +1 -1
  13. package/dist/components/group/AdminPermissionModal.js +1 -1
  14. package/dist/components/group/InviteLinkPanel.js +1 -1
  15. package/dist/components/group/MemberPermissionPanel.js +1 -1
  16. package/dist/components/media-resources/MediaResourcePanel.js +1 -1
  17. package/dist/components/message/MessageList.d.ts +2 -0
  18. package/dist/components/message/MessageList.d.ts.map +1 -1
  19. package/dist/components/message/MessageList.js +2 -2
  20. package/dist/components/message/footer/FilePreview.d.ts +1 -1
  21. package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
  22. package/dist/components/message/footer/FilePreview.js +1 -1
  23. package/dist/components/message/footer/MediaActions.d.ts.map +1 -1
  24. package/dist/components/message/footer/MediaActions.js +2 -12
  25. package/dist/components/message/footer/PasteAndDropPlugin.d.ts.map +1 -1
  26. package/dist/components/message/footer/PasteAndDropPlugin.js +1 -5
  27. package/dist/components/message/item/LinkText.js +1 -1
  28. package/dist/context/ChatContext.d.ts.map +1 -1
  29. package/dist/context/ChatContext.js +8 -3
  30. package/dist/hooks/conversation/useResolveConversation.d.ts.map +1 -1
  31. package/dist/hooks/conversation/useResolveConversation.js +19 -0
  32. package/dist/hooks/message/useMessage.d.ts +1 -1
  33. package/dist/hooks/message/useMessage.d.ts.map +1 -1
  34. package/dist/hooks/message/useMessage.js +41 -3
  35. package/dist/locales/vi/common.json +1 -1
  36. package/dist/screens/chat-bubble/index.d.ts +2 -0
  37. package/dist/screens/chat-bubble/index.d.ts.map +1 -1
  38. package/dist/screens/chat-bubble/index.js +2 -2
  39. package/dist/screens/conversation-detail/index.d.ts +3 -1
  40. package/dist/screens/conversation-detail/index.d.ts.map +1 -1
  41. package/dist/screens/conversation-detail/index.js +3 -3
  42. package/dist/screens/conversation-inbox/index.d.ts +2 -0
  43. package/dist/screens/conversation-inbox/index.d.ts.map +1 -1
  44. package/dist/screens/conversation-inbox/index.js +2 -2
  45. package/dist/screens/desk-message/index.d.ts +3 -1
  46. package/dist/screens/desk-message/index.d.ts.map +1 -1
  47. package/dist/screens/desk-message/index.js +2 -2
  48. package/dist/store/conversation.d.ts.map +1 -1
  49. package/dist/store/conversation.js +43 -2
  50. package/dist/store/type.d.ts +1 -0
  51. package/dist/store/type.d.ts.map +1 -1
  52. package/dist/styles/global.css +1 -1
  53. package/dist/types/chat.d.ts +3 -0
  54. package/dist/types/chat.d.ts.map +1 -1
  55. package/dist/utils/common.js +1 -1
  56. package/dist/utils/conversation.d.ts +1 -1
  57. package/dist/utils/conversation.d.ts.map +1 -1
  58. package/dist/utils/conversation.js +1 -6
  59. package/dist/utils/fileValidation.d.ts +0 -5
  60. package/dist/utils/fileValidation.d.ts.map +1 -1
  61. package/dist/utils/fileValidation.js +1 -19
  62. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
1
  interface ChatBubbleProps {
2
2
  className?: string;
3
3
  onCopyMessageLink?: (conversationId: string, clientMsgID: string) => void;
4
+ /** Called instead of the SDK's default toast when a jumped-to message turns out to be revoked. */
5
+ onSearchMessageRevoked?: () => void;
4
6
  }
5
- declare const ChatBubble: ({ className, onCopyMessageLink }: ChatBubbleProps) => import("react/jsx-runtime").JSX.Element;
7
+ declare const ChatBubble: ({ className, onCopyMessageLink, onSearchMessageRevoked, }: ChatBubbleProps) => import("react/jsx-runtime").JSX.Element;
6
8
  export default ChatBubble;
7
9
  //# sourceMappingURL=ChatBubble.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatBubble.d.ts","sourceRoot":"","sources":["../../../src/components/chat-bubble/ChatBubble.tsx"],"names":[],"mappings":"AASA,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3E;AAED,QAAA,MAAM,UAAU,GAAI,kCAAkC,eAAe,4CA8GpE,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ChatBubble.d.ts","sourceRoot":"","sources":["../../../src/components/chat-bubble/ChatBubble.tsx"],"names":[],"mappings":"AASA,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,kGAAkG;IAClG,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;CACrC;AAED,QAAA,MAAM,UAAU,GAAI,2DAIjB,eAAe,4CAgHjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -7,7 +7,7 @@ import useConversationStore from "../../store/conversation";
7
7
  import { useIsMobile } from "../../hooks/common/useIsMobile";
8
8
  import { useBoolean } from "ahooks";
9
9
  import { ANTD_PRIMARY_COLOR_VAR } from "../../constants";
10
- const ChatBubble = ({ className, onCopyMessageLink }) => {
10
+ const ChatBubble = ({ className, onCopyMessageLink, onSearchMessageRevoked, }) => {
11
11
  const isMobile = useIsMobile();
12
12
  const selectedConversationId = useConversationStore((state) => state.selectedConversationId);
13
13
  const searchClientMsgID = useConversationStore((state) => state.searchClientMsgID);
@@ -24,9 +24,9 @@ const ChatBubble = ({ className, onCopyMessageLink }) => {
24
24
  body: { padding: 0 },
25
25
  }, classNames: {
26
26
  wrapper: "!z-[9999]",
27
- }, width: "100%", push: false, children: _jsx(MessageList, { conversationId: selectedConversationId, className: "flex-1", onClose: setOpenFalse, searchClientMsgID: searchClientMsgID, onCopyMessageLink: onCopyMessageLink }) })] }));
27
+ }, width: "100%", push: false, children: _jsx(MessageList, { conversationId: selectedConversationId, className: "flex-1", onClose: setOpenFalse, searchClientMsgID: searchClientMsgID, onCopyMessageLink: onCopyMessageLink, onSearchMessageRevoked: onSearchMessageRevoked }) })] }));
28
28
  }
29
- return (_jsx(Popover, { placement: "topLeft", trigger: "click", open: isOpen, destroyOnHidden: true, content: () => (_jsx("div", { className: "w-[400px] h-[600px]", children: _jsx(MessageList, { conversationId: selectedConversationId, className: "flex-1", onClose: setOpenFalse, searchClientMsgID: searchClientMsgID, onCopyMessageLink: onCopyMessageLink }) })), styles: { body: { padding: 0 } }, children: _jsx(ConfigProvider, { theme: { token: { colorPrimary: ANTD_PRIMARY_COLOR_VAR } }, children: _jsx(FloatButton, { icon: _jsx("span", { className: "text-white", children: isOpen ? _jsx(CloseOutlined, {}) : _jsx(MessageOutlined, {}) }), type: "primary", style: {
29
+ return (_jsx(Popover, { placement: "topLeft", trigger: "click", open: isOpen, destroyOnHidden: true, content: () => (_jsx("div", { className: "w-[400px] h-[600px]", children: _jsx(MessageList, { conversationId: selectedConversationId, className: "flex-1", onClose: setOpenFalse, searchClientMsgID: searchClientMsgID, onCopyMessageLink: onCopyMessageLink, onSearchMessageRevoked: onSearchMessageRevoked }) })), styles: { body: { padding: 0 } }, children: _jsx(ConfigProvider, { theme: { token: { colorPrimary: ANTD_PRIMARY_COLOR_VAR } }, children: _jsx(FloatButton, { icon: _jsx("span", { className: "text-white", children: isOpen ? _jsx(CloseOutlined, {}) : _jsx(MessageOutlined, {}) }), type: "primary", style: {
30
30
  right: 24,
31
31
  bottom: 24,
32
32
  width: 60,
@@ -6,7 +6,7 @@ import ConversationPeerAvatar from "../../components/conversation-inbox/Conversa
6
6
  import ConversationInboxTitle from "../../components/conversation-inbox/ConversationInboxTitle";
7
7
  import { resolveConversationDisplayName, resolvePeerBadgeLabel, } from "../../utils/conversation";
8
8
  import { useConversationAvatarUrl } from "../../hooks/conversation/useConversationAvatarUrl";
9
- const HeaderIconButton = ({ icon, onClick, testId, }) => (_jsx("button", { type: "button", onClick: onClick, "data-testid": testId, "data-cp-name": "HeaderIconButton", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-primary)]", children: _jsx(Icon, { icon: icon, size: 24 }) }));
9
+ const HeaderIconButton = ({ icon, onClick, testId, }) => (_jsx("button", { type: "button", onClick: onClick, "data-testid": testId, "data-cp-name": "HeaderIconButton", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-nav-icon)]", children: _jsx(Icon, { icon: icon, size: 24 }) }));
10
10
  const ConversationDetailHeader = ({ conversation, onBack, onProfileClick, }) => {
11
11
  const { t } = useTranslation("conversation-inbox");
12
12
  const displayName = resolveConversationDisplayName(conversation, t);
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationDetailInput.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/ConversationDetailInput.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAmB/D,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,QAAA,MAAM,uBAAuB,GAAI,4EAM9B,4BAA4B,4CAurB9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"ConversationDetailInput.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/ConversationDetailInput.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAmB/D,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,QAAA,MAAM,uBAAuB,GAAI,4EAM9B,4BAA4B,4CA8rB9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -84,7 +84,11 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
84
84
  const documentInputRef = useRef(null);
85
85
  const [value, setValue] = useState("");
86
86
  const [listUploadFiles, setListUploadFiles] = useState([]);
87
- const [isVideoLoading, setIsVideoLoading] = useState(false);
87
+ // Tracks each pending video by uid rather than a single boolean: with
88
+ // several videos attached, one flag let the first onLoadedMetadata unblock
89
+ // the send button while the others were still decoding.
90
+ const [pendingVideoUids, setPendingVideoUids] = useState([]);
91
+ const isVideoLoading = pendingVideoUids.length > 0;
88
92
  const [isFocused, setIsFocused] = useState(false);
89
93
  const [isSending, setIsSending] = useState(false);
90
94
  const [previewDismissed, setPreviewDismissed] = useState(false);
@@ -164,7 +168,7 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
164
168
  useEffect(() => {
165
169
  closeMoreOption();
166
170
  setListUploadFiles([]);
167
- setIsVideoLoading(false);
171
+ setPendingVideoUids([]);
168
172
  resetTokens();
169
173
  }, [conversationId, userID, closeMoreOption, resetTokens]);
170
174
  useEffect(() => {
@@ -241,18 +245,18 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
241
245
  const files = Array.from((_a = event.target.files) !== null && _a !== void 0 ? _a : []);
242
246
  if (files.length === 0)
243
247
  return;
244
- const validFiles = processAndValidateFiles(files, {
245
- t: tCommon,
246
- currentUploadedFiles: listUploadFiles,
247
- });
248
+ const validFiles = processAndValidateFiles(files, { t: tCommon });
248
249
  if (validFiles.length > 0) {
249
250
  setListUploadFiles((prev) => [...prev, ...validFiles]);
250
- const hasVideo = validFiles.some((f) => { var _a; return (_a = f.originFileObj) === null || _a === void 0 ? void 0 : _a.type.startsWith("video/"); });
251
- if (hasVideo)
252
- setIsVideoLoading(true);
251
+ const newVideoUids = validFiles
252
+ .filter((f) => { var _a; return (_a = f.originFileObj) === null || _a === void 0 ? void 0 : _a.type.startsWith("video/"); })
253
+ .map((f) => f.uid);
254
+ if (newVideoUids.length > 0) {
255
+ setPendingVideoUids((prev) => [...prev, ...newVideoUids]);
256
+ }
253
257
  }
254
258
  event.target.value = "";
255
- }, [tCommon, listUploadFiles]);
259
+ }, [tCommon]);
256
260
  const handleDocumentInputChange = useCallback((event) => {
257
261
  var _a;
258
262
  const files = Array.from((_a = event.target.files) !== null && _a !== void 0 ? _a : []);
@@ -266,7 +270,7 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
266
270
  }, [tCommon]);
267
271
  const handleRemoveFile = useCallback((uid) => {
268
272
  setListUploadFiles((prev) => prev.filter((f) => f.uid !== uid));
269
- setIsVideoLoading(false);
273
+ setPendingVideoUids((prev) => prev.filter((pending) => pending !== uid));
270
274
  }, []);
271
275
  const handleChange = (nextValue, nextCaretIndex) => {
272
276
  onValueChange(value, nextValue);
@@ -292,7 +296,7 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
292
296
  const resetComposer = () => {
293
297
  setValue("");
294
298
  setListUploadFiles([]);
295
- setIsVideoLoading(false);
299
+ setPendingVideoUids([]);
296
300
  setPreviewDismissed(false);
297
301
  resetTokens();
298
302
  if (conversationId && userID) {
@@ -452,7 +456,7 @@ const ConversationDetailInput = ({ placeholder, onSendMessage, onInputChange, mo
452
456
  if (isViewOnlyMember) {
453
457
  return (_jsxs("div", { "data-testid": "conversation-detail-input-view-only", className: "flex flex-col w-full shrink-0 items-center justify-center gap-3 bg-chat-bubble-neutral/[0.05] px-4 py-3 ", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("thread_detail.view_only_notice") }), _jsx(Button, { type: "primary", size: "small", loading: isJoiningPublicGroup, onClick: handleJoinPublicGroup, children: tCommon("join_group") })] }));
454
458
  }
455
- return (_jsxs("div", { ref: containerRef, "data-testid": "conversation-detail-input", "data-cp-name": "ConversationDetailInput", className: "flex w-full shrink-0 flex-col bg-chat-bubble-neutral/[0.05]", children: [_jsx("input", { ref: mediaInputRef, type: "file", accept: "image/jpeg,image/png,image/jpg,video/*", multiple: true, className: "hidden", onChange: handleMediaInputChange }), _jsx("input", { ref: documentInputRef, type: "file", accept: ".pdf,.doc,.docx", multiple: true, className: "hidden", onChange: handleDocumentInputChange }), _jsx(ReplyPreviewBar, {}), listUploadFiles.length > 0 && (_jsx(FilePreviewList, { files: listUploadFiles, onRemove: (file) => handleRemoveFile(file.uid), onVideoReady: () => setIsVideoLoading(false) })), showLinkPreview && previewUrl && (_jsx(LinkInputPreview, { url: previewUrl, onRemove: () => setPreviewDismissed(true) })), _jsxs("div", { className: "flex items-end gap-3 px-3 py-2", children: [_jsx("div", { className: "flex shrink-0 items-center", children: _jsx("button", { type: "button", onClick: handleToggleMoreOption, "aria-label": t("thread_detail.more_option.toggle"), "aria-expanded": isMoreOptionOpen, "data-testid": "conversation-detail-more-option-toggle", className: "flex py-3 items-center justify-center rounded-full", children: isMoreOptionOpen ? (_jsx(Icon, { icon: "close-circle-b", size: 24, className: "text-[var(--dc-color-primary)]" })) : (_jsx(Icon, { icon: "plus-circle-o", size: 24, className: "text-gray-900" })) }) }), _jsx("div", { className: clsx("flex min-w-0 flex-1 overflow-hidden rounded-xl border bg-white transition-shadow", isFocused
459
+ return (_jsxs("div", { ref: containerRef, "data-testid": "conversation-detail-input", "data-cp-name": "ConversationDetailInput", className: "flex w-full shrink-0 flex-col bg-chat-bubble-neutral/[0.05]", children: [_jsx("input", { ref: mediaInputRef, type: "file", accept: "image/jpeg,image/png,image/jpg,video/*", multiple: true, className: "hidden", onChange: handleMediaInputChange }), _jsx("input", { ref: documentInputRef, type: "file", accept: ".pdf,.doc,.docx", multiple: true, className: "hidden", onChange: handleDocumentInputChange }), _jsx(ReplyPreviewBar, {}), listUploadFiles.length > 0 && (_jsx(FilePreviewList, { files: listUploadFiles, onRemove: (file) => handleRemoveFile(file.uid), onVideoReady: (uid) => setPendingVideoUids((prev) => prev.filter((p) => p !== uid)) })), showLinkPreview && previewUrl && (_jsx(LinkInputPreview, { url: previewUrl, onRemove: () => setPreviewDismissed(true) })), _jsxs("div", { className: "flex items-end gap-3 px-3 py-2", children: [_jsx("div", { className: "flex shrink-0 items-center", children: _jsx("button", { type: "button", onClick: handleToggleMoreOption, "aria-label": t("thread_detail.more_option.toggle"), "aria-expanded": isMoreOptionOpen, "data-testid": "conversation-detail-more-option-toggle", className: "flex py-3 items-center justify-center rounded-full", children: isMoreOptionOpen ? (_jsx(Icon, { icon: "close-circle-b", size: 24, className: "text-[var(--dc-color-primary)]" })) : (_jsx(Icon, { icon: "plus-circle-o", size: 24, className: "text-gray-900" })) }) }), _jsx("div", { className: clsx("flex min-w-0 flex-1 overflow-hidden rounded-xl border bg-white transition-shadow", isFocused
456
460
  ? "border-[var(--dc-color-primary-focus)] shadow-[0px_0px_2px_var(--dc-color-primary-focus)]"
457
461
  : "border-gray-50"), style: { minHeight: CONTAINER_MIN_HEIGHT }, children: _jsxs("div", { className: "flex min-w-0 flex-[1_0_0] items-center gap-2 self-stretch px-3 py-1", children: [onOpenBotMenu && (_jsx("button", { type: "button", onClick: onOpenBotMenu, "aria-label": t("thread_detail.bot.menu.open_menu"), "data-testid": "conversation-detail-open-bot-menu", className: "flex shrink-0 items-center justify-center", children: _jsx(Icon, { icon: "chat-suggest-o", size: 24, className: "text-gray-600" }) })), _jsx("textarea", { ref: textareaRef, value: value, rows: 1, onChange: (event) => {
458
462
  var _a;
@@ -7,7 +7,9 @@ export interface ConversationMessageListProps {
7
7
  * message link" context-menu action is hidden entirely.
8
8
  */
9
9
  onCopyMessageLink?: (conversationId: string, clientMsgID: string) => void;
10
+ /** Called instead of the SDK's default toast when a jumped-to message turns out to be revoked. */
11
+ onSearchMessageRevoked?: () => void;
10
12
  }
11
- declare const ConversationMessageList: ({ bottomSlot, onCopyMessageLink, }: ConversationMessageListProps) => import("react/jsx-runtime").JSX.Element;
13
+ declare const ConversationMessageList: ({ bottomSlot, onCopyMessageLink, onSearchMessageRevoked, }: ConversationMessageListProps) => import("react/jsx-runtime").JSX.Element;
12
14
  export default ConversationMessageList;
13
15
  //# sourceMappingURL=ConversationMessageList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationMessageList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/ConversationMessageList.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAmBzE,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3E;AAED,QAAA,MAAM,uBAAuB,GAAI,oCAG9B,4BAA4B,4CA0N9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"ConversationMessageList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-detail/ConversationMessageList.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAmBzE,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,kGAAkG;IAClG,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;CACrC;AAED,QAAA,MAAM,uBAAuB,GAAI,4DAI9B,4BAA4B,4CA2N9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -17,7 +17,7 @@ import { isGroupChat as resolveIsGroupChat } from "../../utils/conversation";
17
17
  import emitter from "../../utils/events";
18
18
  import MessageItem from "../../components/message/item";
19
19
  import PinLimitModal from "./PinLimitModal";
20
- const ConversationMessageList = ({ bottomSlot, onCopyMessageLink, }) => {
20
+ const ConversationMessageList = ({ bottomSlot, onCopyMessageLink, onSearchMessageRevoked, }) => {
21
21
  const { t } = useTranslation("conversation-inbox");
22
22
  const { t: tCommon } = useTranslation();
23
23
  const { user } = useChatContext();
@@ -31,7 +31,7 @@ const ConversationMessageList = ({ bottomSlot, onCopyMessageLink, }) => {
31
31
  const isGroupChat = conversation ? resolveIsGroupChat(conversation) : false;
32
32
  const permissions = useGroupPermission(conversation === null || conversation === void 0 ? void 0 : conversation.groupID);
33
33
  const canPinMessage = !isGroupChat || permissions.pinMessage;
34
- const messageController = useMessage(conversationId, searchClientMsgID, true, true);
34
+ const messageController = useMessage(conversationId, searchClientMsgID, true, true, onSearchMessageRevoked);
35
35
  const { scrollRef, loadMoreOldMessage, handleInfiniteScroll, scrollToBottomIfAtBottom, scrollToMessage, } = useMessageListScroll(Object.assign({ conversationId, userId: (user === null || user === void 0 ? void 0 : user.userID) || authUserID, isGroupChat }, messageController));
36
36
  const { loadState, moreOldLoading } = messageController;
37
37
  const isMessageLoading = !conversationId || loadState.initLoading;
@@ -26,6 +26,6 @@ const ThreadProfilePanel = ({ open, conversation, onClose, onSelectResource, })
26
26
  });
27
27
  return (_jsxs(Drawer, { open: open, onClose: onClose, placement: "right", closeIcon: false, width: "100%", "data-cp-name": "ThreadProfilePanel", styles: {
28
28
  body: { padding: 0 },
29
- }, getContainer: false, forceRender: true, destroyOnHidden: true, children: [_jsxs("div", { className: "flex h-full flex-col bg-gray-25", children: [_jsxs("div", { className: "flex w-full items-center bg-white p-2", children: [_jsx("button", { type: "button", "data-testid": "thread-profile-back", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-primary)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("thread_detail.options_title") })] }), _jsxs("div", { className: "flex flex-col items-center gap-2 bg-white px-0 py-2", children: [_jsxs("div", { className: "relative h-24 w-24 shrink-0", children: [_jsx(Avatar, { size: PROFILE_AVATAR_SIZE, src: avatarUrl || undefined, alt: displayName, className: "uppercase", children: (displayName === null || displayName === void 0 ? void 0 : displayName.charAt(0)) || "A" }), badgeLabel && (_jsx("span", { className: clsx("absolute bottom-1 right-0 flex h-[17px] items-center justify-center rounded-md border border-white px-1 text-[10px] font-semibold leading-3 text-white shadow-badge-inset", resolvePeerBadgeColor(peerType)), children: badgeLabel }))] }), _jsx("p", { className: "w-full truncate text-center text-[18px] font-bold leading-[1.6] text-gray-900", children: displayName })] }), _jsx("div", { className: "flex flex-col px-3 py-1.5", children: _jsx(MediaEntryCard, { onSelect: onSelectResource }) }), canLeaveGroup && (_jsx("div", { className: "flex flex-col px-3 py-1.5", children: _jsx("div", { className: "overflow-hidden rounded-xl bg-white", children: _jsxs("button", { type: "button", "data-testid": "thread-profile-leave-group", className: "flex w-full cursor-pointer items-center gap-2 p-4 text-danger-400", onClick: openLeaveGroup, children: [_jsx(Icon, { icon: "logout-o", size: 24 }), _jsx("span", { className: "text-[16px] font-medium leading-[1.6]", children: t("thread_detail.leave_group.action") })] }) }) }))] }), _jsx(LeaveGroupConfirmModal, { open: isConfirmOpen, loading: isLeaving, isPublicGroup: isPublicGroup, onCancel: closeConfirm, onConfirm: confirmLeaveGroup }), _jsx(LeaveGroupBlockedModal, { open: isBlockedOpen, onClose: closeBlocked })] }));
29
+ }, getContainer: false, forceRender: true, destroyOnHidden: true, children: [_jsxs("div", { className: "flex h-full flex-col bg-gray-25", children: [_jsxs("div", { className: "flex w-full items-center bg-white p-2", children: [_jsx("button", { type: "button", "data-testid": "thread-profile-back", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-nav-icon)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("thread_detail.options_title") })] }), _jsxs("div", { className: "flex flex-col items-center gap-2 bg-white px-0 py-2", children: [_jsxs("div", { className: "relative h-24 w-24 shrink-0", children: [_jsx(Avatar, { size: PROFILE_AVATAR_SIZE, src: avatarUrl || undefined, alt: displayName, className: "uppercase", children: (displayName === null || displayName === void 0 ? void 0 : displayName.charAt(0)) || "A" }), badgeLabel && (_jsx("span", { className: clsx("absolute bottom-1 right-0 flex h-[17px] items-center justify-center rounded-md border border-white px-1 text-[10px] font-semibold leading-3 text-white shadow-badge-inset", resolvePeerBadgeColor(peerType)), children: badgeLabel }))] }), _jsx("p", { className: "w-full truncate text-center text-[18px] font-bold leading-[1.6] text-gray-900", children: displayName })] }), _jsx("div", { className: "flex flex-col px-3 py-1.5", children: _jsx(MediaEntryCard, { onSelect: onSelectResource }) }), canLeaveGroup && (_jsx("div", { className: "flex flex-col px-3 py-1.5", children: _jsx("div", { className: "overflow-hidden rounded-xl bg-white", children: _jsxs("button", { type: "button", "data-testid": "thread-profile-leave-group", className: "flex w-full cursor-pointer items-center gap-2 p-4 text-danger-400", onClick: openLeaveGroup, children: [_jsx(Icon, { icon: "logout-o", size: 24 }), _jsx("span", { className: "text-[16px] font-medium leading-[1.6]", children: t("thread_detail.leave_group.action") })] }) }) }))] }), _jsx(LeaveGroupConfirmModal, { open: isConfirmOpen, loading: isLeaving, isPublicGroup: isPublicGroup, onCancel: closeConfirm, onConfirm: confirmLeaveGroup }), _jsx(LeaveGroupBlockedModal, { open: isBlockedOpen, onClose: closeBlocked })] }));
30
30
  };
31
31
  export default ThreadProfilePanel;
@@ -4,6 +4,6 @@ import { useTranslation } from "react-i18next";
4
4
  import { Icon } from "../../components/icon";
5
5
  const ConversationInboxHeader = ({ onOpenSearch, title, rightSlot, }) => {
6
6
  const { t } = useTranslation("conversation-inbox");
7
- return (_jsx("div", { "data-testid": "conversation-inbox-header", "data-cp-name": "ConversationInboxHeader", className: "flex w-full flex-col border-b border-gray-100 bg-white", children: _jsxs("div", { className: "flex h-12 items-end px-3", children: [_jsxs("div", { className: "flex h-full flex-col items-center justify-end px-3", children: [_jsx("span", { className: "pb-1.5 text-center text-[16px] font-bold leading-[160%] tracking-[0.16px] text-[var(--dc-color-primary)]", children: title !== null && title !== void 0 ? title : t("tabs.messages") }), _jsx("span", { className: "h-[3px] w-full rounded-t bg-[var(--dc-color-primary)]" })] }), _jsxs("div", { className: "ml-auto mb-1.5 flex shrink-0 items-center gap-2", children: [onOpenSearch && (_jsx("button", { type: "button", "data-testid": "conversation-inbox-search", "aria-label": t("search_placeholder"), className: "flex shrink-0 cursor-pointer items-center justify-center p-1 text-[var(--dc-color-primary)]", onClick: onOpenSearch, children: _jsx(Icon, { icon: "search-o", size: 24 }) })), rightSlot] })] }) }));
7
+ return (_jsx("div", { "data-testid": "conversation-inbox-header", "data-cp-name": "ConversationInboxHeader", className: "flex w-full flex-col border-b border-gray-100 bg-white", children: _jsxs("div", { className: "flex h-12 items-end px-3", children: [_jsxs("div", { className: "flex h-full flex-col items-center justify-end px-3", children: [_jsx("span", { className: "pb-1.5 text-center text-[16px] font-bold leading-[160%] tracking-[0.16px] text-[var(--dc-color-primary)]", children: title !== null && title !== void 0 ? title : t("tabs.messages") }), _jsx("span", { className: "h-[3px] w-full rounded-t bg-[var(--dc-color-primary)]" })] }), _jsxs("div", { className: "ml-auto mb-1.5 flex shrink-0 items-center gap-2", children: [onOpenSearch && (_jsx("button", { type: "button", "data-testid": "conversation-inbox-search", "aria-label": t("search_placeholder"), className: "flex shrink-0 cursor-pointer items-center justify-center p-1 text-[var(--dc-color-nav-icon)]", onClick: onOpenSearch, children: _jsx(Icon, { icon: "search-o", size: 24 }) })), rightSlot] })] }) }));
8
8
  };
9
9
  export default ConversationInboxHeader;
@@ -142,7 +142,7 @@ const ContactSearchPanel = ({ open, onClose }) => {
142
142
  children: renderCommunityTab(),
143
143
  },
144
144
  ];
145
- return (_jsx(Drawer, { open: open, onClose: onClose, placement: "right", closeIcon: false, width: "100%", "data-cp-name": "ContactSearchPanel", styles: { body: { padding: 0 } }, getContainer: false, destroyOnHidden: true, children: _jsxs("div", { className: "flex h-full flex-col bg-white", children: [_jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [_jsx("button", { type: "button", "data-testid": "contact-search-back", "aria-label": t("contact_search.back"), className: "flex shrink-0 cursor-pointer items-center justify-center p-1 text-[var(--dc-color-primary)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx(Input, { allowClear: true, autoFocus: true, value: keyword, "data-testid": "contact-search-input", placeholder: t("search_placeholder"), prefix: _jsx("span", { className: "flex h-10 w-10 items-center justify-center", children: _jsx(Icon, { icon: "search-o", size: CONTACT_SEARCH_ICON_SIZE }) }),
145
+ return (_jsx(Drawer, { open: open, onClose: onClose, placement: "right", closeIcon: false, width: "100%", "data-cp-name": "ContactSearchPanel", styles: { body: { padding: 0 } }, getContainer: false, destroyOnHidden: true, children: _jsxs("div", { className: "flex h-full flex-col bg-white", children: [_jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [_jsx("button", { type: "button", "data-testid": "contact-search-back", "aria-label": t("contact_search.back"), className: "flex shrink-0 cursor-pointer items-center justify-center p-1 text-[var(--dc-color-nav-icon)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx(Input, { allowClear: true, autoFocus: true, value: keyword, "data-testid": "contact-search-input", placeholder: t("search_placeholder"), prefix: _jsx("span", { className: "flex h-10 w-10 items-center justify-center", children: _jsx(Icon, { icon: "search-o", size: CONTACT_SEARCH_ICON_SIZE }) }),
146
146
  // Padding lives on the prefix/input instead of the wrapper so the
147
147
  // icon keeps its 40x40 box from the design.
148
148
  className: "!h-10 !rounded-lg !border-none !bg-gray-25 !p-0 !shadow-none", classNames: {
@@ -135,7 +135,7 @@ const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member,
135
135
  if (inline) {
136
136
  if (!open)
137
137
  return null;
138
- return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-primary)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("admin_permission_settings") })] }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [rows, _jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full border border-gray-300 text-gray-700 text-sm font-medium", onClick: onClose, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full bg-[var(--dc-color-primary)] text-white text-sm font-medium disabled:bg-gray-200 disabled:text-gray-400", disabled: !hasChanges || isSaving, onClick: handleSave, children: t("save") })] })] })] }));
138
+ return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-nav-icon)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("admin_permission_settings") })] }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [rows, _jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full border border-gray-300 text-gray-700 text-sm font-medium", onClick: onClose, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full bg-[var(--dc-color-primary)] text-white text-sm font-medium disabled:bg-gray-200 disabled:text-gray-400", disabled: !hasChanges || isSaving, onClick: handleSave, children: t("save") })] })] })] }));
139
139
  }
140
140
  return (_jsx(Modal, { centered: true, open: open, onOk: handleSave, onCancel: onClose, title: t("admin_permission_settings"), okText: t("save"), cancelText: t("cancel"), confirmLoading: isSaving, okButtonProps: { disabled: !hasChanges }, getContainer: false, forceRender: true, children: _jsx("div", { className: "mt-2", children: rows }) }));
141
141
  };
@@ -56,6 +56,6 @@ const InviteLinkPanel = ({ open, groupID, conversationID, onClose }) => {
56
56
  if (key === "revoke")
57
57
  openRevokeConfirm();
58
58
  };
59
- return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", "data-cp-name": "InviteLinkPanel", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-primary)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("invite_via_link") })] }), _jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: [showOwnerEmptyState && (_jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [_jsx("div", { className: "flex h-24 w-24 items-center justify-center rounded-full bg-gray-100", children: _jsx(Icon, { icon: "link-alt-o", size: 40, className: "text-gray-300" }) }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("p", { className: "text-base font-bold text-gray-900", children: t("invite_link_empty_owner_title") }), _jsx("p", { className: "text-sm text-gray-400", children: t("invite_link_empty_owner_subtitle") })] }), _jsx("button", { type: "button", className: "w-full rounded-full bg-[var(--dc-color-primary)] px-4 py-2.5 text-sm font-medium text-white disabled:bg-gray-200 disabled:text-gray-400", disabled: isMutating, onClick: createLink, children: t("invite_link_create_button") })] })), showMemberEmptyState && (_jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [_jsx("div", { className: "flex h-24 w-24 items-center justify-center rounded-full bg-gray-100", children: _jsx(Icon, { icon: "link-alt-o", size: 40, className: "text-gray-300" }) }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("p", { className: "text-base font-bold text-gray-900", children: t("invite_link_empty_member_title") }), _jsx("p", { className: "text-sm text-gray-400", children: t("invite_link_empty_member_subtitle") })] })] })), isError && (_jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [_jsx("p", { className: "text-sm text-gray-400", children: t("invite_link_load_failed") }), _jsx("button", { type: "button", className: "rounded-full border border-gray-300 px-4 py-1.5 text-sm font-medium text-gray-700", onClick: () => refetch(), children: t("retry") })] })), !isLoading && !isError && link && (_jsxs("div", { className: "flex flex-col gap-2 rounded-lg bg-gray-25 p-3", children: [_jsx("p", { className: "text-sm font-semibold text-gray-900", children: t("invite_link_box_label") }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("p", { className: "min-w-0 flex-1 break-all rounded-lg bg-white px-3 py-2 text-sm text-gray-700", children: inviteUrl }), isOwner ? (_jsx(Dropdown, { menu: { items: ownerMenuItems, onClick: handleMenuClick }, trigger: ["click"], children: _jsx("button", { type: "button", className: "flex shrink-0 items-center justify-center p-2 text-gray-500", children: _jsx(Icon, { icon: "more-horizontal-o", size: 18 }) }) })) : (_jsx("button", { type: "button", className: "flex shrink-0 items-center justify-center p-2 text-gray-500", onClick: handleCopy, "aria-label": t("invite_link_action_copy"), children: _jsx(Icon, { icon: "copy-o", size: 18, color: "var(--dc-color-primary)" }) }))] })] }))] }), _jsx(ConfirmModal, { open: confirmAction === "regenerate", onOk: confirmRegenerate, onCancel: closeConfirm, title: t("invite_link_confirm_title"), okText: t("agree"), cancelText: t("cancel"), confirmLoading: isMutating, children: _jsx("p", { children: t("invite_link_regenerate_confirm_message") }) }), _jsx(ConfirmModal, { open: confirmAction === "revoke", onOk: confirmRevoke, onCancel: closeConfirm, title: t("invite_link_confirm_title"), okText: t("agree"), cancelText: t("cancel"), confirmLoading: isMutating, children: _jsx("p", { children: t("invite_link_revoke_confirm_message") }) })] }));
59
+ return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", "data-cp-name": "InviteLinkPanel", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-nav-icon)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("invite_via_link") })] }), _jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: [showOwnerEmptyState && (_jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [_jsx("div", { className: "flex h-24 w-24 items-center justify-center rounded-full bg-gray-100", children: _jsx(Icon, { icon: "link-alt-o", size: 40, className: "text-gray-300" }) }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("p", { className: "text-base font-bold text-gray-900", children: t("invite_link_empty_owner_title") }), _jsx("p", { className: "text-sm text-gray-400", children: t("invite_link_empty_owner_subtitle") })] }), _jsx("button", { type: "button", className: "w-full rounded-full bg-[var(--dc-color-primary)] px-4 py-2.5 text-sm font-medium text-white disabled:bg-gray-200 disabled:text-gray-400", disabled: isMutating, onClick: createLink, children: t("invite_link_create_button") })] })), showMemberEmptyState && (_jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [_jsx("div", { className: "flex h-24 w-24 items-center justify-center rounded-full bg-gray-100", children: _jsx(Icon, { icon: "link-alt-o", size: 40, className: "text-gray-300" }) }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("p", { className: "text-base font-bold text-gray-900", children: t("invite_link_empty_member_title") }), _jsx("p", { className: "text-sm text-gray-400", children: t("invite_link_empty_member_subtitle") })] })] })), isError && (_jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [_jsx("p", { className: "text-sm text-gray-400", children: t("invite_link_load_failed") }), _jsx("button", { type: "button", className: "rounded-full border border-gray-300 px-4 py-1.5 text-sm font-medium text-gray-700", onClick: () => refetch(), children: t("retry") })] })), !isLoading && !isError && link && (_jsxs("div", { className: "flex flex-col gap-2 rounded-lg bg-gray-25 p-3", children: [_jsx("p", { className: "text-sm font-semibold text-gray-900", children: t("invite_link_box_label") }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("p", { className: "min-w-0 flex-1 break-all rounded-lg bg-white px-3 py-2 text-sm text-gray-700", children: inviteUrl }), isOwner ? (_jsx(Dropdown, { menu: { items: ownerMenuItems, onClick: handleMenuClick }, trigger: ["click"], children: _jsx("button", { type: "button", className: "flex shrink-0 items-center justify-center p-2 text-gray-500", children: _jsx(Icon, { icon: "more-horizontal-o", size: 18 }) }) })) : (_jsx("button", { type: "button", className: "flex shrink-0 items-center justify-center p-2 text-gray-500", onClick: handleCopy, "aria-label": t("invite_link_action_copy"), children: _jsx(Icon, { icon: "copy-o", size: 18, color: "var(--dc-color-primary)" }) }))] })] }))] }), _jsx(ConfirmModal, { open: confirmAction === "regenerate", onOk: confirmRegenerate, onCancel: closeConfirm, title: t("invite_link_confirm_title"), okText: t("agree"), cancelText: t("cancel"), confirmLoading: isMutating, children: _jsx("p", { children: t("invite_link_regenerate_confirm_message") }) }), _jsx(ConfirmModal, { open: confirmAction === "revoke", onOk: confirmRevoke, onCancel: closeConfirm, title: t("invite_link_confirm_title"), okText: t("agree"), cancelText: t("cancel"), confirmLoading: isMutating, children: _jsx("p", { children: t("invite_link_revoke_confirm_message") }) })] }));
60
60
  };
61
61
  export default InviteLinkPanel;
@@ -48,6 +48,6 @@ const MemberPermissionPanel = ({ open, groupID, onClose }) => {
48
48
  };
49
49
  if (!open)
50
50
  return null;
51
- return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", "data-cp-name": "MemberPermissionPanel", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-primary)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("member_permission_settings") })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(ConfigProvider, { theme: { token: { colorPrimary: ANTD_PRIMARY_COLOR_VAR } }, children: _jsxs("div", { className: "flex flex-col py-2", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_send_message") }), _jsx(Switch, { checked: pending.sendMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { sendMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_add_member") }), _jsx(Switch, { checked: pending.addMember, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { addMember: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_pin_message") }), _jsx(Switch, { checked: pending.pinMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { pinMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_view_member_info") }), _jsx(Switch, { checked: pending.viewMemberInformation, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { viewMemberInformation: checked }))) })] })] }) }) }), _jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full border border-gray-300 text-gray-700 text-sm font-medium", onClick: onClose, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full bg-[var(--dc-color-primary)] text-white text-sm font-medium disabled:bg-gray-200 disabled:text-gray-400", disabled: !hasChanges || isSaving, onClick: handleSave, children: t("save") })] })] }));
51
+ return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", "data-cp-name": "MemberPermissionPanel", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-nav-icon)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("member_permission_settings") })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(ConfigProvider, { theme: { token: { colorPrimary: ANTD_PRIMARY_COLOR_VAR } }, children: _jsxs("div", { className: "flex flex-col py-2", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_send_message") }), _jsx(Switch, { checked: pending.sendMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { sendMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_add_member") }), _jsx(Switch, { checked: pending.addMember, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { addMember: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_pin_message") }), _jsx(Switch, { checked: pending.pinMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { pinMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_view_member_info") }), _jsx(Switch, { checked: pending.viewMemberInformation, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { viewMemberInformation: checked }))) })] })] }) }) }), _jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full border border-gray-300 text-gray-700 text-sm font-medium", onClick: onClose, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full bg-[var(--dc-color-primary)] text-white text-sm font-medium disabled:bg-gray-200 disabled:text-gray-400", disabled: !hasChanges || isSaving, onClick: handleSave, children: t("save") })] })] }));
52
52
  };
53
53
  export default MemberPermissionPanel;
@@ -8,6 +8,6 @@ const MediaResourcePanel = ({ open, initialTab, onClose, }) => {
8
8
  const { t } = useTranslation();
9
9
  return (_jsx(Drawer, { "data-cp-name": "MediaResourcePanel", open: open, onClose: onClose, placement: "right", closeIcon: false, width: "100%", styles: {
10
10
  body: { padding: 0 },
11
- }, getContainer: false, forceRender: true, destroyOnHidden: true, children: _jsxs("div", { className: "flex h-full flex-col bg-white", children: [_jsxs("div", { className: "flex w-full items-center p-2", children: [_jsx("button", { type: "button", "data-testid": "media-resource-back", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-primary)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("media_resources_title") })] }), _jsx("div", { className: "min-h-0 flex-1", children: _jsx(MediaResourceTabs, { initialTab: initialTab }) })] }) }));
11
+ }, getContainer: false, forceRender: true, destroyOnHidden: true, children: _jsxs("div", { className: "flex h-full flex-col bg-white", children: [_jsxs("div", { className: "flex w-full items-center p-2", children: [_jsx("button", { type: "button", "data-testid": "media-resource-back", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-[var(--dc-color-nav-icon)]", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("media_resources_title") })] }), _jsx("div", { className: "min-h-0 flex-1", children: _jsx(MediaResourceTabs, { initialTab: initialTab }) })] }) }));
12
12
  };
13
13
  export default MediaResourcePanel;
@@ -6,6 +6,8 @@ interface MessageListProps {
6
6
  openCreateCannedModal?: () => void;
7
7
  onOpenThreadInfo?: () => void;
8
8
  onCopyMessageLink?: (conversationId: string, clientMsgID: string) => void;
9
+ /** Called instead of the SDK's default toast when a jumped-to message turns out to be revoked. */
10
+ onSearchMessageRevoked?: () => void;
9
11
  }
10
12
  declare const MessageList: (props: MessageListProps) => import("react/jsx-runtime").JSX.Element;
11
13
  export default MessageList;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AAiCA,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;IACnC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,iBAAiB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3E;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CAsW3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AAiCA,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;IACnC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,iBAAiB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,kGAAkG;IAClG,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;CACrC;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA6W3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -31,7 +31,7 @@ dayjs.extend(isToday);
31
31
  const MessageList = (props) => {
32
32
  const { t } = useTranslation();
33
33
  const { user, connectStatus } = useChatContext();
34
- const { onClose, conversationId, searchClientMsgID, openCreateCannedModal, onOpenThreadInfo, onCopyMessageLink, } = props;
34
+ const { onClose, conversationId, searchClientMsgID, openCreateCannedModal, onOpenThreadInfo, onCopyMessageLink, onSearchMessageRevoked, } = props;
35
35
  const conversationData = useConversationStore((state) => state.conversationData);
36
36
  const permissions = useGroupPermission(conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID);
37
37
  const isGroupChat = isGroupConversation(conversationData !== null && conversationData !== void 0 ? conversationData : undefined);
@@ -99,7 +99,7 @@ const MessageList = (props) => {
99
99
  setIsViewOnlyMember(false);
100
100
  }
101
101
  }, [isConfirmedGroup, isJoined, isViewOnlyMember, setIsViewOnlyMember]);
102
- const messageController = useMessage(conversationId, searchClientMsgID);
102
+ const messageController = useMessage(conversationId, searchClientMsgID, true, false, onSearchMessageRevoked);
103
103
  const { loadState, moreOldLoading, moreNewLoading } = messageController;
104
104
  const { scrollRef, loadMoreOldMessage, handleInfiniteScroll, scrollToBottom, scrollToMessage, } = useMessageListScroll(Object.assign({ conversationId, userId: user === null || user === void 0 ? void 0 : user.userID, isGroupChat }, messageController));
105
105
  const handleOpenRevoke = useCallback((clientMsgID) => {
@@ -2,7 +2,7 @@ import { UploadFile } from "antd";
2
2
  export declare function FilePreviewList({ files, onRemove, onVideoReady, }: {
3
3
  files: UploadFile[];
4
4
  onRemove: (file: UploadFile) => void;
5
- onVideoReady?: () => void;
5
+ onVideoReady?: (uid: string) => void;
6
6
  }): import("react/jsx-runtime").JSX.Element | null;
7
7
  declare const FilePreview: () => import("react/jsx-runtime").JSX.Element;
8
8
  export default FilePreview;
@@ -1 +1 @@
1
- {"version":3,"file":"FilePreview.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/FilePreview.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AA8IlC,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,YAAY,GACb,EAAE;IACD,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B,kDAsBA;AAED,QAAA,MAAM,WAAW,+CAQhB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"FilePreview.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/FilePreview.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AA8IlC,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,YAAY,GACb,EAAE;IACD,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,kDAsBA;AAED,QAAA,MAAM,WAAW,+CAQhB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -46,7 +46,7 @@ const MediaThumb = ({ file, onRemove, onVideoReady }) => {
46
46
  }, [file.originFileObj, file.url]);
47
47
  const handleLoadedMetadata = (event) => {
48
48
  setDuration(event.currentTarget.duration);
49
- onVideoReady === null || onVideoReady === void 0 ? void 0 : onVideoReady();
49
+ onVideoReady === null || onVideoReady === void 0 ? void 0 : onVideoReady(file.uid);
50
50
  };
51
51
  return (_jsxs("div", { "data-cp-name": "MediaThumb", className: "relative h-12 w-12 shrink-0", children: [isVideo ? (_jsx("video", { src: src, className: "h-12 w-12 rounded-lg object-cover", preload: "metadata", muted: true, onLoadedMetadata: handleLoadedMetadata })) : (_jsx("img", { src: src, alt: file.name, className: "h-12 w-12 rounded-lg object-cover" })), isLoading && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center rounded-lg bg-black/60", children: _jsxs("span", { className: "text-xs font-semibold text-white", children: [percent, "%"] }) })), isVideo && duration !== null && (_jsx("div", { className: "absolute bottom-1 left-1/2 flex w-9 -translate-x-1/2 items-center justify-center rounded-xl bg-black/70 px-1 text-center text-[10px] font-normal leading-4 text-white", children: formatDuration(duration) })), _jsx(RemoveButton, { file: file, onRemove: onRemove })] }));
52
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MediaActions.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/MediaActions.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAkB,UAAU,EAA0B,MAAM,MAAM,CAAC;AAqD1E,UAAU,iBAAiB;IACzB,eAAe,EAAE,UAAU,EAAE,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,eAAe,EACf,aAAa,EACb,eAAe,EACf,eAAsB,GACvB,EAAE,iBAAiB,2CA0KnB"}
1
+ {"version":3,"file":"MediaActions.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/MediaActions.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAkB,UAAU,EAA0B,MAAM,MAAM,CAAC;AAoD1E,UAAU,iBAAiB;IACzB,eAAe,EAAE,UAAU,EAAE,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,eAAe,EACf,aAAa,EACb,eAAe,EACf,eAAsB,GACvB,EAAE,iBAAiB,2CA8JnB"}
@@ -8,7 +8,7 @@ import clsx from "clsx";
8
8
  import { useTranslation } from "react-i18next";
9
9
  import EmojiPicker from "./EmojiPicker";
10
10
  import { Icon } from "../../../components/icon";
11
- import { createUploadFile, validateFile, validateVideoLimit, } from "../../../utils/fileValidation";
11
+ import { createUploadFile, validateFile, } from "../../../utils/fileValidation";
12
12
  import { DOCUMENT_TYPES } from "./editorConfig";
13
13
  import CannedResponseIcon from "../../../assets/svg/canned-response";
14
14
  import { useMessageFooterContext } from ".";
@@ -31,22 +31,12 @@ export default function MediaActions({ listUploadFiles, onFilesChange, buttonCla
31
31
  });
32
32
  setShowEmojiPicker(false);
33
33
  }, [editor]);
34
- const beforeUploadImagesAndVideo = (file, fileList) => {
34
+ const beforeUploadImagesAndVideo = (file) => {
35
35
  const validation = validateFile(file, t);
36
36
  if (!validation.isValid) {
37
37
  antdMessage.error(validation.error);
38
38
  return Upload.LIST_IGNORE;
39
39
  }
40
- const videoValidation = validateVideoLimit([file], listUploadFiles, t);
41
- if (!videoValidation.isValid) {
42
- antdMessage.error(videoValidation.error);
43
- return Upload.LIST_IGNORE;
44
- }
45
- const newVideos = fileList.filter((f) => { var _a; return (_a = f.type) === null || _a === void 0 ? void 0 : _a.startsWith("video/"); });
46
- if (newVideos.length > 1) {
47
- antdMessage.error(t("video_limit_exceeded"));
48
- return Upload.LIST_IGNORE;
49
- }
50
40
  return false;
51
41
  };
52
42
  const beforeUploadFile = (file) => {
@@ -1 +1 @@
1
- {"version":3,"file":"PasteAndDropPlugin.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/PasteAndDropPlugin.tsx"],"names":[],"mappings":"AASA,UAAU,uBAAuB;IAC/B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;CACxC;AAED,QAAA,MAAM,kBAAkB,GAAI,kBAAkB,uBAAuB,SAqIpE,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"PasteAndDropPlugin.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/PasteAndDropPlugin.tsx"],"names":[],"mappings":"AASA,UAAU,uBAAuB;IAC/B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;CACxC;AAED,QAAA,MAAM,kBAAkB,GAAI,kBAAkB,uBAAuB,SAiIpE,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -29,10 +29,7 @@ const PasteAndDropPlugin = ({ onFilesAdded }) => {
29
29
  });
30
30
  if (files.length > 0) {
31
31
  setListUploadFiles((prev) => {
32
- const validFiles = processAndValidateFiles(files, {
33
- t,
34
- currentUploadedFiles: prev,
35
- });
32
+ const validFiles = processAndValidateFiles(files, { t });
36
33
  if (validFiles.length > 0) {
37
34
  onFilesAdded === null || onFilesAdded === void 0 ? void 0 : onFilesAdded(files);
38
35
  return [...prev, ...validFiles];
@@ -63,7 +60,6 @@ const PasteAndDropPlugin = ({ onFilesAdded }) => {
63
60
  setListUploadFiles((prev) => {
64
61
  const validFiles = processAndValidateFiles(imageOrVideoFiles, {
65
62
  t,
66
- currentUploadedFiles: prev,
67
63
  });
68
64
  if (validFiles.length > 0) {
69
65
  onFilesAdded === null || onFilesAdded === void 0 ? void 0 : onFilesAdded(imageOrVideoFiles);
@@ -8,6 +8,6 @@ import { MESSAGE_TEXT_CLASS } from "./textStyle";
8
8
  const LinkText = ({ text }) => {
9
9
  const { t } = useTranslation("conversation-inbox");
10
10
  const segments = parseTextWithLinks(text);
11
- return (_jsx("span", { className: clsx("min-w-0 whitespace-pre-wrap text-left [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), "data-cp-name": "LinkText", children: segments.map((segment, index) => segment.type === "link" ? (_jsx("button", { type: "button", onClick: () => openLink(segment.url, t), className: "inline text-left font-medium text-[var(--dc-color-primary)] underline-offset-2 hover:underline", children: segment.value }, `${segment.url}-${index}`)) : (_jsx("span", { children: segment.value }, `text-${index}`))) }));
11
+ return (_jsx("span", { className: clsx("min-w-0 whitespace-pre-wrap text-left [overflow-wrap:anywhere]", MESSAGE_TEXT_CLASS), "data-cp-name": "LinkText", children: segments.map((segment, index) => segment.type === "link" ? (_jsx("button", { type: "button", onClick: () => openLink(segment.url, t), className: "inline text-left font-medium text-[var(--dc-color-link)] underline-offset-2 hover:underline", children: segment.value }, `${segment.url}-${index}`)) : (_jsx("span", { children: segment.value }, `text-${index}`))) }));
12
12
  };
13
13
  export default LinkText;
@@ -1 +1 @@
1
- {"version":3,"file":"ChatContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatContext.tsx"],"names":[],"mappings":"AAEA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EACL,eAAe,EACf,iBAAiB,EAGlB,MAAM,cAAc,CAAC;AAWtB,eAAO,MAAM,WAAW,0CAQtB,CAAC;AAEH,eAAO,MAAM,cAAc,uBAAgC,CAAC;AAU5D,eAAO,MAAM,YAAY,GAAI,oGAQ1B,iBAAiB,4CAgJnB,CAAC"}
1
+ {"version":3,"file":"ChatContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatContext.tsx"],"names":[],"mappings":"AAEA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EACL,eAAe,EACf,iBAAiB,EAGlB,MAAM,cAAc,CAAC;AAUtB,eAAO,MAAM,WAAW,0CAQtB,CAAC;AAEH,eAAO,MAAM,cAAc,uBAAgC,CAAC;AAa5D,eAAO,MAAM,YAAY,GAAI,oGAQ1B,iBAAiB,4CAmJnB,CAAC"}
@@ -9,7 +9,6 @@ import useAuthStore from "../store/auth";
9
9
  import { setUrlNavigate, setUrlStateEnabled } from "../store/conversation";
10
10
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
11
11
  import { ConfigProvider } from "antd";
12
- import { StyleProvider } from "@ant-design/cssinjs";
13
12
  const queryClient = new QueryClient();
14
13
  export const ChatContext = createContext({
15
14
  user: null,
@@ -27,9 +26,12 @@ const DEFAULT_THEME = {
27
26
  "--dc-color-primary-light": "#E6E9FF",
28
27
  "--dc-color-primary-focus": "#607CFB",
29
28
  "--dc-color-bot-badge": "#59ABFF",
29
+ "--dc-color-mall-badge": "#F28504",
30
+ "--dc-color-nav-icon": "#393E40",
31
+ "--dc-color-link": "#1B3FE4",
30
32
  };
31
33
  export const ChatProvider = ({ children, config, renderCustomMessage, onNavigate, useUrlState = true, renderGroupAccessModal, theme, }) => {
32
- var _a, _b, _c, _d, _e;
34
+ var _a, _b, _c, _d, _e, _f, _g, _h;
33
35
  // The store's clearSelectedConversation touches window.history directly
34
36
  // (it has no React context access) — mirror the flag there so bubble mode
35
37
  // doesn't clobber the host page's own URL.
@@ -52,6 +54,9 @@ export const ChatProvider = ({ children, config, renderCustomMessage, onNavigate
52
54
  "--dc-color-primary-light": (_c = theme === null || theme === void 0 ? void 0 : theme.primaryLight) !== null && _c !== void 0 ? _c : DEFAULT_THEME["--dc-color-primary-light"],
53
55
  "--dc-color-primary-focus": (_d = theme === null || theme === void 0 ? void 0 : theme.primaryFocus) !== null && _d !== void 0 ? _d : DEFAULT_THEME["--dc-color-primary-focus"],
54
56
  "--dc-color-bot-badge": (_e = theme === null || theme === void 0 ? void 0 : theme.botBadge) !== null && _e !== void 0 ? _e : DEFAULT_THEME["--dc-color-bot-badge"],
57
+ "--dc-color-mall-badge": (_f = theme === null || theme === void 0 ? void 0 : theme.mallBadge) !== null && _f !== void 0 ? _f : DEFAULT_THEME["--dc-color-mall-badge"],
58
+ "--dc-color-nav-icon": (_g = theme === null || theme === void 0 ? void 0 : theme.navIcon) !== null && _g !== void 0 ? _g : DEFAULT_THEME["--dc-color-nav-icon"],
59
+ "--dc-color-link": (_h = theme === null || theme === void 0 ? void 0 : theme.link) !== null && _h !== void 0 ? _h : DEFAULT_THEME["--dc-color-link"],
55
60
  };
56
61
  const rootRef = useRef(null);
57
62
  const [connectStatus, setConnectStatus] = useState(ConnectStatus.Disconnected);
@@ -132,5 +137,5 @@ export const ChatProvider = ({ children, config, renderCustomMessage, onNavigate
132
137
  onNavigate,
133
138
  useUrlState,
134
139
  renderGroupAccessModal,
135
- }, children: _jsx(StyleProvider, { hashPriority: "high", children: _jsx(ConfigProvider, { getPopupContainer: () => { var _a; return (_a = rootRef.current) !== null && _a !== void 0 ? _a : document.body; }, children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx("div", { ref: rootRef, style: themeStyle, className: "contents", children: _jsx(MainLayout, { children: children }) }) }) }) }) }));
140
+ }, children: _jsx(ConfigProvider, { getPopupContainer: () => { var _a; return (_a = rootRef.current) !== null && _a !== void 0 ? _a : document.body; }, children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx("div", { ref: rootRef, style: themeStyle, className: "contents", children: _jsx(MainLayout, { children: children }) }) }) }) }));
136
141
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useResolveConversation.d.ts","sourceRoot":"","sources":["../../../src/hooks/conversation/useResolveConversation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAe,MAAM,8BAA8B,CAAC;AAU7E,MAAM,WAAW,4BAA4B;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,eAAO,MAAM,wBAAwB,GACnC,OAAO,MAAM,KACZ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAWjC,CAAC;AAkDF,eAAO,MAAM,sBAAsB,GAAI,wDAMpC,4BAA4B;;;CA4H9B,CAAC"}
1
+ {"version":3,"file":"useResolveConversation.d.ts","sourceRoot":"","sources":["../../../src/hooks/conversation/useResolveConversation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAe,MAAM,8BAA8B,CAAC;AAU7E,MAAM,WAAW,4BAA4B;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,eAAO,MAAM,wBAAwB,GACnC,OAAO,MAAM,KACZ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAWjC,CAAC;AAkDF,eAAO,MAAM,sBAAsB,GAAI,wDAMpC,4BAA4B;;;CAoJ9B,CAAC"}
@@ -85,6 +85,8 @@ export const useResolveConversation = ({ conversationId, userId, groupId, botId,
85
85
  const removedFromGroupModalOpen = useConversationStore((state) => state.removedFromGroupModalOpen);
86
86
  const setConversationData = useConversationStore((state) => state.setConversationData);
87
87
  const setSelectedConversationId = useConversationStore((state) => state.setSelectedConversationId);
88
+ const clearSelectedConversation = useConversationStore((state) => state.clearSelectedConversation);
89
+ const showRemovedFromGroupModal = useConversationStore((state) => state.showRemovedFromGroupModal);
88
90
  const target = { conversationId, userId, groupId, botId };
89
91
  const hasTarget = !!(conversationId || userId || groupId || botId);
90
92
  const currentTargetKey = targetKey(target);
@@ -128,6 +130,21 @@ export const useResolveConversation = ({ conversationId, userId, groupId, botId,
128
130
  });
129
131
  if (cancelled)
130
132
  return;
133
+ // A conversationId/groupId deep link that resolves to nothing means
134
+ // the thread never synced to this device — for a private group the
135
+ // user has not joined, the BE simply never sent it. That is the same
136
+ // "you cannot see this thread" outcome as the membership rejection
137
+ // below, so surface the same modal instead of the generic
138
+ // resolve-failed empty state. Left on the error path deliberately:
139
+ // botId (get-or-create failed) and userId (1:1 peer) are genuine
140
+ // failures, not access denials, and the group wording would be wrong.
141
+ if (!resolved && (conversationId || groupId)) {
142
+ rejectedTargetRef.current = currentTargetKey;
143
+ pendingTargetRef.current = null;
144
+ clearSelectedConversation();
145
+ showRemovedFromGroupModal();
146
+ return;
147
+ }
131
148
  if (!resolved)
132
149
  throw new Error(CONVERSATION_NOT_FOUND_ERROR);
133
150
  // Entry point for notifications/deep links — force a fresh check.
@@ -168,6 +185,8 @@ export const useResolveConversation = ({ conversationId, userId, groupId, botId,
168
185
  isSdkReady,
169
186
  setConversationData,
170
187
  setSelectedConversationId,
188
+ clearSelectedConversation,
189
+ showRemovedFromGroupModal,
171
190
  currentTargetKey,
172
191
  ]);
173
192
  return {
@@ -4,7 +4,7 @@ export declare const isMessageHiddenForViewer: (message: MessageItem, isCrm: boo
4
4
  peerType?: string;
5
5
  conversationType?: number;
6
6
  }) => boolean;
7
- export declare const useMessage: (conversationId?: string, searchClientMsgID?: string, enabled?: boolean, useAppHistory?: boolean) => {
7
+ export declare const useMessage: (conversationId?: string, searchClientMsgID?: string, enabled?: boolean, useAppHistory?: boolean, onSearchMessageRevoked?: () => void) => {
8
8
  loadState: {
9
9
  initLoading: boolean;
10
10
  hasMoreOld: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useMessage.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,WAAW,EACX,WAAW,EAEZ,MAAM,8BAA8B,CAAC;AAatC,eAAO,MAAM,kBAAkB,eAkB9B,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS,WAAW,EACpB,OAAO,OAAO,EACd,eAAe;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,KAC9D,OAqBF,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,iBAAiB,MAAM,EACvB,oBAAoB,MAAM,EAC1B,iBAAc,EACd,uBAAqB;;;;;qBAeA,WAAW,EAAE;;;;;;qBAAb,WAAW,EAAE;;;;;;CAsSnC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,SACpB,CAAC;AAChC,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,SACpB,CAAC;AAClC,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,SACf,CAAC;AAEtC,eAAO,MAAM,kBAAkB,GAC7B,aAAa,WAAW,EAAE,EAC1B,SAAS,WAAW,EACpB,WAAW,MAAM,GAAG,MAAM,KACzB,WAAW,GAAG,SAkBhB,CAAC;AAMF,eAAO,MAAM,oBAAoB,GAC/B,aAAa,WAAW,EAAE,EAC1B,SAAS,WAAW,EACpB,WAAW,MAAM,GAAG,MAAM,KACzB,WAAW,GAAG,SAQhB,CAAC"}
1
+ {"version":3,"file":"useMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useMessage.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,WAAW,EACX,WAAW,EAEZ,MAAM,8BAA8B,CAAC;AAetC,eAAO,MAAM,kBAAkB,eAkB9B,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS,WAAW,EACpB,OAAO,OAAO,EACd,eAAe;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,KAC9D,OAqBF,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,iBAAiB,MAAM,EACvB,oBAAoB,MAAM,EAC1B,iBAAc,EACd,uBAAqB,EAGrB,yBAAyB,MAAM,IAAI;;;;;qBAgBd,WAAW,EAAE;;;;;;qBAAb,WAAW,EAAE;;;;;;CAwUnC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,SACpB,CAAC;AAChC,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,SACpB,CAAC;AAClC,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,SACf,CAAC;AAEtC,eAAO,MAAM,kBAAkB,GAC7B,aAAa,WAAW,EAAE,EAC1B,SAAS,WAAW,EACpB,WAAW,MAAM,GAAG,MAAM,KACzB,WAAW,GAAG,SAkBhB,CAAC;AAMF,eAAO,MAAM,oBAAoB,GAC/B,aAAa,WAAW,EAAE,EAC1B,SAAS,WAAW,EACpB,WAAW,MAAM,GAAG,MAAM,KACzB,WAAW,GAAG,SAQhB,CAAC"}