@planningcenter/chat-react-native 3.2.0-rc.1 → 3.2.0-rc.10

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 (322) hide show
  1. package/build/components/conversation/message_form.d.ts +2 -2
  2. package/build/components/conversation/message_form.d.ts.map +1 -1
  3. package/build/components/conversation/message_form.js +95 -41
  4. package/build/components/conversation/message_form.js.map +1 -1
  5. package/build/components/conversation/message_reaction.d.ts +2 -2
  6. package/build/components/conversations/action_toggle_button.d.ts +21 -0
  7. package/build/components/conversations/action_toggle_button.d.ts.map +1 -0
  8. package/build/components/conversations/action_toggle_button.js +48 -0
  9. package/build/components/conversations/action_toggle_button.js.map +1 -0
  10. package/build/components/conversations/conversation_actions.d.ts +10 -0
  11. package/build/components/conversations/conversation_actions.d.ts.map +1 -0
  12. package/build/components/conversations/conversation_actions.js +84 -0
  13. package/build/components/conversations/conversation_actions.js.map +1 -0
  14. package/build/components/conversations/conversation_preview.d.ts +2 -1
  15. package/build/components/conversations/conversation_preview.d.ts.map +1 -1
  16. package/build/components/conversations/conversation_preview.js +27 -9
  17. package/build/components/conversations/conversation_preview.js.map +1 -1
  18. package/build/components/conversations/conversations.d.ts +2 -3
  19. package/build/components/conversations/conversations.d.ts.map +1 -1
  20. package/build/components/conversations/conversations.js +5 -11
  21. package/build/components/conversations/conversations.js.map +1 -1
  22. package/build/components/conversations/mute_indicator.d.ts +5 -0
  23. package/build/components/conversations/mute_indicator.d.ts.map +1 -0
  24. package/build/components/conversations/mute_indicator.js +19 -0
  25. package/build/components/conversations/mute_indicator.js.map +1 -0
  26. package/build/components/conversations/unread_count_badge.d.ts +2 -1
  27. package/build/components/conversations/unread_count_badge.d.ts.map +1 -1
  28. package/build/components/conversations/unread_count_badge.js +9 -1
  29. package/build/components/conversations/unread_count_badge.js.map +1 -1
  30. package/build/components/display/action_button.js +1 -2
  31. package/build/components/display/action_button.js.map +1 -1
  32. package/build/components/display/badge.d.ts +5 -4
  33. package/build/components/display/badge.d.ts.map +1 -1
  34. package/build/components/display/badge.js +5 -2
  35. package/build/components/display/badge.js.map +1 -1
  36. package/build/components/display/button.d.ts +3 -2
  37. package/build/components/display/button.d.ts.map +1 -1
  38. package/build/components/display/button.js.map +1 -1
  39. package/build/components/display/icon.d.ts +14 -1
  40. package/build/components/display/icon.d.ts.map +1 -1
  41. package/build/components/display/icon.js +9 -0
  42. package/build/components/display/icon.js.map +1 -1
  43. package/build/components/display/icon_button.d.ts +2 -2
  44. package/build/components/display/icon_button.d.ts.map +1 -1
  45. package/build/components/display/icon_button.js.map +1 -1
  46. package/build/components/display/person.d.ts +3 -1
  47. package/build/components/display/person.d.ts.map +1 -1
  48. package/build/components/display/person.js +2 -2
  49. package/build/components/display/person.js.map +1 -1
  50. package/build/components/display/text.js.map +1 -1
  51. package/build/components/display/toggle_button.d.ts +3 -2
  52. package/build/components/display/toggle_button.d.ts.map +1 -1
  53. package/build/components/display/toggle_button.js.map +1 -1
  54. package/build/components/display/utils/button_colors.d.ts +3 -3
  55. package/build/components/display/utils/button_colors.d.ts.map +1 -1
  56. package/build/components/display/utils/button_colors.js +1 -1
  57. package/build/components/display/utils/button_colors.js.map +1 -1
  58. package/build/components/page/error_boundary.d.ts +1 -1
  59. package/build/components/primitive/avatar_primitive.d.ts.map +1 -1
  60. package/build/components/primitive/avatar_primitive.js +3 -2
  61. package/build/components/primitive/avatar_primitive.js.map +1 -1
  62. package/build/components/primitive/banner_primitive.d.ts +2 -1
  63. package/build/components/primitive/banner_primitive.d.ts.map +1 -1
  64. package/build/components/primitive/banner_primitive.js +0 -1
  65. package/build/components/primitive/banner_primitive.js.map +1 -1
  66. package/build/contexts/api_provider.js.map +1 -1
  67. package/build/contexts/chat_context.d.ts +2 -0
  68. package/build/contexts/chat_context.d.ts.map +1 -1
  69. package/build/contexts/chat_context.js +6 -1
  70. package/build/contexts/chat_context.js.map +1 -1
  71. package/build/contexts/conversations_context.d.ts +14 -0
  72. package/build/contexts/conversations_context.d.ts.map +1 -0
  73. package/build/contexts/conversations_context.js +38 -0
  74. package/build/contexts/conversations_context.js.map +1 -0
  75. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +214 -0
  76. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts.map +1 -0
  77. package/build/hooks/groups/use_group_members_for_new_conversation.js +50 -0
  78. package/build/hooks/groups/use_group_members_for_new_conversation.js.map +1 -0
  79. package/build/hooks/use_conversation.d.ts +1 -1
  80. package/build/hooks/use_conversation.d.ts.map +1 -1
  81. package/build/hooks/use_conversation.js +1 -1
  82. package/build/hooks/use_conversation.js.map +1 -1
  83. package/build/hooks/use_conversations.d.ts +6 -32
  84. package/build/hooks/use_conversations.d.ts.map +1 -1
  85. package/build/hooks/use_conversations.js +15 -14
  86. package/build/hooks/use_conversations.js.map +1 -1
  87. package/build/hooks/use_conversations_actions.d.ts +221 -0
  88. package/build/hooks/use_conversations_actions.d.ts.map +1 -0
  89. package/build/hooks/use_conversations_actions.js +93 -0
  90. package/build/hooks/use_conversations_actions.js.map +1 -0
  91. package/build/hooks/use_conversations_cache.d.ts +18 -0
  92. package/build/hooks/use_conversations_cache.d.ts.map +1 -0
  93. package/build/hooks/{use_conversation_jolt_events.js → use_conversations_cache.js} +27 -17
  94. package/build/hooks/use_conversations_cache.js.map +1 -0
  95. package/build/hooks/use_conversations_jolt_events.d.ts +3 -0
  96. package/build/hooks/use_conversations_jolt_events.d.ts.map +1 -0
  97. package/build/hooks/use_conversations_jolt_events.js +12 -0
  98. package/build/hooks/use_conversations_jolt_events.js.map +1 -0
  99. package/build/hooks/use_create_android_ripple_color.d.ts +1 -1
  100. package/build/hooks/use_create_android_ripple_color.d.ts.map +1 -1
  101. package/build/hooks/use_giphy.d.ts +9 -0
  102. package/build/hooks/use_giphy.d.ts.map +1 -0
  103. package/build/hooks/use_giphy.js +63 -0
  104. package/build/hooks/use_giphy.js.map +1 -0
  105. package/build/hooks/use_jolt.d.ts.map +1 -1
  106. package/build/hooks/use_jolt.js +39 -10
  107. package/build/hooks/use_jolt.js.map +1 -1
  108. package/build/hooks/use_message_create.d.ts +11 -0
  109. package/build/hooks/use_message_create.d.ts.map +1 -0
  110. package/build/hooks/use_message_create.js +35 -0
  111. package/build/hooks/use_message_create.js.map +1 -0
  112. package/build/navigation/index.d.ts +23 -6
  113. package/build/navigation/index.d.ts.map +1 -1
  114. package/build/navigation/index.js +25 -8
  115. package/build/navigation/index.js.map +1 -1
  116. package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.d.ts.map +1 -0
  117. package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js.map +1 -0
  118. package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -1
  119. package/build/screens/conversation_filters/components/rows.d.ts +2 -1
  120. package/build/screens/conversation_filters/components/rows.d.ts.map +1 -1
  121. package/build/screens/conversation_filters/components/rows.js +19 -14
  122. package/build/screens/conversation_filters/components/rows.js.map +1 -1
  123. package/build/screens/conversation_filters/hooks/filters.js +1 -1
  124. package/build/screens/conversation_filters/hooks/filters.js.map +1 -1
  125. package/build/screens/conversation_new/components/form_list.d.ts +12 -0
  126. package/build/screens/conversation_new/components/form_list.d.ts.map +1 -0
  127. package/build/screens/conversation_new/components/form_list.js +42 -0
  128. package/build/screens/conversation_new/components/form_list.js.map +1 -0
  129. package/build/screens/conversation_new/components/groups_form.d.ts +7 -0
  130. package/build/screens/conversation_new/components/groups_form.d.ts.map +1 -0
  131. package/build/screens/conversation_new/components/groups_form.js +128 -0
  132. package/build/screens/conversation_new/components/groups_form.js.map +1 -0
  133. package/build/screens/conversation_new/components/member_error_card.d.ts +5 -0
  134. package/build/screens/conversation_new/components/member_error_card.d.ts.map +1 -0
  135. package/build/screens/conversation_new/components/member_error_card.js +17 -0
  136. package/build/screens/conversation_new/components/member_error_card.js.map +1 -0
  137. package/build/screens/conversation_new/components/source_app_error_card.d.ts +2 -0
  138. package/build/screens/conversation_new/components/source_app_error_card.d.ts.map +1 -0
  139. package/build/screens/conversation_new/components/source_app_error_card.js +16 -0
  140. package/build/screens/conversation_new/components/source_app_error_card.js.map +1 -0
  141. package/build/screens/conversation_new/components/team_form.d.ts +8 -0
  142. package/build/screens/conversation_new/components/team_form.d.ts.map +1 -0
  143. package/build/screens/conversation_new/components/team_form.js +11 -0
  144. package/build/screens/conversation_new/components/team_form.js.map +1 -0
  145. package/build/screens/conversation_new/conversation_new_screen.d.ts +12 -0
  146. package/build/screens/conversation_new/conversation_new_screen.d.ts.map +1 -0
  147. package/build/screens/conversation_new/conversation_new_screen.js +16 -0
  148. package/build/screens/conversation_new/conversation_new_screen.js.map +1 -0
  149. package/build/screens/conversation_new/utils/fake_member_data.d.ts +3 -0
  150. package/build/screens/conversation_new/utils/fake_member_data.d.ts.map +1 -0
  151. package/build/screens/conversation_new/utils/fake_member_data.js +129 -0
  152. package/build/screens/conversation_new/utils/fake_member_data.js.map +1 -0
  153. package/build/screens/conversation_screen.d.ts +1 -0
  154. package/build/screens/conversation_screen.d.ts.map +1 -1
  155. package/build/screens/conversation_screen.js +1 -1
  156. package/build/screens/conversation_screen.js.map +1 -1
  157. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts.map +1 -0
  158. package/build/screens/{create → conversation_select_recipients}/conversation_select_recipients_screen.js +6 -5
  159. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js.map +1 -0
  160. package/build/screens/conversations/components/chat_group_badge.js +1 -1
  161. package/build/screens/conversations/components/chat_group_badge.js.map +1 -1
  162. package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
  163. package/build/screens/conversations/components/list_header_component.js +6 -2
  164. package/build/screens/conversations/components/list_header_component.js.map +1 -1
  165. package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
  166. package/build/screens/conversations/conversations_screen.js +6 -13
  167. package/build/screens/conversations/conversations_screen.js.map +1 -1
  168. package/build/screens/design_system_screen.js +1 -0
  169. package/build/screens/design_system_screen.js.map +1 -1
  170. package/build/screens/message_actions_screen.d.ts +2 -2
  171. package/build/screens/message_actions_screen.d.ts.map +1 -1
  172. package/build/screens/message_actions_screen.js +1 -1
  173. package/build/screens/message_actions_screen.js.map +1 -1
  174. package/build/screens/send_giphy_screen.d.ts +10 -0
  175. package/build/screens/send_giphy_screen.d.ts.map +1 -0
  176. package/build/screens/send_giphy_screen.js +98 -0
  177. package/build/screens/send_giphy_screen.js.map +1 -0
  178. package/build/types/resources/groups/groups_group_resource.d.ts +1 -1
  179. package/build/types/resources/groups/groups_group_resource.js.map +1 -1
  180. package/build/types/resources/groups/groups_member_resource_with_person.d.ts +14 -0
  181. package/build/types/resources/groups/groups_member_resource_with_person.d.ts.map +1 -0
  182. package/build/types/resources/groups/groups_member_resource_with_person.js +2 -0
  183. package/build/types/resources/groups/groups_member_resource_with_person.js.map +1 -0
  184. package/build/types/resources/member.d.ts +0 -10
  185. package/build/types/resources/member.d.ts.map +1 -1
  186. package/build/types/resources/member.js.map +1 -1
  187. package/build/utils/cache/page_mutations.d.ts +18 -0
  188. package/build/utils/cache/page_mutations.d.ts.map +1 -1
  189. package/build/utils/cache/page_mutations.js +13 -0
  190. package/build/utils/cache/page_mutations.js.map +1 -1
  191. package/build/utils/client/client.d.ts +2 -2
  192. package/build/utils/client/client.d.ts.map +1 -1
  193. package/build/utils/client/client.js +12 -4
  194. package/build/utils/client/client.js.map +1 -1
  195. package/build/utils/client/request_helpers.d.ts +15 -8
  196. package/build/utils/client/request_helpers.d.ts.map +1 -1
  197. package/build/utils/client/request_helpers.js +2 -1
  198. package/build/utils/client/request_helpers.js.map +1 -1
  199. package/build/utils/client/transform_request_data.d.ts +11 -6
  200. package/build/utils/client/transform_request_data.d.ts.map +1 -1
  201. package/build/utils/client/transform_request_data.js +1 -1
  202. package/build/utils/client/transform_request_data.js.map +1 -1
  203. package/build/utils/client/transform_response.d.ts +1 -1
  204. package/build/utils/client/transform_response.d.ts.map +1 -1
  205. package/build/utils/client/transform_response.js +2 -0
  206. package/build/utils/client/transform_response.js.map +1 -1
  207. package/build/utils/client/utils.d.ts +3 -3
  208. package/build/utils/client/utils.d.ts.map +1 -1
  209. package/build/utils/client/utils.js +6 -6
  210. package/build/utils/client/utils.js.map +1 -1
  211. package/build/utils/date.d.ts.map +1 -1
  212. package/build/utils/date.js +1 -0
  213. package/build/utils/date.js.map +1 -1
  214. package/build/utils/deepCamelCaseKeys.d.ts.map +1 -1
  215. package/build/utils/deepCamelCaseKeys.js +3 -1
  216. package/build/utils/deepCamelCaseKeys.js.map +1 -1
  217. package/build/utils/parse_simple_markdown.d.ts +1 -1
  218. package/build/utils/parse_simple_markdown.d.ts.map +1 -1
  219. package/build/utils/parse_simple_markdown.js +2 -1
  220. package/build/utils/parse_simple_markdown.js.map +1 -1
  221. package/build/utils/request/conversation.d.ts +1 -3
  222. package/build/utils/request/conversation.d.ts.map +1 -1
  223. package/build/utils/request/conversation.js +37 -30
  224. package/build/utils/request/conversation.js.map +1 -1
  225. package/build/utils/space.js.map +1 -1
  226. package/build/utils/uri.d.ts +2 -2
  227. package/build/utils/uri.d.ts.map +1 -1
  228. package/build/utils/uri.js +2 -2
  229. package/build/utils/uri.js.map +1 -1
  230. package/build/vendor/tapestry/alias_tokens_color_map.d.ts +8 -0
  231. package/build/vendor/tapestry/alias_tokens_color_map.d.ts.map +1 -1
  232. package/build/vendor/tapestry/alias_tokens_color_map.js +8 -0
  233. package/build/vendor/tapestry/alias_tokens_color_map.js.map +1 -1
  234. package/build/vendor/tapestry/tokens.d.ts +2 -0
  235. package/build/vendor/tapestry/tokens.d.ts.map +1 -1
  236. package/build/vendor/tapestry/tokens.js +2 -0
  237. package/build/vendor/tapestry/tokens.js.map +1 -1
  238. package/package.json +8 -6
  239. package/src/__tests__/utils/cache/page_mutations.ts +49 -15
  240. package/src/components/conversation/message_form.tsx +127 -58
  241. package/src/components/conversations/action_toggle_button.tsx +84 -0
  242. package/src/components/conversations/conversation_actions.tsx +146 -0
  243. package/src/components/conversations/conversation_preview.tsx +46 -16
  244. package/src/components/conversations/conversations.tsx +13 -18
  245. package/src/components/conversations/mute_indicator.tsx +21 -0
  246. package/src/components/conversations/unread_count_badge.tsx +8 -1
  247. package/src/components/display/action_button.tsx +1 -2
  248. package/src/components/display/badge.tsx +12 -8
  249. package/src/components/display/button.tsx +3 -3
  250. package/src/components/display/icon.tsx +16 -3
  251. package/src/components/display/icon_button.tsx +2 -2
  252. package/src/components/display/person.tsx +4 -3
  253. package/src/components/display/text.tsx +1 -1
  254. package/src/components/display/toggle_button.tsx +3 -3
  255. package/src/components/display/utils/button_colors.ts +8 -3
  256. package/src/components/primitive/avatar_primitive.tsx +5 -3
  257. package/src/components/primitive/banner_primitive.tsx +2 -3
  258. package/src/contexts/api_provider.tsx +1 -1
  259. package/src/contexts/chat_context.tsx +8 -1
  260. package/src/contexts/conversations_context.tsx +69 -0
  261. package/src/hooks/groups/use_group_members_for_new_conversation.ts +57 -0
  262. package/src/hooks/use_conversation.ts +5 -5
  263. package/src/hooks/use_conversations.ts +34 -16
  264. package/src/hooks/use_conversations_actions.ts +108 -0
  265. package/src/hooks/{use_conversation_jolt_events.ts → use_conversations_cache.ts} +35 -20
  266. package/src/hooks/use_conversations_jolt_events.ts +21 -0
  267. package/src/hooks/use_giphy.ts +97 -0
  268. package/src/hooks/use_jolt.ts +53 -12
  269. package/src/hooks/use_message_create.ts +55 -0
  270. package/src/navigation/index.tsx +31 -8
  271. package/src/screens/conversation_filters/components/conversation_filters.tsx +1 -1
  272. package/src/screens/conversation_filters/components/rows.tsx +44 -14
  273. package/src/screens/conversation_filters/hooks/filters.ts +1 -1
  274. package/src/screens/conversation_new/components/form_list.tsx +67 -0
  275. package/src/screens/conversation_new/components/groups_form.tsx +191 -0
  276. package/src/screens/conversation_new/components/member_error_card.tsx +20 -0
  277. package/src/screens/conversation_new/components/source_app_error_card.tsx +24 -0
  278. package/src/screens/conversation_new/components/team_form.tsx +18 -0
  279. package/src/screens/conversation_new/conversation_new_screen.tsx +26 -0
  280. package/src/screens/conversation_new/utils/fake_member_data.ts +130 -0
  281. package/src/screens/conversation_screen.tsx +2 -1
  282. package/src/screens/{create → conversation_select_recipients}/conversation_select_recipients_screen.tsx +6 -5
  283. package/src/screens/conversations/components/chat_group_badge.tsx +1 -1
  284. package/src/screens/conversations/components/list_header_component.tsx +7 -2
  285. package/src/screens/conversations/conversations_screen.tsx +6 -19
  286. package/src/screens/design_system_screen.tsx +1 -0
  287. package/src/screens/message_actions_screen.tsx +4 -4
  288. package/src/screens/send_giphy_screen.tsx +155 -0
  289. package/src/types/resources/groups/groups_group_resource.ts +1 -1
  290. package/src/types/resources/groups/groups_member_resource_with_person.ts +13 -0
  291. package/src/types/resources/member.ts +0 -11
  292. package/src/utils/cache/page_mutations.ts +22 -0
  293. package/src/utils/client/client.ts +15 -7
  294. package/src/utils/client/request_helpers.ts +15 -6
  295. package/src/utils/client/transform_request_data.ts +13 -4
  296. package/src/utils/client/transform_response.ts +3 -0
  297. package/src/utils/client/types.d.ts +2 -1
  298. package/src/utils/client/utils.ts +13 -12
  299. package/src/utils/date.ts +1 -0
  300. package/src/utils/deepCamelCaseKeys.ts +3 -2
  301. package/src/utils/parse_simple_markdown.ts +3 -1
  302. package/src/utils/request/conversation.ts +39 -34
  303. package/src/utils/space.ts +1 -1
  304. package/src/utils/uri.ts +2 -2
  305. package/src/vendor/tapestry/alias_tokens_color_map.ts +12 -0
  306. package/src/vendor/tapestry/tokens.ts +2 -0
  307. package/build/hooks/use_conversation_jolt_events.d.ts +0 -2
  308. package/build/hooks/use_conversation_jolt_events.d.ts.map +0 -1
  309. package/build/hooks/use_conversation_jolt_events.js.map +0 -1
  310. package/build/screens/create/conversation_create_screen.d.ts +0 -9
  311. package/build/screens/create/conversation_create_screen.d.ts.map +0 -1
  312. package/build/screens/create/conversation_create_screen.js +0 -123
  313. package/build/screens/create/conversation_create_screen.js.map +0 -1
  314. package/build/screens/create/conversation_filter_recipients_screen.d.ts.map +0 -1
  315. package/build/screens/create/conversation_filter_recipients_screen.js.map +0 -1
  316. package/build/screens/create/conversation_select_recipients_screen.d.ts.map +0 -1
  317. package/build/screens/create/conversation_select_recipients_screen.js.map +0 -1
  318. package/src/screens/create/conversation_create_screen.tsx +0 -148
  319. /package/build/screens/{create → conversation_filter_recipients}/conversation_filter_recipients_screen.d.ts +0 -0
  320. /package/build/screens/{create → conversation_filter_recipients}/conversation_filter_recipients_screen.js +0 -0
  321. /package/build/screens/{create → conversation_select_recipients}/conversation_select_recipients_screen.d.ts +0 -0
  322. /package/src/screens/{create → conversation_filter_recipients}/conversation_filter_recipients_screen.tsx +0 -0
@@ -9,16 +9,17 @@ import { Icon } from '../components'
9
9
  import { ConversationDetailsScreen } from '../screens/conversation_details_screen'
10
10
  import { ConversationScreen } from '../screens/conversation_screen'
11
11
  import { ConversationsScreen } from '../screens/conversations/conversations_screen'
12
- import { ConversationCreateScreen } from '../screens/create/conversation_create_screen'
12
+ import { ConversationNewScreen } from '../screens/conversation_new/conversation_new_screen'
13
13
  import {
14
14
  ConversationFilterReceipientsScreenOptions,
15
15
  ConversationFilterRecipientsScreen,
16
- } from '../screens/create/conversation_filter_recipients_screen'
17
- import { ConversationSelectRecipientsScreen } from '../screens/create/conversation_select_recipients_screen'
16
+ } from '../screens/conversation_filter_recipients/conversation_filter_recipients_screen'
17
+ import { ConversationSelectRecipientsScreen } from '../screens/conversation_select_recipients/conversation_select_recipients_screen'
18
18
  import {
19
19
  MessageActionsScreen,
20
20
  MessageActionsScreenOptions,
21
21
  } from '../screens/message_actions_screen'
22
+ import { SendGiphyScreen, SendGiphyScreenOptions } from '../screens/send_giphy_screen'
22
23
  import { NotFound } from '../screens/not_found'
23
24
  import { ReactionsScreen, ReactionsScreenOptions } from '../screens/reactions_screen'
24
25
  import { HeaderRightButton } from './header'
@@ -27,8 +28,9 @@ import {
27
28
  ConversationFiltersScreen,
28
29
  ConversationFiltersScreenOptions,
29
30
  } from '../screens/conversation_filters_screen'
31
+ import { ConversationFiltersParams } from '../screens/conversation_filters/screen_props'
30
32
 
31
- export const CreateConversationStack = createNativeStackNavigator({
33
+ export const NewConversationStack = createNativeStackNavigator({
32
34
  initialRouteName: 'ConversationSelectRecipients',
33
35
  screenOptions: {
34
36
  headerBackButtonDisplayMode: 'minimal',
@@ -50,8 +52,8 @@ export const CreateConversationStack = createNativeStackNavigator({
50
52
  screen: ConversationFilterRecipientsScreen,
51
53
  options: ConversationFilterReceipientsScreenOptions,
52
54
  },
53
- ConversationCreate: {
54
- screen: ConversationCreateScreen,
55
+ ConversationNew: {
56
+ screen: ConversationNewScreen,
55
57
  options: {
56
58
  title: 'New conversation',
57
59
  headerLeft: () => null,
@@ -85,6 +87,23 @@ export const ChatStack = createNativeStackNavigator({
85
87
  },
86
88
  Conversation: {
87
89
  screen: ConversationScreen,
90
+ options: ({ route, navigation }) => ({
91
+ headerTitle: (route.params as { title?: string })?.title ?? 'Chat',
92
+ headerLeft: props => (
93
+ <HeaderBackButton
94
+ displayMode="minimal"
95
+ onPress={() => {
96
+ if ((route.params as ConversationFiltersParams)?.chat_group_graph_id) {
97
+ // Ensure that conversations with a graph id pass them back to the conversation list
98
+ navigation.popTo('Conversations', route.params)
99
+ } else {
100
+ navigation.goBack()
101
+ }
102
+ }}
103
+ {...props}
104
+ />
105
+ ),
106
+ }),
88
107
  },
89
108
  ConversationDetails: {
90
109
  screen: ConversationDetailsScreen,
@@ -98,13 +117,17 @@ export const ChatStack = createNativeStackNavigator({
98
117
  ),
99
118
  }),
100
119
  },
101
- Create: {
102
- screen: CreateConversationStack,
120
+ New: {
121
+ screen: NewConversationStack,
103
122
  options: {
104
123
  headerShown: false,
105
124
  presentation: 'modal',
106
125
  },
107
126
  },
127
+ SendGiphy: {
128
+ screen: SendGiphyScreen,
129
+ options: SendGiphyScreenOptions,
130
+ },
108
131
  MessageActions: {
109
132
  screen: MessageActionsScreen,
110
133
  // Something about sheetAllowedDetents declared inline breaks TS
@@ -1,5 +1,5 @@
1
1
  import React, { useContext, useMemo } from 'react'
2
- import { FlatList, RefreshControl, StyleSheet, View, ViewStyle } from 'react-native'
2
+ import { FlatList, StyleSheet, View, ViewStyle } from 'react-native'
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
4
4
  import { Heading } from '../../../components'
5
5
  import { useTheme } from '../../../hooks'
@@ -14,13 +14,22 @@ import { ConversationFilterStackParamList } from '../screen_props'
14
14
  export type FilterProps = { group_source_app_name?: string; isActive: boolean; filter: FilterTypes }
15
15
 
16
16
  export const FilterRow = ({ group_source_app_name, isActive, filter }: FilterProps) => {
17
- const styles = useRowStyles()
17
+ const styles = useRowStyles({ isActive })
18
18
  const { setAppFilter } = useContext(FilterContext)
19
19
 
20
20
  return (
21
- <PressableRow style={styles.row} onPress={() => setAppFilter({ group_source_app_name })}>
21
+ <PressableRow
22
+ style={styles.row}
23
+ onPress={() => setAppFilter({ group_source_app_name })}
24
+ isActive={isActive}
25
+ >
22
26
  <Text>{filter}</Text>
23
- {isActive ? <Icon name="general.check" size={16} style={styles.rowIconRight} /> : null}
27
+ <Icon
28
+ name="general.check"
29
+ size={16}
30
+ style={styles.rowIconRight}
31
+ accessibilityElementsHidden
32
+ />
24
33
  </PressableRow>
25
34
  )
26
35
  }
@@ -31,7 +40,7 @@ export type GroupRowProps = {
31
40
  }
32
41
 
33
42
  export const GroupRow = ({ group, isActive }: GroupRowProps) => {
34
- const styles = useRowStyles()
43
+ const styles = useRowStyles({ isActive })
35
44
  const { setGroupFilter } = useContext(FilterContext)
36
45
 
37
46
  const handleFilterByGroup = () => {
@@ -41,7 +50,7 @@ export const GroupRow = ({ group, isActive }: GroupRowProps) => {
41
50
  const { headerImage, membershipsCount } = group
42
51
 
43
52
  return (
44
- <PressableRow style={styles.row} onPress={handleFilterByGroup}>
53
+ <PressableRow style={styles.row} onPress={handleFilterByGroup} isActive={isActive}>
45
54
  {headerImage?.thumbnail && (
46
55
  <Image
47
56
  source={{ uri: headerImage?.thumbnail }}
@@ -50,13 +59,18 @@ export const GroupRow = ({ group, isActive }: GroupRowProps) => {
50
59
  alt={`Image for ${group.name}`}
51
60
  />
52
61
  )}
53
- <View>
62
+ <View style={styles.rowContent}>
54
63
  <Heading variant="h3" style={styles.rowTitle}>
55
64
  {group.name}
56
65
  </Heading>
57
66
  {membershipsCount && <Text>{group.membershipsCount} members</Text>}
58
67
  </View>
59
- {isActive ? <Icon name="general.check" size={16} style={styles.rowIconRight} /> : null}
68
+ <Icon
69
+ name="general.check"
70
+ size={16}
71
+ style={styles.rowIconRight}
72
+ accessibilityElementsHidden
73
+ />
60
74
  </PressableRow>
61
75
  )
62
76
  }
@@ -67,12 +81,12 @@ export type TeamRowProps = {
67
81
  }
68
82
 
69
83
  export const TeamRow = ({ team }: TeamRowProps) => {
70
- const styles = useRowStyles()
71
84
  const { setGroupFilter } = useContext(FilterContext)
72
85
  const servicesTeams = useServicesTeamsMap()
73
86
  const { params } = useContext(FilterContext)
74
87
  const { chat_group_graph_id } = params
75
88
  const isActive = chat_group_graph_id === team.id.toString()
89
+ const styles = useRowStyles({ isActive })
76
90
 
77
91
  const handleFilterByGroup = () => {
78
92
  setGroupFilter({ chat_group_graph_id: team.id })
@@ -82,14 +96,19 @@ export const TeamRow = ({ team }: TeamRowProps) => {
82
96
  const serviceTypeName = servicesTeam?.serviceTypeName || servicesTeam?.group
83
97
 
84
98
  return (
85
- <PressableRow style={styles.row} onPress={handleFilterByGroup}>
86
- <View>
99
+ <PressableRow style={styles.row} onPress={handleFilterByGroup} isActive={isActive}>
100
+ <View style={styles.rowContent}>
87
101
  <Heading variant="h3" style={styles.rowTitle}>
88
102
  {team.name}
89
103
  </Heading>
90
104
  <Text>{serviceTypeName}</Text>
91
105
  </View>
92
- {isActive ? <Icon name="general.check" size={16} style={styles.rowIconRight} /> : null}
106
+ <Icon
107
+ name="general.check"
108
+ size={16}
109
+ style={styles.rowIconRight}
110
+ accessibilityElementsHidden
111
+ />
93
112
  </PressableRow>
94
113
  )
95
114
  }
@@ -109,12 +128,18 @@ export const ViewMore = ({ routeName }: ViewMoreRowProps) => {
109
128
 
110
129
  export const PressableRow = ({
111
130
  children,
131
+ isActive,
112
132
  onPress,
113
133
  style,
114
- }: PropsWithChildren<{ onPress: () => void; style?: ViewStyle }>) => {
134
+ }: PropsWithChildren<{ isActive: boolean; onPress: () => void; style?: ViewStyle }>) => {
115
135
  const styles = useRowStyles()
116
136
  return (
117
- <PlatformPressable style={styles.container} onPress={onPress}>
137
+ <PlatformPressable
138
+ style={styles.container}
139
+ onPress={onPress}
140
+ accessibilityRole="radio"
141
+ accessibilityState={{ selected: isActive }}
142
+ >
118
143
  <View style={[styles.innerContainer, style]}>{children}</View>
119
144
  </PlatformPressable>
120
145
  )
@@ -124,7 +149,7 @@ const ASPECT_RATIO = 16 / 9
124
149
  const THUMBNAIL_WIDTH = 80
125
150
  const THUMBNAIL_HEIGHT = THUMBNAIL_WIDTH / ASPECT_RATIO
126
151
 
127
- const useRowStyles = () => {
152
+ const useRowStyles = ({ isActive = false }: { isActive?: boolean } = {}) => {
128
153
  const theme = useTheme()
129
154
  return StyleSheet.create({
130
155
  container: {
@@ -153,12 +178,17 @@ const useRowStyles = () => {
153
178
  height: THUMBNAIL_HEIGHT,
154
179
  borderRadius: 4,
155
180
  },
181
+ rowContent: {
182
+ flexShrink: 1,
183
+ },
156
184
  rowIconRight: {
157
185
  marginLeft: 'auto',
158
186
  color: theme.colors.statusSuccessIcon,
187
+ opacity: isActive ? 1 : 0,
159
188
  },
160
189
  rowTitle: {
161
190
  fontSize: 16,
191
+ flexShrink: 1,
162
192
  },
163
193
  })
164
194
  }
@@ -46,7 +46,7 @@ export const useGroupsToFilter = () => {
46
46
  () =>
47
47
  groups
48
48
  .map(group => {
49
- const groupsGroup = groupsData.find(g => group.id.includes(g.id))
49
+ const groupsGroup = groupsData.find(g => group.id === `Groups-Group-${g.id}`)
50
50
  const { membershipsCount, headerImage } = groupsGroup || {}
51
51
 
52
52
  return {
@@ -0,0 +1,67 @@
1
+ import React from 'react'
2
+ import { StyleSheet, View } from 'react-native'
3
+ import { FlashList, type FlashListProps } from '@shopify/flash-list'
4
+ import { MemberResource } from '../../../types'
5
+ import { Person, Text } from '../../../components/display'
6
+ import { useTheme } from '../../../hooks'
7
+
8
+ interface FormListProps {
9
+ memberData: MemberResource[]
10
+ FormContent?: FlashListProps<MemberResource>['ListHeaderComponent']
11
+ listEmptyText?: string
12
+ }
13
+
14
+ export const FormList = ({ memberData, FormContent, listEmptyText }: FormListProps) => {
15
+ const styles = useStyles()
16
+
17
+ return (
18
+ <FlashList
19
+ data={memberData}
20
+ ListHeaderComponent={FormContent}
21
+ renderItem={({ item }) => <Person person={item} style={styles.person} />}
22
+ keyExtractor={item => item.id.toString()}
23
+ estimatedItemSize={45}
24
+ ListEmptyComponent={<ListEmptyText text={listEmptyText || 'No members found'} />}
25
+ />
26
+ )
27
+ }
28
+
29
+ const ListEmptyText = ({ text }: { text: string }) => {
30
+ const styles = useStyles()
31
+
32
+ return (
33
+ <View style={styles.emptyTextContainer}>
34
+ <Text style={styles.emptyText}>{text}</Text>
35
+ </View>
36
+ )
37
+ }
38
+
39
+ export const Divider = () => {
40
+ const styles = useStyles()
41
+
42
+ return <View style={styles.divider} />
43
+ }
44
+
45
+ const useStyles = () => {
46
+ const { colors } = useTheme()
47
+
48
+ return StyleSheet.create({
49
+ person: {
50
+ paddingHorizontal: 16,
51
+ paddingBottom: 12,
52
+ },
53
+ emptyTextContainer: {
54
+ alignItems: 'center',
55
+ justifyContent: 'center',
56
+ padding: 32,
57
+ },
58
+ emptyText: {
59
+ textAlign: 'center',
60
+ color: colors.textColorDefaultSecondary,
61
+ },
62
+ divider: {
63
+ borderBottomWidth: 1,
64
+ borderBottomColor: colors.fillColorNeutral050Base,
65
+ },
66
+ })
67
+ }
@@ -0,0 +1,191 @@
1
+ import { StackActions, useNavigation } from '@react-navigation/native'
2
+ import React, { useCallback, useState } from 'react'
3
+ import { Platform, StyleSheet, TextInput, View } from 'react-native'
4
+ import { Heading, Text } from '../../../components'
5
+ import { ActionButton } from '../../../components/display/action_button'
6
+ import { useSuspenseGet } from '../../../hooks'
7
+ import { useApiClient } from '../../../hooks/use_api_client'
8
+ import { useMutation } from '@tanstack/react-query'
9
+ import {
10
+ ApiResource,
11
+ ConversationResource,
12
+ GroupsGroupResource,
13
+ ResourceObject,
14
+ } from '../../../types'
15
+ import { Divider, FormList } from './form_list'
16
+ import { pluralize } from '../../../utils'
17
+ import { KeyboardView } from '../../../components/display/keyboard_view'
18
+ import { MemberErrorCard } from './member_error_card'
19
+ import { useGroupMembersForNewConversation } from '../../../hooks/groups/use_group_members_for_new_conversation'
20
+
21
+ type GroupsFormProps = {
22
+ groupId: number
23
+ }
24
+
25
+ interface ChatConversationPayload extends ResourceObject {
26
+ value: string
27
+ }
28
+
29
+ export const GroupsForm = ({ groupId }: GroupsFormProps) => {
30
+ const navigation = useNavigation()
31
+ const [title, setTitle] = useState<string>()
32
+ const apiClient = useApiClient()
33
+ const { data: group } = useSuspenseGet<GroupsGroupResource>({
34
+ url: `/me/groups/${groupId}`,
35
+ data: {
36
+ fields: {
37
+ Group: [],
38
+ },
39
+ },
40
+ app: 'groups',
41
+ })
42
+
43
+ const groupMemberships = useGroupMembersForNewConversation({ id: groupId })
44
+
45
+ const { mutate: handleSave } = useMutation({
46
+ throwOnError: true,
47
+ onSuccess: result => {
48
+ handleRedirectToConversation({ conversation_id: result.data.id })
49
+ },
50
+ mutationFn: () =>
51
+ apiClient.groups
52
+ .post<ApiResource<ChatConversationPayload>>({
53
+ url: `/me/groups/${groupId}/chat_conversation_payload`,
54
+ data: {
55
+ data: {
56
+ type: '',
57
+ attributes: {
58
+ title,
59
+ },
60
+ },
61
+ },
62
+ })
63
+ .then(res => res.data.value)
64
+ .then(payload =>
65
+ apiClient.chat.post<ApiResource<ConversationResource>>({
66
+ url: '/me/conversations',
67
+ data: {
68
+ data: {
69
+ type: 'Conversation',
70
+ attributes: {
71
+ payload,
72
+ },
73
+ },
74
+ },
75
+ })
76
+ ),
77
+ })
78
+
79
+ const handleRedirectToConversation = useCallback(
80
+ ({ conversation_id }: { conversation_id: number }) => {
81
+ // exit from the create stack
82
+ navigation.getParent()?.goBack()
83
+ // navigate to the conversation screen
84
+ navigation.dispatch(
85
+ StackActions.push('Conversation', {
86
+ conversation_id,
87
+ })
88
+ )
89
+ },
90
+ [navigation]
91
+ )
92
+
93
+ return (
94
+ <KeyboardView>
95
+ <FormList
96
+ memberData={groupMemberships.data}
97
+ FormContent={
98
+ <FormContent
99
+ group={group}
100
+ title={title}
101
+ setTitle={setTitle}
102
+ isMemberError={groupMemberships.isError}
103
+ />
104
+ }
105
+ />
106
+ <ActionButton
107
+ title="Start Conversation"
108
+ onPress={() => handleSave()}
109
+ infoText="Conversation will be automatically updated if any members are added or removed from this group."
110
+ />
111
+ </KeyboardView>
112
+ )
113
+ }
114
+
115
+ interface FormContentProps {
116
+ group: GroupsGroupResource
117
+ title?: string
118
+ setTitle: (title: string) => void
119
+ isMemberError: boolean
120
+ }
121
+
122
+ function FormContent({ group, title, setTitle, isMemberError }: FormContentProps) {
123
+ const styles = useStyles()
124
+ const { name, membershipsCount } = group
125
+ const memberHeader = pluralize(membershipsCount, 'member')
126
+
127
+ return (
128
+ <View style={styles.formContent}>
129
+ <View style={styles.toSection}>
130
+ <Heading variant="h3">To:</Heading>
131
+ <Text style={styles.groupName}>{name}</Text>
132
+ </View>
133
+ <Divider />
134
+ <View style={styles.titleSection}>
135
+ <Heading variant="h3">Title</Heading>
136
+ <TextInput
137
+ placeholder="Topic of conversation (required)"
138
+ value={title}
139
+ onChangeText={setTitle}
140
+ style={styles.titleInput}
141
+ autoFocus={true}
142
+ />
143
+ </View>
144
+ <Divider />
145
+ <View style={styles.memberSection}>
146
+ <Heading variant="h3">{memberHeader} selected</Heading>
147
+ {isMemberError && (
148
+ <MemberErrorCard description="There was an issue loading group members, please refresh and try again." />
149
+ )}
150
+ </View>
151
+ </View>
152
+ )
153
+ }
154
+
155
+ const useStyles = () => {
156
+ const sectionPadding = 16
157
+ const inputPadding = 8
158
+
159
+ return StyleSheet.create({
160
+ formContent: {
161
+ paddingVertical: sectionPadding,
162
+ flex: 1,
163
+ },
164
+ toSection: {
165
+ padding: sectionPadding,
166
+ flexDirection: 'row',
167
+ gap: 8,
168
+ },
169
+ groupName: {
170
+ fontSize: 18,
171
+ },
172
+ titleSection: {
173
+ padding: sectionPadding,
174
+ paddingBottom: Platform.select({
175
+ ios: sectionPadding,
176
+ android: sectionPadding - inputPadding,
177
+ }),
178
+ gap: Platform.select({
179
+ ios: 8,
180
+ android: 0,
181
+ }),
182
+ },
183
+ titleInput: {
184
+ fontSize: 18,
185
+ },
186
+ memberSection: {
187
+ padding: sectionPadding,
188
+ paddingBottom: 0,
189
+ },
190
+ })
191
+ }
@@ -0,0 +1,20 @@
1
+ import React from 'react'
2
+ import { View, StyleSheet } from 'react-native'
3
+ import { Banner } from '../../../components'
4
+
5
+ export const MemberErrorCard = ({ description }: { description: string }) => {
6
+ const styles = useStyles()
7
+ return (
8
+ <View style={styles.memberErrorBanner}>
9
+ <Banner appearance="error" description={description} />
10
+ </View>
11
+ )
12
+ }
13
+
14
+ const useStyles = () => {
15
+ return StyleSheet.create({
16
+ memberErrorBanner: {
17
+ paddingTop: 16,
18
+ },
19
+ })
20
+ }
@@ -0,0 +1,24 @@
1
+ import { StyleSheet, View } from 'react-native'
2
+ import { Banner } from '../../../components'
3
+
4
+ export const SourceAppErrorCard = () => {
5
+ const styles = useStyles()
6
+
7
+ return (
8
+ <View style={styles.container}>
9
+ <Banner
10
+ appearance="error"
11
+ heading="Invalid Source App"
12
+ description="Something went wrong, try going back and selecting the recipient again."
13
+ />
14
+ </View>
15
+ )
16
+ }
17
+
18
+ const useStyles = () => {
19
+ return StyleSheet.create({
20
+ container: {
21
+ padding: 16,
22
+ },
23
+ })
24
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react'
2
+ import { View } from 'react-native'
3
+ import { Text } from '../../../components'
4
+
5
+ type TeamFormProps = {
6
+ initialTeamIds?: string[]
7
+ initialPlanId?: number
8
+ }
9
+
10
+ export const TeamsForm = ({ initialTeamIds, initialPlanId }: TeamFormProps) => {
11
+ console.log('initialTeamIds', initialTeamIds)
12
+ console.log('initialPlanId', initialPlanId)
13
+ return (
14
+ <View>
15
+ <Text>Services team form coming soon</Text>
16
+ </View>
17
+ )
18
+ }
@@ -0,0 +1,26 @@
1
+ import { StaticScreenProps } from '@react-navigation/native'
2
+ import React from 'react'
3
+ import { GroupsForm } from './components/groups_form'
4
+ import { TeamsForm } from './components/team_form'
5
+ import { SourceAppErrorCard } from './components/source_app_error_card'
6
+ import { AppName } from '../../types/resources/app_name'
7
+
8
+ type ConversationNewScreenProps = StaticScreenProps<{
9
+ group_id?: number
10
+ team_ids?: string[]
11
+ plan_id?: number
12
+ source_app_name: AppName
13
+ }>
14
+
15
+ export const ConversationNewScreen = ({ route }: ConversationNewScreenProps) => {
16
+ const { group_id, team_ids, source_app_name, plan_id } = route.params
17
+
18
+ switch (source_app_name) {
19
+ case 'Groups':
20
+ return group_id ? <GroupsForm groupId={group_id} /> : <SourceAppErrorCard />
21
+ case 'Services':
22
+ return <TeamsForm initialTeamIds={team_ids} initialPlanId={plan_id} />
23
+ default:
24
+ return <SourceAppErrorCard />
25
+ }
26
+ }