@droppii-org/chat-sdk 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/group/AddMemberModal.d.ts.map +1 -1
- package/dist/components/group/AddMemberModal.js +3 -2
- package/dist/components/group/GroupMemberPicker.d.ts.map +1 -1
- package/dist/components/group/GroupMemberPicker.js +3 -2
- package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
- package/dist/components/message/GroupMembersDrawer.js +7 -3
- package/dist/components/message/footer/index.d.ts.map +1 -1
- package/dist/components/message/footer/index.js +7 -1
- package/dist/hooks/group/useEligibleAccounts.d.ts +1 -0
- package/dist/hooks/group/useEligibleAccounts.d.ts.map +1 -1
- package/dist/hooks/group/useEligibleAccounts.js +1 -0
- package/dist/hooks/group/useEligibleAccountsForGroup.d.ts.map +1 -1
- package/dist/hooks/group/useEligibleAccountsForGroup.js +1 -0
- package/dist/hooks/group/useGroupMembers.d.ts.map +1 -1
- package/dist/hooks/group/useGroupMembers.js +14 -0
- package/dist/utils/common.d.ts +1 -0
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +4 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddMemberModal.d.ts","sourceRoot":"","sources":["../../../src/components/group/AddMemberModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AddMemberModal.d.ts","sourceRoot":"","sources":["../../../src/components/group/AddMemberModal.tsx"],"names":[],"mappings":"AAaA,UAAU,mBAAmB;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,cAAc,GAAI,6BAIrB,mBAAmB,4CA4LrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -8,6 +8,7 @@ import { useTranslation } from "react-i18next";
|
|
|
8
8
|
import { Icon } from "../../components/icon";
|
|
9
9
|
import { useEligibleAccountsForGroup } from "../../hooks/group/useEligibleAccountsForGroup";
|
|
10
10
|
import { useAddGroupMember } from "../../hooks/group/useAddGroupMember";
|
|
11
|
+
import { formatMemberLabel } from "../../utils/common";
|
|
11
12
|
const AddMemberModal = ({ open, groupID, onClose, }) => {
|
|
12
13
|
const { t } = useTranslation("conversation-inbox");
|
|
13
14
|
const { t: tCommon } = useTranslation();
|
|
@@ -60,9 +61,9 @@ const AddMemberModal = ({ open, groupID, onClose, }) => {
|
|
|
60
61
|
message.error(errorMessage);
|
|
61
62
|
}
|
|
62
63
|
};
|
|
63
|
-
return (_jsx(Modal, { centered: true, open: open, onCancel: handleClose, footer: null, title: t("add_member.title"), getContainer: false, forceRender: true, children: _jsxs("div", { className: "flex flex-col gap-3 pt-2", children: [_jsx(Input, { value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("create_group.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }) }), _jsxs("div", { className: "flex items-center justify-between px-1", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("create_group.selected_count", { count: selectedMembers.length }) }), selectedMembers.length > 0 && (_jsx("button", { type: "button", className: "text-sm text-primary-400 hover:text-primary-500 hover:underline", onClick: handleClearAll, children: t("create_group.clear_all") }))] }), selectedMembers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2", children: selectedMembers.map((member) => (_jsxs("span", { className: "flex items-center gap-1.5 rounded-full bg-gray-100 pl-1 pr-2 py-1", children: [_jsx(Avatar, { src: member.avatar, size: 20, className: "shrink-0", children: member.displayName.charAt(0) || "A" }), _jsx("span", { className: "max-w-[120px] truncate text-sm text-gray-900", children: member.displayName }), _jsx(Icon, { icon: "close-b", size: 12, className: "shrink-0 cursor-pointer text-gray-400", onClick: () => handleRemoveMember(member.userID) })] }, member.userID))) })), _jsx("div", { className: "max-h-72 overflow-y-auto", onScroll: handleListScroll, children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("create_group.no_member_found") })) : (_jsxs(_Fragment, { children: [accounts.map((account) => {
|
|
64
|
+
return (_jsx(Modal, { centered: true, open: open, onCancel: handleClose, footer: null, title: t("add_member.title"), getContainer: false, forceRender: true, children: _jsxs("div", { className: "flex flex-col gap-3 pt-2", children: [_jsx(Input, { value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("create_group.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }) }), _jsxs("div", { className: "flex items-center justify-between px-1", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("create_group.selected_count", { count: selectedMembers.length }) }), selectedMembers.length > 0 && (_jsx("button", { type: "button", className: "text-sm text-primary-400 hover:text-primary-500 hover:underline", onClick: handleClearAll, children: t("create_group.clear_all") }))] }), selectedMembers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2", children: selectedMembers.map((member) => (_jsxs("span", { className: "flex items-center gap-1.5 rounded-full bg-gray-100 pl-1 pr-2 py-1", children: [_jsx(Avatar, { src: member.avatar, size: 20, className: "shrink-0", children: member.displayName.charAt(0) || "A" }), _jsx("span", { className: "max-w-[120px] truncate text-sm text-gray-900", children: formatMemberLabel(member.displayName, member.username) }), _jsx(Icon, { icon: "close-b", size: 12, className: "shrink-0 cursor-pointer text-gray-400", onClick: () => handleRemoveMember(member.userID) })] }, member.userID))) })), _jsx("div", { className: "max-h-72 overflow-y-auto", onScroll: handleListScroll, children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("create_group.no_member_found") })) : (_jsxs(_Fragment, { children: [accounts.map((account) => {
|
|
64
65
|
const isSelected = selectedIds.has(account.userID);
|
|
65
|
-
return (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 rounded-lg px-3 py-3 transition-colors duration-150 hover:bg-[#f5f5f5]", onClick: () => toggleMember(account), children: [_jsx(Avatar, { src: account.avatar, size: 40, className: "shrink-0", children: account.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: account.displayName }), _jsx("span", { className: clsx("flex h-4 w-4 shrink-0 items-center justify-center rounded border", isSelected
|
|
66
|
+
return (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 rounded-lg px-3 py-3 transition-colors duration-150 hover:bg-[#f5f5f5]", onClick: () => toggleMember(account), children: [_jsx(Avatar, { src: account.avatar, size: 40, className: "shrink-0", children: account.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: formatMemberLabel(account.displayName, account.username) }), _jsx("span", { className: clsx("flex h-4 w-4 shrink-0 items-center justify-center rounded border", isSelected
|
|
66
67
|
? "border-primary-400 bg-primary-400"
|
|
67
68
|
: "border-gray-300 bg-white"), children: isSelected && (_jsx(Icon, { icon: "check-b", size: 11, className: "text-white" })) })] }, account.userID));
|
|
68
69
|
}), isFetchingNextPage && (_jsx("div", { className: "flex items-center justify-center py-3", children: _jsx(Spin, { size: "small" }) }))] })) }), _jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [_jsx(Button, { onClick: handleClose, children: tCommon("cancel") }), _jsx(Button, { type: "primary", disabled: selectedMembers.length === 0, loading: isSubmitting, onClick: handleSubmit, children: t("add_member.confirm") })] })] }) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupMemberPicker.d.ts","sourceRoot":"","sources":["../../../src/components/group/GroupMemberPicker.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"GroupMemberPicker.d.ts","sourceRoot":"","sources":["../../../src/components/group/GroupMemberPicker.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAG7E,UAAU,sBAAsB;IAC9B,eAAe,EAAE,mBAAmB,EAAE,CAAC;IACvC,uBAAuB,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,iBAAiB,GAAI,+CAGxB,sBAAsB,4CAoJxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -7,6 +7,7 @@ import { useState } from "react";
|
|
|
7
7
|
import { useTranslation } from "react-i18next";
|
|
8
8
|
import { Icon } from "../../components/icon";
|
|
9
9
|
import { useEligibleAccounts } from "../../hooks/group/useEligibleAccounts";
|
|
10
|
+
import { formatMemberLabel } from "../../utils/common";
|
|
10
11
|
const GroupMemberPicker = ({ selectedMembers, onChangeSelectedMembers, }) => {
|
|
11
12
|
const { t } = useTranslation("conversation-inbox");
|
|
12
13
|
const [search, setSearch] = useState("");
|
|
@@ -36,9 +37,9 @@ const GroupMemberPicker = ({ selectedMembers, onChangeSelectedMembers, }) => {
|
|
|
36
37
|
};
|
|
37
38
|
return (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "flex flex-col gap-2 rounded-xl border border-gray-200 p-3", children: [_jsx(Input, { value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("create_group.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }) }), _jsx("div", { className: "max-h-64 overflow-y-auto", onScroll: handleListScroll, children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("create_group.no_member_found") })) : (_jsxs(_Fragment, { children: [accounts.map((account) => {
|
|
38
39
|
const isSelected = selectedIds.has(account.userID);
|
|
39
|
-
return (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 rounded-lg px-3 py-3 transition-colors duration-150 hover:bg-[#f5f5f5]", onClick: () => toggleMember(account), children: [_jsx(Avatar, { src: account.avatar, size: 40, className: "shrink-0", children: account.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: account.displayName }), _jsx("span", { className: clsx("flex h-4 w-4 shrink-0 items-center justify-center rounded border", isSelected
|
|
40
|
+
return (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 rounded-lg px-3 py-3 transition-colors duration-150 hover:bg-[#f5f5f5]", onClick: () => toggleMember(account), children: [_jsx(Avatar, { src: account.avatar, size: 40, className: "shrink-0", children: account.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: formatMemberLabel(account.displayName, account.username) }), _jsx("span", { className: clsx("flex h-4 w-4 shrink-0 items-center justify-center rounded border", isSelected
|
|
40
41
|
? "border-primary-400 bg-primary-400"
|
|
41
42
|
: "border-gray-300 bg-white"), children: isSelected && (_jsx(Icon, { icon: "check-b", size: 11, className: "text-white" })) })] }, account.userID));
|
|
42
|
-
}), isFetchingNextPage && (_jsx("div", { className: "flex items-center justify-center py-3", children: _jsx(Spin, { size: "small" }) }))] })) })] }), _jsxs("div", { className: "flex flex-col gap-2 rounded-xl border border-gray-200 p-3", children: [_jsxs("div", { className: "flex items-center justify-between px-1", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("create_group.selected_count", { count: selectedMembers.length }) }), selectedMembers.length > 0 && (_jsx("button", { type: "button", className: "text-sm text-primary-400 hover:text-primary-500 hover:underline", onClick: handleClearAll, children: t("create_group.clear_all") }))] }), _jsx("div", { className: "max-h-64 overflow-y-auto", children: selectedMembers.length === 0 ? (_jsxs("div", { className: "flex h-full min-h-[200px] flex-col items-center justify-center gap-2 text-center", children: [_jsx(Icon, { icon: "user-three-b", size: 28, className: "text-gray-300" }), _jsx("span", { className: "text-sm text-gray-400", children: t("create_group.no_member_selected") })] })) : (selectedMembers.map((member) => (_jsxs("div", { className: "flex items-center gap-3 rounded-lg px-3 py-3", children: [_jsx(Avatar, { src: member.avatar, size: 40, className: "shrink-0", children: member.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: member.displayName }), _jsx(Icon, { icon: "close-b", size: 14, className: "shrink-0 cursor-pointer text-gray-400", onClick: () => handleRemoveMember(member.userID) })] }, member.userID)))) })] })] }));
|
|
43
|
+
}), isFetchingNextPage && (_jsx("div", { className: "flex items-center justify-center py-3", children: _jsx(Spin, { size: "small" }) }))] })) })] }), _jsxs("div", { className: "flex flex-col gap-2 rounded-xl border border-gray-200 p-3", children: [_jsxs("div", { className: "flex items-center justify-between px-1", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("create_group.selected_count", { count: selectedMembers.length }) }), selectedMembers.length > 0 && (_jsx("button", { type: "button", className: "text-sm text-primary-400 hover:text-primary-500 hover:underline", onClick: handleClearAll, children: t("create_group.clear_all") }))] }), _jsx("div", { className: "max-h-64 overflow-y-auto", children: selectedMembers.length === 0 ? (_jsxs("div", { className: "flex h-full min-h-[200px] flex-col items-center justify-center gap-2 text-center", children: [_jsx(Icon, { icon: "user-three-b", size: 28, className: "text-gray-300" }), _jsx("span", { className: "text-sm text-gray-400", children: t("create_group.no_member_selected") })] })) : (selectedMembers.map((member) => (_jsxs("div", { className: "flex items-center gap-3 rounded-lg px-3 py-3", children: [_jsx(Avatar, { src: member.avatar, size: 40, className: "shrink-0", children: member.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: formatMemberLabel(member.displayName, member.username) }), _jsx(Icon, { icon: "close-b", size: 14, className: "shrink-0 cursor-pointer text-gray-400", onClick: () => handleRemoveMember(member.userID) })] }, member.userID)))) })] })] }));
|
|
43
44
|
};
|
|
44
45
|
export default GroupMemberPicker;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAiB/C,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0CD,QAAA,MAAM,kBAAkB,GAAI,wDAKzB,uBAAuB,
|
|
1
|
+
{"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAiB/C,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0CD,QAAA,MAAM,kBAAkB,GAAI,wDAKzB,uBAAuB,4CA6hBzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -189,9 +189,13 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
|
|
|
189
189
|
message.success(member.isAdmin
|
|
190
190
|
? t("remove_from_admin_success")
|
|
191
191
|
: t("assign_as_admin_success"));
|
|
192
|
-
//
|
|
193
|
-
// full refetch replaces every member's object
|
|
194
|
-
// which visibly re-renders/reorders rows that
|
|
192
|
+
// Optimistically patch the role in place instead of refetching the
|
|
193
|
+
// whole list — a full refetch replaces every member's object
|
|
194
|
+
// identity and re-sorts, which visibly re-renders/reorders rows that
|
|
195
|
+
// didn't actually change. permissions[] isn't patched here — BE
|
|
196
|
+
// resets it to the new role's defaults server-side, and useGroupMembers'
|
|
197
|
+
// OnGroupMemberInfoChanged listener picks up that real value shortly
|
|
198
|
+
// after, instead of this component predicting it.
|
|
195
199
|
patchMemberRole(member.userID, nextRoleLevel);
|
|
196
200
|
}
|
|
197
201
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAEL,wBAAwB,EAEzB,MAAM,cAAc,CAAC;AAStB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAEL,wBAAwB,EAEzB,MAAM,cAAc,CAAC;AAStB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAmB/C,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AASD,eAAO,MAAM,oBAAoB,mDAY/B,CAAC;AAEH,eAAO,MAAM,uBAAuB,gCAAyC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,GAAI,4CAG5B,kBAAkB,4CA4SpB,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -30,6 +30,7 @@ import ComposerEditor from "./ComposerEditor";
|
|
|
30
30
|
import SessionClosedModal from "./SessionClosedModal";
|
|
31
31
|
import { useCreateSession, useReopenSession, } from "../../../hooks/session/useReopenOrCreateSession";
|
|
32
32
|
import { emit } from "../../../utils/events";
|
|
33
|
+
import { isGroupConversation } from "../../../utils/imCommon";
|
|
33
34
|
const initialConfig = {
|
|
34
35
|
namespace: "ChatInput",
|
|
35
36
|
theme: editorTheme,
|
|
@@ -63,9 +64,14 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
63
64
|
const [activeCannedIndex, setActiveCannedIndex] = useState(0);
|
|
64
65
|
const [maxActiveCannedIndex, setMaxActiveCannedIndex] = useState(0);
|
|
65
66
|
const [isInternal, setIsInternal] = useState(false);
|
|
66
|
-
const canUseInternal = isCrm && accountType === AccountType.Staff;
|
|
67
67
|
const quotedMessage = useConversationStore((state) => state.quotedMessage);
|
|
68
68
|
const conversationData = useConversationStore((state) => state.conversationData);
|
|
69
|
+
// Internal notes are a CX-support concept (team-only remarks not sent to
|
|
70
|
+
// the customer) — meaningless inside a real member-managed group, where
|
|
71
|
+
// everyone in the thread already is the "team".
|
|
72
|
+
const canUseInternal = isCrm &&
|
|
73
|
+
accountType === AccountType.Staff &&
|
|
74
|
+
!isGroupConversation(conversationData !== null && conversationData !== void 0 ? conversationData : undefined);
|
|
69
75
|
const lockToInternal = Boolean((quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.clientMsgID) && (quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.isInternal));
|
|
70
76
|
const previewUrl = useMemo(() => {
|
|
71
77
|
const urls = extractLinkUrls(composerText);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEligibleAccounts.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useEligibleAccounts.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAKD,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,EAAE,iBAAc;;;;;;
|
|
1
|
+
{"version":3,"file":"useEligibleAccounts.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useEligibleAccounts.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAKD,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,EAAE,iBAAc;;;;;;CAyBjE,CAAC"}
|
|
@@ -11,6 +11,7 @@ export const useEligibleAccounts = (search, enabled = true) => {
|
|
|
11
11
|
const accounts = useMemo(() => candidates.map((candidate) => ({
|
|
12
12
|
userID: candidate.id,
|
|
13
13
|
displayName: candidate.fullName,
|
|
14
|
+
username: candidate.username,
|
|
14
15
|
avatar: candidate.avatar,
|
|
15
16
|
})), [candidates]);
|
|
16
17
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEligibleAccountsForGroup.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useEligibleAccountsForGroup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAIjE,eAAO,MAAM,2BAA2B,GACtC,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,iBAAc;;;;;;
|
|
1
|
+
{"version":3,"file":"useEligibleAccountsForGroup.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useEligibleAccountsForGroup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAIjE,eAAO,MAAM,2BAA2B,GACtC,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,iBAAc;;;;;;CA2Bf,CAAC"}
|
|
@@ -11,6 +11,7 @@ export const useEligibleAccountsForGroup = (search, groupID, enabled = true) =>
|
|
|
11
11
|
const accounts = useMemo(() => candidates.map((candidate) => ({
|
|
12
12
|
userID: candidate.id,
|
|
13
13
|
displayName: candidate.fullName,
|
|
14
|
+
username: candidate.username,
|
|
14
15
|
avatar: candidate.avatar,
|
|
15
16
|
})), [candidates]);
|
|
16
17
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGroupMembers.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useGroupMembers.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,eAAe,EAAE,eAAe,EAA4B,MAAM,8BAA8B,CAAC;AAMpH,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;IAC7B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACtE,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACzE;AAED,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,KACf,
|
|
1
|
+
{"version":3,"file":"useGroupMembers.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useGroupMembers.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,eAAe,EAAE,eAAe,EAA4B,MAAM,8BAA8B,CAAC;AAMpH,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;IAC7B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACtE,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACzE;AAED,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,KACf,qBAyGF,CAAC"}
|
|
@@ -45,11 +45,25 @@ export const useGroupMembers = (groupID) => {
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
const onMemberAdded = () => void fetchMembers();
|
|
48
|
+
// BE pushes the member's full updated record (roleLevel + the
|
|
49
|
+
// permissions[] it reset to) whenever a role/permission change is
|
|
50
|
+
// applied — e.g. setGroupMemberRoleLevel resets permissions to the new
|
|
51
|
+
// role's defaults server-side. Patch straight from this payload instead
|
|
52
|
+
// of predicting what BE would set, so the member list (and any open
|
|
53
|
+
// "Cài đặt quyền quản trị viên" for that member) reflects the real
|
|
54
|
+
// server state without waiting for a manual refetch/F5.
|
|
55
|
+
const onMemberInfoChanged = ({ data }) => {
|
|
56
|
+
if (data.groupID !== groupID)
|
|
57
|
+
return;
|
|
58
|
+
setMembers((prev) => prev.map((member) => (member.userID === data.userID ? data : member)));
|
|
59
|
+
};
|
|
48
60
|
DChatSDK.on(CbEvents.OnGroupMemberDeleted, onMemberDeleted);
|
|
49
61
|
DChatSDK.on(CbEvents.OnGroupMemberAdded, onMemberAdded);
|
|
62
|
+
DChatSDK.on(CbEvents.OnGroupMemberInfoChanged, onMemberInfoChanged);
|
|
50
63
|
return () => {
|
|
51
64
|
DChatSDK.off(CbEvents.OnGroupMemberDeleted, onMemberDeleted);
|
|
52
65
|
DChatSDK.off(CbEvents.OnGroupMemberAdded, onMemberAdded);
|
|
66
|
+
DChatSDK.off(CbEvents.OnGroupMemberInfoChanged, onMemberInfoChanged);
|
|
53
67
|
};
|
|
54
68
|
}, [groupID, fetchMembers]);
|
|
55
69
|
const patchMemberRole = useCallback((userID, roleLevel) => {
|
package/dist/utils/common.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ConversationItem, MessageType } from "@droppii-org/wasm-client-sdk";
|
|
|
2
2
|
import { TFunction } from "i18next";
|
|
3
3
|
import { UrlMetadataInfo } from "../types/chat";
|
|
4
4
|
import { PeerType } from "../types/conversation";
|
|
5
|
+
export declare const formatMemberLabel: (displayName: string, username?: string) => string;
|
|
5
6
|
export declare const parseMessageContent: <T>(content?: string) => Partial<T>;
|
|
6
7
|
export declare const parseUrlMetadata: (ex?: string) => UrlMetadataInfo | undefined;
|
|
7
8
|
export declare function formatDuration(seconds: number): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,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;
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,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;AAOhD,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;AAmCF,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,WAwC1D,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;IAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAClE,UAAU;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAE,WAuG5C,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;AAED,eAAO,MAAM,QAAQ,QAAkD,CAAC;AAExE,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAqC3D;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,CAgEjD"}
|
package/dist/utils/common.js
CHANGED
|
@@ -4,6 +4,10 @@ import DOMPurify from "dompurify";
|
|
|
4
4
|
import { PeerType } from "../types/conversation";
|
|
5
5
|
import { CustomMessageType } from "../types/customMessage";
|
|
6
6
|
import { getGroupNotificationText, getSystemLogMessageText } from "./messageLog";
|
|
7
|
+
// Group member pickers (create-group, add-member) can list several
|
|
8
|
+
// candidates that share the same display name — appending the username
|
|
9
|
+
// disambiguates them.
|
|
10
|
+
export const formatMemberLabel = (displayName, username) => (username ? `${displayName} - ${username}` : displayName);
|
|
7
11
|
export const parseMessageContent = (content) => {
|
|
8
12
|
if (!content)
|
|
9
13
|
return {};
|