@droppii-org/chat-sdk 0.6.44 → 0.6.45

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAYhD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,iCAGhC,8BAA8B,mDA+EhC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
1
+ {"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAahD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,iCAGhC,8BAA8B,mDAyFhC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
@@ -8,11 +8,12 @@ import { useChatNavigate } from "../../hooks/conversation/useChatNavigate";
8
8
  import { useConversationDisplayData } from "../../hooks/conversation/useConversation";
9
9
  import { formatTimestamp, parseLatestMessage } from "../../utils/common";
10
10
  import { isGroupSession } from "../../utils/imCommon";
11
+ import { resolveBotSessionOwnerIdentity } from "../../utils/conversation";
11
12
  import GroupCompositeAvatar from "../../components/group/GroupCompositeAvatar";
12
13
  import ThreadCard from "./ThreadCard";
13
14
  import MentionIndicatorIcon from "./MentionIndicatorIcon";
14
15
  const ConversationBySessionItem = ({ sessionItem, latestPreview, }) => {
15
- var _a;
16
+ var _a, _b;
16
17
  const { t } = useTranslation();
17
18
  const { user } = useChatContext();
18
19
  const onNavigate = useChatNavigate();
@@ -35,6 +36,8 @@ const ConversationBySessionItem = ({ sessionItem, latestPreview, }) => {
35
36
  setSelectedConversationId(conversation.conversationID);
36
37
  };
37
38
  const { avatar, displayName = "" } = useConversationDisplayData(conversation || null);
39
+ const ownerIdentity = resolveBotSessionOwnerIdentity(conversation, sessionItem === null || sessionItem === void 0 ? void 0 : sessionItem.owner, user === null || user === void 0 ? void 0 : user.userID);
40
+ const title = (_a = ownerIdentity === null || ownerIdentity === void 0 ? void 0 : ownerIdentity.displayName) !== null && _a !== void 0 ? _a : displayName;
38
41
  const latestMsg = (latestPreview === null || latestPreview === void 0 ? void 0 : latestPreview.latestMsg) || "";
39
42
  const latestMsgSendTime = (latestPreview === null || latestPreview === void 0 ? void 0 : latestPreview.latestMsgSendTime) || 0;
40
43
  if (!conversation)
@@ -45,6 +48,6 @@ const ConversationBySessionItem = ({ sessionItem, latestPreview, }) => {
45
48
  showName: conversation.showName,
46
49
  }), mentionIndicator: _jsx(MentionIndicatorIcon, { groupAtType: conversation.groupAtType }), time: latestMsgSendTime > 0
47
50
  ? formatTimestamp(latestMsgSendTime, { hasTime: true })
48
- : undefined, avatar: isGroupSession(conversation.conversationType) ? (_jsx(GroupCompositeAvatar, { groupID: conversation.groupID, faceURL: avatar, groupName: displayName, size: 48 })) : (_jsx(Avatar, { size: 48, src: avatar, children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" })), title: _jsx("h3", { className: "truncate text-sm font-semibold text-gray-900", children: displayName }) }));
51
+ : undefined, avatar: ownerIdentity ? (_jsx(Avatar, { size: 48, src: ownerIdentity.avatarUrl, children: title.charAt(0) })) : isGroupSession(conversation.conversationType) ? (_jsx(GroupCompositeAvatar, { groupID: conversation.groupID, faceURL: avatar, groupName: displayName, size: 48 })) : (_jsx(Avatar, { size: 48, src: avatar, children: ((_b = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _b === void 0 ? void 0 : _b.call(displayName, 0)) || "A" })), title: _jsx("h3", { className: "truncate text-sm font-semibold text-gray-900", children: title }) }));
49
52
  };
50
53
  export default ConversationBySessionItem;
@@ -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;AAwBzE,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,4CAgQ9B,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;AAwBzE,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,4CAmQ9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -132,6 +132,7 @@ const ConversationMessageList = ({ bottomSlot, onCopyMessageLink, onSearchMessag
132
132
  target: scrollRef,
133
133
  enable: !!openToolboxMessageId,
134
134
  });
135
- return (_jsxs("div", { "data-testid": "conversation-message-list", "data-cp-name": "ConversationMessageList", className: "relative flex min-h-0 min-w-0 flex-1 flex-col overflow-x-hidden bg-white", children: [isMessageLoading ? (_jsx("div", { className: "flex flex-1 items-center justify-center py-12", children: _jsx(Spin, {}) })) : (_jsxs(MessageInfiniteScroll, { scrollRef: scrollRef, scrollableTargetId: "scrollableConversationMessagesDiv", loadState: loadState, moreOldLoading: moreOldLoading, onLoadMoreOld: loadMoreOldMessage, onScroll: handleInfiniteScroll, containerClassName: "h-full", empty: _jsx("div", { className: "flex flex-1 items-center justify-center py-12", children: _jsx(Empty, { description: t("empty.no_messages") }) }), children: [bottomSlot, loadState.messageList.map((message, index, array) => (_jsx(MessageItem, { message: message, allMessages: array, isGroupChat: isGroupChat, forceHideTip: index === 0 && !!bottomSlot, contextMenuOpen: openToolboxMessageId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenToolboxMessageId(open ? message.clientMsgID : null), onQuoteMessage: setQuotedMessage, onRevokeMessage: handleRevokeMessage, timeRevealed: revealedTimeMsgId === message.clientMsgID, onToggleTimeReveal: handleToggleTimeReveal, onPressQuoteMessage: onPressQuoteMessage, onPinMessage: canPinMessage ? handlePinMessage : undefined, onUnpinMessage: canPinMessage ? handleUnpinMessage : undefined, onCopyMessageLink: handleCopyMessageLink, showUnreadDivider: message.clientMsgID === unreadDividerMessageId, onUnreadDividerSeen: markDividerSeen, enableLongPress: true }, message.clientMsgID)))] })), !isMessageLoading && showJumpButton && (_jsx(UnreadMessageJumpButton, { className: "absolute right-0 top-2 z-10", onClick: handleJumpToFirstUnread })), _jsx(PinLimitModal, { open: pinLimitModalOpen, max: pinnedTotalCount, onClose: () => setPinLimitModalOpen(false) })] }));
135
+ return (_jsxs("div", { "data-testid": "conversation-message-list", "data-cp-name": "ConversationMessageList", className: "relative flex min-h-0 min-w-0 flex-1 flex-col overflow-x-hidden bg-white", children: [isMessageLoading ? (_jsx("div", { className: "flex flex-1 items-center justify-center py-12", children: _jsx(Spin, {}) })) : (_jsxs(MessageInfiniteScroll, { scrollRef: scrollRef, scrollableTargetId: "scrollableConversationMessagesDiv", loadState: loadState, moreOldLoading: moreOldLoading, onLoadMoreOld: loadMoreOldMessage, onScroll: handleInfiniteScroll, containerClassName: "h-full", empty: _jsx("div", { className: "flex flex-1 items-center justify-center py-12", children: _jsx(Empty, { description: t("empty.no_messages") }) }), children: [bottomSlot, loadState.messageList.map((message, index, array) => (_jsx(MessageItem, { message: message, allMessages: array, isGroupChat: isGroupChat, forceHideTip: index === 0 && !!bottomSlot, contextMenuOpen: openToolboxMessageId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenToolboxMessageId(open ? message.clientMsgID : null), onQuoteMessage: setQuotedMessage, onRevokeMessage: handleRevokeMessage, timeRevealed: revealedTimeMsgId === message.clientMsgID, onToggleTimeReveal: handleToggleTimeReveal, onPressQuoteMessage: onPressQuoteMessage, onPinMessage: canPinMessage ? handlePinMessage : undefined, onUnpinMessage: canPinMessage ? handleUnpinMessage : undefined, onCopyMessageLink: handleCopyMessageLink, showUnreadDivider: !!unreadDividerMessageId &&
136
+ message.clientMsgID === unreadDividerMessageId, onUnreadDividerSeen: markDividerSeen, enableLongPress: true }, message.clientMsgID)))] })), !isMessageLoading && showJumpButton && (_jsx(UnreadMessageJumpButton, { className: "absolute right-0 top-2 z-10", onClick: handleJumpToFirstUnread })), _jsx(PinLimitModal, { open: pinLimitModalOpen, max: pinnedTotalCount, onClose: () => setPinLimitModalOpen(false) })] }));
136
137
  };
137
138
  export default ConversationMessageList;
@@ -1 +1 @@
1
- {"version":3,"file":"AdminPermissionModal.d.ts","sourceRoot":"","sources":["../../../src/components/group/AdminPermissionModal.tsx"],"names":[],"mappings":"AAcA,UAAU,0BAA0B;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,UAAU,yBAAyB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IAIpB,MAAM,CAAC,EAAE,OAAO,CAAC;IAKjB,MAAM,CAAC,EAAE,0BAA0B,CAAC;IAKpC,wBAAwB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC5E;AA6DD,QAAA,MAAM,oBAAoB,GAAI,uEAO3B,yBAAyB,mDA2M3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"AdminPermissionModal.d.ts","sourceRoot":"","sources":["../../../src/components/group/AdminPermissionModal.tsx"],"names":[],"mappings":"AAaA,UAAU,0BAA0B;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,UAAU,yBAAyB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IAIpB,MAAM,CAAC,EAAE,OAAO,CAAC;IAGjB,MAAM,CAAC,EAAE,0BAA0B,CAAC;IAKpC,wBAAwB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC5E;AA6DD,QAAA,MAAM,oBAAoB,GAAI,uEAO3B,yBAAyB,mDA2K3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -4,97 +4,72 @@ import { useEffect, useState } from "react";
4
4
  import { ConfigProvider, Modal, Switch, message } from "antd";
5
5
  import { useTranslation } from "react-i18next";
6
6
  import { GroupMemberRole } from "@droppii-org/wasm-client-sdk";
7
- import { useGroupPermission } from "../../hooks/group/useGroupPermission";
8
7
  import { useGroupMembers } from "../../hooks/group/useGroupMembers";
9
8
  import { useSetGroupMemberPermissions } from "../../hooks/group/useGroupMemberActions";
10
9
  import { Icon } from "../../components/icon";
11
10
  import { ANTD_PRIMARY_COLOR_VAR } from "../../constants";
12
11
  import { GROUP_PERMISSION_KEY } from "../../constants/im";
13
12
  // "Cập nhật thông tin nhóm" is one switch in the UI but bundles 3 BE
14
- // permission keys (name/avatar/description) — DROPPII-30533 fix: reading
15
- // only checked UPDATE_GROUP_NAME, so turning the switch off only ever
16
- // stripped that one key, leaving avatar/description at the role default.
13
+ // permission keys (name/avatar/description), so it maps to all three.
17
14
  const UPDATE_GROUP_INFO_KEYS = [
18
15
  GROUP_PERMISSION_KEY.updateGroupName,
19
16
  GROUP_PERMISSION_KEY.updateGroupAvatar,
20
17
  GROUP_PERMISSION_KEY.updateGroupDescription,
21
18
  ];
22
- const permissionListToOverrides = (permissionList) => ({
23
- sendMessage: permissionList.includes(GROUP_PERMISSION_KEY.sendMessage),
24
- pinMessage: permissionList.includes(GROUP_PERMISSION_KEY.pinMessage),
25
- viewMemberInformation: permissionList.includes(GROUP_PERMISSION_KEY.viewMemberInformation),
26
- addMember: permissionList.includes(GROUP_PERMISSION_KEY.addMember),
27
- removeMember: permissionList.includes(GROUP_PERMISSION_KEY.removeMember),
28
- updateGroupInfo: UPDATE_GROUP_INFO_KEYS.every((key) => permissionList.includes(key)),
29
- });
30
- const overridesToPermissionList = (overrides, currentPermissionList) => {
31
- const desired = {
32
- [GROUP_PERMISSION_KEY.sendMessage]: overrides.sendMessage,
33
- [GROUP_PERMISSION_KEY.pinMessage]: overrides.pinMessage,
34
- [GROUP_PERMISSION_KEY.viewMemberInformation]: overrides.viewMemberInformation,
35
- [GROUP_PERMISSION_KEY.addMember]: overrides.addMember,
36
- [GROUP_PERMISSION_KEY.removeMember]: overrides.removeMember,
37
- [GROUP_PERMISSION_KEY.updateGroupName]: overrides.updateGroupInfo,
38
- [GROUP_PERMISSION_KEY.updateGroupAvatar]: overrides.updateGroupInfo,
39
- [GROUP_PERMISSION_KEY.updateGroupDescription]: overrides.updateGroupInfo,
19
+ const SWITCH_PERMISSION_KEYS = {
20
+ sendMessage: [GROUP_PERMISSION_KEY.sendMessage],
21
+ pinMessage: [GROUP_PERMISSION_KEY.pinMessage],
22
+ viewMemberInformation: [GROUP_PERMISSION_KEY.viewMemberInformation],
23
+ addMember: [GROUP_PERMISSION_KEY.addMember],
24
+ removeMember: [GROUP_PERMISSION_KEY.removeMember],
25
+ updateGroupInfo: UPDATE_GROUP_INFO_KEYS,
26
+ };
27
+ const SWITCHES = Object.keys(SWITCH_PERMISSION_KEYS);
28
+ // A switch reads on only when every given permission list grants all of its keys.
29
+ const commonOverrides = (permissionLists) => {
30
+ const grants = (name) => permissionLists.length > 0 &&
31
+ permissionLists.every((list) => SWITCH_PERMISSION_KEYS[name].every((key) => list.includes(key)));
32
+ return {
33
+ sendMessage: grants("sendMessage"),
34
+ pinMessage: grants("pinMessage"),
35
+ viewMemberInformation: grants("viewMemberInformation"),
36
+ addMember: grants("addMember"),
37
+ removeMember: grants("removeMember"),
38
+ updateGroupInfo: grants("updateGroupInfo"),
40
39
  };
41
- const managedKeys = new Set(Object.keys(desired));
42
- const untouched = currentPermissionList.filter((permission) => !managedKeys.has(permission));
43
- const enabled = Object.entries(desired)
44
- .filter(([, isEnabled]) => isEnabled)
45
- .map(([permission]) => permission);
46
- return [...untouched, ...enabled];
47
40
  };
48
- // "Configure Admin Permissions" (DROPPII-30248 follow-up). When `member` is
49
- // passed (from the member list's per-row menu), it patches that one
50
- // member's permission list via setGroupMemberInfo. When used group-wide (no
51
- // `member`, e.g. from GroupThreadInfo's group settings), "Lưu" applies the
52
- // same permission set to every current Admin in the group (DROPPII-30529/
53
- // 30531 fix) — there is no separate BE endpoint for a role-wide default, so
54
- // this fans out the existing per-member call to each current Admin instead
55
- // of only writing to a local override store.
41
+ // Rewrites only the switches that changed; every other key in the list stays as is.
42
+ const applySwitchChanges = (permissionList, changes) => Object.entries(changes).reduce((list, [name, enabled]) => {
43
+ const keys = SWITCH_PERMISSION_KEYS[name];
44
+ const without = list.filter((permission) => !keys.includes(permission));
45
+ return enabled ? [...without, ...keys] : without;
46
+ }, permissionList);
47
+ const isSamePermissionSet = (a, b) => a.length === b.length && a.every((permission) => b.includes(permission));
48
+ // "Configure Admin Permissions". With `member` (a member row's … menu) it edits
49
+ // that one Admin. Without it (the group info panel) it edits every current
50
+ // Admin at once: switches start from what the Admins already share, and "Lưu"
51
+ // writes only the switches the user flipped, so each Admin keeps the rest.
56
52
  const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member, onMemberPermissionsSaved, }) => {
57
53
  const { t } = useTranslation();
58
- const groupPermissions = useGroupPermission(groupID);
59
54
  const { members: groupMembers } = useGroupMembers(member ? undefined : groupID);
60
55
  const { mutateAsync: setMemberPermissions } = useSetGroupMemberPermissions();
61
56
  const [isSaving, setIsSaving] = useState(false);
62
- const isGroupInfoEditable = groupPermissions.updateGroupName &&
63
- groupPermissions.updateGroupAvatar &&
64
- groupPermissions.updateGroupDescription;
65
- const initialOverrides = () => member
66
- ? permissionListToOverrides(member.permissions)
67
- : {
68
- sendMessage: groupPermissions.sendMessage,
69
- pinMessage: groupPermissions.pinMessage,
70
- viewMemberInformation: groupPermissions.viewMemberInformation,
71
- addMember: groupPermissions.addMember,
72
- removeMember: groupPermissions.removeMember,
73
- updateGroupInfo: isGroupInfoEditable,
74
- };
75
- const [pending, setPending] = useState(initialOverrides);
57
+ const [edits, setEdits] = useState({});
76
58
  useEffect(() => {
77
- if (!open)
78
- return;
79
- setPending(initialOverrides());
80
- // eslint-disable-next-line react-hooks/exhaustive-deps
59
+ if (open)
60
+ setEdits({});
81
61
  }, [open, member === null || member === void 0 ? void 0 : member.userID]);
62
+ const admins = groupMembers.filter((groupMember) => groupMember.roleLevel === GroupMemberRole.Admin);
82
63
  const baseline = member
83
- ? permissionListToOverrides(member.permissions)
84
- : {
85
- sendMessage: groupPermissions.sendMessage,
86
- pinMessage: groupPermissions.pinMessage,
87
- viewMemberInformation: groupPermissions.viewMemberInformation,
88
- addMember: groupPermissions.addMember,
89
- removeMember: groupPermissions.removeMember,
90
- updateGroupInfo: isGroupInfoEditable,
91
- };
92
- const hasChanges = pending.sendMessage !== baseline.sendMessage ||
93
- pending.pinMessage !== baseline.pinMessage ||
94
- pending.viewMemberInformation !== baseline.viewMemberInformation ||
95
- pending.addMember !== baseline.addMember ||
96
- pending.removeMember !== baseline.removeMember ||
97
- pending.updateGroupInfo !== baseline.updateGroupInfo;
64
+ ? commonOverrides([member.permissions])
65
+ : commonOverrides(admins.map((admin) => { var _a; return (_a = admin.permissions) !== null && _a !== void 0 ? _a : []; }));
66
+ const pending = Object.assign(Object.assign({}, baseline), edits);
67
+ const changes = Object.fromEntries(SWITCHES.filter((name) => pending[name] !== baseline[name]).map((name) => [
68
+ name,
69
+ pending[name],
70
+ ]));
71
+ const hasChanges = Object.keys(changes).length > 0;
72
+ const setSwitch = (name, checked) => setEdits((prev) => (Object.assign(Object.assign({}, prev), { [name]: checked })));
98
73
  const handleSave = async () => {
99
74
  var _a, _b;
100
75
  if (!groupID)
@@ -102,7 +77,7 @@ const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member,
102
77
  setIsSaving(true);
103
78
  try {
104
79
  if (member) {
105
- const nextPermissions = overridesToPermissionList(pending, member.permissions);
80
+ const nextPermissions = applySwitchChanges(member.permissions, changes);
106
81
  await setMemberPermissions({
107
82
  groupID,
108
83
  userID: member.userID,
@@ -111,13 +86,16 @@ const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member,
111
86
  onMemberPermissionsSaved === null || onMemberPermissionsSaved === void 0 ? void 0 : onMemberPermissionsSaved(member.userID, nextPermissions);
112
87
  }
113
88
  else {
114
- const admins = groupMembers.filter((groupMember) => groupMember.roleLevel === GroupMemberRole.Admin);
115
89
  await Promise.all(admins.map((admin) => {
116
90
  var _a;
91
+ const current = (_a = admin.permissions) !== null && _a !== void 0 ? _a : [];
92
+ const nextPermissions = applySwitchChanges(current, changes);
93
+ if (isSamePermissionSet(current, nextPermissions))
94
+ return undefined;
117
95
  return setMemberPermissions({
118
96
  groupID,
119
97
  userID: admin.userID,
120
- permissions: overridesToPermissionList(pending, (_a = admin.permissions) !== null && _a !== void 0 ? _a : []),
98
+ permissions: nextPermissions,
121
99
  });
122
100
  }));
123
101
  }
@@ -131,7 +109,7 @@ const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member,
131
109
  setIsSaving(false);
132
110
  }
133
111
  };
134
- const rows = (_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_pin_unpin_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-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_remove_member") }), _jsx(Switch, { checked: pending.removeMember, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { removeMember: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_update_group_info") }), _jsx(Switch, { checked: pending.updateGroupInfo, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { updateGroupInfo: checked }))) })] })] }) }));
112
+ const rows = (_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) => setSwitch("sendMessage", checked) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_pin_unpin_message") }), _jsx(Switch, { checked: pending.pinMessage, onChange: (checked) => setSwitch("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) => setSwitch("viewMemberInformation", 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) => setSwitch("addMember", checked) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_remove_member") }), _jsx(Switch, { checked: pending.removeMember, onChange: (checked) => setSwitch("removeMember", checked) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_update_group_info") }), _jsx(Switch, { checked: pending.updateGroupInfo, onChange: (checked) => setSwitch("updateGroupInfo", checked) })] })] }) }));
135
113
  if (inline) {
136
114
  if (!open)
137
115
  return null;
@@ -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,cAAc,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAQ/C,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;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,0DAKpB,kBAAkB,4CA6OpB,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,cAAc,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAgB/C,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;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,0DAKpB,kBAAkB,4CA+QpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -16,17 +16,30 @@ import { isGroupSession, isGroupConversation } from "../../utils/imCommon";
16
16
  import { useGroupPermission } from "../../hooks/group/useGroupPermission";
17
17
  import GroupCompositeAvatar from "../../components/group/GroupCompositeAvatar";
18
18
  import GroupMembersDrawer from "./GroupMembersDrawer";
19
+ import { useGroupMembers } from "../../hooks/group/useGroupMembers";
20
+ import { useGetUserSideInfo } from "../../hooks/session/useGetUserSideInfo";
21
+ import { PeerType } from "../../types/conversation";
22
+ import { isSupportSessionAgentView, resolveBotSessionOwnerIdentity, resolveSupportSessionOwnerId, } from "../../utils/conversation";
19
23
  const MessageHeader = ({ onClose, currentSession, isJoined, onOpenThreadInfo, }) => {
20
- var _a, _b;
24
+ var _a, _b, _c, _d, _e;
21
25
  const { t } = useTranslation();
22
26
  const isCx = useAuthStore((state) => state.isCx);
23
27
  const isCrm = useAuthStore((state) => state.isCrm);
28
+ const selfUserID = useAuthStore((state) => state.userID);
24
29
  const conversationData = useConversationStore((state) => state.conversationData);
25
30
  const groupID = conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID;
26
31
  const currentGroupInfo = useConversationStore((state) => groupID ? state.currentGroupInfo.get(groupID) : undefined);
27
32
  const { mutate: updateSession } = useUpdateSession();
28
33
  const permissions = useGroupPermission(conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID);
29
34
  const { avatar, displayName } = useConversationDisplayData(conversationData);
35
+ // Same chat-service user record as the desk list's session owner.
36
+ const botSessionOwnerId = (conversationData === null || conversationData === void 0 ? void 0 : conversationData.peerType) === PeerType.BOT &&
37
+ isSupportSessionAgentView(conversationData, selfUserID)
38
+ ? resolveSupportSessionOwnerId(conversationData)
39
+ : "";
40
+ const { data: botSessionOwner } = useGetUserSideInfo((_a = conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID) !== null && _a !== void 0 ? _a : "", botSessionOwnerId);
41
+ const ownerIdentity = resolveBotSessionOwnerIdentity(conversationData, botSessionOwner, selfUserID);
42
+ const headerName = (_b = ownerIdentity === null || ownerIdentity === void 0 ? void 0 : ownerIdentity.displayName) !== null && _b !== void 0 ? _b : displayName;
30
43
  const shouldShowMemberCount = isGroupSession(conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationType);
31
44
  // A "real" group (peerType GROUP) vs a CX support thread that happens to
32
45
  // use a Group/WorkingGroup session under the hood (e.g. a multi-agent
@@ -38,6 +51,13 @@ const MessageHeader = ({ onClose, currentSession, isJoined, onOpenThreadInfo, })
38
51
  // may view the member list, so it's bypassed there. The member list
39
52
  // button itself still shows for both (shouldShowMemberCount).
40
53
  const isRealGroup = isGroupConversation(conversationData !== null && conversationData !== void 0 ? conversationData : undefined);
54
+ // Group info is only fetched for peerType GROUP; other threads count the
55
+ // same member list the drawer shows, so the two never disagree.
56
+ const usesGroupInfoCount = (conversationData === null || conversationData === void 0 ? void 0 : conversationData.peerType) === PeerType.GROUP;
57
+ const { members: threadMembers } = useGroupMembers(shouldShowMemberCount && !usesGroupInfoCount ? groupID : undefined);
58
+ const memberCount = usesGroupInfoCount
59
+ ? ((_c = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount) !== null && _c !== void 0 ? _c : 0)
60
+ : threadMembers.length;
41
61
  const canViewMemberList = shouldShowMemberCount &&
42
62
  isJoined === true &&
43
63
  isCrm &&
@@ -145,6 +165,6 @@ const MessageHeader = ({ onClose, currentSession, isJoined, onOpenThreadInfo, })
145
165
  setCurrentSessionStatus(currentSession.status);
146
166
  }
147
167
  }, [currentSession]);
148
- return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", "data-cp-name": "MessageHeader", children: [shouldShowMemberCount ? (_jsx(GroupCompositeAvatar, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID, faceURL: avatar, ownerUserID: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.ownerUserID, groupName: displayName, size: 40, className: "min-w-10 min-h-10" })) : (_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 && !isRealGroup && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && !isRealGroup && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), canViewMemberList && (_jsx(GroupMembersDrawer, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID, conversationId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID, currentSession: currentSession })), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-[var(--dc-color-header-icon)] w-8 h-8 p-0", onClick: onOpenThreadInfo, children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-[var(--dc-color-header-icon)] w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
168
+ return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", "data-cp-name": "MessageHeader", children: [ownerIdentity ? (_jsx(Avatar, { src: ownerIdentity.avatarUrl, size: "large", className: "min-w-10 min-h-10", children: ((_d = headerName === null || headerName === void 0 ? void 0 : headerName.charAt) === null || _d === void 0 ? void 0 : _d.call(headerName, 0)) || "A" })) : shouldShowMemberCount ? (_jsx(GroupCompositeAvatar, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID, faceURL: avatar, ownerUserID: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.ownerUserID, groupName: displayName, size: 40, className: "min-w-10 min-h-10" })) : (_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_e = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _e === void 0 ? void 0 : _e.call(displayName, 0)) || "A" })), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: headerName || "" }), shouldShowMemberCount && (_jsx("p", { className: "text-xs text-gray-500 truncate", children: t("member_count", { count: memberCount }) }))] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && !isRealGroup && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && !isRealGroup && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), canViewMemberList && (_jsx(GroupMembersDrawer, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID, conversationId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID, currentSession: currentSession })), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-[var(--dc-color-header-icon)] w-8 h-8 p-0", onClick: onOpenThreadInfo, children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-[var(--dc-color-header-icon)] w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
149
169
  };
150
170
  export default MessageHeader;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AAoCA,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;IACpC,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CAmZ3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AAoCA,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;IACpC,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CAsZ3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -206,7 +206,8 @@ const MessageList = (props) => {
206
206
  if (!conversationData) {
207
207
  return (_jsx("div", { className: "flex flex-1 items-center justify-center h-full", children: connectStatus !== ConnectStatus.Connected ? (_jsx(Spin, {})) : (_jsx(Empty, { description: t("no_conversation_data") })) }));
208
208
  }
209
- return (_jsxs("div", { className: "flex flex-col flex-1 relative h-full min-w-0 overflow-hidden bg-white", "data-cp-name": "MessageList", children: [_jsx(MessageHeader, { onClose: onClose, currentSession: latestConversationSession, isJoined: isJoined, onOpenThreadInfo: onOpenThreadInfo }), showPinnedMessageBar && (_jsx(PinnedMessageBar, { genericSubtitle: true, canUnpin: canPinMessage })), _jsxs("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [!loadState.initLoading && showJumpButton && (_jsx(UnreadMessageJumpButton, { className: "absolute right-0 top-2 z-10", onClick: handleJumpToFirstUnread })), _jsx(MessageInfiniteScroll, { scrollRef: scrollRef, scrollableTargetId: "scrollableMessagesDiv", loadState: loadState, moreOldLoading: moreOldLoading, onLoadMoreOld: loadMoreOldMessage, onScroll: handleInfiniteScroll, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array, isGroupChat: isGroupChat, contextMenuOpen: openMenuId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenMenuId(open ? message.clientMsgID : null), onRevokeMessage: handleOpenRevoke, onQuoteMessage: setQuotedMessage, onPressQuoteMessage: onPressQuoteMessage, onPinMessage: canPinMessage ? handlePinMessage : undefined, onUnpinMessage: canPinMessage ? handleUnpinMessage : undefined, timeRevealed: revealedTimeMsgId === message.clientMsgID, onToggleTimeReveal: handleToggleTimeReveal, onCopyMessageLink: handleCopyMessageLink, showUnreadDivider: message.clientMsgID === unreadDividerMessageId, onUnreadDividerSeen: markDividerSeen }, message.clientMsgID))) })] }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), (Boolean(rawGroupId) && isCheckingMembership) || !isGroupStateFresh ? (_jsx("div", { className: "border-t bg-white py-4 flex items-center justify-center", children: _jsx(Spin, {}) })) : (latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.status) === SessionStatus.UNASSIGNED ? (_jsx(UnassignedSessionFooter, { sessionId: latestConversationSession.id, teamId: latestConversationSession.teamId })) : !isConfirmedGroup && shouldRestrictToLastSession ? (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", "data-cp-name": "JoinGroupRequired", children: [_jsx("p", { className: "text-sm text-gray-500", children: t("join_group_required") }), _jsx(Button, { type: "primary", onClick: joinGroup, loading: isJoining, children: t("join_group") })] })) : isViewOnlyMember ? (
209
+ return (_jsxs("div", { className: "flex flex-col flex-1 relative h-full min-w-0 overflow-hidden bg-white", "data-cp-name": "MessageList", children: [_jsx(MessageHeader, { onClose: onClose, currentSession: latestConversationSession, isJoined: isJoined, onOpenThreadInfo: onOpenThreadInfo }), showPinnedMessageBar && (_jsx(PinnedMessageBar, { genericSubtitle: true, canUnpin: canPinMessage })), _jsxs("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [!loadState.initLoading && showJumpButton && (_jsx(UnreadMessageJumpButton, { className: "absolute right-0 top-2 z-10", onClick: handleJumpToFirstUnread })), _jsx(MessageInfiniteScroll, { scrollRef: scrollRef, scrollableTargetId: "scrollableMessagesDiv", loadState: loadState, moreOldLoading: moreOldLoading, onLoadMoreOld: loadMoreOldMessage, onScroll: handleInfiniteScroll, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array, isGroupChat: isGroupChat, contextMenuOpen: openMenuId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenMenuId(open ? message.clientMsgID : null), onRevokeMessage: handleOpenRevoke, onQuoteMessage: setQuotedMessage, onPressQuoteMessage: onPressQuoteMessage, onPinMessage: canPinMessage ? handlePinMessage : undefined, onUnpinMessage: canPinMessage ? handleUnpinMessage : undefined, timeRevealed: revealedTimeMsgId === message.clientMsgID, onToggleTimeReveal: handleToggleTimeReveal, onCopyMessageLink: handleCopyMessageLink, showUnreadDivider: !!unreadDividerMessageId &&
210
+ message.clientMsgID === unreadDividerMessageId, onUnreadDividerSeen: markDividerSeen }, message.clientMsgID))) })] }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), (Boolean(rawGroupId) && isCheckingMembership) || !isGroupStateFresh ? (_jsx("div", { className: "border-t bg-white py-4 flex items-center justify-center", children: _jsx(Spin, {}) })) : (latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.status) === SessionStatus.UNASSIGNED ? (_jsx(UnassignedSessionFooter, { sessionId: latestConversationSession.id, teamId: latestConversationSession.teamId })) : !isConfirmedGroup && shouldRestrictToLastSession ? (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", "data-cp-name": "JoinGroupRequired", children: [_jsx("p", { className: "text-sm text-gray-500", children: t("join_group_required") }), _jsx(Button, { type: "primary", onClick: joinGroup, loading: isJoining, children: t("join_group") })] })) : isViewOnlyMember ? (
210
211
  // Brief fallback while isJoined catches up after the kick event.
211
212
  _jsx(MessageFooter, { currentSession: latestConversationSession, openCreateCannedModal: openCreateCannedModal })) : !canSendMessage ? (_jsx("div", { className: "border-t bg-[#f5f5f5] py-3 flex items-center justify-center", children: _jsx("p", { className: "text-sm text-gray-500", children: t(isRestrictedByGroupMute
212
213
  ? "send_message_disabled_group_mute"
@@ -76,6 +76,6 @@ export const useConversationDisplayData = (conversation) => {
76
76
  : ""}`
77
77
  : (conversation === null || conversation === void 0 ? void 0 : conversation.showName) || "",
78
78
  };
79
- }, [conversation, userInfo]);
79
+ }, [conversation, user === null || user === void 0 ? void 0 : user.userID, userInfo === null || userInfo === void 0 ? void 0 : userInfo.ex, userInfo === null || userInfo === void 0 ? void 0 : userInfo.faceURL, userInfo === null || userInfo === void 0 ? void 0 : userInfo.nickname]);
80
80
  return Object.assign({}, conversationDisplayData);
81
81
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useSessionLatestPreview.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useSessionLatestPreview.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAyB,MAAM,8BAA8B,CAAC;AASvF,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAKD,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAkBD,eAAO,MAAM,uBAAuB,GAClC,UAAU,yBAAyB,EAAE,+BAoEtC,CAAC"}
1
+ {"version":3,"file":"useSessionLatestPreview.d.ts","sourceRoot":"","sources":["../../../src/hooks/session/useSessionLatestPreview.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAyB,MAAM,8BAA8B,CAAC;AASvF,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAKD,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAkBD,eAAO,MAAM,uBAAuB,GAClC,UAAU,yBAAyB,EAAE,+BAyEtC,CAAC"}
@@ -60,7 +60,10 @@ export const useSessionLatestPreview = (sessions) => {
60
60
  var _a, _b, _c;
61
61
  const latestMessage = (_a = results[index]) === null || _a === void 0 ? void 0 : _a.data;
62
62
  const latestMsgSendTime = ((_b = session.conversation) === null || _b === void 0 ? void 0 : _b.latestMsgSendTime) || 0;
63
- if (latestMessage && latestMessage.sendTime > latestMsgSendTime) {
63
+ // A seq with no stored message comes back as an id-less placeholder
64
+ // carrying an older message's sendTime — never a preview candidate.
65
+ if ((latestMessage === null || latestMessage === void 0 ? void 0 : latestMessage.clientMsgID) &&
66
+ latestMessage.sendTime > latestMsgSendTime) {
64
67
  map.set(session.conversationId, {
65
68
  latestMsg: JSON.stringify(latestMessage),
66
69
  latestMsgSendTime: latestMessage.sendTime,
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,WAAW,EACX,WAAW,EACZ,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAqB,eAAe,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAShD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,eAAO,MAAM,iBAAiB,GAC5B,aAAa,MAAM,EACnB,WAAW,MAAM,KAChB,MAAmE,CAAC;AAEvE,eAAO,MAAM,mBAAmB,GAAI,CAAC,EAAE,UAAU,MAAM,KAAG,OAAO,CAAC,CAAC,CAQlE,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,eAAe,GAAG,SAQhE,CAAC;AA+BF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAapD;AAED,UAAU,sBAAsB;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,GAC1B,OAAO,MAAM,EACb,UAAS,sBAA2B,WAoBrC,CAAC;AAEF,eAAO,MAAM,iCAAiC,GAC5C,aAAa,WAAW,EACxB,YAAY,MAAM,EAClB,IAAI,SAAS,EACb,YAAY;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EACpD,aAAa;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,WAyC1D,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,YAAY,MAAM,KAAG,OAS5D,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,eAAe,gBAAgB,EAAE,EACjC,OAAO,OAAO,KACb,gBAAgB,EAMlB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,EACjB,gBAAgB,MAAM,EACtB,IAAI,SAAS,EACb,eAAe,yBAAyB,EACxC,UAAU;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAE,WA+G5C,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,kBAAc,WA2Cf,CAAC;AAEF,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAqBR;AAMD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAiBhE;AAED,eAAO,MAAM,QAAQ,QAAiD,CAAC;AAEvE,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAwC3D;AAED,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAOrD,CAAC;AAKF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,OACf,CAAC;AAEnC,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAO9B,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoEjD"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,WAAW,EACX,WAAW,EACZ,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAqB,eAAe,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAShD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,eAAO,MAAM,iBAAiB,GAC5B,aAAa,MAAM,EACnB,WAAW,MAAM,KAChB,MAAmE,CAAC;AAEvE,eAAO,MAAM,mBAAmB,GAAI,CAAC,EAAE,UAAU,MAAM,KAAG,OAAO,CAAC,CAAC,CAQlE,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,eAAe,GAAG,SAQhE,CAAC;AA+BF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAapD;AAED,UAAU,sBAAsB;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,GAC1B,OAAO,MAAM,EACb,UAAS,sBAA2B,WAoBrC,CAAC;AAEF,eAAO,MAAM,iCAAiC,GAC5C,aAAa,WAAW,EACxB,YAAY,MAAM,EAClB,IAAI,SAAS,EACb,YAAY;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EACpD,aAAa;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,WAyC1D,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,YAAY,MAAM,KAAG,OAS5D,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,eAAe,gBAAgB,EAAE,EACjC,OAAO,OAAO,KACb,gBAAgB,EAMlB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,EACjB,gBAAgB,MAAM,EACtB,IAAI,SAAS,EACb,eAAe,yBAAyB,EACxC,UAAU;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAE,WAkH5C,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,kBAAc,WA2Cf,CAAC;AAEF,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAqBR;AAMD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAiBhE;AAED,eAAO,MAAM,QAAQ,QAAiD,CAAC;AAEvE,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAwC3D;AAED,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAOrD,CAAC;AAKF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,OACf,CAAC;AAEnC,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAO9B,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoEjD"}
@@ -144,6 +144,9 @@ export const parseLatestMessage = (latestMsg, currentUserId, t, conversation, op
144
144
  try {
145
145
  const msgData = JSON.parse(latestMsg);
146
146
  const contentType = msgData === null || msgData === void 0 ? void 0 : msgData.contentType;
147
+ // Server placeholder for a seq with no stored message — nothing to show.
148
+ if (!contentType)
149
+ return "";
147
150
  const sender = includeSenderPrefix
148
151
  ? getSenderLabelForLatestPreview(msgData, currentUserId, t, conversation)
149
152
  : undefined;
@@ -14,6 +14,21 @@ export declare const resolveSupportSessionOwnerId: (item?: SupportSessionSource)
14
14
  * PDP CS agent). The owner — BIZ/Mall/Obefe customer — keeps the bot view.
15
15
  */
16
16
  export declare const isSupportSessionAgentView: (item: SupportSessionSource | undefined, viewerUserID?: string) => boolean;
17
+ type SessionOwnerProfile = {
18
+ fullName?: string | null;
19
+ username?: string | null;
20
+ avatar?: string | null;
21
+ } | null;
22
+ /**
23
+ * An agent sees a bot thread as its session owner, "fullName (username)";
24
+ * the owner themself, or a missing profile, keeps the bot view (null).
25
+ */
26
+ export declare const resolveBotSessionOwnerIdentity: (item: (NonNullable<SupportSessionSource> & {
27
+ peerType?: string;
28
+ }) | null | undefined, owner: SessionOwnerProfile | undefined, viewerUserID?: string) => {
29
+ displayName: string;
30
+ avatarUrl?: string;
31
+ } | null;
17
32
  export declare const isBotPeer: (item: ConversationItem) => boolean;
18
33
  export declare const isCustomerPeer: (item: ConversationItem) => boolean;
19
34
  export declare const isGroupChat: (item: ConversationItem) => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/utils/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAe,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAW9B,eAAO,MAAM,sBAAsB,GACjC,IAAI,MAAM,GAAG,SAAS,KACrB,iBAcF,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,MAAM,gBAAgB,KACrB,YAA4D,CAAC;AAEhE,eAAO,MAAM,wBAAwB,GAAI,MAAM,gBAAgB,KAAG,MAOjE,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,IAAI,CAAC;AAIT,eAAO,MAAM,4BAA4B,GACvC,OAAO,oBAAoB,KAC1B,MAiBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACpC,MAAM,oBAAoB,GAAG,SAAS,EACtC,eAAe,MAAM,KACpB,OAGF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,MAAM,gBAAgB,YAChB,CAAC;AAEjC,eAAO,MAAM,cAAc,GAAI,MAAM,gBAAgB,YAChB,CAAC;AAEtC,eAAO,MAAM,WAAW,GAAI,MAAM,gBAAgB,YAChB,CAAC;AAEnC,eAAO,MAAM,8BAA8B,GACzC,MAAM,gBAAgB,EACtB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,KACzB,MAKF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,MAAM,gBAAgB,KACrB,MAAM,GAAG,IAGX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,UAAU,QAAQ,EAClB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,KACzB,MAIF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,UAAU,QAAQ,8EAIvD,CAAC;AAKF;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,GAAI,iBAAiB,MAAM,WAG5D,CAAC;AAET;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,GAC1C,iBAAiB,MAAM,EACvB,aAAa,MAAM,KAClB,MAYF,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/utils/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAe,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAW9B,eAAO,MAAM,sBAAsB,GACjC,IAAI,MAAM,GAAG,SAAS,KACrB,iBAcF,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,MAAM,gBAAgB,KACrB,YAA4D,CAAC;AAEhE,eAAO,MAAM,wBAAwB,GAAI,MAAM,gBAAgB,KAAG,MAOjE,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,IAAI,CAAC;AAIT,eAAO,MAAM,4BAA4B,GACvC,OAAO,oBAAoB,KAC1B,MAiBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACpC,MAAM,oBAAoB,GAAG,SAAS,EACtC,eAAe,MAAM,KACpB,OAGF,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GAAG,IAAI,CAAC;AAET;;;GAGG;AACH,eAAO,MAAM,8BAA8B,GACzC,MAAM,CAAC,WAAW,CAAC,oBAAoB,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EACpF,OAAO,mBAAmB,GAAG,SAAS,EACtC,eAAe,MAAM,KACpB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAShD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,MAAM,gBAAgB,YAChB,CAAC;AAEjC,eAAO,MAAM,cAAc,GAAI,MAAM,gBAAgB,YAChB,CAAC;AAEtC,eAAO,MAAM,WAAW,GAAI,MAAM,gBAAgB,YAChB,CAAC;AAEnC,eAAO,MAAM,8BAA8B,GACzC,MAAM,gBAAgB,EACtB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,KACzB,MAKF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,MAAM,gBAAgB,KACrB,MAAM,GAAG,IAGX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,UAAU,QAAQ,EAClB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,KACzB,MAIF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,UAAU,QAAQ,8EAIvD,CAAC;AAKF;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,GAAI,iBAAiB,MAAM,WAG5D,CAAC;AAET;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,GAC1C,iBAAiB,MAAM,EACvB,aAAa,MAAM,KAClB,MAYF,CAAC"}
@@ -62,6 +62,23 @@ export const isSupportSessionAgentView = (item, viewerUserID) => {
62
62
  const ownerId = resolveSupportSessionOwnerId(item);
63
63
  return !!ownerId && !!viewerUserID && ownerId !== viewerUserID;
64
64
  };
65
+ /**
66
+ * An agent sees a bot thread as its session owner, "fullName (username)";
67
+ * the owner themself, or a missing profile, keeps the bot view (null).
68
+ */
69
+ export const resolveBotSessionOwnerIdentity = (item, owner, viewerUserID) => {
70
+ var _a, _b, _c;
71
+ if ((item === null || item === void 0 ? void 0 : item.peerType) !== PeerType.BOT)
72
+ return null;
73
+ if (!isSupportSessionAgentView(item, viewerUserID))
74
+ return null;
75
+ const fullName = (_a = owner === null || owner === void 0 ? void 0 : owner.fullName) === null || _a === void 0 ? void 0 : _a.trim();
76
+ const username = (_b = owner === null || owner === void 0 ? void 0 : owner.username) === null || _b === void 0 ? void 0 : _b.trim();
77
+ if (!fullName && !username)
78
+ return null;
79
+ const displayName = fullName && username ? `${fullName} (${username})` : fullName || username;
80
+ return { displayName, avatarUrl: ((_c = owner === null || owner === void 0 ? void 0 : owner.avatar) === null || _c === void 0 ? void 0 : _c.trim()) || undefined };
81
+ };
65
82
  export const isBotPeer = (item) => item.peerType === PeerType.BOT;
66
83
  export const isCustomerPeer = (item) => item.peerType === PeerType.CUSTOMER;
67
84
  export const isGroupChat = (item) => item.peerType === PeerType.GROUP;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droppii-org/chat-sdk",
3
- "version": "0.6.44",
3
+ "version": "0.6.45",
4
4
  "description": "Droppii React Chat SDK",
5
5
  "repository": {
6
6
  "type": "git",