@droppii-org/chat-sdk 0.3.5 → 0.3.6

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":"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;AA8CD,QAAA,MAAM,oBAAoB,GAAI,uEAO3B,yBAAyB,mDA0L3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
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"}
@@ -3,19 +3,29 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useState } from "react";
4
4
  import { ConfigProvider, Modal, Switch, message } from "antd";
5
5
  import { useTranslation } from "react-i18next";
6
+ import { GroupMemberRole } from "@droppii-org/wasm-client-sdk";
6
7
  import { useGroupPermission } from "../../hooks/group/useGroupPermission";
8
+ import { useGroupMembers } from "../../hooks/group/useGroupMembers";
7
9
  import { useSetGroupMemberPermissions } from "../../hooks/group/useGroupMemberActions";
8
10
  import { Icon } from "../../components/icon";
9
11
  import { PERMISSION_SWITCH_COLOR } from "../../constants";
10
12
  import { GROUP_PERMISSION_KEY } from "../../constants/im";
11
- import useGroupPermissionOverridesStore from "../../store/groupPermissionOverrides";
13
+ // "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.
17
+ const UPDATE_GROUP_INFO_KEYS = [
18
+ GROUP_PERMISSION_KEY.updateGroupName,
19
+ GROUP_PERMISSION_KEY.updateGroupAvatar,
20
+ GROUP_PERMISSION_KEY.updateGroupDescription,
21
+ ];
12
22
  const permissionListToOverrides = (permissionList) => ({
13
23
  sendMessage: permissionList.includes(GROUP_PERMISSION_KEY.sendMessage),
14
24
  pinMessage: permissionList.includes(GROUP_PERMISSION_KEY.pinMessage),
15
25
  viewMemberInformation: permissionList.includes(GROUP_PERMISSION_KEY.viewMemberInformation),
16
26
  addMember: permissionList.includes(GROUP_PERMISSION_KEY.addMember),
17
27
  removeMember: permissionList.includes(GROUP_PERMISSION_KEY.removeMember),
18
- updateGroupInfo: permissionList.includes(GROUP_PERMISSION_KEY.updateGroupName),
28
+ updateGroupInfo: UPDATE_GROUP_INFO_KEYS.every((key) => permissionList.includes(key)),
19
29
  });
20
30
  const overridesToPermissionList = (overrides, currentPermissionList) => {
21
31
  const desired = {
@@ -25,6 +35,8 @@ const overridesToPermissionList = (overrides, currentPermissionList) => {
25
35
  [GROUP_PERMISSION_KEY.addMember]: overrides.addMember,
26
36
  [GROUP_PERMISSION_KEY.removeMember]: overrides.removeMember,
27
37
  [GROUP_PERMISSION_KEY.updateGroupName]: overrides.updateGroupInfo,
38
+ [GROUP_PERMISSION_KEY.updateGroupAvatar]: overrides.updateGroupInfo,
39
+ [GROUP_PERMISSION_KEY.updateGroupDescription]: overrides.updateGroupInfo,
28
40
  };
29
41
  const managedKeys = new Set(Object.keys(desired));
30
42
  const untouched = currentPermissionList.filter((permission) => !managedKeys.has(permission));
@@ -33,19 +45,23 @@ const overridesToPermissionList = (overrides, currentPermissionList) => {
33
45
  .map(([permission]) => permission);
34
46
  return [...untouched, ...enabled];
35
47
  };
36
- // Mocked config UI (DROPPII-30248 follow-up, "Configure Admin Permissions")
37
- // when used group-wide (no `member`, e.g. from GroupThreadInfo) applies
38
- // to the whole Admin role in the group, no BE persistence yet, committed to
39
- // the in-memory override store on "Lưu" only. When `member` is passed
40
- // (from the member list's per-row menu), it instead patches that member's
41
- // own permission list via the same setGroupMemberInfo call used to mute a
42
- // member real BE persistence, scoped to that user.
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.
43
56
  const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member, onMemberPermissionsSaved, }) => {
44
57
  const { t } = useTranslation();
45
58
  const groupPermissions = useGroupPermission(groupID);
46
- const setAdminOverrides = useGroupPermissionOverridesStore((state) => state.setAdminOverrides);
59
+ const { members: groupMembers } = useGroupMembers(member ? undefined : groupID);
47
60
  const { mutateAsync: setMemberPermissions } = useSetGroupMemberPermissions();
48
61
  const [isSaving, setIsSaving] = useState(false);
62
+ const isGroupInfoEditable = groupPermissions.updateGroupName &&
63
+ groupPermissions.updateGroupAvatar &&
64
+ groupPermissions.updateGroupDescription;
49
65
  const initialOverrides = () => member
50
66
  ? permissionListToOverrides(member.permissions)
51
67
  : {
@@ -54,7 +70,7 @@ const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member,
54
70
  viewMemberInformation: groupPermissions.viewMemberInformation,
55
71
  addMember: groupPermissions.addMember,
56
72
  removeMember: groupPermissions.removeMember,
57
- updateGroupInfo: groupPermissions.updateGroupName,
73
+ updateGroupInfo: isGroupInfoEditable,
58
74
  };
59
75
  const [pending, setPending] = useState(initialOverrides);
60
76
  useEffect(() => {
@@ -71,7 +87,7 @@ const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member,
71
87
  viewMemberInformation: groupPermissions.viewMemberInformation,
72
88
  addMember: groupPermissions.addMember,
73
89
  removeMember: groupPermissions.removeMember,
74
- updateGroupInfo: groupPermissions.updateGroupName,
90
+ updateGroupInfo: isGroupInfoEditable,
75
91
  };
76
92
  const hasChanges = pending.sendMessage !== baseline.sendMessage ||
77
93
  pending.pinMessage !== baseline.pinMessage ||
@@ -95,7 +111,15 @@ const AdminPermissionModal = ({ open, groupID, onClose, inline = false, member,
95
111
  onMemberPermissionsSaved === null || onMemberPermissionsSaved === void 0 ? void 0 : onMemberPermissionsSaved(member.userID, nextPermissions);
96
112
  }
97
113
  else {
98
- setAdminOverrides(groupID, pending);
114
+ const admins = groupMembers.filter((groupMember) => groupMember.roleLevel === GroupMemberRole.Admin);
115
+ await Promise.all(admins.map((admin) => {
116
+ var _a;
117
+ return setMemberPermissions({
118
+ groupID,
119
+ userID: admin.userID,
120
+ permissions: overridesToPermissionList(pending, (_a = admin.permissions) !== null && _a !== void 0 ? _a : []),
121
+ });
122
+ }));
99
123
  }
100
124
  message.success(t("update_admin_permissions_success"));
101
125
  onClose();
@@ -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,4CA6hBzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
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,4CAwjBzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -202,6 +202,16 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
202
202
  message.error(((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || t("update_group_info_failed"));
203
203
  }
204
204
  };
205
+ const handleConfirmAssignAdmin = async () => {
206
+ if ((confirmMemberAction === null || confirmMemberAction === void 0 ? void 0 : confirmMemberAction.type) !== "assign-admin")
207
+ return;
208
+ try {
209
+ await handleToggleAdminRole(confirmMemberAction.member);
210
+ }
211
+ finally {
212
+ setConfirmMemberAction(null);
213
+ }
214
+ };
205
215
  const handleConfirmTransferOwner = async () => {
206
216
  var _a, _b;
207
217
  if (!groupID || (confirmMemberAction === null || confirmMemberAction === void 0 ? void 0 : confirmMemberAction.type) !== "transfer-owner")
@@ -256,7 +266,7 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
256
266
  const leaveGroupItem = {
257
267
  key: "leave-group",
258
268
  label: t("leave_group"),
259
- icon: _jsx(Icon, { icon: "logout-b", size: 16 }),
269
+ icon: _jsx(Icon, { icon: "logout-o", size: 16 }),
260
270
  onClick: handleLeaveGroup,
261
271
  danger: true,
262
272
  };
@@ -266,7 +276,7 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
266
276
  {
267
277
  key: "mute",
268
278
  label: t("mute_member"),
269
- icon: _jsx(Icon, { icon: "bell-off-b", size: 16 }),
279
+ icon: _jsx(Icon, { icon: "bell-off-o", size: 16 }),
270
280
  disabled: true,
271
281
  },
272
282
  leaveGroupItem,
@@ -276,7 +286,7 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
276
286
  {
277
287
  key: "send-message",
278
288
  label: t("send_message"),
279
- icon: _jsx(Icon, { icon: "send-b", size: 16 }),
289
+ icon: _jsx(Icon, { icon: "send-o", size: 16 }),
280
290
  disabled: true,
281
291
  },
282
292
  {
@@ -284,14 +294,14 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
284
294
  label: member.isSendMessageDisabled
285
295
  ? t("unmute_member")
286
296
  : t("mute_member"),
287
- icon: _jsx(Icon, { icon: "bell-off-b", size: 16 }),
297
+ icon: _jsx(Icon, { icon: "bell-off-o", size: 16 }),
288
298
  disabled: !permissions.removeMember,
289
299
  onClick: () => void handleToggleMemberSendMessage(member),
290
300
  },
291
301
  {
292
302
  key: "transfer-owner",
293
303
  label: t("transfer_owner"),
294
- icon: _jsx(Icon, { icon: "key-b", size: 16 }),
304
+ icon: _jsx(Icon, { icon: "key-o", size: 16 }),
295
305
  disabled: !permissions.transferOwnership,
296
306
  onClick: () => setConfirmMemberAction({ type: "transfer-owner", member }),
297
307
  },
@@ -307,7 +317,7 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
307
317
  {
308
318
  key: "remove-admin",
309
319
  label: t("remove_from_admin"),
310
- icon: _jsx(Icon, { icon: "shield-fail-b", size: 16 }),
320
+ icon: _jsx(Icon, { icon: "shield-fail-o", size: 16 }),
311
321
  disabled: !permissions.addAdmin,
312
322
  onClick: () => void handleToggleAdminRole(member),
313
323
  },
@@ -316,15 +326,15 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
316
326
  {
317
327
  key: "assign-admin",
318
328
  label: t("assign_as_admin"),
319
- icon: _jsx(Icon, { icon: "shield-b", size: 16 }),
329
+ icon: _jsx(Icon, { icon: "shield-o", size: 16 }),
320
330
  disabled: !permissions.addAdmin,
321
- onClick: () => void handleToggleAdminRole(member),
331
+ onClick: () => setConfirmMemberAction({ type: "assign-admin", member }),
322
332
  },
323
333
  ]),
324
334
  {
325
335
  key: "remove-member",
326
336
  label: t("remove_from_group"),
327
- icon: _jsx(Icon, { icon: "user-del-b", size: 16 }),
337
+ icon: _jsx(Icon, { icon: "user-del-o", size: 16 }),
328
338
  danger: true,
329
339
  disabled: !permissions.removeMember,
330
340
  onClick: () => setConfirmMemberAction({ type: "remove", member }),
@@ -332,7 +342,7 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
332
342
  {
333
343
  key: "remove-and-block",
334
344
  label: t("remove_and_block"),
335
- icon: _jsx(Icon, { icon: "user-octagon-b", size: 16 }),
345
+ icon: _jsx(Icon, { icon: "user-octagon-o", size: 16 }),
336
346
  danger: true,
337
347
  disabled: true,
338
348
  },
@@ -340,7 +350,7 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
340
350
  return (_jsxs("div", { className: "flex items-center gap-3 px-4 py-2", 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-semibold text-gray-900 truncate", children: member.nickname }), member.isCurrentUser && (_jsx("span", { className: "text-xs text-blue-500 shrink-0", children: t("current_account") }))] }), member.roleLabel && (_jsx("p", { className: "text-sm text-gray-500 truncate", children: member.roleLabel }))] }), (isRealGroup || 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));
341
351
  }) }));
342
352
  };
343
- return (_jsxs("div", { className: "inline-flex shrink-0", 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: {
353
+ return (_jsxs("div", { className: "inline-flex shrink-0", 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-o", size: 22 }) }), _jsx(Drawer, { open: isOpen, onClose: handleCloseDrawer, mask: false, closeIcon: false, styles: {
344
354
  body: {
345
355
  padding: 0,
346
356
  height: "100%",
@@ -354,6 +364,8 @@ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled
354
364
  name: confirmMemberAction === null || confirmMemberAction === void 0 ? void 0 : confirmMemberAction.member.nickname,
355
365
  }) }) }), _jsx(Modal, { centered: true, open: (confirmMemberAction === null || confirmMemberAction === void 0 ? void 0 : confirmMemberAction.type) === "transfer-owner", onOk: handleConfirmTransferOwner, onCancel: () => setConfirmMemberAction(null), title: t("transfer_owner_confirm_title"), okText: t("transfer_owner"), cancelText: t("cancel"), okType: "danger", getContainer: false, forceRender: true, children: _jsx("p", { children: t("transfer_owner_confirm_message", {
356
366
  name: confirmMemberAction === null || confirmMemberAction === void 0 ? void 0 : confirmMemberAction.member.nickname,
367
+ }) }) }), _jsx(Modal, { centered: true, open: (confirmMemberAction === null || confirmMemberAction === void 0 ? void 0 : confirmMemberAction.type) === "assign-admin", onOk: handleConfirmAssignAdmin, onCancel: () => setConfirmMemberAction(null), title: t("assign_admin_confirm_title"), okText: t("agree"), cancelText: t("cancel"), getContainer: false, forceRender: true, children: _jsx("p", { children: t("assign_admin_confirm_message", {
368
+ name: confirmMemberAction === null || confirmMemberAction === void 0 ? void 0 : confirmMemberAction.member.nickname,
357
369
  }) }) })] }));
358
370
  };
359
371
  export default GroupMembersDrawer;
@@ -154,7 +154,7 @@ const MessageItem = ({ message, allMessages, isGroupChat = false, forceHideTip =
154
154
  _jsx(GroupNotificationMessageItem, { message: message })));
155
155
  }
156
156
  const bubbleNode = (_jsx(MessageBubble, { isMine: isMine, isInternal: isInternalMessage, senderName: message === null || message === void 0 ? void 0 : message.senderNickname, showSenderName: showSenderName, showTip: showTip, id: `${MSG_ITEM_CONTENT_PREFIX}${message === null || message === void 0 ? void 0 : message.clientMsgID}`, content: renderBubbleContent(message, onPressQuoteMessage), isTransparent: isStickerMessage }));
157
- const showPinnedBadge = Boolean(message === null || message === void 0 ? void 0 : message.isPinned) && Boolean(onPinMessage);
157
+ const showPinnedBadge = Boolean(message === null || message === void 0 ? void 0 : message.isPinned);
158
158
  const pinnedBadgeNode = showPinnedBadge ? (_jsx("span", { "data-testid": "message-pinned-badge", className: clsx("absolute -top-2.5 z-[1] flex h-[22px] w-[26px] items-center justify-center rounded-full border border-white bg-gray-25", isMine ? "left-0" : "right-0"), children: _jsx(Icon, { icon: "thumbtack-b", size: 12, className: "text-primary-400" }) })) : null;
159
159
  const wrappedBubble = hasContextMenu ? (_jsx(Dropdown, { menu: { items: contextMenuItems }, trigger: ["contextMenu"], open: contextMenuOpen, onOpenChange: onContextMenuOpenChange, overlayClassName: MESSAGE_TOOLBOX_OVERLAY_CLASSNAME, children: _jsxs("div", { ref: bubbleWrapperRef, className: "relative min-w-0", children: [bubbleNode, pinnedBadgeNode] }) })) : (_jsxs("div", { className: "relative min-w-0", children: [bubbleNode, pinnedBadgeNode] }));
160
160
  return (_createElement("div", Object.assign({}, messageContainerProps, { key: message === null || message === void 0 ? void 0 : message.clientMsgID }),
@@ -48,7 +48,7 @@ const ROLE_DEFAULT_PERMISSIONS = {
48
48
  };
49
49
  export const permissionListToGroupPermissions = (permissionList, roleLevel) => {
50
50
  var _a;
51
- if (!permissionList) {
51
+ if (!permissionList || permissionList.length === 0) {
52
52
  return ((_a = ROLE_DEFAULT_PERMISSIONS[roleLevel]) !== null && _a !== void 0 ? _a : ROLE_DEFAULT_PERMISSIONS[GroupMemberRole.Normal]);
53
53
  }
54
54
  return Object.fromEntries(Object.entries(GROUP_PERMISSION_KEY).map(([field, permissionString]) => [
@@ -160,6 +160,9 @@
160
160
  "transfer_owner_confirm_message": "Bạn có chắc muốn chuyển quyền chủ nhóm cho {{name}}? Bạn sẽ trở thành quản trị viên.",
161
161
  "assign_as_admin": "Chỉ định làm quản trị viên",
162
162
  "assign_as_admin_success": "Đã chỉ định làm quản trị viên",
163
+ "assign_admin_confirm_title": "Cấp quyền quản trị viên",
164
+ "assign_admin_confirm_message": "Bạn chắc chắn muốn cấp quyền quản trị viên cho \"{{name}}\" ?",
165
+ "agree": "Đồng ý",
163
166
  "remove_from_admin": "Xoá khỏi quản trị viên",
164
167
  "remove_from_admin_success": "Đã xoá khỏi quản trị viên",
165
168
  "remove_from_group": "Xoá khỏi nhóm",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droppii-org/chat-sdk",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Droppii React Chat SDK",
5
5
  "repository": {
6
6
  "type": "git",