@planningcenter/chat-react-native 3.5.0-rc.0 → 3.5.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.
Files changed (235) hide show
  1. package/build/components/conversation/attachments/audio_attachment.d.ts +2 -2
  2. package/build/components/conversation/attachments/audio_attachment.d.ts.map +1 -1
  3. package/build/components/conversation/attachments/audio_attachment.js +2 -2
  4. package/build/components/conversation/attachments/audio_attachment.js.map +1 -1
  5. package/build/components/conversation/attachments/expanded_link.d.ts +2 -2
  6. package/build/components/conversation/attachments/expanded_link.d.ts.map +1 -1
  7. package/build/components/conversation/attachments/expanded_link.js +2 -2
  8. package/build/components/conversation/attachments/expanded_link.js.map +1 -1
  9. package/build/components/conversation/attachments/generic_file_attachment.d.ts +2 -2
  10. package/build/components/conversation/attachments/generic_file_attachment.d.ts.map +1 -1
  11. package/build/components/conversation/attachments/generic_file_attachment.js +2 -2
  12. package/build/components/conversation/attachments/generic_file_attachment.js.map +1 -1
  13. package/build/components/conversation/attachments/giphy_attachment.d.ts +2 -2
  14. package/build/components/conversation/attachments/giphy_attachment.d.ts.map +1 -1
  15. package/build/components/conversation/attachments/giphy_attachment.js +18 -5
  16. package/build/components/conversation/attachments/giphy_attachment.js.map +1 -1
  17. package/build/components/conversation/attachments/image_attachment.d.ts +2 -2
  18. package/build/components/conversation/attachments/image_attachment.d.ts.map +1 -1
  19. package/build/components/conversation/attachments/image_attachment.js +3 -3
  20. package/build/components/conversation/attachments/image_attachment.js.map +1 -1
  21. package/build/components/conversation/attachments/video_attachment.d.ts +2 -2
  22. package/build/components/conversation/attachments/video_attachment.d.ts.map +1 -1
  23. package/build/components/conversation/attachments/video_attachment.js +2 -2
  24. package/build/components/conversation/attachments/video_attachment.js.map +1 -1
  25. package/build/components/conversation/empty_conversation_blank_state.js +1 -1
  26. package/build/components/conversation/empty_conversation_blank_state.js.map +1 -1
  27. package/build/components/conversation/message.d.ts +5 -2
  28. package/build/components/conversation/message.d.ts.map +1 -1
  29. package/build/components/conversation/message.js +11 -9
  30. package/build/components/conversation/message.js.map +1 -1
  31. package/build/components/conversation/message_attachments.d.ts +3 -2
  32. package/build/components/conversation/message_attachments.d.ts.map +1 -1
  33. package/build/components/conversation/message_attachments.js +9 -9
  34. package/build/components/conversation/message_attachments.js.map +1 -1
  35. package/build/components/conversations/conversation_actions.d.ts.map +1 -1
  36. package/build/components/conversations/conversation_actions.js +1 -1
  37. package/build/components/conversations/conversation_actions.js.map +1 -1
  38. package/build/components/conversations/conversation_preview.d.ts.map +1 -1
  39. package/build/components/conversations/conversation_preview.js +13 -3
  40. package/build/components/conversations/conversation_preview.js.map +1 -1
  41. package/build/components/conversations/conversations.js +3 -3
  42. package/build/components/conversations/conversations.js.map +1 -1
  43. package/build/components/display/action_button.d.ts +4 -1
  44. package/build/components/display/action_button.d.ts.map +1 -1
  45. package/build/components/display/action_button.js +20 -5
  46. package/build/components/display/action_button.js.map +1 -1
  47. package/build/components/display/avatar.d.ts +4 -1
  48. package/build/components/display/avatar.d.ts.map +1 -1
  49. package/build/components/display/avatar.js +3 -2
  50. package/build/components/display/avatar.js.map +1 -1
  51. package/build/components/display/avatar_group.d.ts +4 -1
  52. package/build/components/display/avatar_group.d.ts.map +1 -1
  53. package/build/components/display/avatar_group.js +6 -3
  54. package/build/components/display/avatar_group.js.map +1 -1
  55. package/build/components/display/blank_state.d.ts +7 -2
  56. package/build/components/display/blank_state.d.ts.map +1 -1
  57. package/build/components/display/blank_state.js +6 -5
  58. package/build/components/display/blank_state.js.map +1 -1
  59. package/build/components/display/child_notice.d.ts +2 -1
  60. package/build/components/display/child_notice.d.ts.map +1 -1
  61. package/build/components/display/child_notice.js +4 -4
  62. package/build/components/display/child_notice.js.map +1 -1
  63. package/build/components/display/heading.d.ts +2 -3
  64. package/build/components/display/heading.d.ts.map +1 -1
  65. package/build/components/display/heading.js.map +1 -1
  66. package/build/components/display/icon.d.ts +2 -1
  67. package/build/components/display/icon.d.ts.map +1 -1
  68. package/build/components/display/icon.js +3 -0
  69. package/build/components/display/icon.js.map +1 -1
  70. package/build/components/display/icon_button.d.ts +4 -0
  71. package/build/components/display/icon_button.d.ts.map +1 -1
  72. package/build/components/display/icon_button.js +32 -0
  73. package/build/components/display/icon_button.js.map +1 -1
  74. package/build/components/display/image_attachment_preview.d.ts +14 -0
  75. package/build/components/display/image_attachment_preview.d.ts.map +1 -0
  76. package/build/components/display/image_attachment_preview.js +42 -0
  77. package/build/components/display/image_attachment_preview.js.map +1 -0
  78. package/build/components/display/index.d.ts +2 -0
  79. package/build/components/display/index.d.ts.map +1 -1
  80. package/build/components/display/index.js +2 -0
  81. package/build/components/display/index.js.map +1 -1
  82. package/build/components/display/keyboard_view.d.ts +2 -1
  83. package/build/components/display/keyboard_view.d.ts.map +1 -1
  84. package/build/components/display/keyboard_view.js +13 -11
  85. package/build/components/display/keyboard_view.js.map +1 -1
  86. package/build/components/display/person.d.ts.map +1 -1
  87. package/build/components/display/person.js +4 -1
  88. package/build/components/display/person.js.map +1 -1
  89. package/build/components/display/platform_modal_header_buttons.d.ts +15 -0
  90. package/build/components/display/platform_modal_header_buttons.d.ts.map +1 -0
  91. package/build/components/display/platform_modal_header_buttons.js +43 -0
  92. package/build/components/display/platform_modal_header_buttons.js.map +1 -0
  93. package/build/components/display/video_attachment_preview.d.ts +8 -0
  94. package/build/components/display/video_attachment_preview.d.ts.map +1 -0
  95. package/build/components/display/video_attachment_preview.js +71 -0
  96. package/build/components/display/video_attachment_preview.js.map +1 -0
  97. package/build/components/group_conversation_list.d.ts +1 -1
  98. package/build/components/group_conversation_list.d.ts.map +1 -1
  99. package/build/components/group_conversation_list.js +8 -6
  100. package/build/components/group_conversation_list.js.map +1 -1
  101. package/build/components/page/error_boundary.d.ts.map +1 -1
  102. package/build/components/page/error_boundary.js +4 -1
  103. package/build/components/page/error_boundary.js.map +1 -1
  104. package/build/components/primitive/avatar_primitive.d.ts +6 -1
  105. package/build/components/primitive/avatar_primitive.d.ts.map +1 -1
  106. package/build/components/primitive/avatar_primitive.js +24 -3
  107. package/build/components/primitive/avatar_primitive.js.map +1 -1
  108. package/build/contexts/chat_context.d.ts +1 -0
  109. package/build/contexts/chat_context.d.ts.map +1 -1
  110. package/build/contexts/chat_context.js +5 -3
  111. package/build/contexts/chat_context.js.map +1 -1
  112. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +14 -196
  113. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts.map +1 -1
  114. package/build/hooks/groups/use_group_members_for_new_conversation.js +2 -2
  115. package/build/hooks/groups/use_group_members_for_new_conversation.js.map +1 -1
  116. package/build/hooks/use_app_state.d.ts +2 -0
  117. package/build/hooks/use_app_state.d.ts.map +1 -0
  118. package/build/hooks/use_app_state.js +16 -0
  119. package/build/hooks/use_app_state.js.map +1 -0
  120. package/build/hooks/use_conversation.d.ts.map +1 -1
  121. package/build/hooks/use_conversation.js +7 -1
  122. package/build/hooks/use_conversation.js.map +1 -1
  123. package/build/hooks/use_conversations_actions.d.ts +9 -9
  124. package/build/hooks/use_conversations_actions.js +4 -4
  125. package/build/hooks/use_conversations_actions.js.map +1 -1
  126. package/build/hooks/use_conversations_cache.d.ts.map +1 -1
  127. package/build/hooks/use_conversations_cache.js +8 -0
  128. package/build/hooks/use_conversations_cache.js.map +1 -1
  129. package/build/hooks/use_giphy.js.map +1 -1
  130. package/build/hooks/use_jolt.d.ts +2 -2
  131. package/build/hooks/use_jolt.d.ts.map +1 -1
  132. package/build/hooks/use_jolt.js +30 -7
  133. package/build/hooks/use_jolt.js.map +1 -1
  134. package/build/hooks/use_report_bug_action.d.ts +5 -0
  135. package/build/hooks/use_report_bug_action.d.ts.map +1 -0
  136. package/build/hooks/use_report_bug_action.js +30 -0
  137. package/build/hooks/use_report_bug_action.js.map +1 -0
  138. package/build/navigation/index.d.ts +5 -0
  139. package/build/navigation/index.d.ts.map +1 -1
  140. package/build/navigation/index.js +5 -0
  141. package/build/navigation/index.js.map +1 -1
  142. package/build/screens/attachment_actions/attachment_actions_screen.d.ts +6 -2
  143. package/build/screens/attachment_actions/attachment_actions_screen.d.ts.map +1 -1
  144. package/build/screens/attachment_actions/attachment_actions_screen.js +16 -16
  145. package/build/screens/attachment_actions/attachment_actions_screen.js.map +1 -1
  146. package/build/screens/attachment_actions/hooks/useDeleteAttachment.d.ts +10 -0
  147. package/build/screens/attachment_actions/hooks/useDeleteAttachment.d.ts.map +1 -0
  148. package/build/screens/attachment_actions/hooks/useDeleteAttachment.js +29 -0
  149. package/build/screens/attachment_actions/hooks/useDeleteAttachment.js.map +1 -0
  150. package/build/screens/bug_report_screen.d.ts +5 -0
  151. package/build/screens/bug_report_screen.d.ts.map +1 -0
  152. package/build/screens/bug_report_screen.js +237 -0
  153. package/build/screens/bug_report_screen.js.map +1 -0
  154. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  155. package/build/screens/conversation_details_screen.js +29 -10
  156. package/build/screens/conversation_details_screen.js.map +1 -1
  157. package/build/screens/conversation_new/components/form_list.d.ts +3 -1
  158. package/build/screens/conversation_new/components/form_list.d.ts.map +1 -1
  159. package/build/screens/conversation_new/components/form_list.js +6 -2
  160. package/build/screens/conversation_new/components/form_list.js.map +1 -1
  161. package/build/screens/conversation_new/components/groups_form.d.ts.map +1 -1
  162. package/build/screens/conversation_new/components/groups_form.js +3 -6
  163. package/build/screens/conversation_new/components/groups_form.js.map +1 -1
  164. package/build/screens/conversation_new/components/services_form.js +1 -1
  165. package/build/screens/conversation_new/components/services_form.js.map +1 -1
  166. package/build/screens/conversation_screen.d.ts.map +1 -1
  167. package/build/screens/conversation_screen.js +3 -5
  168. package/build/screens/conversation_screen.js.map +1 -1
  169. package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
  170. package/build/screens/conversations/conversations_screen.js +7 -2
  171. package/build/screens/conversations/conversations_screen.js.map +1 -1
  172. package/build/screens/design_system_screen.d.ts.map +1 -1
  173. package/build/screens/design_system_screen.js +29 -4
  174. package/build/screens/design_system_screen.js.map +1 -1
  175. package/build/types/resources/denormalized_attachment_resource.d.ts +2 -2
  176. package/build/types/resources/denormalized_attachment_resource.js.map +1 -1
  177. package/build/types/resources/member_ability.d.ts +1 -0
  178. package/build/types/resources/member_ability.d.ts.map +1 -1
  179. package/build/types/resources/member_ability.js.map +1 -1
  180. package/build/utils/request/conversation.d.ts +2 -1
  181. package/build/utils/request/conversation.d.ts.map +1 -1
  182. package/build/utils/request/conversation.js.map +1 -1
  183. package/package.json +2 -2
  184. package/src/components/conversation/attachments/audio_attachment.tsx +3 -3
  185. package/src/components/conversation/attachments/expanded_link.tsx +3 -8
  186. package/src/components/conversation/attachments/generic_file_attachment.tsx +3 -3
  187. package/src/components/conversation/attachments/giphy_attachment.tsx +23 -8
  188. package/src/components/conversation/attachments/image_attachment.tsx +4 -4
  189. package/src/components/conversation/attachments/video_attachment.tsx +3 -3
  190. package/src/components/conversation/empty_conversation_blank_state.tsx +1 -1
  191. package/src/components/conversation/message.tsx +20 -8
  192. package/src/components/conversation/message_attachments.tsx +18 -11
  193. package/src/components/conversations/conversation_actions.tsx +1 -0
  194. package/src/components/conversations/conversation_preview.tsx +24 -3
  195. package/src/components/conversations/conversations.tsx +3 -3
  196. package/src/components/display/action_button.tsx +32 -4
  197. package/src/components/display/avatar.tsx +17 -2
  198. package/src/components/display/avatar_group.tsx +19 -3
  199. package/src/components/display/blank_state.tsx +21 -8
  200. package/src/components/display/child_notice.tsx +7 -4
  201. package/src/components/display/heading.tsx +2 -2
  202. package/src/components/display/icon.tsx +4 -1
  203. package/src/components/display/icon_button.tsx +32 -0
  204. package/src/components/display/image_attachment_preview.tsx +74 -0
  205. package/src/components/display/index.ts +2 -0
  206. package/src/components/display/keyboard_view.tsx +16 -17
  207. package/src/components/display/person.tsx +4 -1
  208. package/src/components/display/platform_modal_header_buttons.tsx +83 -0
  209. package/src/components/display/video_attachment_preview.tsx +105 -0
  210. package/src/components/group_conversation_list.tsx +14 -7
  211. package/src/components/page/error_boundary.tsx +4 -1
  212. package/src/components/primitive/avatar_primitive.tsx +42 -4
  213. package/src/contexts/chat_context.tsx +6 -3
  214. package/src/hooks/groups/use_group_members_for_new_conversation.ts +6 -4
  215. package/src/hooks/use_app_state.ts +20 -0
  216. package/src/hooks/use_conversation.ts +7 -1
  217. package/src/hooks/use_conversations_actions.ts +5 -5
  218. package/src/hooks/use_conversations_cache.ts +7 -0
  219. package/src/hooks/use_giphy.ts +2 -2
  220. package/src/hooks/use_jolt.ts +38 -9
  221. package/src/hooks/use_report_bug_action.ts +37 -0
  222. package/src/navigation/index.tsx +5 -0
  223. package/src/screens/attachment_actions/attachment_actions_screen.tsx +35 -16
  224. package/src/screens/attachment_actions/hooks/useDeleteAttachment.tsx +46 -0
  225. package/src/screens/bug_report_screen.tsx +334 -0
  226. package/src/screens/conversation_details_screen.tsx +41 -7
  227. package/src/screens/conversation_new/components/form_list.tsx +17 -1
  228. package/src/screens/conversation_new/components/groups_form.tsx +6 -5
  229. package/src/screens/conversation_new/components/services_form.tsx +3 -1
  230. package/src/screens/conversation_screen.tsx +9 -5
  231. package/src/screens/conversations/conversations_screen.tsx +11 -1
  232. package/src/screens/design_system_screen.tsx +68 -3
  233. package/src/types/resources/denormalized_attachment_resource.ts +2 -2
  234. package/src/types/resources/member_ability.ts +1 -0
  235. package/src/utils/request/conversation.ts +2 -1
@@ -21,7 +21,7 @@ import {
21
21
  } from 'react-native'
22
22
  import { HeaderTitle as ElementsHeaderTitle, HeaderTitleProps } from '@react-navigation/elements'
23
23
  import { Badge, ChildNotice, Heading, Icon, Person, Switch, Text, TextButton } from '../components'
24
- import { useSuspenseGet, useTheme } from '../hooks'
24
+ import { useSuspensePaginator, useTheme } from '../hooks'
25
25
  import {
26
26
  useConversation,
27
27
  useConversationDelete,
@@ -45,6 +45,7 @@ enum SectionTypes {
45
45
  header,
46
46
  hidden,
47
47
  members,
48
+ loadingMembers,
48
49
  setting,
49
50
  view,
50
51
  }
@@ -52,6 +53,7 @@ enum SectionTypes {
52
53
  type SectionListData = Array<
53
54
  | DataItem<{ title: string }, SectionTypes.header>
54
55
  | DataItem<MemberResource, SectionTypes.members>
56
+ | DataItem<any, SectionTypes.loadingMembers>
55
57
  | DataItem<ViewProps, SectionTypes.view>
56
58
  | DataItem<SettingRowProps, SectionTypes.setting>
57
59
  | DataItem<any, SectionTypes.hidden>
@@ -91,7 +93,11 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
91
93
  const canDelete = conversation.memberAbility?.canDelete || false
92
94
  const isLeader = conversation.memberAbility?.leader || false
93
95
 
94
- const { data: members } = useSuspenseGet<MemberResource[]>({
96
+ const {
97
+ data: members,
98
+ fetchNextPage: fetchNextPageOfMembers,
99
+ isFetchingNextPage: isLoadingMembers,
100
+ } = useSuspensePaginator<MemberResource>({
95
101
  url: `/me/conversations/${route.params.conversation_id}/members`,
96
102
  data: {
97
103
  include: ['person'],
@@ -120,6 +126,16 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
120
126
  }
121
127
  })
122
128
 
129
+ const loadingMemberItems = isLoadingMembers
130
+ ? [
131
+ {
132
+ type: SectionTypes.loadingMembers,
133
+ data: {},
134
+ sectionInnerStyle: styles.sectionInnerFirstMember,
135
+ },
136
+ ]
137
+ : []
138
+
123
139
  const childMembers = members.filter(member => member.child)
124
140
  const hasChildren = childMembers.length > 0
125
141
 
@@ -267,6 +283,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
267
283
  sectionInnerStyle: styles.sectionInnerChildNotice,
268
284
  },
269
285
  ...memberItems,
286
+ ...loadingMemberItems,
270
287
  ].filter(item => item.type !== SectionTypes.hidden)
271
288
 
272
289
  const headerIndices = listData
@@ -310,6 +327,18 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
310
327
  <Person person={{ ...item.data }} />
311
328
  </ListSection>
312
329
  )
330
+ case SectionTypes.loadingMembers:
331
+ return (
332
+ <ListSection
333
+ isStart={isStart}
334
+ isEnd={isEnd}
335
+ showBottomBorder={item?.showBottomBorder}
336
+ outerStyle={item?.sectionOuterStyle}
337
+ innerStyle={item?.sectionInnerStyle}
338
+ >
339
+ <Text>Loading more...</Text>
340
+ </ListSection>
341
+ )
313
342
  case SectionTypes.setting:
314
343
  return (
315
344
  <ListSection
@@ -338,6 +367,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
338
367
  return null
339
368
  }
340
369
  }}
370
+ onEndReached={fetchNextPageOfMembers}
341
371
  />
342
372
  </View>
343
373
  )
@@ -408,9 +438,11 @@ function TitleInput({ canUpdate, title, setTitle, style, isEmpty }: InputProps)
408
438
  submitBehavior="blurAndSubmit"
409
439
  />
410
440
  {isEmpty && (
411
- <Text variant="footnote" style={styles.inputValidationText}>
412
- A title is required for your conversation.
413
- </Text>
441
+ <View style={styles.inputValidationContainer}>
442
+ <Text variant="footnote" style={styles.inputValidationText}>
443
+ A title is required for your conversation.
444
+ </Text>
445
+ </View>
414
446
  )}
415
447
  </Pressable>
416
448
  )
@@ -561,12 +593,14 @@ const useStyles = ({ isStart, isEnd }: { isStart?: boolean; isEnd?: boolean } =
561
593
  titleInputDisabled: {
562
594
  color: colors.textColorDefaultSecondary,
563
595
  },
564
- inputValidationText: {
565
- color: colors.statusErrorText,
596
+ inputValidationContainer: {
566
597
  paddingTop: 8,
567
598
  borderTopWidth: 1,
568
599
  borderColor: colors.borderColorStatusError,
569
600
  },
601
+ inputValidationText: {
602
+ color: colors.statusErrorText,
603
+ },
570
604
  settingRow: {
571
605
  flexDirection: 'row',
572
606
  justifyContent: 'space-between',
@@ -7,11 +7,19 @@ import { useTheme } from '../../../hooks'
7
7
 
8
8
  interface FormListProps {
9
9
  memberData: MemberResource[]
10
+ loadingMore?: boolean
10
11
  FormContent?: FlashListProps<MemberResource>['ListHeaderComponent']
11
12
  listEmptyText?: string
13
+ onEndReached?: () => void
12
14
  }
13
15
 
14
- export const FormList = ({ memberData, FormContent, listEmptyText }: FormListProps) => {
16
+ export const FormList = ({
17
+ memberData,
18
+ loadingMore,
19
+ FormContent,
20
+ listEmptyText,
21
+ onEndReached,
22
+ }: FormListProps) => {
15
23
  const styles = useStyles()
16
24
 
17
25
  return (
@@ -19,9 +27,13 @@ export const FormList = ({ memberData, FormContent, listEmptyText }: FormListPro
19
27
  data={memberData}
20
28
  ListHeaderComponent={FormContent}
21
29
  renderItem={({ item }) => <Person person={item} style={styles.person} />}
30
+ ListFooterComponent={
31
+ loadingMore ? <Text style={styles.loadingMore}>Loading more...</Text> : null
32
+ }
22
33
  keyExtractor={item => item.id.toString()}
23
34
  estimatedItemSize={45}
24
35
  ListEmptyComponent={<ListEmptyText text={listEmptyText || 'No members found'} />}
36
+ onEndReached={onEndReached}
25
37
  />
26
38
  )
27
39
  }
@@ -50,6 +62,10 @@ const useStyles = () => {
50
62
  paddingHorizontal: 16,
51
63
  paddingBottom: 12,
52
64
  },
65
+ loadingMore: {
66
+ paddingHorizontal: 16,
67
+ paddingBottom: 12,
68
+ },
53
69
  emptyTextContainer: {
54
70
  alignItems: 'center',
55
71
  justifyContent: 'center',
@@ -58,6 +58,8 @@ export const GroupsForm = ({ groupId, chat_group_graph_id }: GroupsFormProps) =>
58
58
  <KeyboardView>
59
59
  <FormList
60
60
  memberData={groupMemberships.adultMembers}
61
+ loadingMore={groupMemberships.isFetchingNextPage}
62
+ onEndReached={groupMemberships.fetchNextPage}
61
63
  FormContent={
62
64
  <FormContent
63
65
  group={group}
@@ -97,12 +99,9 @@ function FormContent({ group, title, setTitle, groupMemberships }: FormContentPr
97
99
 
98
100
  const childMembers = groupMemberships.childMembers
99
101
  const hasChildren = childMembers.length > 0
100
- const adultCount = groupMemberships.adultMembers.length
101
- const memberCount = isLeader ? membershipsCount : adultCount
102
- const memberHeaderLabel = `${pluralize(memberCount, 'member')} selected`
102
+ const memberHeaderLabel = `${pluralize(membershipsCount, 'member')} selected`
103
103
 
104
104
  const showMemberError = groupMemberships.isError
105
- const showChildNotice = hasChildren && isLeader
106
105
 
107
106
  return (
108
107
  <View style={styles.formContent}>
@@ -124,7 +123,9 @@ function FormContent({ group, title, setTitle, groupMemberships }: FormContentPr
124
123
  <Divider />
125
124
  <View style={styles.memberSection}>
126
125
  <Heading variant="h3">{memberHeaderLabel}</Heading>
127
- {showChildNotice && <ChildNotice childMembers={childMembers} style={styles.banner} />}
126
+ {hasChildren && (
127
+ <ChildNotice childMembers={childMembers} showMembers={isLeader} style={styles.banner} />
128
+ )}
128
129
  {showMemberError && (
129
130
  <Banner
130
131
  appearance="error"
@@ -162,7 +162,9 @@ function FormContent({
162
162
  <Divider />
163
163
  <View style={styles.memberSection}>
164
164
  <Heading variant="h3">{pluralize(memberCount, 'member')} selected</Heading>
165
- {hasChildren && <ChildNotice childMembers={childMembers} style={styles.banner} />}
165
+ {hasChildren && (
166
+ <ChildNotice childMembers={childMembers} showMembers={true} style={styles.banner} />
167
+ )}
166
168
  {isMemberError && (
167
169
  <Banner
168
170
  appearance="error"
@@ -55,6 +55,7 @@ export function ConversationScreen({ route }: ConversationScreenProps) {
55
55
  const { repliesDisabled, memberAbility } = conversation
56
56
  const canReply = memberAbility?.canReply
57
57
  const showLeaderDisabledReplyBanner = canReply && repliesDisabled
58
+ const canDeleteNonAuthoredMessages = memberAbility?.canDeleteNonAuthoredMessages ?? false
58
59
 
59
60
  // Seems to be necessary to define this way so we get the route picked up
60
61
  const headerTitle = useCallback(
@@ -70,7 +71,7 @@ export function ConversationScreen({ route }: ConversationScreenProps) {
70
71
 
71
72
  return (
72
73
  <View style={styles.container}>
73
- <KeyboardView style={styles.keyboardView}>
74
+ <KeyboardView>
74
75
  {noMessages ? (
75
76
  <EmptyConversationBlankState />
76
77
  ) : (
@@ -86,7 +87,13 @@ export function ConversationScreen({ route }: ConversationScreenProps) {
86
87
  return <InlineDateSeparator {...item} />
87
88
  }
88
89
 
89
- return <Message {...item} conversation_id={conversation_id} />
90
+ return (
91
+ <Message
92
+ {...item}
93
+ canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages}
94
+ conversation_id={conversation_id}
95
+ />
96
+ )
90
97
  }}
91
98
  onEndReached={() => fetchNextPage()}
92
99
  />
@@ -252,9 +259,6 @@ const useStyles = () => {
252
259
  backgroundColor: navigationTheme.colors.card,
253
260
  paddingBottom: bottom,
254
261
  },
255
- keyboardView: {
256
- flex: 1,
257
- },
258
262
  listContainer: {
259
263
  gap: 12,
260
264
  paddingHorizontal: 16,
@@ -1,7 +1,7 @@
1
1
  import { StaticScreenProps, useNavigation } from '@react-navigation/native'
2
2
  import React from 'react'
3
3
  import { StyleSheet, View } from 'react-native'
4
- import { Conversations } from '../../components'
4
+ import { Conversations, TextButton } from '../../components'
5
5
  import { ActionButton } from '../../components/display/action_button'
6
6
  import { ConversationsContextProvider } from '../../contexts/conversations_context'
7
7
  import { useCanCreateConversations } from '../../hooks'
@@ -54,6 +54,10 @@ export function ConversationsScreen({ route }: ConversationScreenProps) {
54
54
  })
55
55
  }
56
56
 
57
+ const reportABug = () => {
58
+ return navigation.navigate('BugReport')
59
+ }
60
+
57
61
  return (
58
62
  <View style={styles.container}>
59
63
  <ConversationsContextProvider args={route.params}>
@@ -63,6 +67,12 @@ export function ConversationsScreen({ route }: ConversationScreenProps) {
63
67
  visible={canCreateConversations}
64
68
  title="New conversation"
65
69
  onPress={handleNewConversationNavigation}
70
+ buttonIconNameLeft="churchCenter.signups"
71
+ secondaryButton={
72
+ <TextButton variant="tertiary" onPress={reportABug}>
73
+ Report a bug
74
+ </TextButton>
75
+ }
66
76
  />
67
77
  </View>
68
78
  )
@@ -8,6 +8,7 @@ import {
8
8
  Badge,
9
9
  Banner,
10
10
  BannerCollapsible,
11
+ BlankState,
11
12
  Button,
12
13
  ToggleButton,
13
14
  Heading,
@@ -20,6 +21,7 @@ import {
20
21
  Text,
21
22
  TextButton,
22
23
  TextInlineButton,
24
+ ImageAttachmentPreview,
23
25
  } from '../components/display'
24
26
  import {
25
27
  space,
@@ -28,7 +30,7 @@ import {
28
30
  platformFontWeightMedium,
29
31
  } from '../utils'
30
32
  import BannerPrimitive from '../components/primitive/banner_primitive'
31
- import { BlankState } from '../components/display/blank_state'
33
+ import { VideoAttachmentPreview } from '../components/display/video_attachment_preview'
32
34
 
33
35
  // =================================
34
36
  // ====== Docs Utils ===============
@@ -696,9 +698,41 @@ function ImageIconsSection({ isLast }: SectionProps) {
696
698
  <Image source={{ uri: URL.image }} style={styles.image} alt="" />
697
699
  </Row>
698
700
  </Group>
701
+ <Group
702
+ title="ImageAttachmentPreview"
703
+ description="Displays an image attachment in different sizes with a close button. It takes a `fileName` prop that gets passed to the image's `alt` attribute."
704
+ >
705
+ <Row>
706
+ <ImageAttachmentPreview
707
+ size="sm"
708
+ uri={URL.image}
709
+ fileName="mountains.jpg"
710
+ onClosePress={buttonPress}
711
+ />
712
+ <ImageAttachmentPreview
713
+ uri={URL.image}
714
+ fileName="mountains.jpg"
715
+ onClosePress={buttonPress}
716
+ />
717
+ <ImageAttachmentPreview
718
+ uri={URL.broken}
719
+ fileName="broken.jpg"
720
+ onClosePress={buttonPress}
721
+ />
722
+ </Row>
723
+ </Group>
724
+ <Group
725
+ title="VideoAttachmentPreview"
726
+ description="Displays an video attachment with a close button. It takes a `name` prop and an optional duration."
727
+ >
728
+ <Row>
729
+ <VideoAttachmentPreview name="mountains.mp4" onClosePress={buttonPress} />
730
+ <VideoAttachmentPreview name="mountains.mp4" duration="1:20" onClosePress={buttonPress} />
731
+ </Row>
732
+ </Group>
699
733
  <Group
700
734
  title="Avatar"
701
- description='Displays the profile image for a user in different sizes and has a loading fallback. Can optionally show an online/offline "presence" indicator.'
735
+ description='Displays the profile image for a user in different sizes and has a loading spinner. Can optionally show an online/offline "presence" indicator. Fallback condition and icon are optionally configurable.'
702
736
  >
703
737
  <Row>
704
738
  <Avatar sourceUri={URL.broken} />
@@ -710,10 +744,21 @@ function ImageIconsSection({ isLast }: SectionProps) {
710
744
  <Avatar presence="online" size="md" sourceUri={URL.avatar_fallback} />
711
745
  <Avatar presence="offline" sourceUri={URL.avatar} />
712
746
  </Row>
747
+ <Row>
748
+ <Avatar sourceUri="" />
749
+ <Avatar sourceUri="" size="md" />
750
+ <Avatar sourceUri="" size="sm" />
751
+ <Avatar
752
+ sourceUri={URL.broken}
753
+ showFallback={true}
754
+ fallbackIconName="general.star"
755
+ size="sm"
756
+ />
757
+ </Row>
713
758
  </Group>
714
759
  <Group
715
760
  title="AvatarGroup"
716
- description="Shows 1-4 images in a grid at different sizes. Loading fallback shows until all images successfully load."
761
+ description="Shows 1-4 images in a grid at different sizes. Loading spinner shows until all images successfully load. Fallback condition and icon are optionally configurable."
717
762
  >
718
763
  <Row>
719
764
  <AvatarGroup sourceUris={[URL.broken]} />
@@ -723,6 +768,26 @@ function ImageIconsSection({ isLast }: SectionProps) {
723
768
  <AvatarGroup sourceUris={URL.three_avatars} />
724
769
  <AvatarGroup sourceUris={URL.four_avatars} />
725
770
  </Row>
771
+ <Row>
772
+ <AvatarGroup sourceUris={[]} showFallback={true} fallbackIconName="general.person" />
773
+ <AvatarGroup
774
+ sourceUris={[]}
775
+ showFallback={true}
776
+ fallbackIconName="people.noTextMessage"
777
+ />
778
+ <AvatarGroup
779
+ sourceUris={[]}
780
+ showFallback={true}
781
+ fallbackIconName="general.star"
782
+ size="md"
783
+ />
784
+ <AvatarGroup
785
+ sourceUris={[]}
786
+ showFallback={true}
787
+ fallbackIconName="general.heart"
788
+ size="sm"
789
+ />
790
+ </Row>
726
791
  </Group>
727
792
  <Group
728
793
  title="Icon"
@@ -82,8 +82,8 @@ export interface DenormalizedGiphyAttachmentResourceForCreate extends GenericAtt
82
82
 
83
83
  interface GiphyVariant {
84
84
  url: string
85
- width: number
86
- height: number
85
+ width: string
86
+ height: string
87
87
  size: string
88
88
  frames: string
89
89
  }
@@ -2,6 +2,7 @@ export interface MemberAbilityResource {
2
2
  type: 'MemberAbility'
3
3
  canUpdate: boolean
4
4
  canDelete: boolean
5
+ canDeleteNonAuthoredMessages: boolean
5
6
  leader: boolean
6
7
  canReply: boolean
7
8
  }
@@ -1,8 +1,9 @@
1
+ import { GraphId } from '../../types/resources/group_resource'
1
2
  import { GetRequest } from '../client/types'
2
3
 
3
4
  export interface ConversationRequestArgs {
4
5
  gids: string
5
- chat_group_graph_id?: string
6
+ chat_group_graph_id?: GraphId
6
7
  group_source_app_name?: string
7
8
  }
8
9