@planningcenter/chat-react-native 3.2.0-rc.23 → 3.2.0-rc.24

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,5 +1,13 @@
1
- import { MemberResource } from '../../types';
1
+ import { MemberResource, ResourceObject } from '../../types';
2
2
  import { GroupsGroupMemberResource } from '../../types/resources/groups/groups_member_resource_with_person';
3
+ import { useApiPaginator } from '../use_api';
4
+ type UseApiPaginatorResult<T extends ResourceObject> = ReturnType<typeof useApiPaginator<T>>;
5
+ export type GroupMembersForNewConversationResult = Omit<UseApiPaginatorResult<GroupsGroupMemberResource>, // We are passing our own "members" data shape
6
+ 'data'> & {
7
+ data: MemberResource[];
8
+ adultMembers: MemberResource[];
9
+ childMembers: MemberResource[];
10
+ };
3
11
  /**
4
12
  * This is specifically for the new conversation screen because we assign
5
13
  * the "Conversation owner" badge to the current person.
@@ -223,4 +231,5 @@ export declare function useGroupMembersForNewConversation({ id }: {
223
231
  fetchStatus: import("@tanstack/query-core").FetchStatus;
224
232
  promise: Promise<import("@tanstack/query-core").InfiniteData<import("../../types").ApiCollection<GroupsGroupMemberResource>, unknown>>;
225
233
  };
234
+ export {};
226
235
  //# sourceMappingURL=use_group_members_for_new_conversation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use_group_members_for_new_conversation.d.ts","sourceRoot":"","sources":["../../../src/hooks/groups/use_group_members_for_new_conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,cAAc,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iEAAiE,CAAA;AAI3G;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCvE"}
1
+ {"version":3,"file":"use_group_members_for_new_conversation.d.ts","sourceRoot":"","sources":["../../../src/hooks/groups/use_group_members_for_new_conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iEAAiE,CAAA;AAC3G,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAG5C,KAAK,qBAAqB,CAAC,CAAC,SAAS,cAAc,IAAI,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,CAAA;AAE5F,MAAM,MAAM,oCAAoC,GAAG,IAAI,CACrD,qBAAqB,CAAC,yBAAyB,CAAC,EAAE,8CAA8C;AAChG,MAAM,CACP,GAAG;IACF,IAAI,EAAE,cAAc,EAAE,CAAA;IACtB,YAAY,EAAE,cAAc,EAAE,CAAA;IAC9B,YAAY,EAAE,cAAc,EAAE,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCvE"}
@@ -29,6 +29,7 @@ export function useGroupMembersForNewConversation({ id }) {
29
29
  id: +person.id,
30
30
  name: `${person.firstName} ${person.lastName}`,
31
31
  source: [],
32
+ role: membership.role,
32
33
  };
33
34
  });
34
35
  const adultMembers = members.filter(member => !member.child);
@@ -1 +1 @@
1
- {"version":3,"file":"use_group_members_for_new_conversation.js","sourceRoot":"","sources":["../../../src/hooks/groups/use_group_members_for_new_conversation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD;;;GAGG;AACH,MAAM,UAAU,iCAAiC,CAAC,EAAE,EAAE,EAAkB;IACtE,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;IACxC,MAAM,QAAQ,GAAG,eAAe,CAA4B;QAC1D,GAAG,EAAE,cAAc,EAAE,cAAc;QACnC,IAAI,EAAE;YACJ,OAAO,EAAE,GAAG;YACZ,OAAO,EAAE,CAAC,QAAQ,CAAC;YACnB,MAAM,EAAE;gBACN,UAAU,EAAE,CAAC,cAAc,CAAC;gBAC5B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC;aACnE;SACF;QACD,GAAG,EAAE,QAAQ;KACd,CAAC,CAAA;IAEF,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,EAAE,EAAE,GAAG,QAAQ,CAAA;IAC3C,MAAM,OAAO,GAAqB,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;QAC7D,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;QAC7B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM,CAAC,SAAS;YACxB,MAAM,EAAE,WAAW,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,CAAC;YACjD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE;YACd,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,QAAQ,EAAE;YAC9C,MAAM,EAAE,EAAE;SACX,CAAA;IACH,CAAC,CAAC,CAAA;IACF,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC5D,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE3D,OAAO;QACL,GAAG,QAAQ;QACX,IAAI,EAAE,OAAO;QACb,YAAY;QACZ,YAAY;KACb,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAClB,UAAqC,EACrC,eAAuB;IAEvB,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;IAC7B,MAAM,MAAM,GAAG,EAAE,CAAA;IACjB,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;IAClC,CAAC;IACD,IAAI,MAAM,CAAC,EAAE,KAAK,eAAe,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["import { MemberBadge, MemberResource } from '../../types'\nimport { GroupsGroupMemberResource } from '../../types/resources/groups/groups_member_resource_with_person'\nimport { useApiPaginator } from '../use_api'\nimport { useCurrentPerson } from '../use_current_person'\n\n/**\n * This is specifically for the new conversation screen because we assign\n * the \"Conversation owner\" badge to the current person.\n */\nexport function useGroupMembersForNewConversation({ id }: { id: number }) {\n const currentPerson = useCurrentPerson()\n const response = useApiPaginator<GroupsGroupMemberResource>({\n url: `/me/groups/${id}/memberships`,\n data: {\n perPage: 100,\n include: ['person'],\n fields: {\n Membership: ['person, role'],\n Person: ['avatar_url', 'name', 'first_name', 'last_name', 'child'],\n },\n },\n app: 'groups',\n })\n\n const { data: memberships = [] } = response\n const members: MemberResource[] = memberships.map(membership => {\n const { person } = membership\n return {\n type: 'Member',\n avatar: person.avatarUrl,\n badges: buildBadges(membership, currentPerson.id),\n child: person.child,\n id: +person.id,\n name: `${person.firstName} ${person.lastName}`,\n source: [],\n }\n })\n const adultMembers = members.filter(member => !member.child)\n const childMembers = members.filter(member => member.child)\n\n return {\n ...response,\n data: members,\n adultMembers,\n childMembers,\n }\n}\n\nfunction buildBadges(\n membership: GroupsGroupMemberResource,\n currentPersonId: number\n): MemberBadge[] {\n const { person } = membership\n const badges = []\n if (membership.role === 'leader') {\n badges.push({ title: 'Leader' })\n }\n if (person.id === currentPersonId) {\n badges.push({ title: 'Conversation owner' })\n }\n return badges\n}\n"]}
1
+ {"version":3,"file":"use_group_members_for_new_conversation.js","sourceRoot":"","sources":["../../../src/hooks/groups/use_group_members_for_new_conversation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAaxD;;;GAGG;AACH,MAAM,UAAU,iCAAiC,CAAC,EAAE,EAAE,EAAkB;IACtE,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;IACxC,MAAM,QAAQ,GAAG,eAAe,CAA4B;QAC1D,GAAG,EAAE,cAAc,EAAE,cAAc;QACnC,IAAI,EAAE;YACJ,OAAO,EAAE,GAAG;YACZ,OAAO,EAAE,CAAC,QAAQ,CAAC;YACnB,MAAM,EAAE;gBACN,UAAU,EAAE,CAAC,cAAc,CAAC;gBAC5B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC;aACnE;SACF;QACD,GAAG,EAAE,QAAQ;KACd,CAAC,CAAA;IAEF,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,EAAE,EAAE,GAAG,QAAQ,CAAA;IAC3C,MAAM,OAAO,GAAqB,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;QAC7D,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;QAC7B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM,CAAC,SAAS;YACxB,MAAM,EAAE,WAAW,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,CAAC;YACjD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE;YACd,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,QAAQ,EAAE;YAC9C,MAAM,EAAE,EAAE;YACV,IAAI,EAAE,UAAU,CAAC,IAAI;SACtB,CAAA;IACH,CAAC,CAAC,CAAA;IACF,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC5D,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE3D,OAAO;QACL,GAAG,QAAQ;QACX,IAAI,EAAE,OAAO;QACb,YAAY;QACZ,YAAY;KACb,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAClB,UAAqC,EACrC,eAAuB;IAEvB,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;IAC7B,MAAM,MAAM,GAAG,EAAE,CAAA;IACjB,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;IAClC,CAAC;IACD,IAAI,MAAM,CAAC,EAAE,KAAK,eAAe,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["import { MemberBadge, MemberResource, ResourceObject } from '../../types'\nimport { GroupsGroupMemberResource } from '../../types/resources/groups/groups_member_resource_with_person'\nimport { useApiPaginator } from '../use_api'\nimport { useCurrentPerson } from '../use_current_person'\n\ntype UseApiPaginatorResult<T extends ResourceObject> = ReturnType<typeof useApiPaginator<T>>\n\nexport type GroupMembersForNewConversationResult = Omit<\n UseApiPaginatorResult<GroupsGroupMemberResource>, // We are passing our own \"members\" data shape\n 'data'\n> & {\n data: MemberResource[]\n adultMembers: MemberResource[]\n childMembers: MemberResource[]\n}\n\n/**\n * This is specifically for the new conversation screen because we assign\n * the \"Conversation owner\" badge to the current person.\n */\nexport function useGroupMembersForNewConversation({ id }: { id: number }) {\n const currentPerson = useCurrentPerson()\n const response = useApiPaginator<GroupsGroupMemberResource>({\n url: `/me/groups/${id}/memberships`,\n data: {\n perPage: 100,\n include: ['person'],\n fields: {\n Membership: ['person, role'],\n Person: ['avatar_url', 'name', 'first_name', 'last_name', 'child'],\n },\n },\n app: 'groups',\n })\n\n const { data: memberships = [] } = response\n const members: MemberResource[] = memberships.map(membership => {\n const { person } = membership\n return {\n type: 'Member',\n avatar: person.avatarUrl,\n badges: buildBadges(membership, currentPerson.id),\n child: person.child,\n id: +person.id,\n name: `${person.firstName} ${person.lastName}`,\n source: [],\n role: membership.role,\n }\n })\n const adultMembers = members.filter(member => !member.child)\n const childMembers = members.filter(member => member.child)\n\n return {\n ...response,\n data: members,\n adultMembers,\n childMembers,\n }\n}\n\nfunction buildBadges(\n membership: GroupsGroupMemberResource,\n currentPersonId: number\n): MemberBadge[] {\n const { person } = membership\n const badges = []\n if (membership.role === 'leader') {\n badges.push({ title: 'Leader' })\n }\n if (person.id === currentPersonId) {\n badges.push({ title: 'Conversation owner' })\n }\n return badges\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"groups_form.d.ts","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/groups_form.tsx"],"names":[],"mappings":"AACA,OAAO,KAAgC,MAAM,OAAO,CAAA;AAYpD,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,UAAU,gBAAiB,eAAe,sBAyDtD,CAAA"}
1
+ {"version":3,"file":"groups_form.d.ts","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/groups_form.tsx"],"names":[],"mappings":"AACA,OAAO,KAAyC,MAAM,OAAO,CAAA;AAgB7D,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,UAAU,gBAAiB,eAAe,sBAwDtD,CAAA"}
@@ -1,14 +1,15 @@
1
1
  import { StackActions, useNavigation } from '@react-navigation/native';
2
- import React, { useCallback, useState } from 'react';
2
+ import React, { useCallback, useMemo, useState } from 'react';
3
3
  import { Platform, StyleSheet, TextInput, View } from 'react-native';
4
4
  import { Banner, ChildNotice, Heading, Text } from '../../../components';
5
5
  import { ActionButton } from '../../../components/display/action_button';
6
- import { useSuspenseGet } from '../../../hooks';
6
+ import { useCurrentPerson, useSuspenseGet } from '../../../hooks';
7
7
  import { Divider, FormList } from './form_list';
8
8
  import { pluralize } from '../../../utils';
9
9
  import { KeyboardView } from '../../../components/display/keyboard_view';
10
- import { useGroupMembersForNewConversation } from '../../../hooks/groups/use_group_members_for_new_conversation';
10
+ import { useGroupMembersForNewConversation, } from '../../../hooks/groups/use_group_members_for_new_conversation';
11
11
  import { useGroupsConversationCreate } from '../../../hooks/groups/use_groups_conversation_create';
12
+ import { useTheme } from '../../../hooks';
12
13
  export const GroupsForm = ({ groupId }) => {
13
14
  const navigation = useNavigation();
14
15
  const [title, setTitle] = useState();
@@ -21,6 +22,7 @@ export const GroupsForm = ({ groupId }) => {
21
22
  },
22
23
  app: 'groups',
23
24
  });
25
+ const groupMemberships = useGroupMembersForNewConversation({ id: groupId });
24
26
  const redirectToConversation = useCallback((conversationId) => {
25
27
  // exit from the create stack
26
28
  navigation.getParent()?.goBack();
@@ -29,22 +31,29 @@ export const GroupsForm = ({ groupId }) => {
29
31
  conversation_id: conversationId,
30
32
  }));
31
33
  }, [navigation]);
32
- const groupMemberships = useGroupMembersForNewConversation({ id: groupId });
33
34
  const { mutate: handleSave } = useGroupsConversationCreate({
34
35
  groupId,
35
36
  title,
36
37
  onSuccess: redirectToConversation,
37
38
  });
38
39
  return (<KeyboardView>
39
- <FormList memberData={groupMemberships.adultMembers} FormContent={<FormContent group={group} title={title} setTitle={setTitle} isMemberError={groupMemberships.isError} childMembers={groupMemberships.childMembers}/>}/>
40
+ <FormList memberData={groupMemberships.adultMembers} FormContent={<FormContent group={group} title={title} setTitle={setTitle} groupMemberships={groupMemberships}/>}/>
40
41
  <ActionButton disabled={!title} title="Start Conversation" onPress={() => handleSave()} infoText="Conversation will be automatically updated if any members are added or removed from this group."/>
41
42
  </KeyboardView>);
42
43
  };
43
- function FormContent({ group, title, setTitle, isMemberError, childMembers }) {
44
+ function FormContent({ group, title, setTitle, groupMemberships }) {
44
45
  const styles = useStyles();
46
+ const currentPerson = useCurrentPerson();
45
47
  const { name, membershipsCount } = group;
46
- const memberHeader = pluralize(membershipsCount, 'member');
48
+ const myGroupsMembership = useMemo(() => groupMemberships.data.find(m => m.id === currentPerson.id), [groupMemberships.data, currentPerson.id]);
49
+ const isLeader = myGroupsMembership?.role === 'leader';
50
+ const childMembers = groupMemberships.childMembers;
47
51
  const hasChildren = childMembers.length > 0;
52
+ const adultCount = groupMemberships.adultMembers.length;
53
+ const memberCount = isLeader ? membershipsCount : adultCount;
54
+ const memberHeaderLabel = `${pluralize(memberCount, 'member')} selected`;
55
+ const showMemberError = groupMemberships.isError;
56
+ const showChildNotice = hasChildren && isLeader;
48
57
  return (<View style={styles.formContent}>
49
58
  <View style={styles.toSection}>
50
59
  <Heading variant="h3">To:</Heading>
@@ -57,13 +66,14 @@ function FormContent({ group, title, setTitle, isMemberError, childMembers }) {
57
66
  </View>
58
67
  <Divider />
59
68
  <View style={styles.memberSection}>
60
- <Heading variant="h3">{memberHeader} selected</Heading>
61
- {hasChildren && <ChildNotice childMembers={childMembers} style={styles.banner}/>}
62
- {isMemberError && (<Banner appearance="error" description="There was an issue loading group members, please refresh and try again." style={styles.banner}/>)}
69
+ <Heading variant="h3">{memberHeaderLabel}</Heading>
70
+ {showChildNotice && <ChildNotice childMembers={childMembers} style={styles.banner}/>}
71
+ {showMemberError && (<Banner appearance="error" description="There was an issue loading group members, please refresh and try again." style={styles.banner}/>)}
63
72
  </View>
64
73
  </View>);
65
74
  }
66
75
  const useStyles = () => {
76
+ const { colors } = useTheme();
67
77
  const sectionPadding = 16;
68
78
  const inputPadding = 8;
69
79
  return StyleSheet.create({
@@ -92,6 +102,7 @@ const useStyles = () => {
92
102
  },
93
103
  titleInput: {
94
104
  fontSize: 18,
105
+ color: colors.textColorDefaultPrimary,
95
106
  },
96
107
  memberSection: {
97
108
  padding: sectionPadding,
@@ -1 +1 @@
1
- {"version":3,"file":"groups_form.js","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/groups_form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StackActions, useNavigation } from '@react-navigation/native'\nimport React, { useCallback, useState } from 'react'\nimport { Platform, StyleSheet, TextInput, View } from 'react-native'\nimport { Banner, ChildNotice, Heading, Text } from '../../../components'\nimport { ActionButton } from '../../../components/display/action_button'\nimport { useSuspenseGet } from '../../../hooks'\nimport { GroupsGroupResource, MemberResource } from '../../../types'\nimport { Divider, FormList } from './form_list'\nimport { pluralize } from '../../../utils'\nimport { KeyboardView } from '../../../components/display/keyboard_view'\nimport { useGroupMembersForNewConversation } from '../../../hooks/groups/use_group_members_for_new_conversation'\nimport { useGroupsConversationCreate } from '../../../hooks/groups/use_groups_conversation_create'\n\ntype GroupsFormProps = {\n groupId: number\n}\n\nexport const GroupsForm = ({ groupId }: GroupsFormProps) => {\n const navigation = useNavigation()\n const [title, setTitle] = useState<string>()\n const { data: group } = useSuspenseGet<GroupsGroupResource>({\n url: `/me/groups/${groupId}`,\n data: {\n fields: {\n Group: [],\n },\n },\n app: 'groups',\n })\n\n const redirectToConversation = useCallback(\n (conversationId: number) => {\n // exit from the create stack\n navigation.getParent()?.goBack()\n // navigate to the conversation screen\n navigation.dispatch(\n StackActions.push('Conversation', {\n conversation_id: conversationId,\n })\n )\n },\n [navigation]\n )\n\n const groupMemberships = useGroupMembersForNewConversation({ id: groupId })\n\n const { mutate: handleSave } = useGroupsConversationCreate({\n groupId,\n title,\n onSuccess: redirectToConversation,\n })\n\n return (\n <KeyboardView>\n <FormList\n memberData={groupMemberships.adultMembers}\n FormContent={\n <FormContent\n group={group}\n title={title}\n setTitle={setTitle}\n isMemberError={groupMemberships.isError}\n childMembers={groupMemberships.childMembers}\n />\n }\n />\n <ActionButton\n disabled={!title}\n title=\"Start Conversation\"\n onPress={() => handleSave()}\n infoText=\"Conversation will be automatically updated if any members are added or removed from this group.\"\n />\n </KeyboardView>\n )\n}\n\ninterface FormContentProps {\n group: GroupsGroupResource\n title?: string\n setTitle: (title: string) => void\n isMemberError: boolean\n childMembers: MemberResource[]\n}\n\nfunction FormContent({ group, title, setTitle, isMemberError, childMembers }: FormContentProps) {\n const styles = useStyles()\n const { name, membershipsCount } = group\n const memberHeader = pluralize(membershipsCount, 'member')\n const hasChildren = childMembers.length > 0\n\n return (\n <View style={styles.formContent}>\n <View style={styles.toSection}>\n <Heading variant=\"h3\">To:</Heading>\n <Text style={styles.groupName}>{name}</Text>\n </View>\n <Divider />\n <View style={styles.titleSection}>\n <Heading variant=\"h3\">Title</Heading>\n <TextInput\n placeholder=\"Topic of conversation (required)\"\n value={title}\n onChangeText={setTitle}\n style={styles.titleInput}\n autoFocus={true}\n />\n </View>\n <Divider />\n <View style={styles.memberSection}>\n <Heading variant=\"h3\">{memberHeader} selected</Heading>\n {hasChildren && <ChildNotice childMembers={childMembers} style={styles.banner} />}\n {isMemberError && (\n <Banner\n appearance=\"error\"\n description=\"There was an issue loading group members, please refresh and try again.\"\n style={styles.banner}\n />\n )}\n </View>\n </View>\n )\n}\n\nconst useStyles = () => {\n const sectionPadding = 16\n const inputPadding = 8\n\n return StyleSheet.create({\n formContent: {\n paddingVertical: sectionPadding,\n flex: 1,\n },\n toSection: {\n padding: sectionPadding,\n flexDirection: 'row',\n gap: 8,\n },\n groupName: {\n fontSize: 18,\n },\n titleSection: {\n padding: sectionPadding,\n paddingBottom: Platform.select({\n ios: sectionPadding,\n android: sectionPadding - inputPadding,\n }),\n gap: Platform.select({\n ios: 8,\n android: 0,\n }),\n },\n titleInput: {\n fontSize: 18,\n },\n memberSection: {\n padding: sectionPadding,\n paddingBottom: 0,\n },\n banner: {\n marginTop: 16,\n },\n })\n}\n"]}
1
+ {"version":3,"file":"groups_form.js","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/groups_form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StackActions, useNavigation } from '@react-navigation/native'\nimport React, { useCallback, useMemo, useState } from 'react'\nimport { Platform, StyleSheet, TextInput, View } from 'react-native'\nimport { Banner, ChildNotice, Heading, Text } from '../../../components'\nimport { ActionButton } from '../../../components/display/action_button'\nimport { useCurrentPerson, useSuspenseGet } from '../../../hooks'\nimport { GroupsGroupResource } from '../../../types'\nimport { Divider, FormList } from './form_list'\nimport { pluralize } from '../../../utils'\nimport { KeyboardView } from '../../../components/display/keyboard_view'\nimport {\n useGroupMembersForNewConversation,\n GroupMembersForNewConversationResult,\n} from '../../../hooks/groups/use_group_members_for_new_conversation'\nimport { useGroupsConversationCreate } from '../../../hooks/groups/use_groups_conversation_create'\nimport { useTheme } from '../../../hooks'\n\ntype GroupsFormProps = {\n groupId: number\n}\n\nexport const GroupsForm = ({ groupId }: GroupsFormProps) => {\n const navigation = useNavigation()\n const [title, setTitle] = useState<string>()\n const { data: group } = useSuspenseGet<GroupsGroupResource>({\n url: `/me/groups/${groupId}`,\n data: {\n fields: {\n Group: [],\n },\n },\n app: 'groups',\n })\n\n const groupMemberships = useGroupMembersForNewConversation({ id: groupId })\n\n const redirectToConversation = useCallback(\n (conversationId: number) => {\n // exit from the create stack\n navigation.getParent()?.goBack()\n // navigate to the conversation screen\n navigation.dispatch(\n StackActions.push('Conversation', {\n conversation_id: conversationId,\n })\n )\n },\n [navigation]\n )\n\n const { mutate: handleSave } = useGroupsConversationCreate({\n groupId,\n title,\n onSuccess: redirectToConversation,\n })\n\n return (\n <KeyboardView>\n <FormList\n memberData={groupMemberships.adultMembers}\n FormContent={\n <FormContent\n group={group}\n title={title}\n setTitle={setTitle}\n groupMemberships={groupMemberships}\n />\n }\n />\n <ActionButton\n disabled={!title}\n title=\"Start Conversation\"\n onPress={() => handleSave()}\n infoText=\"Conversation will be automatically updated if any members are added or removed from this group.\"\n />\n </KeyboardView>\n )\n}\n\ninterface FormContentProps {\n group: GroupsGroupResource\n title?: string\n setTitle: (title: string) => void\n groupMemberships: GroupMembersForNewConversationResult\n}\n\nfunction FormContent({ group, title, setTitle, groupMemberships }: FormContentProps) {\n const styles = useStyles()\n const currentPerson = useCurrentPerson()\n const { name, membershipsCount } = group\n\n const myGroupsMembership = useMemo(\n () => groupMemberships.data.find(m => m.id === currentPerson.id),\n [groupMemberships.data, currentPerson.id]\n )\n const isLeader = myGroupsMembership?.role === 'leader'\n\n const childMembers = groupMemberships.childMembers\n const hasChildren = childMembers.length > 0\n const adultCount = groupMemberships.adultMembers.length\n const memberCount = isLeader ? membershipsCount : adultCount\n const memberHeaderLabel = `${pluralize(memberCount, 'member')} selected`\n\n const showMemberError = groupMemberships.isError\n const showChildNotice = hasChildren && isLeader\n\n return (\n <View style={styles.formContent}>\n <View style={styles.toSection}>\n <Heading variant=\"h3\">To:</Heading>\n <Text style={styles.groupName}>{name}</Text>\n </View>\n <Divider />\n <View style={styles.titleSection}>\n <Heading variant=\"h3\">Title</Heading>\n <TextInput\n placeholder=\"Topic of conversation (required)\"\n value={title}\n onChangeText={setTitle}\n style={styles.titleInput}\n autoFocus={true}\n />\n </View>\n <Divider />\n <View style={styles.memberSection}>\n <Heading variant=\"h3\">{memberHeaderLabel}</Heading>\n {showChildNotice && <ChildNotice childMembers={childMembers} style={styles.banner} />}\n {showMemberError && (\n <Banner\n appearance=\"error\"\n description=\"There was an issue loading group members, please refresh and try again.\"\n style={styles.banner}\n />\n )}\n </View>\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const sectionPadding = 16\n const inputPadding = 8\n\n return StyleSheet.create({\n formContent: {\n paddingVertical: sectionPadding,\n flex: 1,\n },\n toSection: {\n padding: sectionPadding,\n flexDirection: 'row',\n gap: 8,\n },\n groupName: {\n fontSize: 18,\n },\n titleSection: {\n padding: sectionPadding,\n paddingBottom: Platform.select({\n ios: sectionPadding,\n android: sectionPadding - inputPadding,\n }),\n gap: Platform.select({\n ios: 8,\n android: 0,\n }),\n },\n titleInput: {\n fontSize: 18,\n color: colors.textColorDefaultPrimary,\n },\n memberSection: {\n padding: sectionPadding,\n paddingBottom: 0,\n },\n banner: {\n marginTop: 16,\n },\n })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "3.2.0-rc.23",
3
+ "version": "3.2.0-rc.24",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -55,5 +55,5 @@
55
55
  "prettier": "^3.4.2",
56
56
  "typescript": "<5.6.0"
57
57
  },
58
- "gitHead": "2c83d20e080e3f75b83d800827ff6c8ac018e830"
58
+ "gitHead": "95297a29c653d2904fa975bc4f1e655d3ccc1366"
59
59
  }
@@ -1,8 +1,19 @@
1
- import { MemberBadge, MemberResource } from '../../types'
1
+ import { MemberBadge, MemberResource, ResourceObject } from '../../types'
2
2
  import { GroupsGroupMemberResource } from '../../types/resources/groups/groups_member_resource_with_person'
3
3
  import { useApiPaginator } from '../use_api'
4
4
  import { useCurrentPerson } from '../use_current_person'
5
5
 
6
+ type UseApiPaginatorResult<T extends ResourceObject> = ReturnType<typeof useApiPaginator<T>>
7
+
8
+ export type GroupMembersForNewConversationResult = Omit<
9
+ UseApiPaginatorResult<GroupsGroupMemberResource>, // We are passing our own "members" data shape
10
+ 'data'
11
+ > & {
12
+ data: MemberResource[]
13
+ adultMembers: MemberResource[]
14
+ childMembers: MemberResource[]
15
+ }
16
+
6
17
  /**
7
18
  * This is specifically for the new conversation screen because we assign
8
19
  * the "Conversation owner" badge to the current person.
@@ -33,6 +44,7 @@ export function useGroupMembersForNewConversation({ id }: { id: number }) {
33
44
  id: +person.id,
34
45
  name: `${person.firstName} ${person.lastName}`,
35
46
  source: [],
47
+ role: membership.role,
36
48
  }
37
49
  })
38
50
  const adultMembers = members.filter(member => !member.child)
@@ -1,15 +1,19 @@
1
1
  import { StackActions, useNavigation } from '@react-navigation/native'
2
- import React, { useCallback, useState } from 'react'
2
+ import React, { useCallback, useMemo, useState } from 'react'
3
3
  import { Platform, StyleSheet, TextInput, View } from 'react-native'
4
4
  import { Banner, ChildNotice, Heading, Text } from '../../../components'
5
5
  import { ActionButton } from '../../../components/display/action_button'
6
- import { useSuspenseGet } from '../../../hooks'
7
- import { GroupsGroupResource, MemberResource } from '../../../types'
6
+ import { useCurrentPerson, useSuspenseGet } from '../../../hooks'
7
+ import { GroupsGroupResource } from '../../../types'
8
8
  import { Divider, FormList } from './form_list'
9
9
  import { pluralize } from '../../../utils'
10
10
  import { KeyboardView } from '../../../components/display/keyboard_view'
11
- import { useGroupMembersForNewConversation } from '../../../hooks/groups/use_group_members_for_new_conversation'
11
+ import {
12
+ useGroupMembersForNewConversation,
13
+ GroupMembersForNewConversationResult,
14
+ } from '../../../hooks/groups/use_group_members_for_new_conversation'
12
15
  import { useGroupsConversationCreate } from '../../../hooks/groups/use_groups_conversation_create'
16
+ import { useTheme } from '../../../hooks'
13
17
 
14
18
  type GroupsFormProps = {
15
19
  groupId: number
@@ -28,6 +32,8 @@ export const GroupsForm = ({ groupId }: GroupsFormProps) => {
28
32
  app: 'groups',
29
33
  })
30
34
 
35
+ const groupMemberships = useGroupMembersForNewConversation({ id: groupId })
36
+
31
37
  const redirectToConversation = useCallback(
32
38
  (conversationId: number) => {
33
39
  // exit from the create stack
@@ -42,8 +48,6 @@ export const GroupsForm = ({ groupId }: GroupsFormProps) => {
42
48
  [navigation]
43
49
  )
44
50
 
45
- const groupMemberships = useGroupMembersForNewConversation({ id: groupId })
46
-
47
51
  const { mutate: handleSave } = useGroupsConversationCreate({
48
52
  groupId,
49
53
  title,
@@ -59,8 +63,7 @@ export const GroupsForm = ({ groupId }: GroupsFormProps) => {
59
63
  group={group}
60
64
  title={title}
61
65
  setTitle={setTitle}
62
- isMemberError={groupMemberships.isError}
63
- childMembers={groupMemberships.childMembers}
66
+ groupMemberships={groupMemberships}
64
67
  />
65
68
  }
66
69
  />
@@ -78,15 +81,28 @@ interface FormContentProps {
78
81
  group: GroupsGroupResource
79
82
  title?: string
80
83
  setTitle: (title: string) => void
81
- isMemberError: boolean
82
- childMembers: MemberResource[]
84
+ groupMemberships: GroupMembersForNewConversationResult
83
85
  }
84
86
 
85
- function FormContent({ group, title, setTitle, isMemberError, childMembers }: FormContentProps) {
87
+ function FormContent({ group, title, setTitle, groupMemberships }: FormContentProps) {
86
88
  const styles = useStyles()
89
+ const currentPerson = useCurrentPerson()
87
90
  const { name, membershipsCount } = group
88
- const memberHeader = pluralize(membershipsCount, 'member')
91
+
92
+ const myGroupsMembership = useMemo(
93
+ () => groupMemberships.data.find(m => m.id === currentPerson.id),
94
+ [groupMemberships.data, currentPerson.id]
95
+ )
96
+ const isLeader = myGroupsMembership?.role === 'leader'
97
+
98
+ const childMembers = groupMemberships.childMembers
89
99
  const hasChildren = childMembers.length > 0
100
+ const adultCount = groupMemberships.adultMembers.length
101
+ const memberCount = isLeader ? membershipsCount : adultCount
102
+ const memberHeaderLabel = `${pluralize(memberCount, 'member')} selected`
103
+
104
+ const showMemberError = groupMemberships.isError
105
+ const showChildNotice = hasChildren && isLeader
90
106
 
91
107
  return (
92
108
  <View style={styles.formContent}>
@@ -107,9 +123,9 @@ function FormContent({ group, title, setTitle, isMemberError, childMembers }: Fo
107
123
  </View>
108
124
  <Divider />
109
125
  <View style={styles.memberSection}>
110
- <Heading variant="h3">{memberHeader} selected</Heading>
111
- {hasChildren && <ChildNotice childMembers={childMembers} style={styles.banner} />}
112
- {isMemberError && (
126
+ <Heading variant="h3">{memberHeaderLabel}</Heading>
127
+ {showChildNotice && <ChildNotice childMembers={childMembers} style={styles.banner} />}
128
+ {showMemberError && (
113
129
  <Banner
114
130
  appearance="error"
115
131
  description="There was an issue loading group members, please refresh and try again."
@@ -122,6 +138,7 @@ function FormContent({ group, title, setTitle, isMemberError, childMembers }: Fo
122
138
  }
123
139
 
124
140
  const useStyles = () => {
141
+ const { colors } = useTheme()
125
142
  const sectionPadding = 16
126
143
  const inputPadding = 8
127
144
 
@@ -151,6 +168,7 @@ const useStyles = () => {
151
168
  },
152
169
  titleInput: {
153
170
  fontSize: 18,
171
+ color: colors.textColorDefaultPrimary,
154
172
  },
155
173
  memberSection: {
156
174
  padding: sectionPadding,