@droppii-org/chat-sdk 0.1.16 → 0.1.18

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 (36) hide show
  1. package/dist/assets/droppiiFontSelection.json +14521 -14521
  2. package/dist/assets/sdk/sql-wasm.wasm +0 -0
  3. package/dist/assets/svg/cannedResponse.tsx +48 -48
  4. package/dist/assets/svg/document.tsx +37 -37
  5. package/dist/assets/svg/index.ts +2 -2
  6. package/dist/components/message/GroupMembersDrawer.d.ts +7 -0
  7. package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -0
  8. package/dist/components/message/GroupMembersDrawer.js +104 -0
  9. package/dist/components/message/MessageHeader.d.ts.map +1 -1
  10. package/dist/components/message/MessageHeader.js +4 -1
  11. package/dist/components/message/MessageList.d.ts.map +1 -1
  12. package/dist/components/message/MessageList.js +14 -2
  13. package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
  14. package/dist/components/thread/ManualAssignPopover.js +16 -3
  15. package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
  16. package/dist/hooks/global/useGlobalEvent.js +7 -0
  17. package/dist/hooks/group/useGroupMembers.d.ts +10 -0
  18. package/dist/hooks/group/useGroupMembers.d.ts.map +1 -0
  19. package/dist/hooks/group/useGroupMembers.js +44 -0
  20. package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
  21. package/dist/hooks/message/useSendMessage.js +42 -6
  22. package/dist/hooks/session/useCloseSession.d.ts.map +1 -1
  23. package/dist/hooks/session/useCloseSession.js +19 -12
  24. package/dist/hooks/session/useUpdateSession.d.ts +1 -1
  25. package/dist/hooks/session/useUpdateSession.d.ts.map +1 -1
  26. package/dist/hooks/session/useUpdateSession.js +20 -12
  27. package/dist/locales/i18n.ts +18 -18
  28. package/dist/locales/vi/common.json +122 -113
  29. package/dist/store/conversation.d.ts.map +1 -1
  30. package/dist/store/conversation.js +5 -8
  31. package/dist/styles/global.css +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/dist/utils/messageEx.d.ts +5 -0
  34. package/dist/utils/messageEx.d.ts.map +1 -0
  35. package/dist/utils/messageEx.js +11 -0
  36. package/package.json +10 -11
File without changes
@@ -1,48 +1,48 @@
1
- interface ISvgProps {
2
- size?: number;
3
- className?: string;
4
- }
5
-
6
- const CannedResponseIcon = (props: ISvgProps) => (
7
- <svg
8
- width={props.size || 18}
9
- height={props.size || 18}
10
- viewBox={`${0} ${0} ${props.size || 18} ${props.size || 18}`}
11
- fill="none"
12
- xmlns="http://www.w3.org/2000/svg"
13
- className={props?.className}
14
- >
15
- <g clipPath="url(#clip0_4070_70030)">
16
- <path
17
- fillRule="evenodd"
18
- clipRule="evenodd"
19
- d="M6.66732 0.833374C7.12755 0.833374 7.50065 1.20647 7.50065 1.66671L5.00065 18.3334C5.00065 18.7936 4.62755 19.1667 4.16732 19.1667C3.70708 19.1667 3.33398 18.7936 3.33398 18.3334L5.83398 1.66671C5.83398 1.20647 6.20708 0.833374 6.66732 0.833374Z"
20
- fill="currentColor"
21
- />
22
- <path
23
- fillRule="evenodd"
24
- clipRule="evenodd"
25
- d="M14.9993 0.833374C15.4596 0.833374 15.8327 1.20647 15.8327 1.66671L13.3327 18.3334C13.3327 18.7936 12.9596 19.1667 12.4993 19.1667C12.0391 19.1667 11.666 18.7936 11.666 18.3334L14.166 1.66671C14.166 1.20647 14.5391 0.833374 14.9993 0.833374Z"
26
- fill="currentColor"
27
- />
28
- <path
29
- fillRule="evenodd"
30
- clipRule="evenodd"
31
- d="M19.1673 5.83333C19.1673 6.29357 18.7942 6.66667 18.334 6.66667H1.66732C1.20708 6.66667 0.833984 6.29357 0.833984 5.83333C0.833984 5.37309 1.20708 5 1.66732 5H18.334C18.7942 5 19.1673 5.3731 19.1673 5.83333Z"
32
- fill="currentColor"
33
- />
34
- <path
35
- fillRule="evenodd"
36
- clipRule="evenodd"
37
- d="M19.1673 14.1667C19.1673 14.627 18.7942 15 18.334 15H1.66732C1.20708 15 0.833984 14.627 0.833984 14.1667C0.833984 13.7065 1.20708 13.3334 1.66732 13.3334H18.334C18.7942 13.3334 19.1673 13.7065 19.1673 14.1667Z"
38
- fill="currentColor"
39
- />
40
- </g>
41
- <defs>
42
- <clipPath id="clip0_4070_70030">
43
- <rect width={props.size || 18} height={props.size || 18} fill="white" />
44
- </clipPath>
45
- </defs>
46
- </svg>
47
- );
48
- export default CannedResponseIcon;
1
+ interface ISvgProps {
2
+ size?: number;
3
+ className?: string;
4
+ }
5
+
6
+ const CannedResponseIcon = (props: ISvgProps) => (
7
+ <svg
8
+ width={props.size || 18}
9
+ height={props.size || 18}
10
+ viewBox={`${0} ${0} ${props.size || 18} ${props.size || 18}`}
11
+ fill="none"
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ className={props?.className}
14
+ >
15
+ <g clipPath="url(#clip0_4070_70030)">
16
+ <path
17
+ fillRule="evenodd"
18
+ clipRule="evenodd"
19
+ d="M6.66732 0.833374C7.12755 0.833374 7.50065 1.20647 7.50065 1.66671L5.00065 18.3334C5.00065 18.7936 4.62755 19.1667 4.16732 19.1667C3.70708 19.1667 3.33398 18.7936 3.33398 18.3334L5.83398 1.66671C5.83398 1.20647 6.20708 0.833374 6.66732 0.833374Z"
20
+ fill="currentColor"
21
+ />
22
+ <path
23
+ fillRule="evenodd"
24
+ clipRule="evenodd"
25
+ d="M14.9993 0.833374C15.4596 0.833374 15.8327 1.20647 15.8327 1.66671L13.3327 18.3334C13.3327 18.7936 12.9596 19.1667 12.4993 19.1667C12.0391 19.1667 11.666 18.7936 11.666 18.3334L14.166 1.66671C14.166 1.20647 14.5391 0.833374 14.9993 0.833374Z"
26
+ fill="currentColor"
27
+ />
28
+ <path
29
+ fillRule="evenodd"
30
+ clipRule="evenodd"
31
+ d="M19.1673 5.83333C19.1673 6.29357 18.7942 6.66667 18.334 6.66667H1.66732C1.20708 6.66667 0.833984 6.29357 0.833984 5.83333C0.833984 5.37309 1.20708 5 1.66732 5H18.334C18.7942 5 19.1673 5.3731 19.1673 5.83333Z"
32
+ fill="currentColor"
33
+ />
34
+ <path
35
+ fillRule="evenodd"
36
+ clipRule="evenodd"
37
+ d="M19.1673 14.1667C19.1673 14.627 18.7942 15 18.334 15H1.66732C1.20708 15 0.833984 14.627 0.833984 14.1667C0.833984 13.7065 1.20708 13.3334 1.66732 13.3334H18.334C18.7942 13.3334 19.1673 13.7065 19.1673 14.1667Z"
38
+ fill="currentColor"
39
+ />
40
+ </g>
41
+ <defs>
42
+ <clipPath id="clip0_4070_70030">
43
+ <rect width={props.size || 18} height={props.size || 18} fill="white" />
44
+ </clipPath>
45
+ </defs>
46
+ </svg>
47
+ );
48
+ export default CannedResponseIcon;
@@ -1,37 +1,37 @@
1
- export const documentIcon = (
2
- <svg
3
- width="40"
4
- height="40"
5
- viewBox="0 0 40 40"
6
- fill="none"
7
- xmlns="http://www.w3.org/2000/svg"
8
- >
9
- <path
10
- d="M10.1923 5.83301L23.4363 5.83301L34.1656 14.2054V29.8639C34.1656 31.8997 32.5286 34.1663 29.8068 34.1663C27.0849 34.1663 10.1923 34.1663 10.1923 34.1663C7.4704 34.1663 5.8335 31.8997 5.8335 29.8639V10.0305C5.8335 7.99475 7.4704 5.83301 10.1923 5.83301Z"
11
- fill="#24B0FF"
12
- ></path>
13
- <path
14
- d="M10.8335 28.1394V20.833H16.0309V22.4222H12.7026V23.5916H15.3612V25.1708H12.7026V28.1394H10.8335Z"
15
- fill="#edf6ff"
16
- ></path>
17
- <path
18
- d="M19.0073 28.0885V20.833H20.8613V26.5118H24.0146V28.0885L19.0073 28.0885Z"
19
- fill="#edf6ff"
20
- ></path>
21
- <path
22
- d="M16.5918 28.1001V20.833H18.4485V28.1001H16.5918Z"
23
- fill="#edf6ff"
24
- ></path>
25
- <path
26
- d="M24.5737 20.833V28.1393H29.7723V26.5573H26.439L26.4422 25.1708H29.1017V23.5916H26.4422V22.4222H29.7723V20.833H24.5737Z"
27
- fill="#edf6ff"
28
- ></path>
29
- <path
30
- opacity="0.302"
31
- fillRule="evenodd"
32
- clipRule="evenodd"
33
- d="M23.2686 5.83301V14.2281H34.1655L23.2686 5.83301Z"
34
- fill="#edf6ff"
35
- ></path>
36
- </svg>
37
- );
1
+ export const documentIcon = (
2
+ <svg
3
+ width="40"
4
+ height="40"
5
+ viewBox="0 0 40 40"
6
+ fill="none"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ >
9
+ <path
10
+ d="M10.1923 5.83301L23.4363 5.83301L34.1656 14.2054V29.8639C34.1656 31.8997 32.5286 34.1663 29.8068 34.1663C27.0849 34.1663 10.1923 34.1663 10.1923 34.1663C7.4704 34.1663 5.8335 31.8997 5.8335 29.8639V10.0305C5.8335 7.99475 7.4704 5.83301 10.1923 5.83301Z"
11
+ fill="#24B0FF"
12
+ ></path>
13
+ <path
14
+ d="M10.8335 28.1394V20.833H16.0309V22.4222H12.7026V23.5916H15.3612V25.1708H12.7026V28.1394H10.8335Z"
15
+ fill="#edf6ff"
16
+ ></path>
17
+ <path
18
+ d="M19.0073 28.0885V20.833H20.8613V26.5118H24.0146V28.0885L19.0073 28.0885Z"
19
+ fill="#edf6ff"
20
+ ></path>
21
+ <path
22
+ d="M16.5918 28.1001V20.833H18.4485V28.1001H16.5918Z"
23
+ fill="#edf6ff"
24
+ ></path>
25
+ <path
26
+ d="M24.5737 20.833V28.1393H29.7723V26.5573H26.439L26.4422 25.1708H29.1017V23.5916H26.4422V22.4222H29.7723V20.833H24.5737Z"
27
+ fill="#edf6ff"
28
+ ></path>
29
+ <path
30
+ opacity="0.302"
31
+ fillRule="evenodd"
32
+ clipRule="evenodd"
33
+ d="M23.2686 5.83301V14.2281H34.1655L23.2686 5.83301Z"
34
+ fill="#edf6ff"
35
+ ></path>
36
+ </svg>
37
+ );
@@ -1,2 +1,2 @@
1
- export * from "./document";
2
- export * from "./cannedResponse";
1
+ export * from "./document";
2
+ export * from "./cannedResponse";
@@ -0,0 +1,7 @@
1
+ interface GroupMembersDrawerProps {
2
+ groupID?: string;
3
+ disabled?: boolean;
4
+ }
5
+ declare const GroupMembersDrawer: ({ groupID, disabled, }: GroupMembersDrawerProps) => import("react/jsx-runtime").JSX.Element;
6
+ export default GroupMembersDrawer;
7
+ //# sourceMappingURL=GroupMembersDrawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AAUA,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsCD,QAAA,MAAM,kBAAkB,GAAI,wBAGzB,uBAAuB,4CAwLzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,104 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { GroupMemberRole } from "@openim/wasm-client-sdk";
3
+ import { Avatar, Button, Drawer, Dropdown, Empty, Spin } from "antd";
4
+ import { useEffect, useMemo, useState } from "react";
5
+ import { useTranslation } from "react-i18next";
6
+ import useAuthStore from "../../store/auth";
7
+ import useConversationStore from "../../store/conversation";
8
+ import { useGroupMembers } from "../../hooks/group/useGroupMembers";
9
+ import { Icon } from "../icon";
10
+ const getMemberDisplayName = (member) => {
11
+ return member.nickname || member.userID || "";
12
+ };
13
+ const getMemberRoleLabel = ({ member, customerUserID, t, }) => {
14
+ if (member.userID === customerUserID ||
15
+ member.roleLevel === GroupMemberRole.Owner) {
16
+ return t("group_creator");
17
+ }
18
+ if (member.roleLevel === GroupMemberRole.Admin) {
19
+ return t("group_admin");
20
+ }
21
+ return t("group_member");
22
+ };
23
+ const GroupMembersDrawer = ({ groupID, disabled = false, }) => {
24
+ var _a, _b;
25
+ const { t } = useTranslation();
26
+ const [isOpen, setIsOpen] = useState(false);
27
+ const authUserID = useAuthStore((state) => state.userID);
28
+ const conversationData = useConversationStore((state) => state.conversationData);
29
+ const { members, isLoading, error } = useGroupMembers(groupID);
30
+ let customerUserID = "";
31
+ try {
32
+ const exConversationInfo = JSON.parse((conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex) || "{}");
33
+ customerUserID = ((_b = (_a = exConversationInfo === null || exConversationInfo === void 0 ? void 0 : exConversationInfo.sessionInfo) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.ownerId) || "";
34
+ }
35
+ catch (error) {
36
+ console.error("Error parsing conversation extra info:", error);
37
+ }
38
+ const sortedMembers = useMemo(() => {
39
+ return [...members]
40
+ .map((member) => ({
41
+ userID: member.userID,
42
+ nickname: getMemberDisplayName(member),
43
+ faceURL: member.faceURL,
44
+ isCustomer: Boolean(customerUserID) && member.userID === customerUserID,
45
+ isCurrentUser: member.userID === authUserID,
46
+ roleLabel: getMemberRoleLabel({
47
+ member,
48
+ customerUserID,
49
+ t,
50
+ }),
51
+ }))
52
+ .sort((memberA, memberB) => {
53
+ if (memberA.isCustomer !== memberB.isCustomer) {
54
+ return memberA.isCustomer ? -1 : 1;
55
+ }
56
+ return memberA.nickname.localeCompare(memberB.nickname, "vi", {
57
+ sensitivity: "base",
58
+ });
59
+ });
60
+ }, [authUserID, members, customerUserID, t]);
61
+ const handleOpenDrawer = () => {
62
+ if (!groupID || disabled) {
63
+ return;
64
+ }
65
+ setIsOpen(true);
66
+ };
67
+ const handleCloseDrawer = () => {
68
+ setIsOpen(false);
69
+ };
70
+ const handleLeaveGroup = () => { };
71
+ useEffect(() => {
72
+ setIsOpen(false);
73
+ }, [groupID]);
74
+ const renderContent = () => {
75
+ if (isLoading) {
76
+ return (_jsx("div", { className: "flex items-center justify-center h-full min-h-40", children: _jsx(Spin, {}) }));
77
+ }
78
+ if (error) {
79
+ return (_jsx("div", { className: "flex items-center justify-center h-full min-h-40 px-6 text-center text-sm text-gray-500", children: t(error) }));
80
+ }
81
+ if (!sortedMembers.length) {
82
+ return _jsx(Empty, { description: t("no_group_members") });
83
+ }
84
+ return (_jsx("div", { className: "flex flex-col", children: sortedMembers.map((member) => {
85
+ const menuItems = [
86
+ {
87
+ key: "leave-group",
88
+ label: t("leave_group"),
89
+ icon: _jsx(Icon, { icon: "logout-b", size: 16 }),
90
+ onClick: handleLeaveGroup,
91
+ danger: true,
92
+ },
93
+ ];
94
+ return (_jsxs("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-gray-100", children: [_jsx(Avatar, { src: member.faceURL, size: 40, className: "shrink-0", children: member.nickname.charAt(0) || "A" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: member.nickname }), member.isCurrentUser && (_jsx("span", { className: "text-xs text-blue-500 shrink-0", children: t("current_account") }))] }), _jsx("p", { className: "text-sm text-gray-500 truncate", children: member.roleLabel })] }), member.isCurrentUser && (_jsx(Dropdown, { menu: { items: menuItems }, trigger: ["click"], placement: "bottomRight", children: _jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 rounded-full text-gray-500 hover:bg-gray-100", onClick: (event) => event.stopPropagation(), children: _jsx(Icon, { icon: "more-horizontal-b", size: 18 }) }) }))] }, member.userID));
95
+ }) }));
96
+ };
97
+ return (_jsxs(_Fragment, { children: [_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: handleOpenDrawer, disabled: disabled || !groupID, children: _jsx(Icon, { icon: "user-two-check-b", size: 22 }) }), _jsx(Drawer, { open: isOpen, onClose: handleCloseDrawer, mask: false, closeIcon: false, styles: {
98
+ body: {
99
+ padding: 0,
100
+ height: "100%",
101
+ },
102
+ }, getContainer: false, width: 360, children: _jsxs("div", { className: "flex flex-col h-full bg-white", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100", children: [_jsx("span", { className: "text-lg font-medium", children: t("members") }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: handleCloseDrawer, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: renderContent() })] }) })] }));
103
+ };
104
+ export default GroupMembersDrawer;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKnD,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,KAAK,sBAAsB,GAAG,aAAa,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,sBAAsB,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,6BAA6B,kBAAkB,4CAoMrE,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOnD,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,KAAK,sBAAsB,GAAG,aAAa,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,sBAAsB,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,6BAA6B,kBAAkB,4CA0MrE,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -12,7 +12,9 @@ import SelectSession from "./SelectSession";
12
12
  import { useUpdateSession } from "../../hooks/session/useUpdateSession";
13
13
  import useAuthStore from "../../store/auth";
14
14
  import SearchDrawer from "../searchConversation/SearchDrawer";
15
+ import { useIsJoinedGroup } from "../../hooks/session/useIsJoinedGroup";
15
16
  import { isGroupSession } from "../../utils/imCommon";
17
+ import GroupMembersDrawer from "./GroupMembersDrawer";
16
18
  const MessageHeader = ({ onClose, currentSession }) => {
17
19
  var _a, _b;
18
20
  const { t } = useTranslation();
@@ -22,6 +24,7 @@ const MessageHeader = ({ onClose, currentSession }) => {
22
24
  const { mutate: updateSession } = useUpdateSession();
23
25
  const { avatar, displayName } = useConversationDisplayData(conversationData);
24
26
  const shouldShowMemberCount = isGroupSession(conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationType);
27
+ const { isJoined } = useIsJoinedGroup(conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID);
25
28
  const [currentSessionStatus, setCurrentSessionStatus] = useState(SessionStatus.UNASSIGNED);
26
29
  const [currentSessionTag, setCurrentSessionTag] = useState(SessionTag.NONE);
27
30
  const statusOptions = useMemo(() => {
@@ -125,6 +128,6 @@ const MessageHeader = ({ onClose, currentSession }) => {
125
128
  setCurrentSessionStatus(currentSession.status);
126
129
  }
127
130
  }, [currentSession]);
128
- return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), shouldShowMemberCount && (_jsx("p", { className: "text-xs text-gray-500 truncate", children: t("member_count", { count: (_b = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount) !== null && _b !== void 0 ? _b : 0 }) }))] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
131
+ return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), shouldShowMemberCount && (_jsx("p", { className: "text-xs text-gray-500 truncate", children: t("member_count", { count: (_b = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount) !== null && _b !== void 0 ? _b : 0 }) }))] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), shouldShowMemberCount && isJoined === true && (_jsx(GroupMembersDrawer, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID })), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
129
132
  };
130
133
  export default MessageHeader;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AA2BA,UAAU,gBAAgB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA6U3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AA2BA,UAAU,gBAAgB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA4V3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -73,7 +73,7 @@ const MessageList = (props) => {
73
73
  revokeMessage,
74
74
  handleCloseRevoke,
75
75
  ]);
76
- const handleMarkConversationMessageAsRead = () => {
76
+ const handleMarkConversationMessageAsRead = useCallback(() => {
77
77
  var _a, _b, _c, _d, _e;
78
78
  const lastMessage = (_b = (_a = latestLoadState === null || latestLoadState === void 0 ? void 0 : latestLoadState.current) === null || _a === void 0 ? void 0 : _a.messageList) === null || _b === void 0 ? void 0 : _b[0];
79
79
  if (!((_c = latestLoadState === null || latestLoadState === void 0 ? void 0 : latestLoadState.current) === null || _c === void 0 ? void 0 : _c.hasMoreNew) &&
@@ -84,7 +84,7 @@ const MessageList = (props) => {
84
84
  ((_e = scrollRef.current) === null || _e === void 0 ? void 0 : _e.scrollTop) >= BOTTOM_THRESHOLD) {
85
85
  markConversationMessageAsRead(conversationId);
86
86
  }
87
- };
87
+ }, [conversationId, moreNewLoading, user === null || user === void 0 ? void 0 : user.userID]);
88
88
  const scrollToBottom = () => {
89
89
  handleMarkConversationMessageAsRead();
90
90
  setTimeout(() => {
@@ -167,6 +167,18 @@ const MessageList = (props) => {
167
167
  loadState.initLoading,
168
168
  handleMarkConversationMessageAsRead,
169
169
  ]);
170
+ useEffect(() => {
171
+ if (!loadState.hasMoreNew &&
172
+ !loadState.initLoading &&
173
+ loadState.messageList.length > 0) {
174
+ handleMarkConversationMessageAsRead();
175
+ }
176
+ }, [
177
+ loadState.messageList.length,
178
+ loadState.hasMoreNew,
179
+ loadState.initLoading,
180
+ handleMarkConversationMessageAsRead,
181
+ ]);
170
182
  useEffect(() => {
171
183
  if (!openMenuId)
172
184
  return;
@@ -1 +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"}
1
+ {"version":3,"file":"ManualAssignPopover.d.ts","sourceRoot":"","sources":["../../../src/components/thread/ManualAssignPopover.tsx"],"names":[],"mappings":"AAiBA,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;AAqDD,QAAA,MAAM,mBAAmB,GAAI,+CAI1B,wBAAwB,4CAmL1B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -11,19 +11,21 @@ import { message as antdMessage } from "antd";
11
11
  import { invalidateSessionQueries } from "../../utils/queryHelpers";
12
12
  import AssignConfirmModal from "./AssignConfirmModal";
13
13
  import { useDebounce } from "ahooks";
14
+ import useAuthStore from "../../store/auth";
14
15
  const SEARCH_DEBOUNCE_WAIT = 300;
15
- const SupporterItem = ({ supporter, onClick, isCurrentAssignee, }) => {
16
+ const SupporterItem = ({ supporter, onClick, isCurrentAssignee, isCurrentUser, }) => {
16
17
  var _a;
17
18
  const { t } = useTranslation();
18
19
  const isOnline = supporter.status === "ONLINE";
19
20
  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
21
  ? "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
+ : "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" }) }), _jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [_jsx("span", { className: "text-sm truncate", children: supporter.displayName }), isCurrentUser && (_jsx("span", { className: "text-xs text-blue-500 shrink-0", children: t("current_account") }))] }), _jsx("div", { className: "flex items-center gap-2 shrink-0", children: isCurrentAssignee && (_jsx("span", { className: "text-xs text-blue-500 shrink-0", children: t("manual_assign_current") })) })] }));
22
23
  };
23
24
  const ManualAssignPopover = ({ sessionId, supporter, teamId: propTeamId, }) => {
24
25
  var _a, _b;
25
26
  const { t } = useTranslation();
26
27
  const queryClient = useQueryClient();
28
+ const authUserID = useAuthStore((state) => state.userID);
27
29
  const [open, setOpen] = useState(false);
28
30
  const [searchText, setSearchText] = useState("");
29
31
  const [selectedAgent, setSelectedAgent] = useState(null);
@@ -75,7 +77,18 @@ const ManualAssignPopover = ({ sessionId, supporter, teamId: propTeamId, }) => {
75
77
  setSearchText("");
76
78
  }
77
79
  };
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") }) })) })] }));
80
+ 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]
81
+ .sort((supporterA, supporterB) => {
82
+ const isSupporterACurrentUser = supporterA.memberId === authUserID;
83
+ const isSupporterBCurrentUser = supporterB.memberId === authUserID;
84
+ if (isSupporterACurrentUser !== isSupporterBCurrentUser) {
85
+ return isSupporterACurrentUser ? -1 : 1;
86
+ }
87
+ return supporterA.displayName.localeCompare(supporterB.displayName, "vi", {
88
+ sensitivity: "base",
89
+ });
90
+ })
91
+ .map((item) => (_jsx(SupporterItem, { supporter: item, onClick: handleSelectAgent, isCurrentAssignee: item.memberId === (supporter === null || supporter === void 0 ? void 0 : supporter.id), isCurrentUser: item.memberId === authUserID }, 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
92
  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
93
  ? "opacity-50 pointer-events-none"
81
94
  : "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 })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"useGlobalEvent.d.ts","sourceRoot":"","sources":["../../../src/hooks/global/useGlobalEvent.ts"],"names":[],"mappings":"AA+BA,eAAO,MAAM,cAAc,YAgS1B,CAAC"}
1
+ {"version":3,"file":"useGlobalEvent.d.ts","sourceRoot":"","sources":["../../../src/hooks/global/useGlobalEvent.ts"],"names":[],"mappings":"AAgCA,eAAO,MAAM,cAAc,YAuS1B,CAAC"}
@@ -11,6 +11,7 @@ import { updateSession } from "../session/useUpdateSession";
11
11
  import { QUERY_KEYS } from "../../services/query";
12
12
  import { useQueryClient } from "@tanstack/react-query";
13
13
  import { isGroupSession } from "../../utils/imCommon";
14
+ import { invalidateSessionQueries } from "../../utils/queryHelpers";
14
15
  const notPushType = [MessageType.TypingMessage, MessageType.RevokeMessage];
15
16
  export const useGlobalEvent = () => {
16
17
  const { user } = useChatContext();
@@ -81,6 +82,12 @@ export const useGlobalEvent = () => {
81
82
  if (!notPushType.includes(newServerMsg.contentType)) {
82
83
  pushNewMessage(newServerMsg);
83
84
  }
85
+ if (newServerMsg.sendID !== (user === null || user === void 0 ? void 0 : user.userID)) {
86
+ queryClient.invalidateQueries({
87
+ queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
88
+ });
89
+ void invalidateSessionQueries(queryClient);
90
+ }
84
91
  };
85
92
  const newMessageHandler = ({ data }) => {
86
93
  var _a;
@@ -0,0 +1,10 @@
1
+ import { GroupMemberItem } from "@openim/wasm-client-sdk";
2
+ interface UseGroupMembersResult {
3
+ members: GroupMemberItem[];
4
+ isLoading: boolean;
5
+ error?: string;
6
+ refetch: () => Promise<void>;
7
+ }
8
+ export declare const useGroupMembers: (groupID?: string) => UseGroupMembersResult;
9
+ export {};
10
+ //# sourceMappingURL=useGroupMembers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGroupMembers.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useGroupMembers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM1D,UAAU,qBAAqB;IAC7B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,KACf,qBA2CF,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { DChatSDK } from "../../constants/sdk";
3
+ const GROUP_MEMBER_LIST_OFFSET = 0;
4
+ const GROUP_MEMBER_LIST_COUNT = 999;
5
+ export const useGroupMembers = (groupID) => {
6
+ const [members, setMembers] = useState([]);
7
+ const [isLoading, setIsLoading] = useState(false);
8
+ const [error, setError] = useState(undefined);
9
+ const fetchMembers = useCallback(async () => {
10
+ if (!groupID) {
11
+ setMembers([]);
12
+ setError(undefined);
13
+ return;
14
+ }
15
+ setIsLoading(true);
16
+ setError(undefined);
17
+ try {
18
+ const { data } = await DChatSDK.getGroupMemberList({
19
+ groupID,
20
+ filter: 0,
21
+ offset: GROUP_MEMBER_LIST_OFFSET,
22
+ count: GROUP_MEMBER_LIST_COUNT,
23
+ });
24
+ setMembers(data !== null && data !== void 0 ? data : []);
25
+ }
26
+ catch (err) {
27
+ console.error("Error fetching group member list:", err);
28
+ setMembers([]);
29
+ setError("load_group_member_list_failed");
30
+ }
31
+ finally {
32
+ setIsLoading(false);
33
+ }
34
+ }, [groupID]);
35
+ useEffect(() => {
36
+ void fetchMembers();
37
+ }, [fetchMembers]);
38
+ return {
39
+ members,
40
+ isLoading,
41
+ error,
42
+ refetch: fetchMembers,
43
+ };
44
+ };
@@ -1 +1 @@
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,iBAAiB,CAAC;AAenD,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;4EA6KpB;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB;oFAoCE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB;mCA5JqB,WAAW;CA6RpC,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;AAY1B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAUlC,OAAO,EAAgB,gBAAgB,EAAyB,MAAM,iBAAiB,CAAC;AAkBxF,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;4EA0NpB;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB;oFAoCE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB;mCA5JqB,WAAW;CA6RpC,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,+BAGvC;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC,KAWM,iBACN,CAAC"}
@@ -3,12 +3,18 @@ import { DChatSDK } from "../../constants/sdk";
3
3
  import { v4 as uuidv4 } from "uuid";
4
4
  import { useChatContext } from "../../context/ChatContext";
5
5
  import { useCallback } from "react";
6
+ import { useQueryClient } from "@tanstack/react-query";
6
7
  import { useTranslation } from "react-i18next";
7
8
  import { pushNewMessage, removeOneMessage, updateOneMessage, } from "./useMessage";
8
9
  import { emit } from "../../utils/events";
9
10
  import useConversationStore from "../../store/conversation";
10
11
  import useAuthStore from "../../store/auth";
12
+ import { apiInstance } from "../../services/api";
13
+ import { ENDPOINTS } from "../../services/routes";
11
14
  import { extractLinks, generateContentBasedOnMessageType, } from "../../utils/common";
15
+ import { SessionStatus, SessionTag } from "../../types/chat";
16
+ import { updateSession } from "../session/useUpdateSession";
17
+ import { invalidateSessionQueries } from "../../utils/queryHelpers";
12
18
  const messageFileStore = new Map();
13
19
  const MEDIA_CONTENT_TYPES = new Set([
14
20
  MessageType.PictureMessage,
@@ -100,11 +106,38 @@ export const createQuoteMessage = async (text, quotedMessage) => {
100
106
  export const useSendMessage = () => {
101
107
  const { user } = useChatContext();
102
108
  const { t } = useTranslation("common");
109
+ const queryClient = useQueryClient();
103
110
  const conversationData = useConversationStore((state) => state.conversationData);
104
111
  const quotedMessage = useConversationStore((state) => state.quotedMessage);
105
112
  const setQuotedMessage = useConversationStore((state) => state.setQuotedMessage);
106
113
  const { userID: recvID, groupID } = conversationData || {};
107
- const dispatchMessage = useCallback(async (message) => {
114
+ const syncSessionAfterPublicMessage = useCallback(async (currentSession) => {
115
+ if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.id)) {
116
+ return;
117
+ }
118
+ const shouldUpdateStatus = currentSession.status === SessionStatus.WAITING_PROCESS ||
119
+ currentSession.tag === SessionTag.AWAITING_REPLY ||
120
+ currentSession.tag === SessionTag.TEMPORARILY_PAUSED;
121
+ if (!shouldUpdateStatus) {
122
+ return;
123
+ }
124
+ try {
125
+ const response = await apiInstance.put(ENDPOINTS.chatService.updateSession(currentSession.id), {
126
+ status: SessionStatus.IN_PROCESS,
127
+ applicationType: useAuthStore.getState().applicationType,
128
+ });
129
+ const updatedSession = response.data.data;
130
+ if (!updatedSession) {
131
+ return;
132
+ }
133
+ updateSession(updatedSession);
134
+ await invalidateSessionQueries(queryClient);
135
+ }
136
+ catch (error) {
137
+ console.error("syncSessionAfterPublicMessage", error);
138
+ }
139
+ }, [queryClient]);
140
+ const dispatchMessage = useCallback(async (message, currentSession) => {
108
141
  var _a, _b;
109
142
  const desc = generateContentBasedOnMessageType(message.contentType, ((_a = message === null || message === void 0 ? void 0 : message.textElem) === null || _a === void 0 ? void 0 : _a.content) || "") || t("new_message");
110
143
  const { data: successMessage } = await DChatSDK.sendMessage({
@@ -125,13 +158,16 @@ export const useSendMessage = () => {
125
158
  },
126
159
  });
127
160
  updateOneMessage(Object.assign(Object.assign({}, successMessage), { ex: successMessage.ex || message.ex || "{}", isInternal: (_b = successMessage.isInternal) !== null && _b !== void 0 ? _b : message.isInternal }));
161
+ if (!message.isInternal) {
162
+ await syncSessionAfterPublicMessage(currentSession);
163
+ }
128
164
  messageFileStore.delete(message.clientMsgID);
129
- }, [recvID, groupID]);
130
- const sendMessage = useCallback(async (message) => {
165
+ }, [groupID, recvID, syncSessionAfterPublicMessage, t, conversationData === null || conversationData === void 0 ? void 0 : conversationData.showName, conversationData === null || conversationData === void 0 ? void 0 : conversationData.faceURL, conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID]);
166
+ const sendMessage = useCallback(async (message, currentSession) => {
131
167
  pushNewMessage(message);
132
168
  emit("CHAT_LIST_SCROLL_TO_BOTTOM");
133
169
  try {
134
- await dispatchMessage(message);
170
+ await dispatchMessage(message, currentSession);
135
171
  }
136
172
  catch (error) {
137
173
  console.error("sendMessage", error);
@@ -242,7 +278,7 @@ export const useSendMessage = () => {
242
278
  currentSession,
243
279
  });
244
280
  let messageItem = Object.assign(Object.assign({}, message), { ex: JSON.stringify(extendMessageInfo) || "{}", isInternal });
245
- sendMessage(messageItem);
281
+ sendMessage(messageItem, currentSession);
246
282
  }, [recvID, groupID, user, sendMessage, quotedMessage, setQuotedMessage]);
247
283
  const sendMergeMessage = useCallback(async ({ richText, plainText, files, currentSession, isInternal, }) => {
248
284
  if (!recvID && !groupID)
@@ -356,7 +392,7 @@ export const useSendMessage = () => {
356
392
  currentSession,
357
393
  });
358
394
  const mMessage = Object.assign(Object.assign({}, message), { ex: JSON.stringify(extendMessageInfo) || "{}", isInternal });
359
- await sendMessage(mMessage);
395
+ await sendMessage(mMessage, currentSession);
360
396
  }
361
397
  }, [recvID, groupID, sendMessage, quotedMessage, setQuotedMessage]);
362
398
  return {