@droppii-org/chat-sdk 0.4.8 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
  2. package/dist/components/conversation/DeskConversationList.js +8 -2
  3. package/dist/components/conversation-detail/ConversationDetailInput.d.ts.map +1 -1
  4. package/dist/components/conversation-detail/ConversationDetailInput.js +10 -5
  5. package/dist/components/conversation-inbox/contact-search/ContactSearchPanel.d.ts.map +1 -1
  6. package/dist/components/conversation-inbox/contact-search/ContactSearchPanel.js +36 -0
  7. package/dist/components/conversation-inbox/contact-search/ContactSearchResultItem.d.ts.map +1 -1
  8. package/dist/components/conversation-inbox/contact-search/ContactSearchResultItem.js +4 -2
  9. package/dist/components/conversation-inbox/contact-search/PublicGroupAvatar.d.ts +9 -0
  10. package/dist/components/conversation-inbox/contact-search/PublicGroupAvatar.d.ts.map +1 -0
  11. package/dist/components/conversation-inbox/contact-search/PublicGroupAvatar.js +19 -0
  12. package/dist/components/conversation-inbox/contact-search/PublicGroupResultItem.d.ts +8 -0
  13. package/dist/components/conversation-inbox/contact-search/PublicGroupResultItem.d.ts.map +1 -0
  14. package/dist/components/conversation-inbox/contact-search/PublicGroupResultItem.js +29 -0
  15. package/dist/components/conversation-inbox/contact-search/constants.d.ts +4 -1
  16. package/dist/components/conversation-inbox/contact-search/constants.d.ts.map +1 -1
  17. package/dist/components/conversation-inbox/contact-search/constants.js +5 -0
  18. package/dist/components/conversation-inbox/contact-search/index.d.ts +2 -0
  19. package/dist/components/conversation-inbox/contact-search/index.d.ts.map +1 -1
  20. package/dist/components/conversation-inbox/contact-search/index.js +2 -0
  21. package/dist/components/message/MessageList.d.ts.map +1 -1
  22. package/dist/components/message/MessageList.js +3 -1
  23. package/dist/components/message/footer/index.d.ts.map +1 -1
  24. package/dist/components/message/footer/index.js +2 -2
  25. package/dist/components/message/footer/mention/MentionMenu.d.ts +1 -0
  26. package/dist/components/message/footer/mention/MentionMenu.d.ts.map +1 -1
  27. package/dist/components/message/footer/mention/MentionMenu.js +66 -6
  28. package/dist/components/message/footer/mention/MentionNode.d.ts +1 -1
  29. package/dist/components/message/footer/mention/MentionNode.d.ts.map +1 -1
  30. package/dist/components/message/footer/mention/MentionNode.js +2 -2
  31. package/dist/components/message/footer/mention/useMentionOptions.d.ts.map +1 -1
  32. package/dist/components/message/footer/mention/useMentionOptions.js +6 -3
  33. package/dist/components/search-conversation/index.d.ts.map +1 -1
  34. package/dist/components/search-conversation/index.js +20 -2
  35. package/dist/components/search-conversation/item/SearchItemAsGroup.d.ts.map +1 -1
  36. package/dist/components/search-conversation/item/SearchItemAsGroup.js +2 -1
  37. package/dist/components/search-conversation/item/SearchItemAsMessage.d.ts.map +1 -1
  38. package/dist/components/search-conversation/item/SearchItemAsMessage.js +4 -1
  39. package/dist/hooks/conversation/useResolveConversation.d.ts.map +1 -1
  40. package/dist/hooks/conversation/useResolveConversation.js +2 -1
  41. package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
  42. package/dist/hooks/global/useGlobalEvent.js +10 -1
  43. package/dist/hooks/group/useJoinPublicGroup.d.ts +6 -0
  44. package/dist/hooks/group/useJoinPublicGroup.d.ts.map +1 -0
  45. package/dist/hooks/group/useJoinPublicGroup.js +20 -0
  46. package/dist/hooks/search/useSearchMessage.d.ts.map +1 -1
  47. package/dist/hooks/search/useSearchMessage.js +11 -1
  48. package/dist/hooks/search/useSearchPublicGroups.d.ts +16 -0
  49. package/dist/hooks/search/useSearchPublicGroups.d.ts.map +1 -0
  50. package/dist/hooks/search/useSearchPublicGroups.js +55 -0
  51. package/dist/locales/vi/common.json +1 -1
  52. package/dist/locales/vi/conversation-inbox.json +7 -2
  53. package/dist/services/query.d.ts +1 -0
  54. package/dist/services/query.d.ts.map +1 -1
  55. package/dist/services/query.js +1 -0
  56. package/dist/store/conversation.d.ts.map +1 -1
  57. package/dist/store/conversation.js +22 -9
  58. package/dist/store/type.d.ts +6 -2
  59. package/dist/store/type.d.ts.map +1 -1
  60. package/dist/styles/global.css +1 -1
  61. package/dist/types/dto.d.ts +1 -0
  62. package/dist/types/dto.d.ts.map +1 -1
  63. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Tabs } from "antd";
4
- import { useMemo, useState } from "react";
4
+ import { useEffect, useMemo, useState } from "react";
5
5
  import { useTranslation } from "react-i18next";
6
6
  import SearchConversationAll from "./SearchAll";
7
7
  import SearchConversationMyInbox from "./SearchConversationMyInbox";
@@ -48,6 +48,24 @@ const SearchConversation = ({ searchTerm }) => {
48
48
  },
49
49
  ];
50
50
  }, [t, searchTerm]);
51
- return (_jsx("div", { className: "h-full", "data-cp-name": "SearchConversation", children: _jsx(Tabs, { defaultActiveKey: SearchConversationTabKey.All, items: items, className: "h-full", activeKey: activeKey, onChange: (key) => setActiveKey(key), destroyOnHidden: true }) }));
51
+ // Clicking a result row while on "All" switches activeKey without any
52
+ // click/focus on the tab header itself — antd's own scroll-into-view for
53
+ // that path relies on measuring .ant-tabs-nav against its scroll parent,
54
+ // which the fixed-width nav below permanently reports as "already fits"
55
+ // (see the renderTabBar comment). Do it ourselves instead.
56
+ useEffect(() => {
57
+ var _a;
58
+ (_a = document
59
+ .querySelector('[data-cp-name="SearchConversation"] .ant-tabs-tab-active')) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ inline: "nearest", block: "nearest" });
60
+ }, [activeKey]);
61
+ return (_jsx("div", { className: "h-full", "data-cp-name": "SearchConversation", children: _jsx(Tabs, { defaultActiveKey: SearchConversationTabKey.All, items: items, className: "h-full", activeKey: activeKey, onChange: (key) => setActiveKey(key), destroyOnHidden: true,
62
+ // Ant's built-in tab-overflow ("...") dropdown never recovers from
63
+ // its initial off-screen measurement inside this Drawer (rendered
64
+ // with getContainer={false} for unrelated scroll-position reasons —
65
+ // see DeskConversationList) — the last tab (Nhóm) becomes
66
+ // permanently unreachable. A plain horizontally-scrollable strip
67
+ // sidesteps that positioning bug entirely: every tab stays a real,
68
+ // always-clickable element: no hidden dropdown involved.
69
+ renderTabBar: (tabBarProps, DefaultTabBar) => (_jsx("div", { className: "overflow-x-auto", children: _jsx(DefaultTabBar, Object.assign({}, tabBarProps, { className: "!w-max" })) })) }) }));
52
70
  };
53
71
  export default SearchConversation;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchItemAsGroup.d.ts","sourceRoot":"","sources":["../../../../src/components/search-conversation/item/SearchItemAsGroup.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAOxF,UAAU,sBAAsB;IAC9B,KAAK,EAAE,4BAA4B,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,iBAAiB,GAAI,OAAO,sBAAsB,4CAgEvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"SearchItemAsGroup.d.ts","sourceRoot":"","sources":["../../../../src/components/search-conversation/item/SearchItemAsGroup.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAOxF,UAAU,sBAAsB;IAC9B,KAAK,EAAE,4BAA4B,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,iBAAiB,GAAI,OAAO,sBAAsB,4CAiEvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -16,7 +16,8 @@ const SearchItemAsGroup = (props) => {
16
16
  const { conversation } = group;
17
17
  const isPublic = group.visibility === GroupVisibility.Public;
18
18
  const onPressItem = () => {
19
- setConversationData(conversation);
19
+ // Result can go stale before the click — force a fresh membership check.
20
+ setConversationData(conversation, undefined, { forceRevalidate: true });
20
21
  setSelectedConversationId(conversation.conversationID);
21
22
  const newSearchParams = new URLSearchParams(window.location.search);
22
23
  newSearchParams.set("threadId", conversation.conversationID);
@@ -1 +1 @@
1
- {"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/search-conversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAA4B,MAAM,8BAA8B,CAAC;AAerF,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,GAAG;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CAwG3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"SearchItemAsMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/search-conversation/item/SearchItemAsMessage.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAA4B,MAAM,8BAA8B,CAAC;AAerF,UAAU,wBAAwB;IAChC,OAAO,EAAE,WAAW,GAAG;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,4CA2G3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -36,7 +36,10 @@ const SearchItemAsMessage = (props) => {
36
36
  }
37
37
  useConversationStore
38
38
  .getState()
39
- .setConversationData(data, message.clientMsgID);
39
+ // Result can be stale — force a fresh membership check.
40
+ .setConversationData(data, message.clientMsgID, {
41
+ forceRevalidate: true,
42
+ });
40
43
  useConversationStore
41
44
  .getState()
42
45
  .setSelectedConversationId(data.conversationID);
@@ -1 +1 @@
1
- {"version":3,"file":"useResolveConversation.d.ts","sourceRoot":"","sources":["../../../src/hooks/conversation/useResolveConversation.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,4BAA4B;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqED,eAAO,MAAM,sBAAsB,GAAI,6CAKpC,4BAA4B;;;CA0E9B,CAAC"}
1
+ {"version":3,"file":"useResolveConversation.d.ts","sourceRoot":"","sources":["../../../src/hooks/conversation/useResolveConversation.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,4BAA4B;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqED,eAAO,MAAM,sBAAsB,GAAI,6CAKpC,4BAA4B;;;CA2E9B,CAAC"}
@@ -78,7 +78,8 @@ export const useResolveConversation = ({ conversationId, userId, groupId, botId,
78
78
  return;
79
79
  if (!resolved)
80
80
  throw new Error(CONVERSATION_NOT_FOUND_ERROR);
81
- setConversationData(resolved);
81
+ // Entry point for notifications/deep links — force a fresh check.
82
+ setConversationData(resolved, undefined, { forceRevalidate: true });
82
83
  setSelectedConversationId(resolved.conversationID);
83
84
  }
84
85
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"useGlobalEvent.d.ts","sourceRoot":"","sources":["../../../src/hooks/global/useGlobalEvent.ts"],"names":[],"mappings":"AAyCA,eAAO,MAAM,cAAc,YA6hB1B,CAAC"}
1
+ {"version":3,"file":"useGlobalEvent.d.ts","sourceRoot":"","sources":["../../../src/hooks/global/useGlobalEvent.ts"],"names":[],"mappings":"AAyCA,eAAO,MAAM,cAAc,YAsiB1B,CAAC"}
@@ -40,7 +40,12 @@ export const useGlobalEvent = () => {
40
40
  if (!(currentConversation === null || currentConversation === void 0 ? void 0 : currentConversation.groupID) || !isGroupConversation(currentConversation)) {
41
41
  return;
42
42
  }
43
- await Promise.all([
43
+ // allSettled, not all — getSelfGroupPermissionByReq's underlying wasm
44
+ // call never resolves for a non-member group (see the same guard in
45
+ // store/conversation.ts's updateCurrentConversation), which would hang
46
+ // this indefinitely and keep the message footer stuck on its loading
47
+ // spinner instead of ever reaching the "Join Group" prompt.
48
+ await Promise.allSettled([
44
49
  getCurrentGroupInfoByReq(currentConversation.groupID),
45
50
  getSelfGroupPermissionByReq(currentConversation.groupID),
46
51
  // roleLevel comes only from this call — without it, isAdminOrOwner
@@ -272,6 +277,10 @@ export const useGlobalEvent = () => {
272
277
  if (isCurrentGroupOpen && staysViewOnly) {
273
278
  useConversationStore.setState({ isViewOnlyMember: true });
274
279
  void getCurrentGroupInfoByReq(data.groupID);
280
+ // Without this, isJoined stays stale and the rejoin footer never shows.
281
+ void queryClient.invalidateQueries({
282
+ queryKey: [QUERY_KEYS.IS_JOINED_GROUP, data.groupID],
283
+ });
275
284
  }
276
285
  else if (isCurrentGroupOpen) {
277
286
  useConversationStore.getState().clearSelectedConversation();
@@ -0,0 +1,6 @@
1
+ interface JoinPublicGroupInput {
2
+ groupID: string;
3
+ }
4
+ export declare const useJoinPublicGroup: () => import("@tanstack/react-query").UseMutationResult<unknown, Error, JoinPublicGroupInput, unknown>;
5
+ export {};
6
+ //# sourceMappingURL=useJoinPublicGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useJoinPublicGroup.d.ts","sourceRoot":"","sources":["../../../src/hooks/group/useJoinPublicGroup.ts"],"names":[],"mappings":"AAOA,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,eAAO,MAAM,kBAAkB,wGAa9B,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { useMutation } from "@tanstack/react-query";
3
+ import { GroupJoinSource } from "@droppii-org/wasm-client-sdk";
4
+ import { DChatSDK } from "../../constants/sdk";
5
+ import emitter from "../../utils/events";
6
+ // Joining straight from search results, matching chat-mobile's GroupItem —
7
+ // GroupJoinSource.Search is what BE uses to attribute the join.
8
+ export const useJoinPublicGroup = () => {
9
+ return useMutation({
10
+ mutationFn: async ({ groupID }) => {
11
+ const { data } = await DChatSDK.joinGroup({
12
+ groupID,
13
+ reqMsg: "",
14
+ joinSource: GroupJoinSource.Search,
15
+ });
16
+ emitter.emit("GROUP_MEMBERS_CHANGED");
17
+ return data;
18
+ },
19
+ });
20
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"useSearchMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/search/useSearchMessage.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAMrB,UAAU,uBAAuB;IAC/B,OAAO,EAAE,IAAI,CACX,oBAAoB,EACpB,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,GAAG,KAAK,CAC7D,CAAC;IACF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3D;AAED,eAAO,MAAM,gBAAgB,GAAI,uBAG9B,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEzB,CAAC"}
1
+ {"version":3,"file":"useSearchMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/search/useSearchMessage.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAQrB,UAAU,uBAAuB;IAC/B,OAAO,EAAE,IAAI,CACX,oBAAoB,EACpB,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,GAAG,KAAK,CAC7D,CAAC;IACF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3D;AAED,eAAO,MAAM,gBAAgB,GAAI,uBAG9B,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoFzB,CAAC"}
@@ -16,6 +16,8 @@ import { ENDPOINTS } from "../../services/routes";
16
16
  import { useMemo } from "react";
17
17
  import dayjs from "dayjs";
18
18
  import useAuthStore from "../../store/auth";
19
+ import useConversationStore from "../../store/conversation";
20
+ import { isGroupSession } from "../../utils/imCommon";
19
21
  import { PAGE_SIZE } from "../../constants";
20
22
  export const useSearchMessage = ({ payload, options, }) => {
21
23
  const _a = useInfiniteQuery({
@@ -45,7 +47,15 @@ export const useSearchMessage = ({ payload, options, }) => {
45
47
  groupedData: {},
46
48
  dataFlatten: [],
47
49
  };
48
- const allItems = ((_b = (_a = data === null || data === void 0 ? void 0 : data.pages) === null || _a === void 0 ? void 0 : _a.flatMap) === null || _b === void 0 ? void 0 : _b.call(_a, (page) => page.data)) || [];
50
+ const rawItems = ((_b = (_a = data === null || data === void 0 ? void 0 : data.pages) === null || _a === void 0 ? void 0 : _a.flatMap) === null || _b === void 0 ? void 0 : _b.call(_a, (page) => page.data)) || [];
51
+ // BE search isn't scoped to live membership — filter defensively
52
+ // against conversationList, which leftGroupHandler keeps in sync.
53
+ const joinedGroupIDs = new Set(useConversationStore
54
+ .getState()
55
+ .conversationList.filter((c) => isGroupSession(c.conversationType))
56
+ .map((c) => c.groupID));
57
+ const allItems = rawItems.filter((item) => !isGroupSession(item.chatLog.sessionType) ||
58
+ joinedGroupIDs.has(item.chatLog.groupID));
49
59
  const mGroupeddata = allItems.reduce((acc, item) => {
50
60
  const dateKey = dayjs(item.chatLog.sendTime).format("YYYY-MM-DD");
51
61
  if (!acc[dateKey])
@@ -0,0 +1,16 @@
1
+ import { type SearchPublicGroupInfo } from "@droppii-org/wasm-client-sdk";
2
+ interface UseSearchPublicGroupsParams {
3
+ searchTerm: string;
4
+ enabled?: boolean;
5
+ pageSize?: number;
6
+ }
7
+ export declare const useSearchPublicGroups: ({ searchTerm, enabled, pageSize, }: UseSearchPublicGroupsParams) => {
8
+ groups: SearchPublicGroupInfo[];
9
+ fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("@droppii-org/wasm-client-sdk").SearchPublicGroupsResult, unknown>, Error>>;
10
+ hasNextPage: boolean;
11
+ isFetchingNextPage: boolean;
12
+ isLoading: boolean;
13
+ isError: boolean;
14
+ };
15
+ export {};
16
+ //# sourceMappingURL=useSearchPublicGroups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSearchPublicGroups.d.ts","sourceRoot":"","sources":["../../../src/hooks/search/useSearchPublicGroups.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAKtC,UAAU,2BAA2B;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,eAAO,MAAM,qBAAqB,GAAI,oCAInC,2BAA2B;;;;;;;CAqD7B,CAAC"}
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { useMemo } from "react";
3
+ import { useInfiniteQuery } from "@tanstack/react-query";
4
+ import { PublicGroupJoinStatus, } from "@droppii-org/wasm-client-sdk";
5
+ import { DChatSDK } from "../../constants/sdk";
6
+ import { QUERY_KEYS } from "../../services/query";
7
+ import { PAGE_SIZE } from "../../constants";
8
+ // Community results come from the IM SDK rather than the contacts REST API —
9
+ // same call chat-mobile uses for its `Cộng đồng` tab, so both platforms return
10
+ // the identical public-group set (joined and not yet joined).
11
+ export const useSearchPublicGroups = ({ searchTerm, enabled = true, pageSize = PAGE_SIZE.medium, }) => {
12
+ const trimmedSearchTerm = searchTerm.trim();
13
+ const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isError } = useInfiniteQuery({
14
+ initialPageParam: 0,
15
+ queryKey: [QUERY_KEYS.SEARCH_PUBLIC_GROUPS, trimmedSearchTerm, pageSize],
16
+ queryFn: async ({ pageParam = 0 }) => {
17
+ const { data: result } = await DChatSDK.searchPublicGroups({
18
+ keyword: trimmedSearchTerm,
19
+ joinStatus: PublicGroupJoinStatus.All,
20
+ offset: pageParam,
21
+ count: pageSize,
22
+ });
23
+ return result;
24
+ },
25
+ // The SDK paginates by offset, not page number.
26
+ getNextPageParam: (lastPage, allPages) => {
27
+ var _a;
28
+ const fetched = allPages.reduce((total, page) => { var _a, _b; return total + ((_b = (_a = page === null || page === void 0 ? void 0 : page.groups) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0); }, 0);
29
+ return fetched < ((_a = lastPage === null || lastPage === void 0 ? void 0 : lastPage.total) !== null && _a !== void 0 ? _a : 0) ? fetched : undefined;
30
+ },
31
+ enabled: enabled && trimmedSearchTerm !== "",
32
+ });
33
+ // A group can repeat across offsets while the backing list shifts.
34
+ const groups = useMemo(() => {
35
+ var _a, _b;
36
+ const seen = new Set();
37
+ return ((_b = (_a = data === null || data === void 0 ? void 0 : data.pages) === null || _a === void 0 ? void 0 : _a.flatMap((page) => {
38
+ var _a;
39
+ return ((_a = page === null || page === void 0 ? void 0 : page.groups) !== null && _a !== void 0 ? _a : []).filter((group) => {
40
+ if (seen.has(group.groupID))
41
+ return false;
42
+ seen.add(group.groupID);
43
+ return true;
44
+ });
45
+ })) !== null && _b !== void 0 ? _b : []);
46
+ }, [data]);
47
+ return {
48
+ groups,
49
+ fetchNextPage,
50
+ hasNextPage,
51
+ isFetchingNextPage,
52
+ isLoading,
53
+ isError,
54
+ };
55
+ };
@@ -207,7 +207,7 @@
207
207
  "my_messages": "Tin nhắn của tôi",
208
208
  "my_inbox_tab": "My inbox",
209
209
  "team_messages": "Tin nhắn nhóm",
210
- "join_group_required": "Bạn phải thành viên để gửi tin nhắn",
210
+ "join_group_required": "Bạn cần tham gia nhóm để gửi tin nhắn",
211
211
  "send_message_disabled": "Chỉ quản trị viên được phép gửi tin nhắn",
212
212
  "send_message_disabled_group_mute": "Chỉ chủ nhóm và quản trị viên được phép gửi tin nhắn",
213
213
  "join_group": "Tham gia",
@@ -124,7 +124,8 @@
124
124
  "tabs": {
125
125
  "all": "Tất cả",
126
126
  "contacts": "Liên hệ",
127
- "messages": "Tin nhắn"
127
+ "messages": "Tin nhắn",
128
+ "community": "Cộng đồng"
128
129
  },
129
130
  "view_all": "Xem tất cả",
130
131
  "initial": "Bạn có thể tìm kiếm theo liên hệ hoặc nội dung tin nhắn",
@@ -138,6 +139,10 @@
138
139
  "pdp": "PDP",
139
140
  "group": "Nhóm",
140
141
  "seller": "Người bán"
141
- }
142
+ },
143
+ "group_no_description": "Chưa có mô tả nhóm",
144
+ "public_group_fallback": "Nhóm công khai",
145
+ "group_join": "Tham gia",
146
+ "group_access": "Truy cập"
142
147
  }
143
148
  }
@@ -41,6 +41,7 @@ export declare const QUERY_KEYS: {
41
41
  GET_CONVERSATION_GROUPS: string;
42
42
  SEARCH_CONVERSATION_GROUPS: string;
43
43
  SEARCH_CONTACTS: string;
44
+ SEARCH_PUBLIC_GROUPS: string;
44
45
  GET_BLACK_LIST: string;
45
46
  DELETE_CONVERSATION: string;
46
47
  };
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/services/query.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CtB,CAAC"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/services/query.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CtB,CAAC"}
@@ -41,6 +41,7 @@ export const QUERY_KEYS = {
41
41
  GET_CONVERSATION_GROUPS: "GET_CONVERSATION_GROUPS",
42
42
  SEARCH_CONVERSATION_GROUPS: "SEARCH_CONVERSATION_GROUPS",
43
43
  SEARCH_CONTACTS: "SEARCH_CONTACTS",
44
+ SEARCH_PUBLIC_GROUPS: "SEARCH_PUBLIC_GROUPS",
44
45
  GET_BLACK_LIST: "GET_BLACK_LIST",
45
46
  DELETE_CONVERSATION: "DELETE_CONVERSATION",
46
47
  };
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/store/conversation.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAM3C,QAAA,MAAM,oBAAoB,gFAmWvB,CAAC;AAEJ,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/store/conversation.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAM3C,QAAA,MAAM,oBAAoB,gFAkXvB,CAAC;AAEJ,eAAe,oBAAoB,CAAC"}
@@ -6,8 +6,8 @@ import useUserStore from "./user";
6
6
  const CONVERSATION_SPLIT_COUNT = 500;
7
7
  const useConversationStore = create((set, get) => ({
8
8
  conversationData: null,
9
- setConversationData: (data, dataSearchClientMsgID) => {
10
- void get().updateCurrentConversation(data);
9
+ setConversationData: (data, dataSearchClientMsgID, options) => {
10
+ void get().updateCurrentConversation(data, options);
11
11
  set({
12
12
  conversationData: data,
13
13
  selectedSourceId: (data === null || data === void 0 ? void 0 : data.conversationType) === SessionType.Group
@@ -83,7 +83,7 @@ const useConversationStore = create((set, get) => ({
83
83
  conversationList: conversationSort([...list, ...filterArr]),
84
84
  }));
85
85
  },
86
- updateCurrentConversation: async (conversation) => {
86
+ updateCurrentConversation: async (conversation, options) => {
87
87
  var _a, _b;
88
88
  if (!conversation) {
89
89
  set({
@@ -105,9 +105,19 @@ const useConversationStore = create((set, get) => ({
105
105
  set({ isViewOnlyMember: false });
106
106
  // Cache hit: a previously-viewed group's info/membership is still
107
107
  // in the Map — render from it immediately, no fetch, no spinner.
108
- // Invalidation is WS-event-driven only (no background refetch).
108
+ // forceRevalidate bypasses the cache hit for external entry points
109
+ // (notification/search click) that may have missed the WS event.
109
110
  const hasCachedMember = get().currentMemberInGroup.has(groupID);
110
- if (!hasCachedMember) {
111
+ if (!hasCachedMember || (options === null || options === void 0 ? void 0 : options.forceRevalidate)) {
112
+ if (options === null || options === void 0 ? void 0 : options.forceRevalidate) {
113
+ // The refetch below only ever SETS on success, so clear first —
114
+ // otherwise a removed user's empty response leaves this stale.
115
+ set((state) => {
116
+ const memberInGroup = new Map(state.currentMemberInGroup);
117
+ memberInGroup.delete(groupID);
118
+ return { currentMemberInGroup: memberInGroup };
119
+ });
120
+ }
111
121
  // allSettled, not all — getSelfGroupPermissionByReq's underlying
112
122
  // wasm call never resolves for a non-member group, which would
113
123
  // hang this block forever and block the view-only detection below.
@@ -143,6 +153,9 @@ const useConversationStore = create((set, get) => ({
143
153
  let groupInfo;
144
154
  try {
145
155
  const { data } = await DChatSDK.getSpecifiedGroupsInfo([groupID]);
156
+ // Disbanded group: empty array, not a thrown error — don't crash below.
157
+ if (!data[0])
158
+ return;
146
159
  groupInfo = data[0];
147
160
  }
148
161
  catch (error) {
@@ -211,11 +224,11 @@ const useConversationStore = create((set, get) => ({
211
224
  return;
212
225
  }
213
226
  set((state) => {
214
- // Merge onto this groupID's existing cache entry, if any the Map
215
- // key IS the groupID, so no separate "same group?" check is needed
216
- // (unlike the old single-field shape, where a stale different-group
217
- // record could otherwise get spread onto this one).
227
+ // getSelfUserInfo isn't a membership check only merge, never create,
228
+ // or it can resurrect a record another call just correctly cleared.
218
229
  const base = state.currentMemberInGroup.get(groupID);
230
+ if (!base)
231
+ return state;
219
232
  const next = new Map(state.currentMemberInGroup);
220
233
  next.set(groupID, Object.assign(Object.assign({}, base), { groupID, userID: selfInfo.userID, nickname: selfInfo.nickname, faceURL: selfInfo.faceURL, permissions: selfInfo.permissions }));
221
234
  return { currentMemberInGroup: next };
@@ -45,7 +45,9 @@ export interface IFilterSummary {
45
45
  }
46
46
  export interface ConversationStore {
47
47
  conversationData: ConversationItem | null;
48
- setConversationData: (data: ConversationItem, searchClientMsgID?: string) => void;
48
+ setConversationData: (data: ConversationItem, searchClientMsgID?: string, options?: {
49
+ forceRevalidate?: boolean;
50
+ }) => void;
49
51
  selectedConversationId: string;
50
52
  selectedSourceId: string;
51
53
  setSelectedConversationId: (threadId: string) => void;
@@ -55,7 +57,9 @@ export interface ConversationStore {
55
57
  currentMemberInGroup: Map<string, GroupMemberItem>;
56
58
  getConversationListByReq: (isOffset?: boolean, appParams?: ConversationListAppParams) => Promise<boolean>;
57
59
  updateConversationList: (list: ConversationItem[], type: ConversationListUpdateType) => void;
58
- updateCurrentConversation: (conversation?: ConversationItem) => Promise<void>;
60
+ updateCurrentConversation: (conversation?: ConversationItem, options?: {
61
+ forceRevalidate?: boolean;
62
+ }) => Promise<void>;
59
63
  getCurrentGroupInfoByReq: (groupID: string) => Promise<void>;
60
64
  getCurrentMemberInGroupByReq: (groupID: string) => Promise<void>;
61
65
  getSelfGroupPermissionByReq: (groupID: string) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/store/type.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/store/type.ts"],"names":[],"mappings":"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"}