@planningcenter/chat-react-native 3.1.0-rc.9 → 3.2.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.
Files changed (298) hide show
  1. package/build/components/conversation/attachments/attachment_card.d.ts +9 -0
  2. package/build/components/conversation/attachments/attachment_card.d.ts.map +1 -0
  3. package/build/components/conversation/attachments/attachment_card.js +35 -0
  4. package/build/components/conversation/attachments/attachment_card.js.map +1 -0
  5. package/build/components/conversation/attachments/audio_attachment.d.ts +6 -0
  6. package/build/components/conversation/attachments/audio_attachment.d.ts.map +1 -0
  7. package/build/components/conversation/attachments/audio_attachment.js +84 -0
  8. package/build/components/conversation/attachments/audio_attachment.js.map +1 -0
  9. package/build/components/conversation/attachments/constants.d.ts +3 -0
  10. package/build/components/conversation/attachments/constants.d.ts.map +1 -0
  11. package/build/components/conversation/attachments/constants.js +4 -0
  12. package/build/components/conversation/attachments/constants.js.map +1 -0
  13. package/build/components/conversation/attachments/download_attachment_button.d.ts +9 -0
  14. package/build/components/conversation/attachments/download_attachment_button.d.ts.map +1 -0
  15. package/build/components/conversation/attachments/download_attachment_button.js +29 -0
  16. package/build/components/conversation/attachments/download_attachment_button.js.map +1 -0
  17. package/build/components/conversation/attachments/expanded_link.d.ts +5 -0
  18. package/build/components/conversation/attachments/expanded_link.d.ts.map +1 -0
  19. package/build/components/conversation/attachments/expanded_link.js +44 -0
  20. package/build/components/conversation/attachments/expanded_link.js.map +1 -0
  21. package/build/components/conversation/attachments/generic_file_attachment.d.ts +7 -0
  22. package/build/components/conversation/attachments/generic_file_attachment.d.ts.map +1 -0
  23. package/build/components/conversation/attachments/generic_file_attachment.js +63 -0
  24. package/build/components/conversation/attachments/generic_file_attachment.js.map +1 -0
  25. package/build/components/conversation/attachments/giphy_attachment.d.ts +6 -0
  26. package/build/components/conversation/attachments/giphy_attachment.d.ts.map +1 -0
  27. package/build/components/conversation/attachments/giphy_attachment.js +42 -0
  28. package/build/components/conversation/attachments/giphy_attachment.js.map +1 -0
  29. package/build/components/conversation/attachments/image_attachment.d.ts +5 -0
  30. package/build/components/conversation/attachments/image_attachment.d.ts.map +1 -0
  31. package/build/components/conversation/attachments/image_attachment.js +24 -0
  32. package/build/components/conversation/attachments/image_attachment.js.map +1 -0
  33. package/build/components/conversation/attachments/video_attachment.d.ts +6 -0
  34. package/build/components/conversation/attachments/video_attachment.d.ts.map +1 -0
  35. package/build/components/conversation/attachments/video_attachment.js +64 -0
  36. package/build/components/conversation/attachments/video_attachment.js.map +1 -0
  37. package/build/components/conversation/message.d.ts +1 -1
  38. package/build/components/conversation/message.d.ts.map +1 -1
  39. package/build/components/conversation/message.js +13 -7
  40. package/build/components/conversation/message.js.map +1 -1
  41. package/build/components/conversation/message_attachments.d.ts +6 -0
  42. package/build/components/conversation/message_attachments.d.ts.map +1 -0
  43. package/build/components/conversation/message_attachments.js +52 -0
  44. package/build/components/conversation/message_attachments.js.map +1 -0
  45. package/build/components/conversation/message_markdown.d.ts +7 -0
  46. package/build/components/conversation/message_markdown.d.ts.map +1 -0
  47. package/build/components/conversation/message_markdown.js +38 -0
  48. package/build/components/conversation/message_markdown.js.map +1 -0
  49. package/build/components/conversations/conversation_preview.d.ts +9 -0
  50. package/build/components/conversations/conversation_preview.d.ts.map +1 -0
  51. package/build/components/conversations/conversation_preview.js +58 -0
  52. package/build/components/conversations/conversation_preview.js.map +1 -0
  53. package/build/components/conversations/conversations.d.ts +8 -0
  54. package/build/components/conversations/conversations.d.ts.map +1 -0
  55. package/build/components/conversations/conversations.js +40 -0
  56. package/build/components/conversations/conversations.js.map +1 -0
  57. package/build/components/conversations/unread_count_badge.d.ts +5 -0
  58. package/build/components/conversations/unread_count_badge.d.ts.map +1 -0
  59. package/build/components/conversations/unread_count_badge.js +33 -0
  60. package/build/components/conversations/unread_count_badge.js.map +1 -0
  61. package/build/components/display/badge.d.ts +9 -1
  62. package/build/components/display/badge.d.ts.map +1 -1
  63. package/build/components/display/badge.js +22 -10
  64. package/build/components/display/badge.js.map +1 -1
  65. package/build/components/display/button.d.ts +1 -1
  66. package/build/components/display/button.d.ts.map +1 -1
  67. package/build/components/display/button.js.map +1 -1
  68. package/build/components/display/child_notice.js +2 -2
  69. package/build/components/display/child_notice.js.map +1 -1
  70. package/build/components/display/icon.d.ts.map +1 -1
  71. package/build/components/display/icon.js +10 -8
  72. package/build/components/display/icon.js.map +1 -1
  73. package/build/components/display/text.js +2 -8
  74. package/build/components/display/text.js.map +1 -1
  75. package/build/components/index.d.ts +1 -1
  76. package/build/components/index.d.ts.map +1 -1
  77. package/build/components/index.js +1 -1
  78. package/build/components/index.js.map +1 -1
  79. package/build/components/page/error_boundary.d.ts +1 -1
  80. package/build/hooks/use_api.d.ts +6 -4
  81. package/build/hooks/use_api.d.ts.map +1 -1
  82. package/build/hooks/use_api.js +5 -2
  83. package/build/hooks/use_api.js.map +1 -1
  84. package/build/hooks/use_api_client.d.ts +1 -2
  85. package/build/hooks/use_api_client.d.ts.map +1 -1
  86. package/build/hooks/use_api_client.js.map +1 -1
  87. package/build/hooks/use_conversation.d.ts +76 -0
  88. package/build/hooks/use_conversation.d.ts.map +1 -1
  89. package/build/hooks/use_conversation.js +47 -3
  90. package/build/hooks/use_conversation.js.map +1 -1
  91. package/build/hooks/use_conversation_jolt_events.js +1 -1
  92. package/build/hooks/use_conversation_jolt_events.js.map +1 -1
  93. package/build/hooks/use_conversation_messages_jolt_events.js +1 -1
  94. package/build/hooks/use_conversation_messages_jolt_events.js.map +1 -1
  95. package/build/hooks/use_conversations.d.ts +2 -3
  96. package/build/hooks/use_conversations.d.ts.map +1 -1
  97. package/build/hooks/use_conversations.js +3 -29
  98. package/build/hooks/use_conversations.js.map +1 -1
  99. package/build/hooks/use_groups.d.ts +214 -0
  100. package/build/hooks/use_groups.d.ts.map +1 -0
  101. package/build/hooks/use_groups.js +22 -0
  102. package/build/hooks/use_groups.js.map +1 -0
  103. package/build/hooks/use_groups_groups.d.ts +208 -0
  104. package/build/hooks/use_groups_groups.d.ts.map +1 -0
  105. package/build/hooks/use_groups_groups.js +18 -0
  106. package/build/hooks/use_groups_groups.js.map +1 -0
  107. package/build/hooks/use_services_team.d.ts +4 -0
  108. package/build/hooks/use_services_team.d.ts.map +1 -0
  109. package/build/hooks/use_services_team.js +22 -0
  110. package/build/hooks/use_services_team.js.map +1 -0
  111. package/build/hooks/use_suspense_api.d.ts +2 -1
  112. package/build/hooks/use_suspense_api.d.ts.map +1 -1
  113. package/build/hooks/use_suspense_api.js +2 -1
  114. package/build/hooks/use_suspense_api.js.map +1 -1
  115. package/build/hooks/use_teams.d.ts +208 -0
  116. package/build/hooks/use_teams.d.ts.map +1 -0
  117. package/build/hooks/use_teams.js +22 -0
  118. package/build/hooks/use_teams.js.map +1 -0
  119. package/build/navigation/index.d.ts +4 -0
  120. package/build/navigation/index.d.ts.map +1 -1
  121. package/build/navigation/index.js +5 -0
  122. package/build/navigation/index.js.map +1 -1
  123. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  124. package/build/screens/conversation_details_screen.js +139 -59
  125. package/build/screens/conversation_details_screen.js.map +1 -1
  126. package/build/screens/conversation_filters/components/conversation_filters.d.ts +3 -0
  127. package/build/screens/conversation_filters/components/conversation_filters.d.ts.map +1 -0
  128. package/build/screens/conversation_filters/components/conversation_filters.js +173 -0
  129. package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -0
  130. package/build/screens/conversation_filters/components/rows.d.ts +31 -0
  131. package/build/screens/conversation_filters/components/rows.d.ts.map +1 -0
  132. package/build/screens/conversation_filters/components/rows.js +111 -0
  133. package/build/screens/conversation_filters/components/rows.js.map +1 -0
  134. package/build/screens/conversation_filters/context/conversation_filter_context.d.ts +23 -0
  135. package/build/screens/conversation_filters/context/conversation_filter_context.d.ts.map +1 -0
  136. package/build/screens/conversation_filters/context/conversation_filter_context.js +51 -0
  137. package/build/screens/conversation_filters/context/conversation_filter_context.js.map +1 -0
  138. package/build/screens/conversation_filters/filter_types.d.ts +7 -0
  139. package/build/screens/conversation_filters/filter_types.d.ts.map +1 -0
  140. package/build/screens/conversation_filters/filter_types.js +8 -0
  141. package/build/screens/conversation_filters/filter_types.js.map +1 -0
  142. package/build/screens/conversation_filters/group_filters.d.ts +6 -0
  143. package/build/screens/conversation_filters/group_filters.d.ts.map +1 -0
  144. package/build/screens/conversation_filters/group_filters.js +15 -0
  145. package/build/screens/conversation_filters/group_filters.js.map +1 -0
  146. package/build/screens/conversation_filters/hooks/filters.d.ts +415 -0
  147. package/build/screens/conversation_filters/hooks/filters.d.ts.map +1 -0
  148. package/build/screens/conversation_filters/hooks/filters.js +41 -0
  149. package/build/screens/conversation_filters/hooks/filters.js.map +1 -0
  150. package/build/screens/conversation_filters/screen_props.d.ts +13 -0
  151. package/build/screens/conversation_filters/screen_props.d.ts.map +1 -0
  152. package/build/screens/conversation_filters/screen_props.js +2 -0
  153. package/build/screens/conversation_filters/screen_props.js.map +1 -0
  154. package/build/screens/conversation_filters/team_filters.d.ts +6 -0
  155. package/build/screens/conversation_filters/team_filters.d.ts.map +1 -0
  156. package/build/screens/conversation_filters/team_filters.js +15 -0
  157. package/build/screens/conversation_filters/team_filters.js.map +1 -0
  158. package/build/screens/conversation_filters_screen.d.ts +6 -0
  159. package/build/screens/conversation_filters_screen.d.ts.map +1 -0
  160. package/build/screens/conversation_filters_screen.js +125 -0
  161. package/build/screens/conversation_filters_screen.js.map +1 -0
  162. package/build/screens/conversation_screen.js +10 -4
  163. package/build/screens/conversation_screen.js.map +1 -1
  164. package/build/screens/conversations_screen.d.ts +4 -2
  165. package/build/screens/conversations_screen.d.ts.map +1 -1
  166. package/build/screens/conversations_screen.js +139 -11
  167. package/build/screens/conversations_screen.js.map +1 -1
  168. package/build/screens/create/conversation_select_recipients_screen.d.ts.map +1 -1
  169. package/build/screens/create/conversation_select_recipients_screen.js +3 -11
  170. package/build/screens/create/conversation_select_recipients_screen.js.map +1 -1
  171. package/build/types/resources/group_resource.d.ts +4 -2
  172. package/build/types/resources/group_resource.d.ts.map +1 -1
  173. package/build/types/resources/group_resource.js.map +1 -1
  174. package/build/types/resources/index.d.ts +1 -0
  175. package/build/types/resources/index.d.ts.map +1 -1
  176. package/build/types/resources/index.js +1 -0
  177. package/build/types/resources/index.js.map +1 -1
  178. package/build/types/resources/member_ability.d.ts +1 -0
  179. package/build/types/resources/member_ability.d.ts.map +1 -1
  180. package/build/types/resources/member_ability.js.map +1 -1
  181. package/build/types/resources/services/index.d.ts +2 -0
  182. package/build/types/resources/services/index.d.ts.map +1 -0
  183. package/build/types/resources/services/index.js +2 -0
  184. package/build/types/resources/services/index.js.map +1 -0
  185. package/build/types/resources/services/team_resource.d.ts +48 -0
  186. package/build/types/resources/services/team_resource.d.ts.map +1 -0
  187. package/build/types/resources/services/team_resource.js +7 -0
  188. package/build/types/resources/services/team_resource.js.map +1 -0
  189. package/build/utils/index.d.ts +1 -0
  190. package/build/utils/index.d.ts.map +1 -1
  191. package/build/utils/index.js +1 -0
  192. package/build/utils/index.js.map +1 -1
  193. package/build/utils/native_adapters/audio.d.ts +13 -0
  194. package/build/utils/native_adapters/audio.d.ts.map +1 -0
  195. package/build/utils/native_adapters/audio.js +7 -0
  196. package/build/utils/native_adapters/audio.js.map +1 -0
  197. package/build/utils/native_adapters/configuration.d.ts +7 -1
  198. package/build/utils/native_adapters/configuration.d.ts.map +1 -1
  199. package/build/utils/native_adapters/configuration.js +17 -1
  200. package/build/utils/native_adapters/configuration.js.map +1 -1
  201. package/build/utils/native_adapters/index.d.ts +2 -0
  202. package/build/utils/native_adapters/index.d.ts.map +1 -1
  203. package/build/utils/native_adapters/index.js +2 -0
  204. package/build/utils/native_adapters/index.js.map +1 -1
  205. package/build/utils/native_adapters/video.d.ts +25 -0
  206. package/build/utils/native_adapters/video.d.ts.map +1 -0
  207. package/build/utils/native_adapters/video.js +7 -0
  208. package/build/utils/native_adapters/video.js.map +1 -0
  209. package/build/utils/parse_simple_markdown.d.ts +7 -0
  210. package/build/utils/parse_simple_markdown.d.ts.map +1 -0
  211. package/build/utils/parse_simple_markdown.js +32 -0
  212. package/build/utils/parse_simple_markdown.js.map +1 -0
  213. package/build/utils/pluralize.d.ts +2 -0
  214. package/build/utils/pluralize.d.ts.map +1 -0
  215. package/build/utils/pluralize.js +10 -0
  216. package/build/utils/pluralize.js.map +1 -0
  217. package/build/utils/request/conversation.d.ts +10 -0
  218. package/build/utils/request/conversation.d.ts.map +1 -0
  219. package/build/utils/request/conversation.js +32 -0
  220. package/build/utils/request/conversation.js.map +1 -0
  221. package/build/utils/request/messages.d.ts +15 -0
  222. package/build/utils/request/messages.d.ts.map +1 -0
  223. package/build/utils/request/messages.js +22 -0
  224. package/build/utils/request/messages.js.map +1 -0
  225. package/build/utils/theme.d.ts +1 -1
  226. package/build/utils/theme.d.ts.map +1 -1
  227. package/build/utils/theme.js +1 -1
  228. package/build/utils/theme.js.map +1 -1
  229. package/package.json +2 -2
  230. package/src/__tests__/utils/parse_simple_markdown.ts +93 -0
  231. package/src/__tests__/utils/pluralize.tsx +17 -0
  232. package/src/components/conversation/attachments/attachment_card.tsx +46 -0
  233. package/src/components/conversation/attachments/audio_attachment.tsx +102 -0
  234. package/src/components/conversation/attachments/constants.ts +5 -0
  235. package/src/components/conversation/attachments/download_attachment_button.tsx +46 -0
  236. package/src/components/conversation/attachments/expanded_link.tsx +54 -0
  237. package/src/components/conversation/attachments/generic_file_attachment.tsx +75 -0
  238. package/src/components/conversation/attachments/giphy_attachment.tsx +56 -0
  239. package/src/components/conversation/attachments/image_attachment.tsx +31 -0
  240. package/src/components/conversation/attachments/video_attachment.tsx +92 -0
  241. package/src/components/conversation/message.tsx +15 -6
  242. package/src/components/conversation/message_attachments.tsx +61 -0
  243. package/src/components/conversation/message_markdown.tsx +52 -0
  244. package/src/components/conversations/conversation_preview.tsx +84 -0
  245. package/src/components/conversations/conversations.tsx +79 -0
  246. package/src/components/conversations/unread_count_badge.tsx +38 -0
  247. package/src/components/display/badge.tsx +41 -10
  248. package/src/components/display/button.tsx +1 -1
  249. package/src/components/display/child_notice.tsx +2 -2
  250. package/src/components/display/icon.tsx +10 -8
  251. package/src/components/display/text.tsx +1 -7
  252. package/src/components/index.tsx +1 -1
  253. package/src/hooks/use_api.ts +11 -10
  254. package/src/hooks/use_api_client.ts +1 -1
  255. package/src/hooks/use_conversation.ts +51 -3
  256. package/src/hooks/use_conversation_jolt_events.ts +1 -1
  257. package/src/hooks/use_conversation_messages_jolt_events.ts +1 -1
  258. package/src/hooks/use_conversations.ts +3 -31
  259. package/src/hooks/use_groups.ts +31 -0
  260. package/src/hooks/use_groups_groups.ts +20 -0
  261. package/src/hooks/use_services_team.ts +30 -0
  262. package/src/hooks/use_suspense_api.ts +4 -4
  263. package/src/hooks/use_teams.ts +25 -0
  264. package/src/navigation/index.tsx +8 -0
  265. package/src/screens/conversation_details_screen.tsx +224 -111
  266. package/src/screens/conversation_filters/components/conversation_filters.tsx +233 -0
  267. package/src/screens/conversation_filters/components/rows.tsx +164 -0
  268. package/src/screens/conversation_filters/context/conversation_filter_context.tsx +65 -0
  269. package/src/screens/conversation_filters/filter_types.ts +6 -0
  270. package/src/screens/conversation_filters/group_filters.tsx +31 -0
  271. package/src/screens/conversation_filters/hooks/filters.ts +68 -0
  272. package/src/screens/conversation_filters/screen_props.ts +15 -0
  273. package/src/screens/conversation_filters/team_filters.tsx +31 -0
  274. package/src/screens/conversation_filters_screen.tsx +152 -0
  275. package/src/screens/conversation_screen.tsx +16 -4
  276. package/src/screens/conversations_screen.tsx +210 -13
  277. package/src/screens/create/conversation_select_recipients_screen.tsx +3 -11
  278. package/src/types/resources/group_resource.ts +5 -2
  279. package/src/types/resources/index.ts +1 -0
  280. package/src/types/resources/member_ability.ts +1 -0
  281. package/src/types/resources/services/index.ts +1 -0
  282. package/src/types/resources/services/team_resource.ts +60 -0
  283. package/src/utils/client/types.d.ts +2 -1
  284. package/src/utils/index.ts +1 -0
  285. package/src/utils/native_adapters/audio.ts +15 -0
  286. package/src/utils/native_adapters/configuration.ts +24 -1
  287. package/src/utils/native_adapters/index.ts +2 -0
  288. package/src/utils/native_adapters/video.ts +30 -0
  289. package/src/utils/parse_simple_markdown.ts +40 -0
  290. package/src/utils/pluralize.ts +11 -0
  291. package/src/utils/request/conversation.ts +46 -0
  292. package/src/utils/request/messages.ts +21 -0
  293. package/src/utils/theme.ts +2 -2
  294. package/build/components/conversations.d.ts +0 -3
  295. package/build/components/conversations.d.ts.map +0 -1
  296. package/build/components/conversations.js +0 -100
  297. package/build/components/conversations.js.map +0 -1
  298. package/src/components/conversations.tsx +0 -144
@@ -17,12 +17,15 @@ import {
17
17
  type ViewProps,
18
18
  Pressable,
19
19
  Alert,
20
+ Platform,
20
21
  } from 'react-native'
21
- import { ChildNotice, Heading, Icon, Person, Switch, Text, TextButton } from '../components'
22
+ import { HeaderTitle as ElementsHeaderTitle, HeaderTitleProps } from '@react-navigation/elements'
23
+ import { Badge, ChildNotice, Heading, Icon, Person, Switch, Text, TextButton } from '../components'
22
24
  import { useSuspenseGet, useTheme } from '../hooks'
23
25
  import {
24
26
  useConversation,
25
27
  useConversationDelete,
28
+ useConversationDisableReplies,
26
29
  useConversationMute,
27
30
  useConversationUpdate,
28
31
  } from '../hooks/use_conversation'
@@ -32,6 +35,7 @@ import { FlashList } from '@shopify/flash-list'
32
35
  import { space } from '../utils'
33
36
  import { tokens } from '../vendor/tapestry/tokens'
34
37
  import { ButtonAppearanceUnion } from '../components/display/utils/button_colors'
38
+ import { GroupResource } from '../types/resources/group_resource'
35
39
 
36
40
  // =========================================
37
41
  // ====== Factory Constants & Types ========
@@ -58,6 +62,7 @@ interface DataItem<T, TName extends SectionTypes> {
58
62
  data: T
59
63
  sectionOuterStyle?: ViewStyle
60
64
  sectionInnerStyle?: ViewStyle
65
+ showBottomBorder?: boolean
61
66
  }
62
67
 
63
68
  // =================================
@@ -75,6 +80,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
75
80
  const { data: conversation } = useConversation(route.params)
76
81
  const [title, setTitle] = useState(conversation.title)
77
82
  const { muted, setMuted } = useConversationMute(route.params)
83
+ const { repliesDisabled, setRepliesDisabled } = useConversationDisableReplies(route.params)
78
84
  const { mutate: saveTitle } = useConversationUpdate(route.params)
79
85
  const { mutate: deleteConversation } = useConversationDelete(route.params)
80
86
 
@@ -83,6 +89,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
83
89
 
84
90
  const canUpdate = conversation.memberAbility?.canUpdate || false
85
91
  const canDelete = conversation.memberAbility?.canDelete || false
92
+ const isLeader = conversation.memberAbility?.leader || false
86
93
 
87
94
  const { data: members } = useSuspenseGet<MemberResource[]>({
88
95
  url: `/me/conversations/${route.params.conversation_id}/members`,
@@ -94,16 +101,39 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
94
101
  },
95
102
  })
96
103
 
104
+ const memberSectionStyleMap = {
105
+ first: styles.sectionInnerFirstMember,
106
+ middle: styles.sectionInnerMiddleMiddle,
107
+ last: styles.sectionInnerLastMember,
108
+ }
109
+
110
+ const memberItems = members.map((data, index) => {
111
+ const isFirst = index === 0
112
+ const isLast = index === members.length - 1
113
+ const memberPosition = isFirst ? 'first' : isLast ? 'last' : 'middle'
114
+ const memberSectionStyle = memberSectionStyleMap[memberPosition]
115
+
116
+ return {
117
+ type: data.child ? SectionTypes.hidden : SectionTypes.members,
118
+ data,
119
+ sectionInnerStyle: memberSectionStyle,
120
+ }
121
+ })
122
+
97
123
  const childMembers = members.filter(member => member.child)
98
124
  const hasChildren = childMembers.length > 0
99
- const isLeader = true // TODO: replace with value from the server
100
125
 
101
- const memberItems = members.map(data => ({
102
- type: data.child ? SectionTypes.hidden : SectionTypes.members,
103
- data,
104
- sectionOuterStyle: styles.memberSectionOuter,
105
- sectionInnerStyle: styles.memberSectionInner,
106
- }))
126
+ const teamsGroup =
127
+ conversation.groups
128
+ ?.filter(g => g.sourceAppName === 'Services')
129
+ ?.filter(g => ['Team', 'PlanTeam'].includes(g.sourceType))
130
+ ?.filter(g => g.name !== null) || []
131
+ const hasTeams = teamsGroup.length > 0
132
+
133
+ const badge = conversation.badges?.[0]
134
+ const resourceType = badge?.pcoResourceType || ''
135
+ const productName = badge?.appName
136
+ const name = badge?.text || undefined
107
137
 
108
138
  const handleDelete = useCallback(() => {
109
139
  Alert.alert(
@@ -126,6 +156,24 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
126
156
  )
127
157
  }, [deleteConversation, navigation, title])
128
158
 
159
+ const HeaderTitle = useCallback(
160
+ (props: HeaderTitleProps) => {
161
+ return (
162
+ <View style={styles.headerTitleContainer}>
163
+ <ElementsHeaderTitle {...props} />
164
+ <Badge
165
+ variant="metaSubtle"
166
+ label={resourceType}
167
+ metaLabel={name}
168
+ style={styles.headerTitleBadge}
169
+ productLogoName={productName}
170
+ />
171
+ </View>
172
+ )
173
+ },
174
+ [name, productName, resourceType, styles.headerTitleBadge, styles.headerTitleContainer]
175
+ )
176
+
129
177
  const HeaderRight = useCallback(() => {
130
178
  return (
131
179
  <HeaderRightButton
@@ -142,8 +190,9 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
142
190
  useEffect(() => {
143
191
  navigation.setOptions({
144
192
  headerRight: HeaderRight,
193
+ headerTitle: HeaderTitle,
145
194
  })
146
- }, [HeaderRight, navigation])
195
+ }, [HeaderRight, HeaderTitle, navigation])
147
196
 
148
197
  const listData = [
149
198
  {
@@ -158,11 +207,13 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
158
207
  />
159
208
  ),
160
209
  },
210
+ sectionInnerStyle: styles.sectionInnerTitleInput,
161
211
  },
162
212
  {
163
213
  type: SectionTypes.header,
164
214
  data: { title: 'Settings' },
165
- sectionInnerStyle: styles.addBottomBorder,
215
+ showBottomBorder: true,
216
+ sectionInnerStyle: styles.sectionInnerHeaderWithBottomBorder,
166
217
  },
167
218
  {
168
219
  type: SectionTypes.setting,
@@ -170,28 +221,50 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
170
221
  title: 'Mute',
171
222
  rightItem: <Switch value={muted} onChange={() => setMuted(!muted)} />,
172
223
  },
173
- sectionInnerStyle: styles.addBottomBorder,
224
+ showBottomBorder: true,
225
+ },
226
+ {
227
+ type: canUpdate ? SectionTypes.setting : SectionTypes.hidden,
228
+ data: {
229
+ title: 'Freeze converation',
230
+ subtitle: 'Disables replies for everyone except leaders.',
231
+ rightItem: (
232
+ <Switch value={repliesDisabled} onChange={() => setRepliesDisabled(!repliesDisabled)} />
233
+ ),
234
+ },
235
+ showBottomBorder: true,
174
236
  },
175
237
  {
176
238
  type: canDelete ? SectionTypes.setting : SectionTypes.hidden,
177
239
  data: {
178
240
  title: 'Delete conversation…',
179
- style: styles.deleteButton,
180
241
  buttonTextStyle: styles.deleteButtonText,
181
242
  appearance: 'danger',
182
243
  onPress: handleDelete,
183
244
  },
184
245
  },
246
+ {
247
+ type: hasTeams ? SectionTypes.header : SectionTypes.hidden,
248
+ data: { title: 'Teams' },
249
+ sectionInnerStyle: styles.sectionInnerHeader,
250
+ },
251
+ {
252
+ type: hasTeams ? SectionTypes.view : SectionTypes.hidden,
253
+ data: {
254
+ children: <TeamsGroup teams={teamsGroup} />,
255
+ },
256
+ },
185
257
  {
186
258
  type: SectionTypes.header,
187
- data: { title: 'Members' },
259
+ data: { title: 'People' },
260
+ sectionInnerStyle: styles.sectionInnerHeader,
188
261
  },
189
262
  {
190
263
  type: hasChildren && isLeader ? SectionTypes.view : SectionTypes.hidden,
191
264
  data: {
192
265
  children: <ChildNotice childMembers={childMembers} />,
193
266
  },
194
- sectionOuterStyle: styles.childNoticeSectionOuter,
267
+ sectionInnerStyle: styles.sectionInnerChildNotice,
195
268
  },
196
269
  ...memberItems,
197
270
  ].filter(item => item.type !== SectionTypes.hidden)
@@ -201,97 +274,98 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
201
274
  .filter(isDefined)
202
275
 
203
276
  return (
204
- <FlashList
205
- data={listData as SectionListData}
206
- estimatedItemSize={52}
207
- contentContainerStyle={styles.contentContainer}
208
- renderItem={({ item, index }) => {
209
- const [isStart, isEnd] = [
210
- index === 0 || headerIndices.includes(index),
211
- index === listData.length - 1 || headerIndices.includes(index + 1),
212
- ]
213
-
214
- switch (item.type) {
215
- case SectionTypes.header:
216
- return (
217
- <ListSection
218
- isStart={isStart}
219
- isEnd={isEnd}
220
- outerStyle={item?.sectionOuterStyle}
221
- innerStyle={item?.sectionInnerStyle}
222
- >
223
- <SectionHeading title={item.data.title} />
224
- </ListSection>
225
- )
226
- case SectionTypes.members:
227
- return (
228
- <ListSection
229
- isStart={isStart}
230
- isEnd={isEnd}
231
- outerStyle={item?.sectionOuterStyle}
232
- innerStyle={item?.sectionInnerStyle}
233
- >
234
- <Person person={{ ...item.data }} />
235
- </ListSection>
236
- )
237
- case SectionTypes.setting:
238
- return (
239
- <ListSection
240
- isStart={isStart}
241
- isEnd={isEnd}
242
- outerStyle={item?.sectionOuterStyle}
243
- innerStyle={item?.sectionInnerStyle}
244
- >
245
- <SettingRow {...item.data} />
246
- </ListSection>
247
- )
248
- case SectionTypes.view:
249
- return (
250
- <ListSection
251
- isStart={isStart}
252
- isEnd={isEnd}
253
- outerStyle={item?.sectionOuterStyle}
254
- innerStyle={item?.sectionInnerStyle}
255
- >
256
- <View {...item.data} style={item.data.style} />
257
- </ListSection>
258
- )
259
- default:
260
- return null
261
- }
262
- }}
263
- />
277
+ <View style={styles.listContainer}>
278
+ <FlashList
279
+ data={listData as SectionListData}
280
+ estimatedItemSize={52}
281
+ contentContainerStyle={styles.contentContainer}
282
+ renderItem={({ item, index }) => {
283
+ const [isStart, isEnd] = [
284
+ index === 0 || headerIndices.includes(index),
285
+ index === listData.length - 1 || headerIndices.includes(index + 1),
286
+ ]
287
+
288
+ switch (item.type) {
289
+ case SectionTypes.header:
290
+ return (
291
+ <ListSection
292
+ isStart={isStart}
293
+ isEnd={isEnd}
294
+ showBottomBorder={item?.showBottomBorder}
295
+ outerStyle={item?.sectionOuterStyle}
296
+ innerStyle={item?.sectionInnerStyle}
297
+ >
298
+ <Heading variant="h3">{item.data.title}</Heading>
299
+ </ListSection>
300
+ )
301
+ case SectionTypes.members:
302
+ return (
303
+ <ListSection
304
+ isStart={isStart}
305
+ isEnd={isEnd}
306
+ showBottomBorder={item?.showBottomBorder}
307
+ outerStyle={item?.sectionOuterStyle}
308
+ innerStyle={item?.sectionInnerStyle}
309
+ >
310
+ <Person person={{ ...item.data }} />
311
+ </ListSection>
312
+ )
313
+ case SectionTypes.setting:
314
+ return (
315
+ <ListSection
316
+ isStart={isStart}
317
+ isEnd={isEnd}
318
+ showBottomBorder={item?.showBottomBorder}
319
+ outerStyle={item?.sectionOuterStyle}
320
+ innerStyle={item?.sectionInnerStyle}
321
+ >
322
+ <SettingRow {...item.data} />
323
+ </ListSection>
324
+ )
325
+ case SectionTypes.view:
326
+ return (
327
+ <ListSection
328
+ isStart={isStart}
329
+ isEnd={isEnd}
330
+ showBottomBorder={item?.showBottomBorder}
331
+ outerStyle={item?.sectionOuterStyle}
332
+ innerStyle={item?.sectionInnerStyle}
333
+ >
334
+ <View {...item.data} style={item.data.style} />
335
+ </ListSection>
336
+ )
337
+ default:
338
+ return null
339
+ }
340
+ }}
341
+ />
342
+ </View>
264
343
  )
265
344
  }
266
345
 
267
346
  interface ListSectionProps {
268
347
  isStart?: boolean
269
348
  isEnd?: boolean
349
+ showBottomBorder?: boolean
270
350
  outerStyle?: ViewStyle
271
351
  innerStyle?: ViewStyle
272
352
  children: ReactNode
273
353
  }
274
354
 
275
- function ListSection({ isStart, isEnd, outerStyle, innerStyle, children }: ListSectionProps) {
355
+ function ListSection({
356
+ isStart,
357
+ isEnd,
358
+ showBottomBorder,
359
+ outerStyle,
360
+ innerStyle,
361
+ children,
362
+ }: ListSectionProps) {
276
363
  const styles = useStyles({ isStart, isEnd })
364
+ const bottomBorder = showBottomBorder ? styles.sectionInnerBottomBorder : {}
277
365
 
278
366
  return (
279
- <View style={[styles.sectionOuter, outerStyle]}>
280
- <View style={[styles.sectionInner, innerStyle]}>{children}</View>
281
- </View>
282
- )
283
- }
284
-
285
- interface SectionHeadingProps {
286
- title: string
287
- }
288
-
289
- function SectionHeading({ title }: SectionHeadingProps) {
290
- const styles = useStyles()
291
-
292
- return (
293
- <View style={styles.header}>
294
- <Heading variant="h3">{title}</Heading>
367
+ <View style={[styles.sectionOuterBase, outerStyle]}>
368
+ <View style={[styles.sectionInnerBase, bottomBorder, innerStyle]}>{children}</View>
295
369
  </View>
296
370
  )
297
371
  }
@@ -393,20 +467,37 @@ function SettingRow({
393
467
  )
394
468
  }
395
469
 
470
+ function TeamsGroup({ teams }: { teams: GroupResource[] }) {
471
+ const styles = useStyles()
472
+
473
+ if (teams.length === 0) return null
474
+
475
+ return (
476
+ <View style={styles.teamGroup}>
477
+ {teams.map((team, index) => (
478
+ <Badge key={index} label={team.name as string} />
479
+ ))}
480
+ </View>
481
+ )
482
+ }
483
+
396
484
  // =================================
397
485
  // ====== Styles ===================
398
486
  // =================================
399
487
 
400
488
  const useStyles = ({ isStart, isEnd }: { isStart?: boolean; isEnd?: boolean } = {}) => {
401
489
  const { colors } = useTheme()
490
+ const headerBottomPadding = space(0.5)
402
491
 
403
492
  return StyleSheet.create({
404
- contentContainer: {
493
+ listContainer: {
494
+ flex: 1,
405
495
  backgroundColor: colors.fillColorNeutral080,
496
+ },
497
+ contentContainer: {
406
498
  padding: space(2),
407
499
  },
408
- sectionOuter: {
409
- paddingTop: space(1),
500
+ sectionOuterBase: {
410
501
  paddingLeft: space(2),
411
502
  backgroundColor: colors.fillColorNeutral100Inverted,
412
503
  borderTopLeftRadius: isStart ? space(1) : 0,
@@ -415,15 +506,40 @@ const useStyles = ({ isStart, isEnd }: { isStart?: boolean; isEnd?: boolean } =
415
506
  borderBottomRightRadius: isEnd ? space(1) : 0,
416
507
  marginBottom: isEnd ? space(2) : 0,
417
508
  },
418
- sectionInner: {
419
- borderBottomWidth: 0,
420
- borderBottomColor: colors.borderColorDefaultBase,
509
+ sectionInnerBase: {
421
510
  paddingRight: space(2),
422
- paddingBottom: space(1),
511
+ paddingTop: isStart ? space(2) : space(1.5),
512
+ paddingBottom: isEnd ? space(2) : space(1.5),
423
513
  },
424
- addBottomBorder: {
514
+ sectionInnerHeader: {
515
+ paddingBottom: headerBottomPadding,
516
+ },
517
+ sectionInnerHeaderWithBottomBorder: {
518
+ paddingBottom: space(2),
519
+ },
520
+ sectionInnerBottomBorder: {
521
+ borderBottomColor: colors.borderColorDefaultBase,
425
522
  borderBottomWidth: isEnd ? 0 : 1,
426
523
  },
524
+ sectionInnerTitleInput: {
525
+ paddingTop: space(1.5), // paddingVertical doesn't override the sectionInner padding
526
+ paddingBottom: space(1.5),
527
+ },
528
+ sectionInnerChildNotice: {
529
+ paddingBottom: headerBottomPadding,
530
+ },
531
+ sectionInnerMiddleMiddle: {
532
+ paddingTop: 0,
533
+ paddingBottom: space(1.5),
534
+ },
535
+ sectionInnerFirstMember: {
536
+ paddingTop: space(1.5),
537
+ paddingBottom: space(1.5),
538
+ },
539
+ sectionInnerLastMember: {
540
+ paddingTop: 0,
541
+ paddingBottom: space(2),
542
+ },
427
543
  titleContainer: {
428
544
  gap: 4,
429
545
  },
@@ -451,9 +567,6 @@ const useStyles = ({ isStart, isEnd }: { isStart?: boolean; isEnd?: boolean } =
451
567
  borderTopWidth: 1,
452
568
  borderColor: colors.borderColorStatusError,
453
569
  },
454
- header: {
455
- paddingVertical: space(1.5),
456
- },
457
570
  settingRow: {
458
571
  flexDirection: 'row',
459
572
  justifyContent: 'space-between',
@@ -463,23 +576,23 @@ const useStyles = ({ isStart, isEnd }: { isStart?: boolean; isEnd?: boolean } =
463
576
  settingRowContent: {
464
577
  flex: 1,
465
578
  },
466
- deleteButton: {
467
- paddingVertical: 4,
468
- },
469
579
  deleteButtonText: {
470
580
  fontWeight: 'normal',
471
581
  },
472
582
  settingRowText: {
473
583
  lineHeight: 20,
474
584
  },
475
- childNoticeSectionOuter: {
476
- paddingTop: 0,
585
+ teamGroup: {
586
+ flexDirection: 'row',
587
+ gap: 4,
588
+ flexWrap: 'wrap',
477
589
  },
478
- memberSectionOuter: {
479
- paddingTop: 6,
590
+ headerTitleBadge: {
591
+ alignSelf: Platform.select({ android: 'flex-start', default: 'center' }),
592
+ marginTop: 2,
480
593
  },
481
- memberSectionInner: {
482
- paddingBottom: 6,
594
+ headerTitleContainer: {
595
+ alignItems: Platform.select({ android: 'flex-start', default: 'center' }),
483
596
  },
484
597
  })
485
598
  }