@planningcenter/chat-react-native 4.2.1-rc.0 → 4.3.0-rc.0

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.
@@ -8,6 +8,7 @@ export * from './use_chat_permissions';
8
8
  export * from './use_create_android_ripple_color';
9
9
  export * from './use_current_person';
10
10
  export * from './use_deleting_ids';
11
+ export * from './use_direct_message_eligibility';
11
12
  export * from './use_direct_messages_eligible';
12
13
  export * from './use_font_scale';
13
14
  export * from './use_has_direct_messages';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,yCAAyC,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,qBAAqB,CAAA;AACnC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,mCAAmC,CAAA;AACjD,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kBAAkB,CAAA;AAChC,cAAc,2BAA2B,CAAA;AACzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,sCAAsC,CAAA;AACpD,cAAc,2CAA2C,CAAA;AACzD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,yCAAyC,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,qBAAqB,CAAA;AACnC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,mCAAmC,CAAA;AACjD,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kCAAkC,CAAA;AAChD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kBAAkB,CAAA;AAChC,cAAc,2BAA2B,CAAA;AACzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,sCAAsC,CAAA;AACpD,cAAc,2CAA2C,CAAA;AACzD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA"}
@@ -8,6 +8,7 @@ export * from './use_chat_permissions';
8
8
  export * from './use_create_android_ripple_color';
9
9
  export * from './use_current_person';
10
10
  export * from './use_deleting_ids';
11
+ export * from './use_direct_message_eligibility';
11
12
  export * from './use_direct_messages_eligible';
12
13
  export * from './use_font_scale';
13
14
  export * from './use_has_direct_messages';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["useApiClient"],"sources":["../../src/hooks/index.ts"],"sourcesContent":["export * from './use_animated_message_background_color'\nexport { useApiClient } from './use_api_client'\nexport * from './use_api'\nexport * from './use_app_state'\nexport * from './use_async_storage'\nexport * from './use_at_font_scale_breakpoint'\nexport * from './use_chat_permissions'\nexport * from './use_create_android_ripple_color'\nexport * from './use_current_person'\nexport * from './use_deleting_ids'\nexport * from './use_direct_messages_eligible'\nexport * from './use_font_scale'\nexport * from './use_has_direct_messages'\nexport * from './use_groups_groups'\nexport * from './use_groups'\nexport * from './use_selected_chip_background_color'\nexport * from './use_interaction_tinted_background_color'\nexport * from './use_message_reaction_toggle'\nexport * from './use_new_conversation_entry'\nexport * from './use_organization'\nexport * from './use_people_person'\nexport * from './use_preview_avatar_diameter'\nexport * from './use_product_analytics'\nexport * from './use_qualified_by_age'\nexport * from './use_scalable_number_of_lines'\nexport * from './use_submit_age_check'\nexport * from './use_suspense_api'\nexport * from './use_theme'\n"],"mappings":"AAAA,cAAc,yCAAyC;AACvD,SAASA,YAAY,QAAQ,kBAAkB;AAC/C,cAAc,WAAW;AACzB,cAAc,iBAAiB;AAC/B,cAAc,qBAAqB;AACnC,cAAc,gCAAgC;AAC9C,cAAc,wBAAwB;AACtC,cAAc,mCAAmC;AACjD,cAAc,sBAAsB;AACpC,cAAc,oBAAoB;AAClC,cAAc,gCAAgC;AAC9C,cAAc,kBAAkB;AAChC,cAAc,2BAA2B;AACzC,cAAc,qBAAqB;AACnC,cAAc,cAAc;AAC5B,cAAc,sCAAsC;AACpD,cAAc,2CAA2C;AACzD,cAAc,+BAA+B;AAC7C,cAAc,8BAA8B;AAC5C,cAAc,oBAAoB;AAClC,cAAc,qBAAqB;AACnC,cAAc,+BAA+B;AAC7C,cAAc,yBAAyB;AACvC,cAAc,wBAAwB;AACtC,cAAc,gCAAgC;AAC9C,cAAc,wBAAwB;AACtC,cAAc,oBAAoB;AAClC,cAAc,aAAa","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["useApiClient"],"sources":["../../src/hooks/index.ts"],"sourcesContent":["export * from './use_animated_message_background_color'\nexport { useApiClient } from './use_api_client'\nexport * from './use_api'\nexport * from './use_app_state'\nexport * from './use_async_storage'\nexport * from './use_at_font_scale_breakpoint'\nexport * from './use_chat_permissions'\nexport * from './use_create_android_ripple_color'\nexport * from './use_current_person'\nexport * from './use_deleting_ids'\nexport * from './use_direct_message_eligibility'\nexport * from './use_direct_messages_eligible'\nexport * from './use_font_scale'\nexport * from './use_has_direct_messages'\nexport * from './use_groups_groups'\nexport * from './use_groups'\nexport * from './use_selected_chip_background_color'\nexport * from './use_interaction_tinted_background_color'\nexport * from './use_message_reaction_toggle'\nexport * from './use_new_conversation_entry'\nexport * from './use_organization'\nexport * from './use_people_person'\nexport * from './use_preview_avatar_diameter'\nexport * from './use_product_analytics'\nexport * from './use_qualified_by_age'\nexport * from './use_scalable_number_of_lines'\nexport * from './use_submit_age_check'\nexport * from './use_suspense_api'\nexport * from './use_theme'\n"],"mappings":"AAAA,cAAc,yCAAyC;AACvD,SAASA,YAAY,QAAQ,kBAAkB;AAC/C,cAAc,WAAW;AACzB,cAAc,iBAAiB;AAC/B,cAAc,qBAAqB;AACnC,cAAc,gCAAgC;AAC9C,cAAc,wBAAwB;AACtC,cAAc,mCAAmC;AACjD,cAAc,sBAAsB;AACpC,cAAc,oBAAoB;AAClC,cAAc,kCAAkC;AAChD,cAAc,gCAAgC;AAC9C,cAAc,kBAAkB;AAChC,cAAc,2BAA2B;AACzC,cAAc,qBAAqB;AACnC,cAAc,cAAc;AAC5B,cAAc,sCAAsC;AACpD,cAAc,2CAA2C;AACzD,cAAc,+BAA+B;AAC7C,cAAc,8BAA8B;AAC5C,cAAc,oBAAoB;AAClC,cAAc,qBAAqB;AACnC,cAAc,+BAA+B;AAC7C,cAAc,yBAAyB;AACvC,cAAc,wBAAwB;AACtC,cAAc,gCAAgC;AAC9C,cAAc,wBAAwB;AACtC,cAAc,oBAAoB;AAClC,cAAc,aAAa","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ export interface DirectMessageEligibility {
2
+ canDirectMessage: boolean;
3
+ directMessagesDisabled: boolean;
4
+ }
5
+ export declare function useDirectMessageEligibility({ groupId, personId, enabled, }: {
6
+ groupId: string;
7
+ personId: number;
8
+ enabled?: boolean;
9
+ }): {
10
+ eligibility: DirectMessageEligibility | undefined;
11
+ isLoading: boolean;
12
+ isError: boolean;
13
+ };
14
+ //# sourceMappingURL=use_direct_message_eligibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_direct_message_eligibility.d.ts","sourceRoot":"","sources":["../../src/hooks/use_direct_message_eligibility.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,EAAE,OAAO,CAAA;IACzB,sBAAsB,EAAE,OAAO,CAAA;CAChC;AAED,wBAAgB,2BAA2B,CAAC,EAC1C,OAAO,EACP,QAAQ,EACR,OAAc,GACf,EAAE;IACD,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;;;;EAsBA"}
@@ -0,0 +1,87 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useQuery } from '@tanstack/react-query';
3
+ import { useApiClient } from './use_api_client';
4
+ export function useDirectMessageEligibility(t0) {
5
+ const $ = _c(15);
6
+ const {
7
+ groupId,
8
+ personId,
9
+ enabled: t1
10
+ } = t0;
11
+ const enabled = t1 === undefined ? true : t1;
12
+ const apiClient = useApiClient();
13
+ const url = `/me/groups/${groupId}/members/${personId}`;
14
+ let t2;
15
+ if ($[0] !== url) {
16
+ t2 = ["chat", url, "direct_message_eligibility"];
17
+ $[0] = url;
18
+ $[1] = t2;
19
+ } else {
20
+ t2 = $[1];
21
+ }
22
+ let t3;
23
+ if ($[2] !== apiClient || $[3] !== url) {
24
+ t3 = () => apiClient.chat.get({
25
+ url,
26
+ data: {
27
+ fields: {
28
+ Member: ["can_direct_message", "direct_messages_disabled"]
29
+ }
30
+ }
31
+ });
32
+ $[2] = apiClient;
33
+ $[3] = url;
34
+ $[4] = t3;
35
+ } else {
36
+ t3 = $[4];
37
+ }
38
+ let t4;
39
+ if ($[5] !== enabled || $[6] !== t2 || $[7] !== t3) {
40
+ t4 = {
41
+ queryKey: t2,
42
+ queryFn: t3,
43
+ enabled,
44
+ retry: false
45
+ };
46
+ $[5] = enabled;
47
+ $[6] = t2;
48
+ $[7] = t3;
49
+ $[8] = t4;
50
+ } else {
51
+ t4 = $[8];
52
+ }
53
+ const {
54
+ data,
55
+ isLoading,
56
+ isError
57
+ } = useQuery(t4);
58
+ const member = data?.data;
59
+ let t5;
60
+ if ($[9] !== member) {
61
+ t5 = member && {
62
+ canDirectMessage: member.canDirectMessage ?? false,
63
+ directMessagesDisabled: member.directMessagesDisabled ?? false
64
+ };
65
+ $[9] = member;
66
+ $[10] = t5;
67
+ } else {
68
+ t5 = $[10];
69
+ }
70
+ const eligibility = t5;
71
+ let t6;
72
+ if ($[11] !== eligibility || $[12] !== isError || $[13] !== isLoading) {
73
+ t6 = {
74
+ eligibility,
75
+ isLoading,
76
+ isError
77
+ };
78
+ $[11] = eligibility;
79
+ $[12] = isError;
80
+ $[13] = isLoading;
81
+ $[14] = t6;
82
+ } else {
83
+ t6 = $[14];
84
+ }
85
+ return t6;
86
+ }
87
+ //# sourceMappingURL=use_direct_message_eligibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_direct_message_eligibility.js","names":["useQuery","useApiClient","useDirectMessageEligibility","t0","$","_c","groupId","personId","enabled","t1","undefined","apiClient","url","t2","t3","chat","get","data","fields","Member","t4","queryKey","queryFn","retry","isLoading","isError","member","t5","canDirectMessage","directMessagesDisabled","eligibility","t6"],"sources":["../../src/hooks/use_direct_message_eligibility.ts"],"sourcesContent":["import { useQuery } from '@tanstack/react-query'\nimport { ApiResource, MemberResource } from '../types'\nimport { useApiClient } from './use_api_client'\n\nexport interface DirectMessageEligibility {\n canDirectMessage: boolean\n directMessagesDisabled: boolean\n}\n\nexport function useDirectMessageEligibility({\n groupId,\n personId,\n enabled = true,\n}: {\n groupId: string\n personId: number\n enabled?: boolean\n}) {\n const apiClient = useApiClient()\n const url = `/me/groups/${groupId}/members/${personId}`\n\n const { data, isLoading, isError } = useQuery({\n queryKey: ['chat', url, 'direct_message_eligibility'],\n queryFn: () =>\n apiClient.chat.get({\n url,\n data: { fields: { Member: ['can_direct_message', 'direct_messages_disabled'] } },\n }) as Promise<ApiResource<MemberResource>>,\n enabled,\n retry: false,\n })\n\n const member = data?.data\n const eligibility: DirectMessageEligibility | undefined = member && {\n canDirectMessage: member.canDirectMessage ?? false,\n directMessagesDisabled: member.directMessagesDisabled ?? false,\n }\n\n return { eligibility, isLoading, isError }\n}\n"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,uBAAuB;AAEhD,SAASC,YAAY,QAAQ,kBAAkB;AAO/C,OAAO,SAAAC,4BAAAC,EAAA;EAAA,MAAAC,CAAA,GAAAC,EAAA;EAAqC;IAAAC,OAAA;IAAAC,QAAA;IAAAC,OAAA,EAAAC;EAAA,IAAAN,EAQ3C;EALC,MAAAK,OAAA,GAAAC,EAAc,KAAdC,SAAc,GAAd,IAAc,GAAdD,EAAc;EAMd,MAAAE,SAAA,GAAkBV,YAAY,CAAC,CAAC;EAChC,MAAAW,GAAA,GAAY,cAAcN,OAAO,YAAYC,QAAQ,EAAE;EAAA,IAAAM,EAAA;EAAA,IAAAT,CAAA,QAAAQ,GAAA;IAG3CC,EAAA,IAAC,MAAM,EAAED,GAAG,EAAE,4BAA4B,CAAC;IAAAR,CAAA,MAAAQ,GAAA;IAAAR,CAAA,MAAAS,EAAA;EAAA;IAAAA,EAAA,GAAAT,CAAA;EAAA;EAAA,IAAAU,EAAA;EAAA,IAAAV,CAAA,QAAAO,SAAA,IAAAP,CAAA,QAAAQ,GAAA;IAC5CE,EAAA,GAAAA,CAAA,KACPH,SAAS,CAAAI,IAAK,CAAAC,GAAI,CAAC;MAAAJ,GAAA;MAAAK,IAAA,EAEX;QAAAC,MAAA,EAAU;UAAAC,MAAA,EAAU,CAAC,oBAAoB,EAAE,0BAA0B;QAAE;MAAE;IACjF,CAAC,CAAyC;IAAAf,CAAA,MAAAO,SAAA;IAAAP,CAAA,MAAAQ,GAAA;IAAAR,CAAA,MAAAU,EAAA;EAAA;IAAAA,EAAA,GAAAV,CAAA;EAAA;EAAA,IAAAgB,EAAA;EAAA,IAAAhB,CAAA,QAAAI,OAAA,IAAAJ,CAAA,QAAAS,EAAA,IAAAT,CAAA,QAAAU,EAAA;IANAM,EAAA;MAAAC,QAAA,EAClCR,EAA2C;MAAAS,OAAA,EAC5CR,EAImC;MAAAN,OAAA;MAAAe,KAAA,EAErC;IACT,CAAC;IAAAnB,CAAA,MAAAI,OAAA;IAAAJ,CAAA,MAAAS,EAAA;IAAAT,CAAA,MAAAU,EAAA;IAAAV,CAAA,MAAAgB,EAAA;EAAA;IAAAA,EAAA,GAAAhB,CAAA;EAAA;EATD;IAAAa,IAAA;IAAAO,SAAA;IAAAC;EAAA,IAAqCzB,QAAQ,CAACoB,EAS7C,CAAC;EAEF,MAAAM,MAAA,GAAeT,IAAI,EAAAA,IAAM;EAAA,IAAAU,EAAA;EAAA,IAAAvB,CAAA,QAAAsB,MAAA;IACiCC,EAAA,GAAAD,MAGzD,IAHyD;MAAAE,gBAAA,EACtCF,MAAM,CAAAE,gBAA0B,IAAhC,KAAgC;MAAAC,sBAAA,EAC1BH,MAAM,CAAAG,sBAAgC,IAAtC;IAC1B,CAAC;IAAAzB,CAAA,MAAAsB,MAAA;IAAAtB,CAAA,OAAAuB,EAAA;EAAA;IAAAA,EAAA,GAAAvB,CAAA;EAAA;EAHD,MAAA0B,WAAA,GAA0DH,EAGzD;EAAA,IAAAI,EAAA;EAAA,IAAA3B,CAAA,SAAA0B,WAAA,IAAA1B,CAAA,SAAAqB,OAAA,IAAArB,CAAA,SAAAoB,SAAA;IAEMO,EAAA;MAAAD,WAAA;MAAAN,SAAA;MAAAC;IAAkC,CAAC;IAAArB,CAAA,OAAA0B,WAAA;IAAA1B,CAAA,OAAAqB,OAAA;IAAArB,CAAA,OAAAoB,SAAA;IAAApB,CAAA,OAAA2B,EAAA;EAAA;IAAAA,EAAA,GAAA3B,CAAA;EAAA;EAAA,OAAnC2B,EAAmC;AAAA","ignoreList":[]}
@@ -6,6 +6,7 @@ export interface MemberResource {
6
6
  badges: MemberBadge[];
7
7
  child: boolean;
8
8
  directMessagesDisabled?: boolean;
9
+ canDirectMessage?: boolean;
9
10
  gender: string | null;
10
11
  role?: string;
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../../../src/types/resources/member.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,KAAK,EAAE,OAAO,CAAA;IACd,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;CACd"}
1
+ {"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../../../src/types/resources/member.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,KAAK,EAAE,OAAO,CAAA;IACd,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;CACd"}
@@ -1 +1 @@
1
- {"version":3,"file":"member.js","names":[],"sources":["../../../src/types/resources/member.ts"],"sourcesContent":["export interface MemberResource {\n type: 'Member'\n id: number\n name: string\n avatar: string\n badges: MemberBadge[]\n child: boolean\n directMessagesDisabled?: boolean\n gender: string | null\n role?: string\n}\n\nexport interface MemberBadge {\n title: string\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"member.js","names":[],"sources":["../../../src/types/resources/member.ts"],"sourcesContent":["export interface MemberResource {\n type: 'Member'\n id: number\n name: string\n avatar: string\n badges: MemberBadge[]\n child: boolean\n directMessagesDisabled?: boolean\n canDirectMessage?: boolean\n gender: string | null\n role?: string\n}\n\nexport interface MemberBadge {\n title: string\n}\n"],"mappings":"","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "4.2.1-rc.0",
3
+ "version": "4.3.0-rc.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -84,5 +84,5 @@
84
84
  "sf-symbols-typescript": "^2.2.0",
85
85
  "typescript": "~6.0.3"
86
86
  },
87
- "gitHead": "ed5238bdc4544af321e18dd44135a3f1a38b61c7"
87
+ "gitHead": "2d5f97948a3f69f26435fa88e8cbfdd264270022"
88
88
  }
@@ -0,0 +1,83 @@
1
+ import { QueryClientProvider } from '@tanstack/react-query'
2
+ import { renderHook, waitFor } from '@testing-library/react-native'
3
+ import React from 'react'
4
+ import { buildTestQueryClient } from '../../__utils__/query_client'
5
+ import { useApiClient } from '../../hooks/use_api_client'
6
+ import { useDirectMessageEligibility } from '../../hooks/use_direct_message_eligibility'
7
+
8
+ jest.mock('../../hooks/use_api_client')
9
+
10
+ const mockedUseApiClient = useApiClient as jest.MockedFunction<typeof useApiClient>
11
+ const mockGet = jest.fn()
12
+
13
+ beforeEach(() => {
14
+ mockGet.mockReset()
15
+ mockedUseApiClient.mockReturnValue({ chat: { get: mockGet } } as any)
16
+ })
17
+
18
+ const createWrapper = () => {
19
+ const queryClient = buildTestQueryClient()
20
+ return ({ children }: { children: React.ReactNode }) => (
21
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
22
+ )
23
+ }
24
+
25
+ const args = { groupId: 'Groups-Group-42', personId: 75179873 }
26
+
27
+ test("reads the member's eligibility from the chat group", async () => {
28
+ mockGet.mockResolvedValue({
29
+ data: {
30
+ id: '75179873',
31
+ type: 'Member',
32
+ canDirectMessage: false,
33
+ directMessagesDisabled: true,
34
+ },
35
+ })
36
+
37
+ const { result } = renderHook(() => useDirectMessageEligibility(args), {
38
+ wrapper: createWrapper(),
39
+ })
40
+
41
+ await waitFor(() => expect(result.current.eligibility).toBeDefined())
42
+
43
+ expect(mockGet).toHaveBeenCalledWith({
44
+ url: '/me/groups/Groups-Group-42/members/75179873',
45
+ data: { fields: { Member: ['can_direct_message', 'direct_messages_disabled'] } },
46
+ })
47
+ expect(result.current.eligibility).toEqual({
48
+ canDirectMessage: false,
49
+ directMessagesDisabled: true,
50
+ })
51
+ })
52
+
53
+ test('has no answer until the member loads', () => {
54
+ mockGet.mockReturnValue(new Promise(() => {}))
55
+
56
+ const { result } = renderHook(() => useDirectMessageEligibility(args), {
57
+ wrapper: createWrapper(),
58
+ })
59
+
60
+ expect(result.current.eligibility).toBeUndefined()
61
+ expect(result.current.isLoading).toBe(true)
62
+ })
63
+
64
+ test('reports a failed lookup without an answer', async () => {
65
+ mockGet.mockRejectedValue(new Error('404'))
66
+
67
+ const { result } = renderHook(() => useDirectMessageEligibility(args), {
68
+ wrapper: createWrapper(),
69
+ })
70
+
71
+ await waitFor(() => expect(result.current.isError).toBe(true))
72
+
73
+ expect(result.current.eligibility).toBeUndefined()
74
+ expect(result.current.isLoading).toBe(false)
75
+ })
76
+
77
+ test('does not ask when disabled', () => {
78
+ renderHook(() => useDirectMessageEligibility({ ...args, enabled: false }), {
79
+ wrapper: createWrapper(),
80
+ })
81
+
82
+ expect(mockGet).not.toHaveBeenCalled()
83
+ })
@@ -8,6 +8,7 @@ export * from './use_chat_permissions'
8
8
  export * from './use_create_android_ripple_color'
9
9
  export * from './use_current_person'
10
10
  export * from './use_deleting_ids'
11
+ export * from './use_direct_message_eligibility'
11
12
  export * from './use_direct_messages_eligible'
12
13
  export * from './use_font_scale'
13
14
  export * from './use_has_direct_messages'
@@ -0,0 +1,40 @@
1
+ import { useQuery } from '@tanstack/react-query'
2
+ import { ApiResource, MemberResource } from '../types'
3
+ import { useApiClient } from './use_api_client'
4
+
5
+ export interface DirectMessageEligibility {
6
+ canDirectMessage: boolean
7
+ directMessagesDisabled: boolean
8
+ }
9
+
10
+ export function useDirectMessageEligibility({
11
+ groupId,
12
+ personId,
13
+ enabled = true,
14
+ }: {
15
+ groupId: string
16
+ personId: number
17
+ enabled?: boolean
18
+ }) {
19
+ const apiClient = useApiClient()
20
+ const url = `/me/groups/${groupId}/members/${personId}`
21
+
22
+ const { data, isLoading, isError } = useQuery({
23
+ queryKey: ['chat', url, 'direct_message_eligibility'],
24
+ queryFn: () =>
25
+ apiClient.chat.get({
26
+ url,
27
+ data: { fields: { Member: ['can_direct_message', 'direct_messages_disabled'] } },
28
+ }) as Promise<ApiResource<MemberResource>>,
29
+ enabled,
30
+ retry: false,
31
+ })
32
+
33
+ const member = data?.data
34
+ const eligibility: DirectMessageEligibility | undefined = member && {
35
+ canDirectMessage: member.canDirectMessage ?? false,
36
+ directMessagesDisabled: member.directMessagesDisabled ?? false,
37
+ }
38
+
39
+ return { eligibility, isLoading, isError }
40
+ }
@@ -6,6 +6,7 @@ export interface MemberResource {
6
6
  badges: MemberBadge[]
7
7
  child: boolean
8
8
  directMessagesDisabled?: boolean
9
+ canDirectMessage?: boolean
9
10
  gender: string | null
10
11
  role?: string
11
12
  }