@planningcenter/chat-react-native 3.2.0-rc.9 → 3.3.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 (362) hide show
  1. package/build/components/conversation/message_form/message_form_attachment_image.d.ts +13 -0
  2. package/build/components/conversation/message_form/message_form_attachment_image.d.ts.map +1 -0
  3. package/build/components/conversation/message_form/message_form_attachment_image.js +78 -0
  4. package/build/components/conversation/message_form/message_form_attachment_image.js.map +1 -0
  5. package/build/components/conversation/message_form.d.ts.map +1 -1
  6. package/build/components/conversation/message_form.js +128 -16
  7. package/build/components/conversation/message_form.js.map +1 -1
  8. package/build/components/conversations/conversation_actions.d.ts +2 -2
  9. package/build/components/conversations/conversation_actions.d.ts.map +1 -1
  10. package/build/components/conversations/conversation_actions.js.map +1 -1
  11. package/build/components/conversations/conversation_preview.d.ts +3 -1
  12. package/build/components/conversations/conversation_preview.d.ts.map +1 -1
  13. package/build/components/conversations/conversation_preview.js +2 -2
  14. package/build/components/conversations/conversation_preview.js.map +1 -1
  15. package/build/components/display/action_button.d.ts +2 -1
  16. package/build/components/display/action_button.d.ts.map +1 -1
  17. package/build/components/display/action_button.js +3 -4
  18. package/build/components/display/action_button.js.map +1 -1
  19. package/build/components/display/banner.d.ts +6 -1
  20. package/build/components/display/banner.d.ts.map +1 -1
  21. package/build/components/display/banner.js +2 -2
  22. package/build/components/display/banner.js.map +1 -1
  23. package/build/components/display/banner_collapsible.d.ts +1 -1
  24. package/build/components/display/banner_collapsible.d.ts.map +1 -1
  25. package/build/components/display/banner_collapsible.js +2 -2
  26. package/build/components/display/banner_collapsible.js.map +1 -1
  27. package/build/components/display/child_notice.d.ts +3 -1
  28. package/build/components/display/child_notice.d.ts.map +1 -1
  29. package/build/components/display/child_notice.js +2 -2
  30. package/build/components/display/child_notice.js.map +1 -1
  31. package/build/components/group_conversation_list.d.ts +19 -0
  32. package/build/components/group_conversation_list.d.ts.map +1 -0
  33. package/build/components/group_conversation_list.js +48 -0
  34. package/build/components/group_conversation_list.js.map +1 -0
  35. package/build/components/index.d.ts +1 -0
  36. package/build/components/index.d.ts.map +1 -1
  37. package/build/components/index.js +1 -0
  38. package/build/components/index.js.map +1 -1
  39. package/build/components/primitive/banner_primitive.d.ts +3 -0
  40. package/build/components/primitive/banner_primitive.d.ts.map +1 -1
  41. package/build/components/primitive/banner_primitive.js +4 -4
  42. package/build/components/primitive/banner_primitive.js.map +1 -1
  43. package/build/contexts/api_provider.d.ts +1 -1
  44. package/build/contexts/api_provider.d.ts.map +1 -1
  45. package/build/contexts/api_provider.js +3 -3
  46. package/build/contexts/api_provider.js.map +1 -1
  47. package/build/contexts/chat_context.d.ts +4 -4
  48. package/build/contexts/chat_context.d.ts.map +1 -1
  49. package/build/contexts/chat_context.js +3 -3
  50. package/build/contexts/chat_context.js.map +1 -1
  51. package/build/contexts/conversations_context.js +1 -1
  52. package/build/contexts/conversations_context.js.map +1 -1
  53. package/build/hooks/attachments/supported_extensions.d.ts +2 -0
  54. package/build/hooks/attachments/supported_extensions.d.ts.map +1 -0
  55. package/build/hooks/attachments/supported_extensions.js +48 -0
  56. package/build/hooks/attachments/supported_extensions.js.map +1 -0
  57. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +235 -0
  58. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts.map +1 -0
  59. package/build/hooks/groups/use_group_members_for_new_conversation.js +55 -0
  60. package/build/hooks/groups/use_group_members_for_new_conversation.js.map +1 -0
  61. package/build/hooks/groups/use_groups_conversation_create.d.ts +9 -0
  62. package/build/hooks/groups/use_groups_conversation_create.d.ts.map +1 -0
  63. package/build/hooks/groups/use_groups_conversation_create.js +36 -0
  64. package/build/hooks/groups/use_groups_conversation_create.js.map +1 -0
  65. package/build/hooks/index.d.ts +4 -0
  66. package/build/hooks/index.d.ts.map +1 -1
  67. package/build/hooks/index.js +4 -0
  68. package/build/hooks/index.js.map +1 -1
  69. package/build/hooks/use_api.d.ts +43 -43
  70. package/build/hooks/use_api.d.ts.map +1 -1
  71. package/build/hooks/use_api.js +5 -0
  72. package/build/hooks/use_api.js.map +1 -1
  73. package/build/hooks/use_api_client.d.ts.map +1 -1
  74. package/build/hooks/use_api_client.js +5 -3
  75. package/build/hooks/use_api_client.js.map +1 -1
  76. package/build/hooks/use_attachment_uploader.d.ts +26 -0
  77. package/build/hooks/use_attachment_uploader.d.ts.map +1 -0
  78. package/build/hooks/use_attachment_uploader.js +111 -0
  79. package/build/hooks/use_attachment_uploader.js.map +1 -0
  80. package/build/hooks/use_chat_permissions.d.ts +14 -14
  81. package/build/hooks/use_conversation.d.ts.map +1 -1
  82. package/build/hooks/use_conversation.js +1 -0
  83. package/build/hooks/use_conversation.js.map +1 -1
  84. package/build/hooks/use_conversations_actions.d.ts.map +1 -1
  85. package/build/hooks/use_conversations_actions.js +10 -0
  86. package/build/hooks/use_conversations_actions.js.map +1 -1
  87. package/build/hooks/use_conversations_jolt_events.d.ts.map +1 -1
  88. package/build/hooks/use_conversations_jolt_events.js +4 -1
  89. package/build/hooks/use_conversations_jolt_events.js.map +1 -1
  90. package/build/hooks/use_current_person.d.ts +15 -0
  91. package/build/hooks/use_current_person.d.ts.map +1 -1
  92. package/build/hooks/use_current_person.js +26 -9
  93. package/build/hooks/use_current_person.js.map +1 -1
  94. package/build/hooks/use_groups.d.ts +26 -26
  95. package/build/hooks/use_groups_groups.d.ts +26 -26
  96. package/build/hooks/use_jolt.d.ts.map +1 -1
  97. package/build/hooks/use_jolt.js +15 -22
  98. package/build/hooks/use_jolt.js.map +1 -1
  99. package/build/hooks/use_message_create.js +2 -2
  100. package/build/hooks/use_message_create.js.map +1 -1
  101. package/build/hooks/use_suspense_api.d.ts.map +1 -1
  102. package/build/hooks/use_suspense_api.js +5 -0
  103. package/build/hooks/use_suspense_api.js.map +1 -1
  104. package/build/hooks/use_teams.d.ts +26 -26
  105. package/build/hooks/use_upload_client.d.ts +28 -0
  106. package/build/hooks/use_upload_client.d.ts.map +1 -0
  107. package/build/hooks/use_upload_client.js +32 -0
  108. package/build/hooks/use_upload_client.js.map +1 -0
  109. package/build/index.d.ts +3 -2
  110. package/build/index.d.ts.map +1 -1
  111. package/build/index.js +3 -2
  112. package/build/index.js.map +1 -1
  113. package/build/navigation/index.d.ts +52 -34
  114. package/build/navigation/index.d.ts.map +1 -1
  115. package/build/navigation/index.js +16 -2
  116. package/build/navigation/index.js.map +1 -1
  117. package/build/screens/conversation_details_screen.js +2 -2
  118. package/build/screens/conversation_details_screen.js.map +1 -1
  119. package/build/screens/conversation_filter_recipients/components/checkbox_row.d.ts +10 -0
  120. package/build/screens/conversation_filter_recipients/components/checkbox_row.d.ts.map +1 -0
  121. package/build/screens/conversation_filter_recipients/components/checkbox_row.js +74 -0
  122. package/build/screens/conversation_filter_recipients/components/checkbox_row.js.map +1 -0
  123. package/build/screens/conversation_filter_recipients/components/header_row.d.ts +10 -0
  124. package/build/screens/conversation_filter_recipients/components/header_row.d.ts.map +1 -0
  125. package/build/screens/conversation_filter_recipients/components/header_row.js +69 -0
  126. package/build/screens/conversation_filter_recipients/components/header_row.js.map +1 -0
  127. package/build/screens/conversation_filter_recipients/components/navigation_header.d.ts +5 -0
  128. package/build/screens/conversation_filter_recipients/components/navigation_header.d.ts.map +1 -0
  129. package/build/screens/conversation_filter_recipients/components/navigation_header.js +46 -0
  130. package/build/screens/conversation_filter_recipients/components/navigation_header.js.map +1 -0
  131. package/build/screens/conversation_filter_recipients/context/conversation_filter_recipients_context.d.ts +17 -0
  132. package/build/screens/conversation_filter_recipients/context/conversation_filter_recipients_context.d.ts.map +1 -0
  133. package/build/screens/conversation_filter_recipients/context/conversation_filter_recipients_context.js +37 -0
  134. package/build/screens/conversation_filter_recipients/context/conversation_filter_recipients_context.js.map +1 -0
  135. package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.d.ts +1 -3
  136. package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.d.ts.map +1 -1
  137. package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js +67 -32
  138. package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js.map +1 -1
  139. package/build/screens/conversation_filter_recipients/hooks/use_flattened_array_of_service_types_with_teams.d.ts +10 -0
  140. package/build/screens/conversation_filter_recipients/hooks/use_flattened_array_of_service_types_with_teams.d.ts.map +1 -0
  141. package/build/screens/conversation_filter_recipients/hooks/use_flattened_array_of_service_types_with_teams.js +32 -0
  142. package/build/screens/conversation_filter_recipients/hooks/use_flattened_array_of_service_types_with_teams.js.map +1 -0
  143. package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.d.ts +8 -0
  144. package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.d.ts.map +1 -0
  145. package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.js +65 -0
  146. package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.js.map +1 -0
  147. package/build/screens/conversation_filter_recipients/types.d.ts +38 -0
  148. package/build/screens/conversation_filter_recipients/types.d.ts.map +1 -0
  149. package/build/screens/conversation_filter_recipients/types.js +6 -0
  150. package/build/screens/conversation_filter_recipients/types.js.map +1 -0
  151. package/build/screens/conversation_filters/components/conversation_filters.js +5 -2
  152. package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -1
  153. package/build/screens/conversation_filters/components/rows.d.ts.map +1 -1
  154. package/build/screens/conversation_filters/components/rows.js +6 -1
  155. package/build/screens/conversation_filters/components/rows.js.map +1 -1
  156. package/build/screens/conversation_filters/group_filters.d.ts.map +1 -1
  157. package/build/screens/conversation_filters/group_filters.js +12 -4
  158. package/build/screens/conversation_filters/group_filters.js.map +1 -1
  159. package/build/screens/conversation_filters/hooks/filters.d.ts +40 -40
  160. package/build/screens/conversation_filters/hooks/filters.js +1 -1
  161. package/build/screens/conversation_filters/hooks/filters.js.map +1 -1
  162. package/build/screens/conversation_filters/team_filters.d.ts.map +1 -1
  163. package/build/screens/conversation_filters/team_filters.js +12 -4
  164. package/build/screens/conversation_filters/team_filters.js.map +1 -1
  165. package/build/screens/conversation_filters_screen.js +1 -0
  166. package/build/screens/conversation_filters_screen.js.map +1 -1
  167. package/build/screens/conversation_new/components/groups_form.d.ts +4 -2
  168. package/build/screens/conversation_new/components/groups_form.d.ts.map +1 -1
  169. package/build/screens/conversation_new/components/groups_form.js +40 -55
  170. package/build/screens/conversation_new/components/groups_form.js.map +1 -1
  171. package/build/screens/conversation_new/components/team_form.d.ts +1 -1
  172. package/build/screens/conversation_new/components/team_form.js.map +1 -1
  173. package/build/screens/conversation_new/conversation_new_screen.d.ts +5 -2
  174. package/build/screens/conversation_new/conversation_new_screen.d.ts.map +1 -1
  175. package/build/screens/conversation_new/conversation_new_screen.js +2 -2
  176. package/build/screens/conversation_new/conversation_new_screen.js.map +1 -1
  177. package/build/screens/conversation_screen.d.ts +7 -0
  178. package/build/screens/conversation_screen.d.ts.map +1 -1
  179. package/build/screens/conversation_screen.js +103 -4
  180. package/build/screens/conversation_screen.js.map +1 -1
  181. package/build/screens/conversation_select_recipients/components/groups_without_chat_disclaimer_row.d.ts +2 -0
  182. package/build/screens/conversation_select_recipients/components/groups_without_chat_disclaimer_row.d.ts.map +1 -0
  183. package/build/screens/conversation_select_recipients/components/groups_without_chat_disclaimer_row.js +17 -0
  184. package/build/screens/conversation_select_recipients/components/groups_without_chat_disclaimer_row.js.map +1 -0
  185. package/build/screens/conversation_select_recipients/components/recipient_link_row.d.ts +12 -0
  186. package/build/screens/conversation_select_recipients/components/recipient_link_row.d.ts.map +1 -0
  187. package/build/screens/conversation_select_recipients/components/recipient_link_row.js +61 -0
  188. package/build/screens/conversation_select_recipients/components/recipient_link_row.js.map +1 -0
  189. package/build/screens/conversation_select_recipients/components/view_more_link_row.d.ts +7 -0
  190. package/build/screens/conversation_select_recipients/components/view_more_link_row.d.ts.map +1 -0
  191. package/build/screens/conversation_select_recipients/components/view_more_link_row.js +21 -0
  192. package/build/screens/conversation_select_recipients/components/view_more_link_row.js.map +1 -0
  193. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.d.ts +4 -0
  194. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.d.ts.map +1 -0
  195. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js +48 -0
  196. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js.map +1 -0
  197. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts +2 -6
  198. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts.map +1 -1
  199. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js +37 -49
  200. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js.map +1 -1
  201. package/build/screens/conversation_select_recipients/types/screen_props.d.ts +9 -0
  202. package/build/screens/conversation_select_recipients/types/screen_props.d.ts.map +1 -0
  203. package/build/screens/conversation_select_recipients/types/screen_props.js +2 -0
  204. package/build/screens/conversation_select_recipients/types/screen_props.js.map +1 -0
  205. package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
  206. package/build/screens/conversations/components/list_header_component.js +18 -4
  207. package/build/screens/conversations/components/list_header_component.js.map +1 -1
  208. package/build/screens/conversations/conversations_screen.d.ts +2 -1
  209. package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
  210. package/build/screens/conversations/conversations_screen.js +32 -1
  211. package/build/screens/conversations/conversations_screen.js.map +1 -1
  212. package/build/screens/send_giphy_screen.js +29 -1
  213. package/build/screens/send_giphy_screen.js.map +1 -1
  214. package/build/types/resources/groups/groups_group_resource.d.ts +1 -1
  215. package/build/types/resources/groups/groups_group_resource.js.map +1 -1
  216. package/build/types/resources/groups/groups_member_resource_with_person.d.ts +14 -0
  217. package/build/types/resources/groups/groups_member_resource_with_person.d.ts.map +1 -0
  218. package/build/types/resources/groups/groups_member_resource_with_person.js +2 -0
  219. package/build/types/resources/groups/groups_member_resource_with_person.js.map +1 -0
  220. package/build/types/resources/member.d.ts +0 -10
  221. package/build/types/resources/member.d.ts.map +1 -1
  222. package/build/types/resources/member.js.map +1 -1
  223. package/build/types/resources/message.d.ts +2 -0
  224. package/build/types/resources/message.d.ts.map +1 -1
  225. package/build/types/resources/message.js.map +1 -1
  226. package/build/types/resources/oauth_token.d.ts +4 -4
  227. package/build/types/resources/oauth_token.d.ts.map +1 -1
  228. package/build/types/resources/oauth_token.js.map +1 -1
  229. package/build/utils/client/client.d.ts +4 -8
  230. package/build/utils/client/client.d.ts.map +1 -1
  231. package/build/utils/client/client.js +10 -9
  232. package/build/utils/client/client.js.map +1 -1
  233. package/build/utils/date.d.ts +5 -0
  234. package/build/utils/date.d.ts.map +1 -1
  235. package/build/utils/date.js +8 -1
  236. package/build/utils/date.js.map +1 -1
  237. package/build/utils/destructure_chat_group_graph_id.d.ts +10 -0
  238. package/build/utils/destructure_chat_group_graph_id.d.ts.map +1 -0
  239. package/build/utils/destructure_chat_group_graph_id.js +8 -0
  240. package/build/utils/destructure_chat_group_graph_id.js.map +1 -0
  241. package/build/utils/index.d.ts +1 -0
  242. package/build/utils/index.d.ts.map +1 -1
  243. package/build/utils/index.js +1 -0
  244. package/build/utils/index.js.map +1 -1
  245. package/build/utils/native_adapters/configuration.d.ts +4 -1
  246. package/build/utils/native_adapters/configuration.d.ts.map +1 -1
  247. package/build/utils/native_adapters/configuration.js +13 -1
  248. package/build/utils/native_adapters/configuration.js.map +1 -1
  249. package/build/utils/native_adapters/image_picker.d.ts +25 -0
  250. package/build/utils/native_adapters/image_picker.d.ts.map +1 -0
  251. package/build/utils/native_adapters/image_picker.js +9 -0
  252. package/build/utils/native_adapters/image_picker.js.map +1 -0
  253. package/build/utils/native_adapters/index.d.ts +1 -0
  254. package/build/utils/native_adapters/index.d.ts.map +1 -1
  255. package/build/utils/native_adapters/index.js +1 -0
  256. package/build/utils/native_adapters/index.js.map +1 -1
  257. package/build/utils/session.d.ts +6 -2
  258. package/build/utils/session.d.ts.map +1 -1
  259. package/build/utils/session.js +6 -1
  260. package/build/utils/session.js.map +1 -1
  261. package/build/utils/upload_uri.d.ts +23 -0
  262. package/build/utils/upload_uri.d.ts.map +1 -0
  263. package/build/utils/upload_uri.js +60 -0
  264. package/build/utils/upload_uri.js.map +1 -0
  265. package/build/utils/uri.d.ts +10 -2
  266. package/build/utils/uri.d.ts.map +1 -1
  267. package/build/utils/uri.js +24 -6
  268. package/build/utils/uri.js.map +1 -1
  269. package/build/vendor/tapestry/alias_tokens_color_map.d.ts +2 -0
  270. package/build/vendor/tapestry/alias_tokens_color_map.d.ts.map +1 -1
  271. package/build/vendor/tapestry/alias_tokens_color_map.js +2 -0
  272. package/build/vendor/tapestry/alias_tokens_color_map.js.map +1 -1
  273. package/package.json +4 -3
  274. package/src/__tests__/hooks/useTheme.tsx +1 -1
  275. package/src/__tests__/{client.ts → utils/client.ts} +7 -115
  276. package/src/__tests__/{session.ts → utils/session.ts} +4 -4
  277. package/src/__tests__/utils/uri.ts +107 -0
  278. package/src/components/conversation/message_form/message_form_attachment_image.tsx +121 -0
  279. package/src/components/conversation/message_form.tsx +197 -31
  280. package/src/components/conversations/conversation_actions.tsx +2 -2
  281. package/src/components/conversations/conversation_preview.tsx +8 -2
  282. package/src/components/display/action_button.tsx +4 -3
  283. package/src/components/display/banner.tsx +7 -1
  284. package/src/components/display/banner_collapsible.tsx +6 -1
  285. package/src/components/display/child_notice.tsx +9 -3
  286. package/src/components/group_conversation_list.tsx +82 -0
  287. package/src/components/index.tsx +1 -0
  288. package/src/components/primitive/banner_primitive.tsx +12 -5
  289. package/src/contexts/api_provider.tsx +3 -3
  290. package/src/contexts/chat_context.tsx +7 -7
  291. package/src/contexts/conversations_context.tsx +1 -1
  292. package/src/hooks/attachments/supported_extensions.ts +47 -0
  293. package/src/hooks/groups/use_group_members_for_new_conversation.ts +74 -0
  294. package/src/hooks/groups/use_groups_conversation_create.ts +50 -0
  295. package/src/hooks/index.ts +4 -0
  296. package/src/hooks/use_api.ts +13 -7
  297. package/src/hooks/use_api_client.ts +7 -3
  298. package/src/hooks/use_attachment_uploader.ts +179 -0
  299. package/src/hooks/use_conversation.ts +1 -0
  300. package/src/hooks/use_conversations_actions.ts +11 -0
  301. package/src/hooks/use_conversations_jolt_events.ts +5 -1
  302. package/src/hooks/use_current_person.ts +37 -9
  303. package/src/hooks/use_jolt.ts +18 -23
  304. package/src/hooks/use_message_create.ts +2 -2
  305. package/src/hooks/use_suspense_api.ts +6 -0
  306. package/src/hooks/use_upload_client.ts +67 -0
  307. package/src/index.tsx +3 -1
  308. package/src/navigation/index.tsx +23 -2
  309. package/src/screens/conversation_details_screen.tsx +2 -2
  310. package/src/screens/conversation_filter_recipients/components/checkbox_row.tsx +101 -0
  311. package/src/screens/conversation_filter_recipients/components/header_row.tsx +99 -0
  312. package/src/screens/conversation_filter_recipients/components/navigation_header.tsx +68 -0
  313. package/src/screens/conversation_filter_recipients/context/conversation_filter_recipients_context.tsx +53 -0
  314. package/src/screens/conversation_filter_recipients/conversation_filter_recipients_screen.tsx +90 -49
  315. package/src/screens/conversation_filter_recipients/hooks/use_flattened_array_of_service_types_with_teams.tsx +50 -0
  316. package/src/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.ts +90 -0
  317. package/src/screens/conversation_filter_recipients/types.tsx +47 -0
  318. package/src/screens/conversation_filters/components/conversation_filters.tsx +5 -2
  319. package/src/screens/conversation_filters/components/rows.tsx +6 -1
  320. package/src/screens/conversation_filters/group_filters.tsx +23 -14
  321. package/src/screens/conversation_filters/hooks/filters.ts +1 -1
  322. package/src/screens/conversation_filters/team_filters.tsx +23 -14
  323. package/src/screens/conversation_filters_screen.tsx +1 -0
  324. package/src/screens/conversation_new/components/groups_form.tsx +66 -72
  325. package/src/screens/conversation_new/components/team_form.tsx +1 -1
  326. package/src/screens/conversation_new/conversation_new_screen.tsx +11 -4
  327. package/src/screens/conversation_screen.tsx +123 -4
  328. package/src/screens/conversation_select_recipients/components/groups_without_chat_disclaimer_row.tsx +21 -0
  329. package/src/screens/conversation_select_recipients/components/recipient_link_row.tsx +91 -0
  330. package/src/screens/conversation_select_recipients/components/view_more_link_row.tsx +30 -0
  331. package/src/screens/conversation_select_recipients/conversation_select_group_recipients_screen.tsx +79 -0
  332. package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx +57 -65
  333. package/src/screens/conversation_select_recipients/types/screen_props.tsx +11 -0
  334. package/src/screens/conversations/components/list_header_component.tsx +20 -4
  335. package/src/screens/conversations/conversations_screen.tsx +37 -2
  336. package/src/screens/send_giphy_screen.tsx +30 -1
  337. package/src/types/resources/groups/groups_group_resource.ts +1 -1
  338. package/src/types/resources/groups/groups_member_resource_with_person.ts +13 -0
  339. package/src/types/resources/member.ts +0 -11
  340. package/src/types/resources/message.ts +2 -0
  341. package/src/types/resources/oauth_token.ts +4 -4
  342. package/src/utils/client/client.ts +13 -13
  343. package/src/utils/date.ts +11 -1
  344. package/src/utils/destructure_chat_group_graph_id.ts +25 -0
  345. package/src/utils/index.ts +1 -0
  346. package/src/utils/native_adapters/configuration.ts +15 -1
  347. package/src/utils/native_adapters/image_picker.ts +31 -0
  348. package/src/utils/native_adapters/index.ts +1 -0
  349. package/src/utils/session.ts +10 -4
  350. package/src/utils/upload_uri.ts +69 -0
  351. package/src/utils/uri.ts +30 -6
  352. package/src/vendor/tapestry/alias_tokens_color_map.ts +3 -0
  353. package/build/screens/conversation_new/components/member_error_card.d.ts +0 -5
  354. package/build/screens/conversation_new/components/member_error_card.d.ts.map +0 -1
  355. package/build/screens/conversation_new/components/member_error_card.js +0 -17
  356. package/build/screens/conversation_new/components/member_error_card.js.map +0 -1
  357. package/build/screens/conversation_new/utils/fake_member_data.d.ts +0 -3
  358. package/build/screens/conversation_new/utils/fake_member_data.d.ts.map +0 -1
  359. package/build/screens/conversation_new/utils/fake_member_data.js +0 -129
  360. package/build/screens/conversation_new/utils/fake_member_data.js.map +0 -1
  361. package/src/screens/conversation_new/components/member_error_card.tsx +0 -20
  362. package/src/screens/conversation_new/utils/fake_member_data.ts +0 -130
@@ -2,7 +2,7 @@ import { InfiniteData, useMutation } from '@tanstack/react-query'
2
2
  import { getMessagesQueryKey, getMessagesRequestArgs } from './use_conversation_messages'
3
3
  import { useApiClient } from './use_api_client'
4
4
  import { ApiCollection, ApiResource, MessageResource } from '../types'
5
- import { queryClient } from '../contexts/api_provider'
5
+ import { chatQueryClient } from '../contexts/api_provider'
6
6
  import { updateOrCreateRecordInPagesData } from '../utils'
7
7
  import { DenormalizedAttachmentResourceForCreate } from '../types/resources/denormalized_attachment_resource'
8
8
 
@@ -42,7 +42,7 @@ export function useMessageCreate({ conversationId }: Props) {
42
42
  type QueryData = InfiniteData<ApiCollection<MessageResource>>
43
43
  const queryKey = getMessagesQueryKey({ conversation_id: conversationId })
44
44
 
45
- queryClient.setQueryData<QueryData>(queryKey, data =>
45
+ chatQueryClient.setQueryData<QueryData>(queryKey, data =>
46
46
  updateOrCreateRecordInPagesData({
47
47
  data,
48
48
  record: updatedMessage,
@@ -16,9 +16,15 @@ export const useSuspenseGet = <T extends ResourceObject | ResourceObject[]>(
16
16
  args: SuspenseGetOptions
17
17
  ) => {
18
18
  type Resource = ApiResource<T>
19
+ const apiClient = useApiClient()
19
20
 
20
21
  const { data, ...query } = useSuspenseQuery<Resource, Response>({
21
22
  queryKey: getRequestQueryKey(args),
23
+ queryFn: ({ queryKey }) => {
24
+ const [url, d, headers, app = 'chat'] = queryKey as RequestQueryKey
25
+
26
+ return apiClient[app].get({ url, data: d, headers }) as Promise<Resource>
27
+ },
22
28
  })
23
29
 
24
30
  return { ...data, ...query }
@@ -0,0 +1,67 @@
1
+ import { useContext, useMemo } from 'react'
2
+ import { ChatContext } from '../contexts/chat_context'
3
+ import { UploadUri } from '../utils/upload_uri'
4
+ import { Client } from '../utils'
5
+
6
+ export interface FileForUploadClient {
7
+ uri: string
8
+ name: string
9
+ type: string // Should be a MIME type
10
+ }
11
+
12
+ export const useUploadClient = () => {
13
+ const { session, onUnauthorizedResponse } = useContext(ChatContext)
14
+
15
+ const uri = useMemo(() => new UploadUri({ session }), [session])
16
+
17
+ const api = useMemo(
18
+ () =>
19
+ new UploadClient({
20
+ version: '2025-05-16', // not really needed, but required by the Client constructor
21
+ root: uri.baseUrl,
22
+ defaultHeaders: uri.headers,
23
+ onUnauthorizedResponse,
24
+ }),
25
+ [uri, onUnauthorizedResponse]
26
+ )
27
+
28
+ return api
29
+ }
30
+
31
+ class UploadClient extends Client {
32
+ async uploadFile(file: FileForUploadClient): Promise<UploadedResource> {
33
+ const formData = new FormData()
34
+ formData.append('file', file as unknown as Blob)
35
+
36
+ const response = await fetch(`${this.root}/v2/files`, {
37
+ method: 'POST',
38
+ headers: this.headers,
39
+ body: formData,
40
+ })
41
+
42
+ if (!response.ok) {
43
+ return this.handleNotOk(response)
44
+ }
45
+
46
+ const jsonResponse = await response.json()
47
+
48
+ return jsonResponse.data[0]
49
+ }
50
+ }
51
+
52
+ interface UploadedResource {
53
+ id: string
54
+ type: string
55
+ attributes: {
56
+ organization_id: string
57
+ person_id: string
58
+ md5: string
59
+ created_at: string
60
+ expires_at: string
61
+ source_ip: string
62
+ name: string
63
+ content_type: string
64
+ file_size: number
65
+ location: string
66
+ }
67
+ }
package/src/index.tsx CHANGED
@@ -1,14 +1,16 @@
1
1
  export * from './contexts/chat_context'
2
- export { ApiProvider } from './contexts/api_provider'
2
+ export { ApiProvider, chatQueryClient } from './contexts/api_provider'
3
3
  export { DesignSystemScreen } from './screens'
4
4
  export * from './navigation'
5
5
  export * from './types'
6
6
  export * from './utils/client'
7
+ export { GroupConversations } from './components'
7
8
 
8
9
  export {
9
10
  TemporaryDefaultColorsType,
10
11
  ChatAdapters,
11
12
  ClipboardAdapter,
12
13
  Session,
14
+ Uri,
13
15
  platformFontWeightBold,
14
16
  } from './utils'
@@ -29,6 +29,7 @@ import {
29
29
  ConversationFiltersScreenOptions,
30
30
  } from '../screens/conversation_filters_screen'
31
31
  import { ConversationFiltersParams } from '../screens/conversation_filters/screen_props'
32
+ import { ConversationSelectGroupRecipientsScreen } from '../screens/conversation_select_recipients/conversation_select_group_recipients_screen'
32
33
 
33
34
  export const NewConversationStack = createNativeStackNavigator({
34
35
  initialRouteName: 'ConversationSelectRecipients',
@@ -46,6 +47,21 @@ export const NewConversationStack = createNativeStackNavigator({
46
47
  Cancel
47
48
  </HeaderRightButton>
48
49
  ),
50
+ headerBackVisible: false,
51
+ }),
52
+ },
53
+ ConversationSelectGroupRecipients: {
54
+ screen: ConversationSelectGroupRecipientsScreen,
55
+ options: ({ navigation, route }) => ({
56
+ title: 'New conversation',
57
+ headerRight: (props: NativeStackHeaderRightProps) => (
58
+ <HeaderRightButton
59
+ {...props}
60
+ onPress={() => navigation.popTo('Conversations', route.params)}
61
+ >
62
+ Cancel
63
+ </HeaderRightButton>
64
+ ),
49
65
  }),
50
66
  },
51
67
  ConversationFilterRecipients: {
@@ -54,10 +70,15 @@ export const NewConversationStack = createNativeStackNavigator({
54
70
  },
55
71
  ConversationNew: {
56
72
  screen: ConversationNewScreen,
57
- options: {
73
+ options: ({ navigation }) => ({
58
74
  title: 'New conversation',
59
75
  headerLeft: () => null,
60
- },
76
+ headerRight: (props: NativeStackHeaderRightProps) => (
77
+ <HeaderRightButton {...props} onPress={() => navigation.getParent()?.goBack()}>
78
+ Cancel
79
+ </HeaderRightButton>
80
+ ),
81
+ }),
61
82
  },
62
83
  },
63
84
  })
@@ -492,14 +492,14 @@ const useStyles = ({ isStart, isEnd }: { isStart?: boolean; isEnd?: boolean } =
492
492
  return StyleSheet.create({
493
493
  listContainer: {
494
494
  flex: 1,
495
- backgroundColor: colors.fillColorNeutral080,
495
+ backgroundColor: colors.surfaceColor080,
496
496
  },
497
497
  contentContainer: {
498
498
  padding: space(2),
499
499
  },
500
500
  sectionOuterBase: {
501
501
  paddingLeft: space(2),
502
- backgroundColor: colors.fillColorNeutral100Inverted,
502
+ backgroundColor: colors.surfaceColor100,
503
503
  borderTopLeftRadius: isStart ? space(1) : 0,
504
504
  borderTopRightRadius: isStart ? space(1) : 0,
505
505
  borderBottomLeftRadius: isEnd ? space(1) : 0,
@@ -0,0 +1,101 @@
1
+ import { Pressable, View, StyleSheet, type ViewStyle } from 'react-native'
2
+ import { useTheme } from '../../../hooks'
3
+ import { Icon, Text } from '../../../components'
4
+ import { tokens } from '../../../vendor/tapestry/tokens'
5
+ import { ConversationFilterRecipientsScreenProps, TeamProps } from '../types'
6
+ import { type RouteProp, useRoute } from '@react-navigation/native'
7
+ import { useFilterRecipientsContext } from '../context/conversation_filter_recipients_context'
8
+
9
+ interface TeamRowProps {
10
+ data: TeamProps
11
+ style?: ViewStyle
12
+ accessibilityLabelledBy: string
13
+ }
14
+
15
+ export const CheckboxRow = ({ data, style, accessibilityLabelledBy }: TeamRowProps) => {
16
+ const styles = useStyles()
17
+ const route = useRoute<RouteProp<ConversationFilterRecipientsScreenProps['route']>>()
18
+ const { setTeamFilters } = useFilterRecipientsContext()
19
+
20
+ const { teamId, teamName } = data
21
+ const { team_ids: currentTeamIds } = route.params
22
+
23
+ const checked = currentTeamIds?.includes(teamId) ?? false
24
+ const newTeamIdAdded = [...(currentTeamIds ?? []), teamId]
25
+ const newTeamIdRemoved = (currentTeamIds ?? []).filter(currentId => currentId !== teamId)
26
+
27
+ const handlePress = () => {
28
+ setTeamFilters({
29
+ team_ids: checked ? newTeamIdRemoved : newTeamIdAdded,
30
+ })
31
+ }
32
+
33
+ return (
34
+ <Pressable
35
+ style={({ pressed }) => [styles.checkboxRow, pressed && styles.checkboxRowPressed, style]}
36
+ onPress={handlePress}
37
+ accessibilityRole="checkbox"
38
+ accessibilityState={{ checked }}
39
+ accessibilityLabelledBy={accessibilityLabelledBy}
40
+ accessibilityLabel={`${teamName} team`}
41
+ >
42
+ <CheckboxIcon checked={checked} />
43
+ <Text style={styles.label} numberOfLines={2}>
44
+ {teamName}
45
+ </Text>
46
+ </Pressable>
47
+ )
48
+ }
49
+
50
+ function CheckboxIcon({ checked }: { checked: boolean }) {
51
+ const styles = useStyles()
52
+ const checkedStyle = checked ? styles.checkedContainer : styles.uncheckedContainer
53
+
54
+ return (
55
+ <View style={checkedStyle}>
56
+ {checked && <Icon name="general.thickCheckmark" style={styles.checkedIcon} />}
57
+ </View>
58
+ )
59
+ }
60
+
61
+ const useStyles = () => {
62
+ const { colors } = useTheme()
63
+
64
+ const baseCheckboxStyles: ViewStyle = {
65
+ width: 20,
66
+ height: 20,
67
+ borderRadius: 40,
68
+ alignItems: 'center',
69
+ justifyContent: 'center',
70
+ }
71
+
72
+ return StyleSheet.create({
73
+ checkboxRow: {
74
+ flexDirection: 'row',
75
+ alignItems: 'center',
76
+ gap: 12,
77
+ padding: 16,
78
+ borderTopWidth: 1,
79
+ borderTopColor: colors.borderColorDefaultDim,
80
+ backgroundColor: colors.surfaceColor100,
81
+ },
82
+ checkboxRowPressed: {
83
+ opacity: 0.5,
84
+ },
85
+ label: {
86
+ flex: 1,
87
+ },
88
+ checkedContainer: {
89
+ ...baseCheckboxStyles,
90
+ backgroundColor: colors.statusSuccessIcon,
91
+ },
92
+ uncheckedContainer: {
93
+ ...baseCheckboxStyles,
94
+ borderWidth: 2,
95
+ borderColor: colors.borderColorDefaultDarker,
96
+ },
97
+ checkedIcon: {
98
+ color: tokens.colorNeutral100White,
99
+ },
100
+ })
101
+ }
@@ -0,0 +1,99 @@
1
+ import { View, StyleSheet, type ViewStyle } from 'react-native'
2
+ import { useTheme } from '../../../hooks'
3
+ import { Icon, Heading, TextButton } from '../../../components'
4
+ import type { ConversationFilterRecipientsScreenProps, ServiceTypeProps } from '../types'
5
+ import { tokens } from '../../../vendor/tapestry/tokens'
6
+ import { pluralize } from '../../../utils'
7
+ import { useRoute, type RouteProp } from '@react-navigation/native'
8
+ import { useFilterRecipientsContext } from '../context/conversation_filter_recipients_context'
9
+
10
+ const BULK_SELECT_LIMIT = 10
11
+
12
+ interface HeaderRowProps {
13
+ data: ServiceTypeProps
14
+ nativeID: string
15
+ style?: ViewStyle
16
+ }
17
+
18
+ export const HeaderRow = ({ data, nativeID, style }: HeaderRowProps) => {
19
+ const styles = useStyles()
20
+ const { setTeamFilters } = useFilterRecipientsContext()
21
+ const route = useRoute<RouteProp<ConversationFilterRecipientsScreenProps['route']>>()
22
+
23
+ const { serviceTypeName, teamIdsForServiceType } = data
24
+ const { team_ids: currentTeamIds = [] } = route.params
25
+
26
+ const newTeamIdsAdded = [...new Set([...currentTeamIds, ...teamIdsForServiceType])]
27
+ const newTeamIdsRemoved = currentTeamIds.filter(id => !teamIdsForServiceType.includes(id))
28
+
29
+ const allTeamsSelected = teamIdsForServiceType.every(id => currentTeamIds.includes(id))
30
+ const showSelectAll = teamIdsForServiceType.length <= BULK_SELECT_LIMIT
31
+ const selectLabel = allTeamsSelected ? 'Deselect' : 'Select'
32
+
33
+ const headingAccessibilityHint = `${pluralize(teamIdsForServiceType.length, 'team')} available to select`
34
+ const selectAllAccessibilityLabel = `${selectLabel} ${pluralize(teamIdsForServiceType.length, 'team')} for ${serviceTypeName}`
35
+
36
+ const handleSelectAll = () => {
37
+ setTeamFilters({
38
+ team_ids: allTeamsSelected ? newTeamIdsRemoved : newTeamIdsAdded,
39
+ })
40
+ }
41
+
42
+ return (
43
+ <View style={[styles.headerRow, style]}>
44
+ <View style={styles.headerContent}>
45
+ <Icon name="services.folderClosed" style={styles.headerIcon} />
46
+ <Heading
47
+ variant="h3"
48
+ style={styles.headerText}
49
+ numberOfLines={2}
50
+ nativeID={nativeID}
51
+ accessibilityHint={headingAccessibilityHint}
52
+ >
53
+ {serviceTypeName}
54
+ </Heading>
55
+ </View>
56
+
57
+ {showSelectAll && (
58
+ <TextButton
59
+ variant="tertiary"
60
+ onPress={handleSelectAll}
61
+ accessibilityLabel={selectAllAccessibilityLabel}
62
+ >
63
+ {selectLabel} all
64
+ </TextButton>
65
+ )}
66
+ </View>
67
+ )
68
+ }
69
+
70
+ const useStyles = () => {
71
+ const { colors } = useTheme()
72
+
73
+ return StyleSheet.create({
74
+ headerRow: {
75
+ flexDirection: 'row',
76
+ justifyContent: 'space-between',
77
+ alignItems: 'center',
78
+ padding: 16,
79
+ gap: 12,
80
+ backgroundColor: colors.surfaceColor100,
81
+ },
82
+ headerText: {
83
+ fontWeight: 'normal',
84
+ flex: 1,
85
+ color: colors.textColorDefaultPrimary,
86
+ fontSize: tokens.fontSizeSm,
87
+ },
88
+ headerContent: {
89
+ flexDirection: 'row',
90
+ alignItems: 'center',
91
+ gap: 12,
92
+ flex: 1,
93
+ },
94
+ headerIcon: {
95
+ color: colors.interaction,
96
+ fontSize: tokens.fontSizeMd,
97
+ },
98
+ })
99
+ }
@@ -0,0 +1,68 @@
1
+ import { HeaderTitle, HeaderTitleProps } from '@react-navigation/elements'
2
+ import React from 'react'
3
+ import { StyleSheet, View } from 'react-native'
4
+ import { Button, TextButton } from '../../../components'
5
+ import { RouteProp, useRoute } from '@react-navigation/native'
6
+ import { tokens } from '../../../vendor/tapestry/tokens'
7
+ import {
8
+ FilterRecipientsProvider,
9
+ useFilterRecipientsContext,
10
+ } from '../context/conversation_filter_recipients_context'
11
+ import { ConversationFilterRecipientsScreenProps } from '../types'
12
+
13
+ export const FilterHeaderTitle = ({ tintColor }: HeaderTitleProps) => {
14
+ const styles = useStyles()
15
+
16
+ return <HeaderTitle style={[styles.headerTitle, { color: tintColor }]}>Teams I lead</HeaderTitle>
17
+ }
18
+
19
+ const HeaderRight = () => {
20
+ const styles = useStyles()
21
+ const route = useRoute<RouteProp<ConversationFilterRecipientsScreenProps['route']>>()
22
+ const { resetTeamFilters, applyTeamFilters } = useFilterRecipientsContext()
23
+
24
+ const { team_ids } = route.params
25
+ const noTeamsSelected = team_ids?.length === 0 || !team_ids
26
+ const applyButtonAccessibilityHint = noTeamsSelected
27
+ ? 'Select at least one team to navigate to the final step in creating your conversation.'
28
+ : 'Saves selected teams and navigates to the final step to create your conversation.'
29
+
30
+ return (
31
+ <View style={styles.headerRight}>
32
+ <TextButton
33
+ onPress={resetTeamFilters}
34
+ accessibilityHint="Cancels any selected teams and closes this modal."
35
+ >
36
+ Reset
37
+ </TextButton>
38
+ <Button
39
+ title="Apply"
40
+ accessibilityHint={applyButtonAccessibilityHint}
41
+ onPress={() => applyTeamFilters(route.params)}
42
+ disabled={noTeamsSelected}
43
+ />
44
+ </View>
45
+ )
46
+ }
47
+
48
+ export const HeaderRightWithContext = () => {
49
+ return (
50
+ <FilterRecipientsProvider>
51
+ <HeaderRight />
52
+ </FilterRecipientsProvider>
53
+ )
54
+ }
55
+
56
+ const useStyles = () => {
57
+ return StyleSheet.create({
58
+ headerTitle: {
59
+ fontSize: tokens.fontSizeLg,
60
+ flex: 1,
61
+ },
62
+ headerRight: {
63
+ flexDirection: 'row',
64
+ gap: 16,
65
+ alignItems: 'center',
66
+ },
67
+ })
68
+ }
@@ -0,0 +1,53 @@
1
+ import React from 'react'
2
+ import { createContext, PropsWithChildren } from 'react'
3
+ import { RouteProp, StackActions, useNavigation, useRoute } from '@react-navigation/native'
4
+ import {
5
+ ConversationFilterRecipientsParams,
6
+ ConversationFilterRecipientsScreenProps,
7
+ } from '../types'
8
+ import { NativeStackNavigationProp } from '@react-navigation/native-stack'
9
+
10
+ export const FilterRecipientsContext = createContext<{
11
+ params: ConversationFilterRecipientsParams
12
+ resetTeamFilters: () => void
13
+ setTeamFilters: (params: ConversationFilterRecipientsParams) => void
14
+ applyTeamFilters: (params: ConversationFilterRecipientsParams) => void
15
+ }>({
16
+ params: {
17
+ source_app_name: undefined,
18
+ team_ids: [],
19
+ },
20
+ resetTeamFilters: () => {},
21
+ setTeamFilters: () => {},
22
+ applyTeamFilters: () => {},
23
+ })
24
+
25
+ export const FilterRecipientsProvider = ({ children }: PropsWithChildren) => {
26
+ const navigation =
27
+ useNavigation<NativeStackNavigationProp<ConversationFilterRecipientsScreenProps>>()
28
+ const route = useRoute<RouteProp<ConversationFilterRecipientsScreenProps['route']>>()
29
+ const filterContextValue = {
30
+ params: route.params,
31
+ resetTeamFilters: () => {
32
+ navigation.goBack()
33
+ },
34
+ setTeamFilters: (params: Omit<ConversationFilterRecipientsParams, 'source_app_name'>) => {
35
+ navigation.setParams({
36
+ team_ids: params.team_ids,
37
+ })
38
+ },
39
+ applyTeamFilters: (params: ConversationFilterRecipientsParams) => {
40
+ navigation.dispatch(StackActions.popTo('ConversationNew', params))
41
+ },
42
+ }
43
+
44
+ return (
45
+ <FilterRecipientsContext.Provider value={filterContextValue}>
46
+ {children}
47
+ </FilterRecipientsContext.Provider>
48
+ )
49
+ }
50
+
51
+ export const useFilterRecipientsContext = () => {
52
+ return React.useContext(FilterRecipientsContext)
53
+ }
@@ -1,79 +1,120 @@
1
- import { StackActions, StaticScreenProps, useNavigation } from '@react-navigation/native'
2
1
  import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
3
2
  import React from 'react'
4
- import { StyleSheet, View } from 'react-native'
3
+ import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native'
5
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
6
- import { Button } from '../../components'
5
+ import { FlashList } from '@shopify/flash-list'
6
+ import { Heading } from '../../components'
7
7
  import { useTheme } from '../../hooks'
8
+ import { useFlattenedArrayOfServiceTypesWithTeams } from './hooks/use_flattened_array_of_service_types_with_teams'
9
+ import { ConversationFilterRecipientsScreenProps, SectionTypes } from './types'
10
+ import { HeaderRow } from './components/header_row'
11
+ import { tokens } from '../../vendor/tapestry/tokens'
12
+ import { CheckboxRow } from './components/checkbox_row'
13
+ import { useHeaderHeight } from '@react-navigation/elements'
14
+ import { FilterRecipientsProvider } from './context/conversation_filter_recipients_context'
15
+ import { HeaderRightWithContext, FilterHeaderTitle } from './components/navigation_header'
16
+ import { useServiceTypesWithTeams } from './hooks/use_service_types_with_teams'
17
+
18
+ const SERVICE_TYPE_LABELLED_BY_PREFIX = 'header-'
8
19
 
9
20
  export const ConversationFilterReceipientsScreenOptions: NativeStackNavigationOptions = {
10
- presentation: 'formSheet',
11
- headerShown: false,
12
- sheetAllowedDetents: [0.75],
21
+ presentation: Platform.select({ android: 'modal', ios: 'formSheet' }),
22
+ sheetAllowedDetents: Platform.select({
23
+ android: [0.75, 0.94],
24
+ default: [0.75, 1],
25
+ }),
13
26
  sheetGrabberVisible: true,
27
+ headerBackVisible: false,
28
+ headerRight: HeaderRightWithContext,
29
+ headerTitle: FilterHeaderTitle,
30
+ headerTitleAlign: 'left',
14
31
  }
15
32
 
16
- type ConversationFilterRecipientsScreenProps = StaticScreenProps<{}>
17
-
18
33
  export const ConversationFilterRecipientsScreen = ({}: ConversationFilterRecipientsScreenProps) => {
19
34
  const styles = useStyles()
20
- const navigation = useNavigation()
35
+
36
+ const { serviceTypes } = useServiceTypesWithTeams()
37
+ const data = useFlattenedArrayOfServiceTypesWithTeams({
38
+ data: serviceTypes,
39
+ firstRowStyle: styles.firstRow,
40
+ lastRowStyle: styles.lastRow,
41
+ })
21
42
 
22
43
  return (
23
- <View style={styles.container}>
24
- <View style={styles.section}>
25
- <Button
26
- style={styles.selectTeamsButton}
27
- onPress={() =>
28
- navigation.dispatch(
29
- StackActions.popTo('ConversationSelectRecipients', {
30
- chat_group_graph_id: 'TBD',
31
- })
32
- )
44
+ <FilterRecipientsProvider>
45
+ <View style={styles.listWrapper}>
46
+ <FlashList
47
+ data={data}
48
+ ListHeaderComponent={
49
+ <Heading variant="h3" style={styles.listHeader}>
50
+ Service Types
51
+ </Heading>
33
52
  }
34
- title="Redirect to select"
35
- variant="outline"
36
- />
37
-
38
- <Button
39
- style={styles.selectTeamsButton}
40
- onPress={() =>
41
- navigation.dispatch(
42
- StackActions.popTo('ConversationCreate', {
43
- chat_group_graph_id: 'TBD',
44
- })
45
- )
53
+ estimatedItemSize={50}
54
+ contentContainerStyle={styles.listContentContainer}
55
+ keyExtractor={item =>
56
+ `${item.type === SectionTypes.header ? item.data.serviceTypeId : item.data.teamId}`
46
57
  }
47
- title="Redirect to form"
48
- variant="outline"
58
+ renderItem={({ item }) => {
59
+ switch (item.type) {
60
+ case SectionTypes.header:
61
+ return (
62
+ <HeaderRow
63
+ data={item.data}
64
+ style={item.sectionStyle}
65
+ nativeID={`${SERVICE_TYPE_LABELLED_BY_PREFIX}${item.data.serviceTypeId}`}
66
+ />
67
+ )
68
+ case SectionTypes.team:
69
+ return (
70
+ <CheckboxRow
71
+ data={item.data}
72
+ style={item.sectionStyle}
73
+ accessibilityLabelledBy={`${SERVICE_TYPE_LABELLED_BY_PREFIX}${item.data.serviceTypeId}`}
74
+ />
75
+ )
76
+ default:
77
+ return null
78
+ }
79
+ }}
49
80
  />
50
81
  </View>
51
- </View>
82
+ </FilterRecipientsProvider>
52
83
  )
53
84
  }
54
85
 
55
86
  const useStyles = () => {
56
- const { bottom } = useSafeAreaInsets()
57
- const theme = useTheme()
87
+ const { colors } = useTheme()
88
+ const { top, bottom } = useSafeAreaInsets()
89
+ const { height } = useWindowDimensions()
90
+ const headerHeight = useHeaderHeight()
91
+
92
+ const containerHeight = Platform.select({
93
+ android: height,
94
+ ios: height - top - headerHeight,
95
+ })
58
96
 
59
97
  return StyleSheet.create({
60
- container: {
61
- flex: 1,
62
- gap: 8,
63
- },
64
- section: {
65
- padding: 16,
66
- flexDirection: 'row',
67
- justifyContent: 'space-between',
98
+ listWrapper: {
68
99
  flex: 1,
100
+ height: containerHeight,
101
+ backgroundColor: colors.surfaceColor080,
69
102
  },
70
- selectTeamsButton: {},
71
- routeDebug: {
72
- alignContent: 'center',
103
+ listContentContainer: {
73
104
  padding: 16,
74
105
  paddingBottom: bottom,
75
- borderTopWidth: 1,
76
- borderTopColor: theme.colors.fillColorNeutral050Base,
106
+ },
107
+ listHeader: {
108
+ paddingBottom: 16,
109
+ },
110
+ firstRow: {
111
+ borderTopStartRadius: tokens.borderRadiusLg,
112
+ borderTopEndRadius: tokens.borderRadiusLg,
113
+ },
114
+ lastRow: {
115
+ borderBottomStartRadius: tokens.borderRadiusLg,
116
+ borderBottomEndRadius: tokens.borderRadiusLg,
117
+ marginBottom: 16,
77
118
  },
78
119
  })
79
120
  }