@droppii-org/chat-sdk 0.1.1 → 0.1.3

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 (107) hide show
  1. package/dist/assets/sdk/sql-wasm.wasm +0 -0
  2. package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
  3. package/dist/components/conversation/ConversationBySessionItem.js +6 -2
  4. package/dist/components/mediaCollection/LinkCollection.js +1 -1
  5. package/dist/components/message/MediaPreviewIcon.d.ts +7 -0
  6. package/dist/components/message/MediaPreviewIcon.d.ts.map +1 -0
  7. package/dist/components/message/MediaPreviewIcon.js +24 -0
  8. package/dist/components/message/MessageHeader.js +1 -1
  9. package/dist/components/message/MessageList.d.ts.map +1 -1
  10. package/dist/components/message/MessageList.js +48 -5
  11. package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
  12. package/dist/components/message/footer/ActionBar.js +15 -86
  13. package/dist/components/message/footer/EmojiPicker.d.ts.map +1 -1
  14. package/dist/components/message/footer/EmojiPicker.js +9 -5
  15. package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
  16. package/dist/components/message/footer/EnterHandler.js +16 -5
  17. package/dist/components/message/footer/FilePreview.d.ts +5 -0
  18. package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
  19. package/dist/components/message/footer/FilePreview.js +15 -12
  20. package/dist/components/message/footer/MediaActions.d.ts +10 -0
  21. package/dist/components/message/footer/MediaActions.d.ts.map +1 -0
  22. package/dist/components/message/footer/MediaActions.js +78 -0
  23. package/dist/components/message/footer/QuotedMessage.d.ts +2 -0
  24. package/dist/components/message/footer/QuotedMessage.d.ts.map +1 -0
  25. package/dist/components/message/footer/QuotedMessage.js +24 -0
  26. package/dist/components/message/footer/editorConfig.d.ts +24 -0
  27. package/dist/components/message/footer/editorConfig.d.ts.map +1 -0
  28. package/dist/components/message/footer/editorConfig.js +33 -0
  29. package/dist/components/message/footer/index.d.ts.map +1 -1
  30. package/dist/components/message/footer/index.js +6 -27
  31. package/dist/components/message/item/MessageStatusIndicator.d.ts +8 -0
  32. package/dist/components/message/item/MessageStatusIndicator.d.ts.map +1 -0
  33. package/dist/components/message/item/MessageStatusIndicator.js +16 -0
  34. package/dist/components/message/item/QuoteMessage.d.ts +9 -0
  35. package/dist/components/message/item/QuoteMessage.d.ts.map +1 -0
  36. package/dist/components/message/item/QuoteMessage.js +22 -0
  37. package/dist/components/message/item/RevokeMessage.d.ts +5 -0
  38. package/dist/components/message/item/RevokeMessage.d.ts.map +1 -0
  39. package/dist/components/message/item/RevokeMessage.js +8 -0
  40. package/dist/components/message/item/TextMessage.js +1 -1
  41. package/dist/components/message/item/UrlTextMessage.d.ts.map +1 -1
  42. package/dist/components/message/item/UrlTextMessage.js +3 -3
  43. package/dist/components/message/item/index.d.ts +6 -1
  44. package/dist/components/message/item/index.d.ts.map +1 -1
  45. package/dist/components/message/item/index.js +88 -25
  46. package/dist/components/richTextEditor/RichTextEditor.d.ts +12 -0
  47. package/dist/components/richTextEditor/RichTextEditor.d.ts.map +1 -0
  48. package/dist/components/richTextEditor/RichTextEditor.js +62 -0
  49. package/dist/components/searchConversation/SearchDrawer.js +1 -1
  50. package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts +3 -1
  51. package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts.map +1 -1
  52. package/dist/components/searchConversation/item/SearchItemAsMessage.js +5 -2
  53. package/dist/components/thread/AssignConfirmModal.d.ts +12 -0
  54. package/dist/components/thread/AssignConfirmModal.d.ts.map +1 -0
  55. package/dist/components/thread/AssignConfirmModal.js +11 -0
  56. package/dist/components/thread/ManualAssignPopover.d.ts +14 -0
  57. package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -0
  58. package/dist/components/thread/ManualAssignPopover.js +83 -0
  59. package/dist/components/thread/SessionSection.d.ts.map +1 -1
  60. package/dist/components/thread/SessionSection.js +11 -6
  61. package/dist/components/thread/UserSection.js +1 -1
  62. package/dist/hooks/message/useMessage.d.ts +1 -0
  63. package/dist/hooks/message/useMessage.d.ts.map +1 -1
  64. package/dist/hooks/message/useMessage.js +7 -0
  65. package/dist/hooks/message/useRevokeMessage.d.ts +5 -0
  66. package/dist/hooks/message/useRevokeMessage.d.ts.map +1 -0
  67. package/dist/hooks/message/useRevokeMessage.js +16 -0
  68. package/dist/hooks/message/useSendMessage.d.ts +6 -0
  69. package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
  70. package/dist/hooks/message/useSendMessage.js +170 -32
  71. package/dist/hooks/session/useAssignSession.d.ts +8 -0
  72. package/dist/hooks/session/useAssignSession.d.ts.map +1 -0
  73. package/dist/hooks/session/useAssignSession.js +15 -0
  74. package/dist/hooks/session/useCreateNote.d.ts.map +1 -1
  75. package/dist/hooks/session/useCreateNote.js +2 -1
  76. package/dist/hooks/session/useGetTeamSupporters.d.ts +8 -0
  77. package/dist/hooks/session/useGetTeamSupporters.d.ts.map +1 -0
  78. package/dist/hooks/session/useGetTeamSupporters.js +20 -0
  79. package/dist/index.d.ts +1 -0
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +1 -0
  82. package/dist/locales/vi/common.json +49 -37
  83. package/dist/services/query.d.ts +2 -0
  84. package/dist/services/query.d.ts.map +1 -1
  85. package/dist/services/query.js +2 -0
  86. package/dist/services/routes.d.ts +2 -0
  87. package/dist/services/routes.d.ts.map +1 -1
  88. package/dist/services/routes.js +2 -0
  89. package/dist/store/conversation.d.ts.map +1 -1
  90. package/dist/store/conversation.js +7 -1
  91. package/dist/styles/global.css +1 -1
  92. package/dist/tsconfig.tsbuildinfo +1 -1
  93. package/dist/types/chat.d.ts +1 -1
  94. package/dist/types/chat.d.ts.map +1 -1
  95. package/dist/types/dto.d.ts +26 -0
  96. package/dist/types/dto.d.ts.map +1 -1
  97. package/dist/utils/common.d.ts +3 -2
  98. package/dist/utils/common.d.ts.map +1 -1
  99. package/dist/utils/common.js +43 -19
  100. package/dist/utils/events.d.ts +1 -0
  101. package/dist/utils/events.d.ts.map +1 -1
  102. package/dist/utils/fileValidation.d.ts.map +1 -1
  103. package/dist/utils/fileValidation.js +2 -8
  104. package/dist/utils/queryHelpers.d.ts +3 -0
  105. package/dist/utils/queryHelpers.d.ts.map +1 -0
  106. package/dist/utils/queryHelpers.js +11 -0
  107. package/package.json +11 -10
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { LexicalComposer } from "@lexical/react/LexicalComposer";
5
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
6
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
7
+ import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
8
+ import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
9
+ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
10
+ import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
11
+ import { $generateHtmlFromNodes, $generateNodesFromDOM } from "@lexical/html";
12
+ import { $getRoot } from "lexical";
13
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
14
+ import { useEffect } from "react";
15
+ import { ToolbarPlugin } from "../message/footer/ToolbarPlugin";
16
+ import MediaActions from "../message/footer/MediaActions";
17
+ import { FilePreviewList } from "../message/footer/FilePreview";
18
+ import { editorTheme, editorNodes, editorOnError, } from "../message/footer/editorConfig";
19
+ const EDITOR_CONFIG = {
20
+ namespace: "CannedResponseEditor",
21
+ theme: editorTheme,
22
+ onError: editorOnError,
23
+ nodes: editorNodes,
24
+ };
25
+ function HtmlPlugin({ initialHtml }) {
26
+ const [editor] = useLexicalComposerContext();
27
+ useEffect(() => {
28
+ if (!initialHtml)
29
+ return;
30
+ editor.update(() => {
31
+ const parser = new DOMParser();
32
+ const dom = parser.parseFromString(initialHtml, "text/html");
33
+ const nodes = $generateNodesFromDOM(editor, dom);
34
+ const root = $getRoot();
35
+ root.clear();
36
+ root.append(...nodes);
37
+ }, { tag: "initial-html" });
38
+ }, [editor, initialHtml]);
39
+ return null;
40
+ }
41
+ export default function RichTextEditor({ initialHtml, placeholder, onChange, onFilesChange, minHeight = "160px", showMediaUpload = true, }) {
42
+ const [listUploadFiles, setListUploadFiles] = useState([]);
43
+ const handleChange = (editorState, editor, tags) => {
44
+ if (tags.has("initial-html"))
45
+ return;
46
+ editorState.read(() => {
47
+ const html = $generateHtmlFromNodes(editor);
48
+ const plainText = $getRoot().getTextContent().trim();
49
+ onChange === null || onChange === void 0 ? void 0 : onChange(html, plainText);
50
+ });
51
+ };
52
+ const handleRemoveFile = (file) => {
53
+ const newList = listUploadFiles.filter((f) => f.uid !== file.uid);
54
+ setListUploadFiles(newList);
55
+ onFilesChange === null || onFilesChange === void 0 ? void 0 : onFilesChange(newList);
56
+ };
57
+ const handleFilesChange = (files) => {
58
+ setListUploadFiles(files);
59
+ onFilesChange === null || onFilesChange === void 0 ? void 0 : onFilesChange(files);
60
+ };
61
+ return (_jsxs(LexicalComposer, { initialConfig: EDITOR_CONFIG, children: [_jsxs("div", { className: "border border-gray-200 rounded-lg", children: [_jsx(FilePreviewList, { files: listUploadFiles, onRemove: handleRemoveFile }), _jsx("div", { className: "relative", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "px-3 py-2 text-sm outline-none", style: { minHeight } }), ErrorBoundary: LexicalErrorBoundary, placeholder: placeholder ? (_jsx("div", { className: "absolute top-2 left-3 pointer-events-none", children: _jsx("p", { className: "text-gray-400 text-sm", children: placeholder }) })) : null }) }), _jsxs("div", { className: "flex items-center border-t border-gray-100 px-2 py-1", children: [_jsx(ToolbarPlugin, {}), _jsx(MediaActions, { listUploadFiles: listUploadFiles, onFilesChange: handleFilesChange, showMediaUpload: showMediaUpload })] })] }), _jsx(LinkPlugin, {}), _jsx(ListPlugin, {}), _jsx(OnChangePlugin, { onChange: handleChange, ignoreSelectionChange: true }), _jsx(HtmlPlugin, { initialHtml: initialHtml })] }));
62
+ }
@@ -26,7 +26,7 @@ const SearchDrawer = () => {
26
26
  padding: 0,
27
27
  height: "100%",
28
28
  },
29
- }, getContainer: false, width: isMobile ? "100%" : 360, children: _jsxs("div", { className: "flex flex-col h-full", children: [_jsxs("div", { className: "flex items-center justify-between p-3", children: [_jsx("span", { className: "text-lg font-medium", children: "T\u00ECm ki\u1EBFm tin nh\u1EAFn" }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: toggle, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "px-3", children: _jsx(Input, { ref: searchInputRef, placeholder: t("search"), prefix: _jsx(Icon, { icon: "search-o", size: 18, className: "text-gray-400" }), onChange: (e) => {
29
+ }, getContainer: false, width: isMobile ? "100%" : 360, children: _jsxs("div", { className: "flex flex-col h-full", children: [_jsxs("div", { className: "flex items-center justify-between p-3", children: [_jsx("span", { className: "text-lg font-medium", children: t("search_message_title") }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: toggle, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "px-3", children: _jsx(Input, { ref: searchInputRef, placeholder: t("search"), prefix: _jsx(Icon, { icon: "search-o", size: 18, className: "text-gray-400" }), onChange: (e) => {
30
30
  setSearch(e.target.value);
31
31
  }, className: "rounded-lg text-sm", size: "large", allowClear: true, value: search, autoFocus: false }) }), _jsx("div", { className: "flex-1 py-3 overflow-auto", children: _jsx(SearchMessageOnCurrentConversation, { searchTerm: search, onClose: toggle }) })] }) })] }));
32
32
  };
@@ -1,6 +1,8 @@
1
1
  import { MessageItem } from "@openim/wasm-client-sdk";
2
2
  interface SearchItemAsMessageProps {
3
- message: MessageItem;
3
+ message: MessageItem & {
4
+ isRevoked?: boolean;
5
+ };
4
6
  searchTerm: string;
5
7
  onClick?: () => void;
6
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/searchConversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AAWnE,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CA+F3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/searchConversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAA4B,MAAM,yBAAyB,CAAC;AAehF,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,GAAG;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CAkG3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { SessionType } from "@openim/wasm-client-sdk";
4
4
  import { Avatar } from "antd";
5
- import { formatTimestamp, highlightSearch, sanitizeHtml } from "../../../utils/common";
5
+ import { formatTimestamp, highlightSearch, sanitizeHtml, } from "../../../utils/common";
6
6
  import { DChatSDK } from "../../../constants/sdk";
7
7
  import { useChatContext } from "../../../context/ChatContext";
8
8
  import { message as antdMessage } from "antd";
@@ -44,7 +44,10 @@ const SearchItemAsMessage = (props) => {
44
44
  };
45
45
  let msgContent = "";
46
46
  try {
47
- msgContent = ((_a = JSON.parse((message === null || message === void 0 ? void 0 : message.content) || "{}")) === null || _a === void 0 ? void 0 : _a.content) || "";
47
+ msgContent =
48
+ (message === null || message === void 0 ? void 0 : message.isRevoked) === true
49
+ ? t("revoked")
50
+ : ((_a = JSON.parse((message === null || message === void 0 ? void 0 : message.content) || "{}")) === null || _a === void 0 ? void 0 : _a.content) || "";
48
51
  }
49
52
  catch (error) {
50
53
  console.error("Failed to parse message content", error);
@@ -0,0 +1,12 @@
1
+ import { ISupporterResponse } from "../../types/dto";
2
+ interface AssignConfirmModalProps {
3
+ open: boolean;
4
+ agent: ISupporterResponse | null;
5
+ loading: boolean;
6
+ onCancel: () => void;
7
+ onConfirm: () => void;
8
+ afterClose?: () => void;
9
+ }
10
+ declare const AssignConfirmModal: ({ open, agent, loading, onCancel, onConfirm, afterClose, }: AssignConfirmModalProps) => import("react/jsx-runtime").JSX.Element;
11
+ export default AssignConfirmModal;
12
+ //# sourceMappingURL=AssignConfirmModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssignConfirmModal.d.ts","sourceRoot":"","sources":["../../../src/components/thread/AssignConfirmModal.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrD,UAAU,uBAAuB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,QAAA,MAAM,kBAAkB,GAAI,4DAOzB,uBAAuB,4CAwDzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Modal, Button, Avatar } from "antd";
3
+ import { useTranslation, Trans } from "react-i18next";
4
+ const AssignConfirmModal = ({ open, agent, loading, onCancel, onConfirm, afterClose, }) => {
5
+ var _a;
6
+ const { t } = useTranslation();
7
+ return (_jsx(Modal, { open: open, onCancel: onCancel, footer: null, closable: !loading, centered: true, forceRender: true, width: 400, maskClosable: !loading, keyboard: !loading, afterClose: afterClose, children: _jsxs("div", { className: "flex flex-col items-center gap-4 pt-2", role: "alertdialog", "aria-label": t("manual_assign_confirm_question", {
8
+ name: agent === null || agent === void 0 ? void 0 : agent.displayName,
9
+ }), children: [_jsx(Avatar, { src: agent === null || agent === void 0 ? void 0 : agent.avatar, size: 48, children: ((_a = agent === null || agent === void 0 ? void 0 : agent.displayName) === null || _a === void 0 ? void 0 : _a.charAt(0)) || "A" }), _jsx("p", { className: "text-base text-center", children: _jsx(Trans, { i18nKey: "manual_assign_confirm_question", values: { name: agent === null || agent === void 0 ? void 0 : agent.displayName }, components: { bold: _jsx("strong", {}) } }) }), _jsxs("div", { className: "flex gap-3 w-full", children: [_jsx(Button, { className: "flex-1", size: "large", onClick: onCancel, disabled: loading, children: t("cancel") }), _jsx(Button, { type: "primary", className: "flex-1", size: "large", onClick: onConfirm, loading: loading, disabled: !agent, children: t("manual_assign_button_reassign") })] })] }) }));
10
+ };
11
+ export default AssignConfirmModal;
@@ -0,0 +1,14 @@
1
+ interface SupporterInfo {
2
+ avatar: string;
3
+ username: string;
4
+ fullName: string;
5
+ id: string;
6
+ }
7
+ interface ManualAssignPopoverProps {
8
+ sessionId: string;
9
+ supporter: SupporterInfo;
10
+ teamId?: string;
11
+ }
12
+ declare const ManualAssignPopover: ({ sessionId, supporter, teamId: propTeamId, }: ManualAssignPopoverProps) => import("react/jsx-runtime").JSX.Element;
13
+ export default ManualAssignPopover;
14
+ //# sourceMappingURL=ManualAssignPopover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManualAssignPopover.d.ts","sourceRoot":"","sources":["../../../src/components/thread/ManualAssignPopover.tsx"],"names":[],"mappings":"AAgBA,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,wBAAwB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA0CD,QAAA,MAAM,mBAAmB,GAAI,+CAI1B,wBAAwB,4CA8J1B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Popover, Input, Avatar, Spin, Badge } from "antd";
4
+ import { useTranslation } from "react-i18next";
5
+ import clsx from "clsx";
6
+ import { Icon } from "../icon";
7
+ import { useGetTeamSupporters } from "../../hooks/session/useGetTeamSupporters";
8
+ import { useAssignSession } from "../../hooks/session/useAssignSession";
9
+ import { useQueryClient } from "@tanstack/react-query";
10
+ import { message as antdMessage } from "antd";
11
+ import { invalidateSessionQueries } from "../../utils/queryHelpers";
12
+ import AssignConfirmModal from "./AssignConfirmModal";
13
+ import { useDebounce } from "ahooks";
14
+ const SEARCH_DEBOUNCE_WAIT = 300;
15
+ const SupporterItem = ({ supporter, onClick, isCurrentAssignee, }) => {
16
+ var _a;
17
+ const { t } = useTranslation();
18
+ const isOnline = supporter.status === "ONLINE";
19
+ return (_jsxs("div", { role: "option", tabIndex: 0, "aria-selected": isCurrentAssignee, className: clsx("flex items-center gap-3 px-3 py-2 rounded-md transition-colors", isCurrentAssignee
20
+ ? "bg-blue-50 border border-blue-200 pointer-events-none"
21
+ : "cursor-pointer hover:bg-gray-50"), onClick: () => onClick(supporter), children: [_jsx(Badge, { dot: true, color: isOnline ? "#52c41a" : "#d9d9d9", offset: [-2, 24], children: _jsx(Avatar, { src: supporter.avatar, size: 32, children: ((_a = supporter.displayName) === null || _a === void 0 ? void 0 : _a.charAt(0)) || "A" }) }), _jsx("span", { className: "text-sm truncate flex-1", children: supporter.displayName }), isCurrentAssignee && (_jsx("span", { className: "text-xs text-blue-500 shrink-0", children: t("manual_assign_current") }))] }));
22
+ };
23
+ const ManualAssignPopover = ({ sessionId, supporter, teamId: propTeamId, }) => {
24
+ var _a, _b;
25
+ const { t } = useTranslation();
26
+ const queryClient = useQueryClient();
27
+ const [open, setOpen] = useState(false);
28
+ const [searchText, setSearchText] = useState("");
29
+ const [selectedAgent, setSelectedAgent] = useState(null);
30
+ const [confirmModalOpen, setConfirmModalOpen] = useState(false);
31
+ const debouncedSearch = useDebounce(searchText, {
32
+ wait: SEARCH_DEBOUNCE_WAIT,
33
+ });
34
+ const teamId = propTeamId || "";
35
+ const { data: supporters, isLoading, isFetching, } = useGetTeamSupporters({
36
+ teamId,
37
+ search: debouncedSearch || undefined,
38
+ });
39
+ const { mutate: assignSession, isPending: isAssigning } = useAssignSession();
40
+ const handleSelectAgent = (agent) => {
41
+ if (isAssigning)
42
+ return;
43
+ setSelectedAgent(agent);
44
+ setConfirmModalOpen(true);
45
+ };
46
+ const handleConfirmAssign = () => {
47
+ if (!selectedAgent || isAssigning)
48
+ return;
49
+ assignSession({ sessionId, supporterId: selectedAgent.memberId }, {
50
+ onSuccess: () => {
51
+ antdMessage.success(t("manual_assign_success"));
52
+ setConfirmModalOpen(false);
53
+ setOpen(false);
54
+ setSearchText("");
55
+ invalidateSessionQueries(queryClient);
56
+ },
57
+ onError: () => {
58
+ antdMessage.error(t("manual_assign_failed"));
59
+ },
60
+ });
61
+ };
62
+ const handleCancelConfirm = () => {
63
+ setConfirmModalOpen(false);
64
+ };
65
+ const handleAfterClose = () => {
66
+ setSelectedAgent(null);
67
+ };
68
+ const handleOpenChange = (newOpen) => {
69
+ if (isAssigning)
70
+ return;
71
+ if (!newOpen && confirmModalOpen)
72
+ return;
73
+ setOpen(newOpen);
74
+ if (!newOpen) {
75
+ setSearchText("");
76
+ }
77
+ };
78
+ const popoverContent = (_jsxs("div", { className: "w-64", children: [_jsx("div", { className: "mb-2", children: _jsx(Input, { autoFocus: true, placeholder: t("manual_assign_search_placeholder"), value: searchText, onChange: (e) => setSearchText(e.target.value), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }), className: "rounded-lg border-gray-300 focus-within:border-[#3278f7] focus-within:shadow-[0_0_0_2px_rgba(50,120,247,0.12)]", allowClear: true }) }), _jsx("div", { className: "max-h-72 overflow-y-auto", role: "listbox", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(Spin, {}) })) : supporters && supporters.length > 0 ? (_jsx("div", { className: clsx("flex flex-col transition-opacity duration-200", isFetching && "opacity-50 pointer-events-none"), children: supporters.map((item) => (_jsx(SupporterItem, { supporter: item, onClick: handleSelectAgent, isCurrentAssignee: item.memberId === (supporter === null || supporter === void 0 ? void 0 : supporter.id) }, item.memberId))) })) : (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx("span", { className: "text-sm text-gray-400", children: t("manual_assign_no_results") }) })) })] }));
79
+ return (_jsxs(_Fragment, { children: [_jsx(Popover, { content: popoverContent, trigger: "click", open: open, onOpenChange: handleOpenChange, placement: "topLeft", arrow: false, children: _jsxs("div", { role: "button", tabIndex: 0, "aria-label": t("manual_assign_button_reassign"), className: clsx("flex items-center border border-gray-200 rounded-lg p-1 gap-1 transition-opacity", isAssigning
80
+ ? "opacity-50 pointer-events-none"
81
+ : "cursor-pointer hover:opacity-80"), children: [_jsx(Avatar, { src: supporter === null || supporter === void 0 ? void 0 : supporter.avatar, size: 28, children: ((_b = (_a = supporter === null || supporter === void 0 ? void 0 : supporter.fullName) === null || _a === void 0 ? void 0 : _a.charAt) === null || _b === void 0 ? void 0 : _b.call(_a, 0)) || "A" }), _jsx("span", { className: "text-purple-500", children: _jsx(Icon, { icon: "shuffle-b", size: 20 }) })] }) }), _jsx(AssignConfirmModal, { open: confirmModalOpen, agent: selectedAgent, loading: isAssigning, onCancel: handleCancelConfirm, onConfirm: handleConfirmAssign, afterClose: handleAfterClose })] }));
82
+ };
83
+ export default ManualAssignPopover;
@@ -1 +1 @@
1
- {"version":3,"file":"SessionSection.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SessionSection.tsx"],"names":[],"mappings":"AASA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAmBnE,eAAO,MAAM,iBAAiB,GAAI,wBAG/B;IACD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB,4CAsMA,CAAC;AA8CF,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,cAAc,GAAI,yBAAyB,mBAAmB,4CAkDnE,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"SessionSection.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SessionSection.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAoBnE,eAAO,MAAM,iBAAiB,GAAI,wBAG/B;IACD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB,4CA6MA,CAAC;AA+CF,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,cAAc,GAAI,yBAAyB,mBAAmB,4CAmDnE,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -2,12 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useBoolean, useDebounce } from "ahooks";
3
3
  import { Icon } from "../icon";
4
4
  import { Button, Select, Spin, Tag, Input, message, Avatar } from "antd";
5
+ import ManualAssignPopover from "./ManualAssignPopover";
5
6
  import { useGetLabelSession } from "../../hooks/session/useGetLabelSession";
6
7
  import { useUpdateSessionInfo } from "../../hooks/session/useUpdateSessionInfo";
7
8
  import { useCloseSession } from "../../hooks/session/useCloseSession";
8
9
  import { useQueryClient } from "@tanstack/react-query";
9
10
  import { QUERY_KEYS } from "../../services/query";
10
11
  import { useEffect, useState } from "react";
12
+ import { useTranslation } from "react-i18next";
11
13
  const { TextArea } = Input;
12
14
  const formatSessionDate = (dateString) => {
13
15
  if (!dateString)
@@ -22,6 +24,7 @@ const formatSessionDate = (dateString) => {
22
24
  export const SessionDetailCard = ({ session, isActive, }) => {
23
25
  var _a, _b, _c, _d, _e;
24
26
  const queryClient = useQueryClient();
27
+ const { t } = useTranslation("common");
25
28
  const { data: availableLabels, isLoading: isLoadingLabels } = useGetLabelSession();
26
29
  const { mutate: updateSession } = useUpdateSessionInfo();
27
30
  const { mutate: closeSession, isPending: isClosing } = useCloseSession();
@@ -95,13 +98,13 @@ export const SessionDetailCard = ({ session, isActive, }) => {
95
98
  const handleCloseSession = () => {
96
99
  closeSession(session.id, {
97
100
  onSuccess: () => {
98
- message.success("Đóng phiên chat thành công");
101
+ message.success(t("close_session_success"));
99
102
  queryClient.invalidateQueries({
100
103
  queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
101
104
  });
102
105
  },
103
106
  onError: () => {
104
- message.error("Đóng phiên chat thất bại");
107
+ message.error(t("close_session_failed"));
105
108
  },
106
109
  });
107
110
  };
@@ -109,13 +112,14 @@ export const SessionDetailCard = ({ session, isActive, }) => {
109
112
  value: label.id,
110
113
  label: label.name,
111
114
  }));
112
- return (_jsxs("div", { className: `p-3 border rounded-lg shadow-md ${isActive ? "border-blue-500" : "border-gray-300"}`, children: [_jsxs("div", { className: "flex justify-between items-start mb-3", children: [_jsx("div", { className: "flex items-center gap-2", children: _jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Icon, { icon: "chat-square-b", size: 16, className: "text-gray-500" }), _jsxs("p", { className: "font-semibold text-sm", children: ["Session ", session.order] })] }), _jsx("p", { className: "text-xs text-gray-400", children: formatSessionDate(session.closedDate || session.createdDate) })] }) }), isActive ? (_jsx(Tag, { color: "processing", children: "\u0110ang ho\u1EA1t \u0111\u1ED9ng" })) : (_jsx(Avatar, { src: (_a = session.supporter) === null || _a === void 0 ? void 0 : _a.avatar, size: 24, children: ((_d = (_c = (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.username) === null || _c === void 0 ? void 0 : _c.charAt) === null || _d === void 0 ? void 0 : _d.call(_c, 0)) || "A" }))] }), _jsxs("div", { className: "flex flex-col gap-3 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2 text-gray-500", children: [_jsx(Icon, { icon: "tag-o", size: 16, className: "mt-1" }), _jsx(Select, { mode: "multiple", loading: isLoadingLabels, className: "w-full", placeholder: "Th\u00EAm th\u1EBB...", options: labelOptions, value: (_e = session.labels) === null || _e === void 0 ? void 0 : _e.map((label) => label.id), onChange: handleUpdateLabels, removeIcon: true })] }), _jsxs("div", { className: "flex items-start gap-2 text-gray-500", children: [_jsx(Icon, { icon: "info-circle-o", size: 16, className: "mt-1" }), _jsx(TextArea, { value: issueDetailInput.value, onChange: (e) => setIssueDetailInput({
115
+ return (_jsxs("div", { className: `p-3 border rounded-lg shadow-md ${isActive ? "border-blue-500" : "border-gray-300"}`, children: [_jsxs("div", { className: "flex justify-between items-start mb-3", children: [_jsx("div", { className: "flex items-center gap-2", children: _jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Icon, { icon: "chat-square-b", size: 16, className: "text-gray-500" }), _jsx("p", { className: "font-semibold text-sm", children: t("session_label", { order: session.order }) })] }), _jsx("p", { className: "text-xs text-gray-400", children: formatSessionDate(session.closedDate || session.createdDate) })] }) }), isActive ? (_jsx(Tag, { color: "processing", children: t("session_active") })) : (_jsx(Avatar, { src: (_a = session.supporter) === null || _a === void 0 ? void 0 : _a.avatar, size: 24, children: ((_d = (_c = (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.fullName) === null || _c === void 0 ? void 0 : _c.charAt) === null || _d === void 0 ? void 0 : _d.call(_c, 0)) || "A" }))] }), _jsxs("div", { className: "flex flex-col gap-3 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2 text-gray-500", children: [_jsx(Icon, { icon: "tag-o", size: 16, className: "mt-1" }), _jsx(Select, { mode: "multiple", loading: isLoadingLabels, className: "w-full", placeholder: t("session_add_tag_placeholder"), options: labelOptions, value: (_e = session.labels) === null || _e === void 0 ? void 0 : _e.map((label) => label.id), onChange: handleUpdateLabels, removeIcon: true })] }), _jsxs("div", { className: "flex items-start gap-2 text-gray-500", children: [_jsx(Icon, { icon: "info-circle-o", size: 16, className: "mt-1" }), _jsx(TextArea, { value: issueDetailInput.value, onChange: (e) => setIssueDetailInput({
113
116
  value: e.target.value,
114
117
  sessionId: session.id,
115
- }), placeholder: "V\u1EA5n \u0111\u1EC1 c\u1EE5 th\u1EC3...", className: "border-none !shadow-none py-0 px-2", autoSize: { minRows: 1, maxRows: 3 } })] }), _jsxs("div", { className: "flex items-start gap-2 text-gray-500", children: [_jsx(Icon, { icon: "paper-o", size: 16, className: "mt-1" }), _jsx(TextArea, { value: noteInput.value, onChange: (e) => setNoteInput({ value: e.target.value, sessionId: session.id }), placeholder: "Ghi ch\u00FA...", className: "border-none !shadow-none py-0 px-2", autoSize: { minRows: 1, maxRows: 3 } })] })] }), isActive && (_jsx(Button, { type: "primary", block: true, className: "mt-4", onClick: handleCloseSession, loading: isClosing, children: "\u0110\u00F3ng" }))] }));
118
+ }), placeholder: t("session_issue_detail_placeholder"), className: "border-none !shadow-none py-0 px-2", autoSize: { minRows: 1, maxRows: 3 } })] }), _jsxs("div", { className: "flex items-start gap-2 text-gray-500", children: [_jsx(Icon, { icon: "paper-o", size: 16, className: "mt-1" }), _jsx(TextArea, { value: noteInput.value, onChange: (e) => setNoteInput({ value: e.target.value, sessionId: session.id }), placeholder: t("session_note_placeholder"), className: "border-none !shadow-none py-0 px-2", autoSize: { minRows: 1, maxRows: 3 } })] })] }), isActive && (_jsxs("div", { className: "flex items-center gap-2 mt-4 border-t border-gray-200 pt-4", children: [_jsx(ManualAssignPopover, { sessionId: session.id, supporter: session.supporter, teamId: session.teamId }), _jsx(Button, { type: "primary", className: "flex-1", onClick: handleCloseSession, loading: isClosing, children: t("session_close_button") })] }))] }));
116
119
  };
117
120
  const ClosedSessionItem = ({ session, expandedSessionId, onToggleExpand, }) => {
118
121
  var _a, _b, _c, _d;
122
+ const { t } = useTranslation("common");
119
123
  const isExpanded = session.id === expandedSessionId;
120
124
  const handleClick = () => {
121
125
  onToggleExpand(session.id);
@@ -123,9 +127,10 @@ const ClosedSessionItem = ({ session, expandedSessionId, onToggleExpand, }) => {
123
127
  if (isExpanded) {
124
128
  return (_jsx("div", { children: _jsx(SessionDetailCard, { session: session, isActive: false }) }));
125
129
  }
126
- return (_jsxs("div", { className: "flex justify-between items-center p-2 rounded-md hover:bg-gray-100 cursor-pointer", onClick: handleClick, children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Icon, { icon: "chat-square-b", size: 16, className: "text-gray-500" }), _jsxs("span", { className: "font-semibold", children: ["Session ", session.order] }), _jsx("span", { className: "text-gray-400 text-xs", children: formatSessionDate(session.closedDate || session.createdDate) })] }), _jsx(Avatar, { src: (_a = session.supporter) === null || _a === void 0 ? void 0 : _a.avatar, size: 24, children: ((_d = (_c = (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.username) === null || _c === void 0 ? void 0 : _c.charAt) === null || _d === void 0 ? void 0 : _d.call(_c, 0)) || "A" })] }));
130
+ return (_jsxs("div", { className: "flex justify-between items-center p-2 rounded-md hover:bg-gray-100 cursor-pointer", onClick: handleClick, children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Icon, { icon: "chat-square-b", size: 16, className: "text-gray-500" }), _jsx("span", { className: "font-semibold", children: t("session_label", { order: session.order }) }), _jsx("span", { className: "text-gray-400 text-xs", children: formatSessionDate(session.closedDate || session.createdDate) })] }), _jsx(Avatar, { src: (_a = session.supporter) === null || _a === void 0 ? void 0 : _a.avatar, size: 24, children: ((_d = (_c = (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.fullName) === null || _c === void 0 ? void 0 : _c.charAt) === null || _d === void 0 ? void 0 : _d.call(_c, 0)) || "A" })] }));
127
131
  };
128
132
  const SessionSection = ({ sessions, isLoading }) => {
133
+ const { t } = useTranslation("common");
129
134
  const [isOpen, { toggle }] = useBoolean(true);
130
135
  const [expandedSessionId, setExpandedSessionId] = useState(null);
131
136
  const handleToggleExpand = (sessionId) => {
@@ -136,6 +141,6 @@ const SessionSection = ({ sessions, isLoading }) => {
136
141
  setExpandedSessionId(null);
137
142
  }
138
143
  }, [isOpen]);
139
- return (_jsxs("div", { className: "flex flex-col border-b", children: [_jsxs("div", { role: "button", onClick: toggle, className: "flex items-center justify-between px-4 py-2 rounded-md hover:bg-gray-100 sticky top-0 bg-white z-10", children: [_jsx("h3", { className: "font-bold text-gray-500 text-xs tracking-wider", children: "SESSIONS" }), _jsx(Icon, { icon: isOpen ? "angle-up-o" : "angle-down-o", size: 18 })] }), isOpen && (_jsx("div", { className: "px-4 pt-2 pb-4", children: isLoading ? (_jsx("div", { className: "text-center mt-4", children: _jsx(Spin, {}) })) : (_jsx("div", { className: "flex flex-col gap-1", children: sessions.map((session) => (_jsx(ClosedSessionItem, { session: session, expandedSessionId: expandedSessionId, onToggleExpand: handleToggleExpand }, session.id))) })) }))] }));
144
+ return (_jsxs("div", { className: "flex flex-col border-b", children: [_jsxs("div", { role: "button", onClick: toggle, className: "flex items-center justify-between px-4 py-2 rounded-md hover:bg-gray-100 sticky top-0 bg-white z-10", children: [_jsx("h3", { className: "font-bold text-gray-500 text-xs tracking-wider", children: t("sessions_heading") }), _jsx(Icon, { icon: isOpen ? "angle-up-o" : "angle-down-o", size: 18 })] }), isOpen && (_jsx("div", { className: "px-4 pt-2 pb-4", children: isLoading ? (_jsx("div", { className: "text-center mt-4", children: _jsx(Spin, {}) })) : (_jsx("div", { className: "flex flex-col gap-1", children: sessions.map((session) => (_jsx(ClosedSessionItem, { session: session, expandedSessionId: expandedSessionId, onToggleExpand: handleToggleExpand }, session.id))) })) }))] }));
140
145
  };
141
146
  export default SessionSection;
@@ -70,7 +70,7 @@ const UserSection = () => {
70
70
  navigator.clipboard.writeText((data === null || data === void 0 ? void 0 : data.id) || "");
71
71
  message.success(t("copied_to_clipboard"));
72
72
  } })] }), _jsxs("div", { className: "flex justify-between items-center gap-2", children: [_jsxs("p", { className: "text-sm truncate flex gap-3", children: [_jsx("span", { className: "font-light text-gray-400 w-16", children: "Username" }), (data === null || data === void 0 ? void 0 : data.username) || ""] }), _jsx(Icon, { icon: "copy-o", size: 16, onClick: () => {
73
- navigator.clipboard.writeText((data === null || data === void 0 ? void 0 : data.id) || "");
73
+ navigator.clipboard.writeText((data === null || data === void 0 ? void 0 : data.username) || "");
74
74
  message.success(t("copied_to_clipboard"));
75
75
  } })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("p", { className: "text-sm flex gap-3", children: _jsx("span", { className: "font-light text-gray-400 w-16", children: "Note" }) }), _jsx(TextArea, { value: noteValue, placeholder: t("add_note"), className: "border-none py-0", autoSize: { minRows: 1, maxRows: 6 }, onChange: (e) => {
76
76
  const v = e.target.value;
@@ -20,5 +20,6 @@ export declare const useMessage: (conversationId?: string, searchClientMsgID?: s
20
20
  };
21
21
  export declare const pushNewMessage: (message: MessageItem) => void;
22
22
  export declare const updateOneMessage: (message: MessageItem) => void;
23
+ export declare const removeOneMessage: (clientMsgID: string) => void;
23
24
  export declare const getVisibleNeighbor: (allMessages: MessageItem[], current: MessageItem, direction: "prev" | "next") => MessageItem | undefined;
24
25
  //# sourceMappingURL=useMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useMessage.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAQ7E,eAAO,MAAM,kBAAkB,eAc9B,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,iBAAiB,MAAM,EACvB,oBAAoB,MAAM;;;;;qBAML,WAAW,EAAE;;;;;;qBAAb,WAAW,EAAE;;;;;;CAuMnC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,SACpB,CAAC;AAChC,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,SACpB,CAAC;AAElC,eAAO,MAAM,kBAAkB,GAC7B,aAAa,WAAW,EAAE,EAC1B,SAAS,WAAW,EACpB,WAAW,MAAM,GAAG,MAAM,KACzB,WAAW,GAAG,SAkBhB,CAAC"}
1
+ {"version":3,"file":"useMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useMessage.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAQ7E,eAAO,MAAM,kBAAkB,eAe9B,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,iBAAiB,MAAM,EACvB,oBAAoB,MAAM;;;;;qBAML,WAAW,EAAE;;;;;;qBAAb,WAAW,EAAE;;;;;;CAkNnC,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"}
@@ -19,6 +19,7 @@ export const visibleTypeMessage = [
19
19
  MessageType.QuoteMessage,
20
20
  MessageType.FaceMessage,
21
21
  MessageType.UrlTextMessage,
22
+ MessageType.RevokeMessage,
22
23
  ];
23
24
  export const useMessage = (conversationId, searchClientMsgID) => {
24
25
  const [loadState, setLoadState] = useState({
@@ -143,11 +144,16 @@ export const useMessage = (conversationId, searchClientMsgID) => {
143
144
  return Object.assign(Object.assign({}, preState), { messageList: tmpList });
144
145
  });
145
146
  };
147
+ const removeOneMessage = (clientMsgID) => {
148
+ setLoadState((preState) => (Object.assign(Object.assign({}, preState), { messageList: preState.messageList.filter((msg) => msg.clientMsgID !== clientMsgID) })));
149
+ };
146
150
  emitter.on("PUSH_NEW_MSG", pushNewMessage);
147
151
  emitter.on("UPDATE_ONE_MSG", updateOneMessage);
152
+ emitter.on("REMOVE_ONE_MSG", removeOneMessage);
148
153
  return () => {
149
154
  emitter.off("PUSH_NEW_MSG", pushNewMessage);
150
155
  emitter.off("UPDATE_ONE_MSG", updateOneMessage);
156
+ emitter.off("REMOVE_ONE_MSG", removeOneMessage);
151
157
  };
152
158
  }, []);
153
159
  useEffect(() => {
@@ -179,6 +185,7 @@ export const useMessage = (conversationId, searchClientMsgID) => {
179
185
  };
180
186
  export const pushNewMessage = (message) => emit("PUSH_NEW_MSG", message);
181
187
  export const updateOneMessage = (message) => emit("UPDATE_ONE_MSG", message);
188
+ export const removeOneMessage = (clientMsgID) => emit("REMOVE_ONE_MSG", clientMsgID);
182
189
  export const getVisibleNeighbor = (allMessages, current, direction) => {
183
190
  const currentIndex = allMessages.findIndex((m) => m.clientMsgID === current.clientMsgID);
184
191
  if (currentIndex === -1)
@@ -0,0 +1,5 @@
1
+ export declare const useRevokeMessage: () => {
2
+ revokeMessage: (conversationID: string, clientMsgID: string) => Promise<void>;
3
+ loading: boolean;
4
+ };
5
+ //# sourceMappingURL=useRevokeMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRevokeMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useRevokeMessage.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB;;;CAiB5B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { DChatSDK } from "../../constants/sdk";
2
+ import { useRequest } from "ahooks";
3
+ export const useRevokeMessage = () => {
4
+ const { loading, runAsync: revokeMessage } = useRequest(async (conversationID, clientMsgID) => {
5
+ await DChatSDK.revokeMessage({
6
+ conversationID,
7
+ clientMsgID,
8
+ });
9
+ }, {
10
+ manual: true,
11
+ });
12
+ return {
13
+ revokeMessage,
14
+ loading,
15
+ };
16
+ };
@@ -2,12 +2,17 @@ import { MergerMsgParams, MessageItem } from "@openim/wasm-client-sdk";
2
2
  import { ExtendMessageInfo, FileMsgParamsByFile, ImageMsgParamsByFile, VideoMsgParamsByFile } from "../../types/chat";
3
3
  import { UploadFile } from "antd";
4
4
  import { ISessionByStatus } from "../../store/type";
5
+ export declare const isMediaResendable: (message: {
6
+ clientMsgID: string;
7
+ contentType: number;
8
+ }) => boolean;
5
9
  export declare const createTextMessage: (text: string) => Promise<MessageItem | null>;
6
10
  export declare const createImageMessageByFile: (file: ImageMsgParamsByFile) => Promise<MessageItem | null>;
7
11
  export declare const createMergerMessage: (mergerMsgParams: MergerMsgParams) => Promise<MessageItem | null>;
8
12
  export declare const createVideoMessageByFile: (file: VideoMsgParamsByFile) => Promise<MessageItem | null>;
9
13
  export declare const createFileMessageByFile: (file: FileMsgParamsByFile) => Promise<MessageItem | null>;
10
14
  export declare const createUrlTextMessage: (text: string, urls: string[]) => Promise<MessageItem | null>;
15
+ export declare const createQuoteMessage: (text: string, quotedMessage: MessageItem) => Promise<MessageItem | null>;
11
16
  export declare const useSendMessage: () => {
12
17
  sendTextMessage: ({ plainText, richText, currentSession, }: {
13
18
  plainText: string;
@@ -20,6 +25,7 @@ export declare const useSendMessage: () => {
20
25
  files: UploadFile[];
21
26
  currentSession?: ISessionByStatus;
22
27
  }) => Promise<void>;
28
+ resendMessage: (failedMessage: MessageItem) => Promise<void>;
23
29
  };
24
30
  export declare const generateExtendMessageInfo: ({ richText, currentSession, }: {
25
31
  richText?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"useSendMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useSendMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,WAAW,EAEZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAQlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,gCAanD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,iBAAiB,eAAe,gCAazE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,MAAM,mBAAmB,gCAatE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,gCActE,CAAC;AAEF,eAAO,MAAM,cAAc;gEAsDpB;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,gBAAgB,CAAC;KACnC;wEA+BE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,cAAc,CAAC,EAAE,gBAAgB,CAAC;KACnC;CA0GJ,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,+BAGvC;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC,KAWM,iBACN,CAAC"}
1
+ {"version":3,"file":"useSendMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/message/useSendMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,WAAW,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAQlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAepD,eAAO,MAAM,iBAAiB,GAAI,SAAS;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,YAE0C,CAAC;AAE5C,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,gCAanD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,iBAAiB,eAAe,gCAazE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,oBAAoB,gCAaxE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,MAAM,mBAAmB,gCAatE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,gCActE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,EACZ,eAAe,WAAW,gCAc3B,CAAC;AAEF,eAAO,MAAM,cAAc;gEAgKpB;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,gBAAgB,CAAC;KACnC;wEAkCE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,cAAc,CAAC,EAAE,gBAAgB,CAAC;KACnC;mCAhJqB,WAAW;CAgRpC,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,+BAGvC;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC,KAWM,iBACN,CAAC"}