@planningcenter/chat-react-native 4.4.0-rc.7 → 4.4.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 (339) hide show
  1. package/build/components/conversation/jump_to_bottom_button.d.ts.map +1 -1
  2. package/build/components/conversation/jump_to_bottom_button.js +42 -40
  3. package/build/components/conversation/jump_to_bottom_button.js.map +1 -1
  4. package/build/components/conversation/message.d.ts +2 -1
  5. package/build/components/conversation/message.d.ts.map +1 -1
  6. package/build/components/conversation/message.js +3 -1
  7. package/build/components/conversation/message.js.map +1 -1
  8. package/build/components/conversation/message_form.d.ts.map +1 -1
  9. package/build/components/conversation/message_form.js +3 -1
  10. package/build/components/conversation/message_form.js.map +1 -1
  11. package/build/components/conversation/message_list.d.ts.map +1 -1
  12. package/build/components/conversation/message_list.js +35 -31
  13. package/build/components/conversation/message_list.js.map +1 -1
  14. package/build/components/conversation/message_reaction.d.ts +2 -1
  15. package/build/components/conversation/message_reaction.d.ts.map +1 -1
  16. package/build/components/conversation/message_reaction.js +67 -60
  17. package/build/components/conversation/message_reaction.js.map +1 -1
  18. package/build/components/conversation/messages_disabled_banners.d.ts +7 -5
  19. package/build/components/conversation/messages_disabled_banners.d.ts.map +1 -1
  20. package/build/components/conversation/messages_disabled_banners.js +15 -14
  21. package/build/components/conversation/messages_disabled_banners.js.map +1 -1
  22. package/build/components/conversation/system_message.d.ts +2 -1
  23. package/build/components/conversation/system_message.d.ts.map +1 -1
  24. package/build/components/conversation/system_message.js +133 -100
  25. package/build/components/conversation/system_message.js.map +1 -1
  26. package/build/components/conversations/archived_results_footer.d.ts +6 -0
  27. package/build/components/conversations/archived_results_footer.d.ts.map +1 -0
  28. package/build/components/conversations/archived_results_footer.js +51 -0
  29. package/build/components/conversations/archived_results_footer.js.map +1 -0
  30. package/build/components/conversations/conversation_actions.d.ts.map +1 -1
  31. package/build/components/conversations/conversation_actions.js +241 -206
  32. package/build/components/conversations/conversation_actions.js.map +1 -1
  33. package/build/components/conversations/conversation_preview.d.ts.map +1 -1
  34. package/build/components/conversations/conversation_preview.js +102 -93
  35. package/build/components/conversations/conversation_preview.js.map +1 -1
  36. package/build/components/conversations/conversations.d.ts.map +1 -1
  37. package/build/components/conversations/conversations.js +66 -41
  38. package/build/components/conversations/conversations.js.map +1 -1
  39. package/build/components/conversations/conversations_blank_state.d.ts.map +1 -1
  40. package/build/components/conversations/conversations_blank_state.js +55 -12
  41. package/build/components/conversations/conversations_blank_state.js.map +1 -1
  42. package/build/components/conversations/filtered_results_footer.d.ts +2 -0
  43. package/build/components/conversations/filtered_results_footer.d.ts.map +1 -0
  44. package/build/components/conversations/filtered_results_footer.js +77 -0
  45. package/build/components/conversations/filtered_results_footer.js.map +1 -0
  46. package/build/components/display/action_button.d.ts.map +1 -1
  47. package/build/components/display/action_button.js +18 -16
  48. package/build/components/display/action_button.js.map +1 -1
  49. package/build/components/display/filter_dropdown.d.ts +14 -0
  50. package/build/components/display/filter_dropdown.d.ts.map +1 -0
  51. package/build/components/display/filter_dropdown.js +193 -0
  52. package/build/components/display/filter_dropdown.js.map +1 -0
  53. package/build/components/display/icon_tile.d.ts +13 -0
  54. package/build/components/display/icon_tile.d.ts.map +1 -0
  55. package/build/components/display/icon_tile.js +149 -0
  56. package/build/components/display/icon_tile.js.map +1 -0
  57. package/build/components/display/index.d.ts +2 -0
  58. package/build/components/display/index.d.ts.map +1 -1
  59. package/build/components/display/index.js +2 -0
  60. package/build/components/display/index.js.map +1 -1
  61. package/build/contexts/api_provider.d.ts.map +1 -1
  62. package/build/contexts/api_provider.js +21 -9
  63. package/build/contexts/api_provider.js.map +1 -1
  64. package/build/contexts/conversations_context.d.ts.map +1 -1
  65. package/build/contexts/conversations_context.js +21 -18
  66. package/build/contexts/conversations_context.js.map +1 -1
  67. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +196 -16
  68. package/build/hooks/groups/use_group_members_for_new_conversation.d.ts.map +1 -1
  69. package/build/hooks/groups/use_group_members_for_new_conversation.js +72 -58
  70. package/build/hooks/groups/use_group_members_for_new_conversation.js.map +1 -1
  71. package/build/hooks/index.d.ts +3 -0
  72. package/build/hooks/index.d.ts.map +1 -1
  73. package/build/hooks/index.js +3 -0
  74. package/build/hooks/index.js.map +1 -1
  75. package/build/hooks/use_animated_message_background_color.d.ts.map +1 -1
  76. package/build/hooks/use_animated_message_background_color.js +5 -3
  77. package/build/hooks/use_animated_message_background_color.js.map +1 -1
  78. package/build/hooks/use_api.d.ts +3 -2
  79. package/build/hooks/use_api.d.ts.map +1 -1
  80. package/build/hooks/use_api.js.map +1 -1
  81. package/build/hooks/use_can_browse_archived_conversations.d.ts +2 -0
  82. package/build/hooks/use_can_browse_archived_conversations.d.ts.map +1 -0
  83. package/build/hooks/use_can_browse_archived_conversations.js +29 -0
  84. package/build/hooks/use_can_browse_archived_conversations.js.map +1 -0
  85. package/build/hooks/use_clear_conversation_filters.d.ts +2 -0
  86. package/build/hooks/use_clear_conversation_filters.d.ts.map +1 -0
  87. package/build/hooks/use_clear_conversation_filters.js +25 -0
  88. package/build/hooks/use_clear_conversation_filters.js.map +1 -0
  89. package/build/hooks/use_conversation.d.ts +73 -1
  90. package/build/hooks/use_conversation.d.ts.map +1 -1
  91. package/build/hooks/use_conversation.js +130 -3
  92. package/build/hooks/use_conversation.js.map +1 -1
  93. package/build/hooks/use_conversation_messages.d.ts.map +1 -1
  94. package/build/hooks/use_conversation_messages.js +29 -26
  95. package/build/hooks/use_conversation_messages.js.map +1 -1
  96. package/build/hooks/use_current_person.d.ts.map +1 -1
  97. package/build/hooks/use_current_person.js +1 -1
  98. package/build/hooks/use_current_person.js.map +1 -1
  99. package/build/hooks/use_jolt.d.ts +1 -0
  100. package/build/hooks/use_jolt.d.ts.map +1 -1
  101. package/build/hooks/use_jolt.js +59 -0
  102. package/build/hooks/use_jolt.js.map +1 -1
  103. package/build/hooks/use_manual_archiving_enabled.d.ts +2 -0
  104. package/build/hooks/use_manual_archiving_enabled.d.ts.map +1 -0
  105. package/build/hooks/use_manual_archiving_enabled.js +18 -0
  106. package/build/hooks/use_manual_archiving_enabled.js.map +1 -0
  107. package/build/hooks/use_mark_latest_message_read.d.ts.map +1 -1
  108. package/build/hooks/use_mark_latest_message_read.js +3 -3
  109. package/build/hooks/use_mark_latest_message_read.js.map +1 -1
  110. package/build/hooks/use_reduce_motion.d.ts +2 -0
  111. package/build/hooks/use_reduce_motion.d.ts.map +1 -0
  112. package/build/hooks/use_reduce_motion.js +28 -0
  113. package/build/hooks/use_reduce_motion.js.map +1 -0
  114. package/build/hooks/use_unarchive_conversation_action.d.ts +7 -0
  115. package/build/hooks/use_unarchive_conversation_action.d.ts.map +1 -0
  116. package/build/hooks/use_unarchive_conversation_action.js +52 -0
  117. package/build/hooks/use_unarchive_conversation_action.js.map +1 -0
  118. package/build/screens/attachment_actions/attachment_actions_screen.d.ts.map +1 -1
  119. package/build/screens/attachment_actions/attachment_actions_screen.js +84 -61
  120. package/build/screens/attachment_actions/attachment_actions_screen.js.map +1 -1
  121. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  122. package/build/screens/conversation_details_screen.js +490 -395
  123. package/build/screens/conversation_details_screen.js.map +1 -1
  124. package/build/screens/conversation_filters/components/conversation_filters.d.ts.map +1 -1
  125. package/build/screens/conversation_filters/components/conversation_filters.js +88 -18
  126. package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -1
  127. package/build/screens/conversation_filters/components/rows.d.ts +9 -0
  128. package/build/screens/conversation_filters/components/rows.d.ts.map +1 -1
  129. package/build/screens/conversation_filters/components/rows.js +93 -1
  130. package/build/screens/conversation_filters/components/rows.js.map +1 -1
  131. package/build/screens/conversation_filters/context/conversation_filter_context.d.ts.map +1 -1
  132. package/build/screens/conversation_filters/context/conversation_filter_context.js +8 -4
  133. package/build/screens/conversation_filters/context/conversation_filter_context.js.map +1 -1
  134. package/build/screens/conversation_filters/filter_types.d.ts +1 -0
  135. package/build/screens/conversation_filters/filter_types.d.ts.map +1 -1
  136. package/build/screens/conversation_filters/filter_types.js +1 -0
  137. package/build/screens/conversation_filters/filter_types.js.map +1 -1
  138. package/build/screens/conversation_filters/screen_props.d.ts +1 -0
  139. package/build/screens/conversation_filters/screen_props.d.ts.map +1 -1
  140. package/build/screens/conversation_filters/screen_props.js.map +1 -1
  141. package/build/screens/conversation_filters_screen.d.ts +1 -0
  142. package/build/screens/conversation_filters_screen.d.ts.map +1 -1
  143. package/build/screens/conversation_filters_screen.js +79 -48
  144. package/build/screens/conversation_filters_screen.js.map +1 -1
  145. package/build/screens/conversation_new/components/groups_form.d.ts.map +1 -1
  146. package/build/screens/conversation_new/components/groups_form.js +37 -34
  147. package/build/screens/conversation_new/components/groups_form.js.map +1 -1
  148. package/build/screens/conversation_screen.d.ts.map +1 -1
  149. package/build/screens/conversation_screen.js +13 -10
  150. package/build/screens/conversation_screen.js.map +1 -1
  151. package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts +2 -0
  152. package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts.map +1 -0
  153. package/build/screens/conversations/components/filter_dropdown_list_header_component.js +580 -0
  154. package/build/screens/conversations/components/filter_dropdown_list_header_component.js.map +1 -0
  155. package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
  156. package/build/screens/conversations/components/list_header_component.js +95 -90
  157. package/build/screens/conversations/components/list_header_component.js.map +1 -1
  158. package/build/screens/conversations/components/search_list_header_component.d.ts.map +1 -1
  159. package/build/screens/conversations/components/search_list_header_component.js +100 -95
  160. package/build/screens/conversations/components/search_list_header_component.js.map +1 -1
  161. package/build/screens/conversations/conversations_screen.d.ts +1 -0
  162. package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
  163. package/build/screens/conversations/conversations_screen.js +15 -2
  164. package/build/screens/conversations/conversations_screen.js.map +1 -1
  165. package/build/screens/design_system_screen.d.ts.map +1 -1
  166. package/build/screens/design_system_screen.js +275 -215
  167. package/build/screens/design_system_screen.js.map +1 -1
  168. package/build/screens/message_actions_screen.d.ts.map +1 -1
  169. package/build/screens/message_actions_screen.js +112 -92
  170. package/build/screens/message_actions_screen.js.map +1 -1
  171. package/build/screens/search/search_screen.d.ts.map +1 -1
  172. package/build/screens/search/search_screen.js +10 -2
  173. package/build/screens/search/search_screen.js.map +1 -1
  174. package/build/screens/send_giphy_screen.d.ts +1 -0
  175. package/build/screens/send_giphy_screen.d.ts.map +1 -1
  176. package/build/screens/send_giphy_screen.js +108 -106
  177. package/build/screens/send_giphy_screen.js.map +1 -1
  178. package/build/screens/team_conversation_screen.js +1 -1
  179. package/build/screens/team_conversation_screen.js.map +1 -1
  180. package/build/types/jolt_events/message_events.d.ts +2 -0
  181. package/build/types/jolt_events/message_events.d.ts.map +1 -1
  182. package/build/types/jolt_events/message_events.js.map +1 -1
  183. package/build/types/resources/conversation.d.ts +2 -2
  184. package/build/types/resources/conversation.d.ts.map +1 -1
  185. package/build/types/resources/conversation.js.map +1 -1
  186. package/build/types/resources/member_ability.d.ts +2 -0
  187. package/build/types/resources/member_ability.d.ts.map +1 -1
  188. package/build/types/resources/member_ability.js.map +1 -1
  189. package/build/types/resources/message.d.ts +2 -0
  190. package/build/types/resources/message.d.ts.map +1 -1
  191. package/build/types/resources/message.js.map +1 -1
  192. package/build/types/resources/person.d.ts +1 -0
  193. package/build/types/resources/person.d.ts.map +1 -1
  194. package/build/types/resources/person.js.map +1 -1
  195. package/build/utils/archived_conversation.d.ts +5 -0
  196. package/build/utils/archived_conversation.d.ts.map +1 -0
  197. package/build/utils/archived_conversation.js +5 -0
  198. package/build/utils/archived_conversation.js.map +1 -0
  199. package/build/utils/date.d.ts +1 -0
  200. package/build/utils/date.d.ts.map +1 -1
  201. package/build/utils/date.js +9 -0
  202. package/build/utils/date.js.map +1 -1
  203. package/build/utils/index.d.ts +1 -0
  204. package/build/utils/index.d.ts.map +1 -1
  205. package/build/utils/index.js +1 -0
  206. package/build/utils/index.js.map +1 -1
  207. package/build/utils/jolt/transform_message_event_data_to_message_resource.d.ts.map +1 -1
  208. package/build/utils/jolt/transform_message_event_data_to_message_resource.js +2 -1
  209. package/build/utils/jolt/transform_message_event_data_to_message_resource.js.map +1 -1
  210. package/build/utils/native_adapters/configuration.d.ts +3 -0
  211. package/build/utils/native_adapters/configuration.d.ts.map +1 -1
  212. package/build/utils/native_adapters/configuration.js +3 -0
  213. package/build/utils/native_adapters/configuration.js.map +1 -1
  214. package/build/utils/native_adapters/index.d.ts +1 -0
  215. package/build/utils/native_adapters/index.d.ts.map +1 -1
  216. package/build/utils/native_adapters/index.js +1 -0
  217. package/build/utils/native_adapters/index.js.map +1 -1
  218. package/build/utils/native_adapters/menu.d.ts +41 -0
  219. package/build/utils/native_adapters/menu.d.ts.map +1 -0
  220. package/build/utils/native_adapters/menu.js +56 -0
  221. package/build/utils/native_adapters/menu.js.map +1 -0
  222. package/build/utils/request/conversation.d.ts +2 -1
  223. package/build/utils/request/conversation.d.ts.map +1 -1
  224. package/build/utils/request/conversation.js +4 -1
  225. package/build/utils/request/conversation.js.map +1 -1
  226. package/build/utils/request/messages_data_options.d.ts.map +1 -1
  227. package/build/utils/request/messages_data_options.js +1 -1
  228. package/build/utils/request/messages_data_options.js.map +1 -1
  229. package/build/utils/system_messages.d.ts +7 -5
  230. package/build/utils/system_messages.d.ts.map +1 -1
  231. package/build/utils/system_messages.js +10 -2
  232. package/build/utils/system_messages.js.map +1 -1
  233. package/build/vendor/font_awesome_pro_solid_icons.d.ts +1 -0
  234. package/build/vendor/font_awesome_pro_solid_icons.d.ts.map +1 -1
  235. package/build/vendor/font_awesome_pro_solid_icons.js +5 -0
  236. package/build/vendor/font_awesome_pro_solid_icons.js.map +1 -1
  237. package/package.json +3 -3
  238. package/src/__tests__/hooks/use_can_browse_archived_conversations.test.tsx +98 -0
  239. package/src/__tests__/screens/conversation_filters/components/conversation_filters.test.tsx +132 -0
  240. package/src/__tests__/screens/conversation_filters_screen.test.tsx +76 -0
  241. package/src/__tests__/screens/conversation_new/components/services_form.test.tsx +1 -0
  242. package/src/__tests__/screens/message_actions_screen.test.tsx +65 -2
  243. package/src/__tests__/screens/send_giphy_screen.test.tsx +102 -0
  244. package/src/__tests__/utils/system_messages.ts +19 -32
  245. package/src/components/conversation/__tests__/message_list.test.tsx +68 -2
  246. package/src/components/conversation/__tests__/system_message.test.tsx +106 -0
  247. package/src/components/conversation/jump_to_bottom_button.tsx +4 -3
  248. package/src/components/conversation/message.tsx +3 -0
  249. package/src/components/conversation/message_form.tsx +3 -1
  250. package/src/components/conversation/message_list.tsx +9 -1
  251. package/src/components/conversation/message_reaction.tsx +7 -2
  252. package/src/components/conversation/messages_disabled_banners.tsx +17 -18
  253. package/src/components/conversation/system_message.tsx +44 -16
  254. package/src/components/conversations/__tests__/conversation_actions.test.tsx +67 -0
  255. package/src/components/conversations/__tests__/conversation_preview.test.tsx +105 -0
  256. package/src/components/conversations/__tests__/conversations.test.tsx +93 -0
  257. package/src/components/conversations/__tests__/conversations_blank_state.test.tsx +73 -0
  258. package/src/components/conversations/archived_results_footer.tsx +36 -0
  259. package/src/components/conversations/conversation_actions.tsx +27 -19
  260. package/src/components/conversations/conversation_preview.tsx +39 -10
  261. package/src/components/conversations/conversations.tsx +26 -3
  262. package/src/components/conversations/conversations_blank_state.tsx +21 -0
  263. package/src/components/conversations/filtered_results_footer.tsx +38 -0
  264. package/src/components/display/__tests__/filter_dropdown.test.tsx +114 -0
  265. package/src/components/display/__tests__/icon_tile.test.tsx +16 -0
  266. package/src/components/display/action_button.tsx +4 -3
  267. package/src/components/display/filter_dropdown.tsx +124 -0
  268. package/src/components/display/icon_tile.tsx +67 -0
  269. package/src/components/display/index.ts +2 -0
  270. package/src/contexts/api_provider.tsx +8 -0
  271. package/src/contexts/conversations_context.tsx +2 -1
  272. package/src/hooks/__tests__/use_conversation_archive.test.tsx +152 -0
  273. package/src/hooks/__tests__/use_conversation_jolt_events.test.tsx +74 -0
  274. package/src/hooks/__tests__/use_conversation_messages.test.tsx +10 -2
  275. package/src/hooks/__tests__/use_jolt.test.tsx +100 -1
  276. package/src/hooks/__tests__/use_mark_latest_message_read.test.tsx +21 -7
  277. package/src/hooks/__tests__/use_reduce_motion.test.tsx +61 -0
  278. package/src/hooks/__tests__/use_unarchive_conversation_action.test.tsx +67 -0
  279. package/src/hooks/groups/use_group_members_for_new_conversation.ts +21 -16
  280. package/src/hooks/index.ts +3 -0
  281. package/src/hooks/use_animated_message_background_color.ts +6 -3
  282. package/src/hooks/use_api.ts +9 -2
  283. package/src/hooks/use_can_browse_archived_conversations.ts +17 -0
  284. package/src/hooks/use_clear_conversation_filters.ts +16 -0
  285. package/src/hooks/use_conversation.ts +44 -3
  286. package/src/hooks/use_conversation_messages.ts +7 -5
  287. package/src/hooks/use_current_person.ts +1 -0
  288. package/src/hooks/use_jolt.ts +57 -1
  289. package/src/hooks/use_manual_archiving_enabled.ts +10 -0
  290. package/src/hooks/use_mark_latest_message_read.ts +4 -3
  291. package/src/hooks/use_reduce_motion.ts +19 -0
  292. package/src/hooks/use_unarchive_conversation_action.ts +24 -0
  293. package/src/screens/__tests__/conversation_details_screen.test.tsx +305 -0
  294. package/src/screens/attachment_actions/__tests__/attachment_actions_screen.test.tsx +72 -0
  295. package/src/screens/attachment_actions/attachment_actions_screen.tsx +3 -1
  296. package/src/screens/conversation_details_screen.tsx +80 -16
  297. package/src/screens/conversation_filters/__tests__/conversation_filters.test.tsx +101 -0
  298. package/src/screens/conversation_filters/components/conversation_filters.tsx +40 -7
  299. package/src/screens/conversation_filters/components/rows.tsx +29 -1
  300. package/src/screens/conversation_filters/context/conversation_filter_context.tsx +4 -0
  301. package/src/screens/conversation_filters/filter_types.ts +1 -0
  302. package/src/screens/conversation_filters/screen_props.ts +1 -0
  303. package/src/screens/conversation_filters_screen.tsx +25 -5
  304. package/src/screens/conversation_new/components/groups_form.tsx +1 -0
  305. package/src/screens/conversation_screen.tsx +4 -2
  306. package/src/screens/conversations/__tests__/conversations_screen.test.tsx +52 -0
  307. package/src/screens/conversations/components/__tests__/filter_dropdown_list_header_component.test.tsx +259 -0
  308. package/src/screens/conversations/components/__tests__/list_header_component.test.tsx +21 -4
  309. package/src/screens/conversations/components/filter_dropdown_list_header_component.tsx +286 -0
  310. package/src/screens/conversations/components/list_header_component.tsx +17 -12
  311. package/src/screens/conversations/components/search_list_header_component.tsx +17 -12
  312. package/src/screens/conversations/conversations_screen.tsx +15 -2
  313. package/src/screens/design_system_screen.tsx +26 -0
  314. package/src/screens/message_actions_screen.tsx +29 -20
  315. package/src/screens/search/__tests__/search_screen.test.tsx +13 -1
  316. package/src/screens/search/search_screen.tsx +8 -2
  317. package/src/screens/send_giphy_screen.tsx +6 -3
  318. package/src/screens/team_conversation_screen.tsx +1 -1
  319. package/src/types/jolt_events/message_events.ts +2 -0
  320. package/src/types/resources/conversation.ts +2 -2
  321. package/src/types/resources/member_ability.ts +2 -0
  322. package/src/types/resources/message.ts +3 -0
  323. package/src/types/resources/person.ts +1 -0
  324. package/src/utils/__tests__/conversation.test.ts +1 -0
  325. package/src/utils/__tests__/date.test.ts +23 -0
  326. package/src/utils/__tests__/group_messages.test.ts +1 -0
  327. package/src/utils/archived_conversation.ts +13 -0
  328. package/src/utils/date.ts +8 -0
  329. package/src/utils/index.ts +1 -0
  330. package/src/utils/jolt/__tests__/transform_message_event_data_to_message_resource.test.ts +35 -0
  331. package/src/utils/jolt/transform_message_event_data_to_message_resource.ts +1 -0
  332. package/src/utils/native_adapters/__tests__/menu.test.tsx +46 -0
  333. package/src/utils/native_adapters/configuration.ts +5 -0
  334. package/src/utils/native_adapters/index.ts +1 -0
  335. package/src/utils/native_adapters/menu.tsx +70 -0
  336. package/src/utils/request/conversation.ts +4 -0
  337. package/src/utils/request/messages_data_options.ts +1 -0
  338. package/src/utils/system_messages.ts +19 -10
  339. package/src/vendor/font_awesome_pro_solid_icons.ts +12 -0
@@ -1,15 +1,14 @@
1
+ import { keepPreviousData } from '@tanstack/react-query'
1
2
  import { useMemo } from 'react'
2
3
  import { MemberResource, ResourceObject } from '../../types'
3
4
  import { GroupsGroupMemberResource } from '../../types/resources/groups/groups_member_resource_with_person'
5
+ import { useApiPaginator } from '../use_api'
4
6
  import { useEnrichPeople } from '../use_enrich_people'
5
- import { useSuspensePaginator } from '../use_suspense_api'
6
7
 
7
- type UseSuspensePaginatorResult<T extends ResourceObject> = ReturnType<
8
- typeof useSuspensePaginator<T>
9
- >
8
+ type UseApiPaginatorResult<T extends ResourceObject> = ReturnType<typeof useApiPaginator<T>>
10
9
 
11
10
  export type GroupMembersForNewConversationResult = Omit<
12
- UseSuspensePaginatorResult<GroupsGroupMemberResource>, // We are passing our own "members" data shape
11
+ UseApiPaginatorResult<GroupsGroupMemberResource>, // We are passing our own "members" data shape
13
12
  'data'
14
13
  > & {
15
14
  data: MemberResource[]
@@ -24,19 +23,25 @@ export function useGroupMembersForNewConversation({
24
23
  id: number
25
24
  gender: string | null
26
25
  }) {
27
- const response = useSuspensePaginator<GroupsGroupMemberResource>({
28
- url: `/me/groups/${id}/memberships`,
29
- data: {
30
- perPage: 100,
31
- include: ['person'],
32
- fields: {
33
- Membership: ['person, role'],
34
- Person: ['avatar_url', 'name', 'first_name', 'last_name', 'child', 'gender'],
26
+ const response = useApiPaginator<GroupsGroupMemberResource>(
27
+ {
28
+ url: `/me/groups/${id}/memberships`,
29
+ data: {
30
+ perPage: 100,
31
+ include: ['person'],
32
+ fields: {
33
+ Membership: ['person, role'],
34
+ Person: ['avatar_url', 'name', 'first_name', 'last_name', 'child', 'gender'],
35
+ },
36
+ ...(gender ? { where: { gender } } : {}),
35
37
  },
36
- ...(gender ? { where: { gender } } : {}),
38
+ app: 'groups',
37
39
  },
38
- app: 'groups',
39
- })
40
+ {
41
+ throwOnError: (_error, query) => query.state.data === undefined,
42
+ placeholderData: keepPreviousData,
43
+ }
44
+ )
40
45
 
41
46
  const { data: memberships = [] } = response
42
47
  const personIds = useMemo(() => memberships.map(m => +m.person.id), [memberships])
@@ -3,6 +3,7 @@ export { useApiClient } from './use_api_client'
3
3
  export * from './use_api'
4
4
  export * from './use_app_state'
5
5
  export * from './use_async_storage'
6
+ export * from './use_can_browse_archived_conversations'
6
7
  export * from './use_at_font_scale_breakpoint'
7
8
  export * from './use_chat_permissions'
8
9
  export * from './use_create_android_ripple_color'
@@ -16,6 +17,7 @@ export * from './use_groups_groups'
16
17
  export * from './use_groups'
17
18
  export * from './use_selected_chip_background_color'
18
19
  export * from './use_interaction_tinted_background_color'
20
+ export * from './use_manual_archiving_enabled'
19
21
  export * from './use_message_reaction_toggle'
20
22
  export * from './use_new_conversation_entry'
21
23
  export * from './use_organization'
@@ -23,6 +25,7 @@ export * from './use_people_person'
23
25
  export * from './use_preview_avatar_diameter'
24
26
  export * from './use_product_analytics'
25
27
  export * from './use_qualified_by_age'
28
+ export * from './use_reduce_motion'
26
29
  export * from './use_scalable_number_of_lines'
27
30
  export * from './use_submit_age_check'
28
31
  export * from './use_suspense_api'
@@ -10,6 +10,7 @@ import {
10
10
  Easing,
11
11
  ReduceMotion,
12
12
  } from 'react-native-reanimated'
13
+ import { useReduceMotion } from './use_reduce_motion'
13
14
  import { useTheme } from './use_theme'
14
15
 
15
16
  const FLASH_IN_MS = 150
@@ -18,10 +19,12 @@ const FLASH_OUT_MS = 1500
18
19
 
19
20
  export function useAnimatedMessageBackgroundColor() {
20
21
  const { colors } = useTheme()
22
+ const reduceMotion = useReduceMotion()
21
23
  const pressProgress = useSharedValue(0)
22
24
  const flashProgress = useSharedValue(0)
23
25
 
24
- const tintColor = colors.fillColorNeutral050Base
26
+ const tintColor =
27
+ colors.name === 'dark' ? colors.fillColorNeutral040 : colors.fillColorNeutral050Base
25
28
  const tintsOnPress = Platform.OS === 'ios'
26
29
 
27
30
  const animatedBackgroundColor = useAnimatedStyle(() => {
@@ -53,12 +56,12 @@ export function useAnimatedMessageBackgroundColor() {
53
56
  withTiming(0, {
54
57
  duration: FLASH_OUT_MS,
55
58
  easing: Easing.out(Easing.ease),
56
- reduceMotion: ReduceMotion.System,
59
+ reduceMotion: reduceMotion ? ReduceMotion.Always : ReduceMotion.Never,
57
60
  }),
58
61
  ReduceMotion.Never
59
62
  )
60
63
  )
61
- }, [flashProgress])
64
+ }, [flashProgress, reduceMotion])
62
65
 
63
66
  return {
64
67
  animatedBackgroundColor,
@@ -1,4 +1,10 @@
1
- import { InfiniteData, useInfiniteQuery, useQuery } from '@tanstack/react-query'
1
+ import {
2
+ InfiniteData,
3
+ keepPreviousData,
4
+ Query,
5
+ useInfiniteQuery,
6
+ useQuery,
7
+ } from '@tanstack/react-query'
2
8
  import { useContext } from 'react'
3
9
  import { ChatContext } from '../contexts/chat_context'
4
10
  import { ApiCollection, ApiResource, ResourceObject } from '../types'
@@ -16,7 +22,8 @@ export type ApiGetQueryOptions = {
16
22
  staleTime?: number
17
23
  gcTime?: number
18
24
  enabled?: boolean
19
- throwOnError?: boolean | ((error: ResponseError) => boolean)
25
+ throwOnError?: boolean | ((error: ResponseError, query: Query<any, ResponseError>) => boolean)
26
+ placeholderData?: typeof keepPreviousData
20
27
  }
21
28
 
22
29
  export const useApiGet = <T extends ResourceObject | ResourceObject[]>(
@@ -0,0 +1,17 @@
1
+ import { CurrentPersonResource } from '../types'
2
+ import { FIVE_MINUTES } from '../utils/time'
3
+ import { useApiGet } from './use_api'
4
+ import { currentPersonRequestArgs } from './use_current_person'
5
+ import { useManualArchivingEnabled } from './use_manual_archiving_enabled'
6
+
7
+ export const useCanBrowseArchivedConversations = (): boolean => {
8
+ const manualArchivingEnabled = useManualArchivingEnabled()
9
+ const { data: person, isFetched } = useApiGet<CurrentPersonResource>(currentPersonRequestArgs, {
10
+ enabled: manualArchivingEnabled,
11
+ staleTime: FIVE_MINUTES,
12
+ })
13
+
14
+ if (!manualArchivingEnabled || !isFetched) return false
15
+
16
+ return person?.canBrowseArchivedConversations ?? false
17
+ }
@@ -0,0 +1,16 @@
1
+ import { useNavigation } from '@react-navigation/native'
2
+ import { useCallback } from 'react'
3
+
4
+ export function useClearConversationFilters() {
5
+ const navigation = useNavigation()
6
+
7
+ return useCallback(() => {
8
+ navigation.setParams({
9
+ title: undefined,
10
+ chat_group_graph_id: undefined,
11
+ group_source_app_name: undefined,
12
+ show_direct_messages: undefined,
13
+ show_archived: undefined,
14
+ })
15
+ }, [navigation])
16
+ }
@@ -1,11 +1,13 @@
1
1
  import { useMutation, useQueryClient } from '@tanstack/react-query'
2
2
  import { useState } from 'react'
3
+ import { Alert } from 'react-native'
3
4
  import { ApiResource, ConversationResource } from '../types'
4
5
  import { transformGetToPost } from '../utils/client/request_helpers'
5
6
  import { Haptic } from '../utils/native_adapters'
6
7
  import { getConversationsRequestArgs } from '../utils/request/conversation'
7
8
  import { useApiClient } from './use_api_client'
8
- import { getRequestQueryKey, useSuspenseGet } from './use_suspense_api'
9
+ import { useCurrentPersonCache } from './use_current_person'
10
+ import { getRequestQueryKey, SuspenseGetQueryOptions, useSuspenseGet } from './use_suspense_api'
9
11
 
10
12
  export const getConversationRequestArgs = ({ conversation_id }: { conversation_id: number }) => ({
11
13
  url: `/me/conversations/${conversation_id}`,
@@ -49,6 +51,8 @@ export const getConversationRequestArgs = ({ conversation_id }: { conversation_i
49
51
  'can_reply',
50
52
  'can_delete_non_authored_messages',
51
53
  'can_message_available_members',
54
+ 'can_archive',
55
+ 'can_unarchive',
52
56
  ],
53
57
  ConversationMembership: [
54
58
  'last_read_message_sort_key',
@@ -70,10 +74,13 @@ export const getConversationRequestArgs = ({ conversation_id }: { conversation_i
70
74
  },
71
75
  })
72
76
 
73
- export const useConversation = ({ conversation_id }: { conversation_id: number }) => {
77
+ export const useConversation = (
78
+ { conversation_id }: { conversation_id: number },
79
+ options?: SuspenseGetQueryOptions<ConversationResource>
80
+ ) => {
74
81
  const args = getConversationRequestArgs({ conversation_id })
75
82
 
76
- return useSuspenseGet<ConversationResource>(args)
83
+ return useSuspenseGet<ConversationResource>(args, options)
77
84
  }
78
85
 
79
86
  export const useConversationMute = ({ conversation_id }: { conversation_id: number }) => {
@@ -179,6 +186,40 @@ export const useConversationDelete = ({ conversation_id }: { conversation_id: nu
179
186
  })
180
187
  }
181
188
 
189
+ export const useConversationArchive = ({ conversation_id }: { conversation_id: number }) => {
190
+ const apiClient = useApiClient()
191
+ const queryClient = useQueryClient()
192
+ const currentPersonCache = useCurrentPersonCache()
193
+ const conversationQueryKey = getRequestQueryKey(getConversationRequestArgs({ conversation_id }))
194
+ const { url } = getConversationsRequestArgs()
195
+
196
+ const { mutate: setArchived, ...mutation } = useMutation({
197
+ mutationKey: ['archiveConversation'],
198
+ mutationFn: async (archived: boolean) => {
199
+ const action = archived ? 'archive' : 'unarchive'
200
+
201
+ return apiClient.chat.post({
202
+ url: `/me/conversations/${conversation_id}/${action}`,
203
+ data: { data: { type: 'Conversation', attributes: {} } },
204
+ })
205
+ },
206
+ onSuccess: (_response, archived) => {
207
+ Haptic.notificationSuccess()
208
+ if (archived) currentPersonCache.update({ canBrowseArchivedConversations: true })
209
+ queryClient.invalidateQueries({ queryKey: [url] })
210
+ return queryClient.invalidateQueries({ queryKey: conversationQueryKey })
211
+ },
212
+ onError: (_error, archived) => {
213
+ Alert.alert(
214
+ 'Oops',
215
+ `Couldn't ${archived ? 'archive' : 'unarchive'} this conversation. Please try again.`
216
+ )
217
+ },
218
+ })
219
+
220
+ return { setArchived, ...mutation }
221
+ }
222
+
182
223
  export const useConversationDisableReplies = ({ conversation_id }: { conversation_id: number }) => {
183
224
  const apiClient = useApiClient()
184
225
  const queryClient = useQueryClient()
@@ -72,6 +72,8 @@ export const useConversationMessages = (
72
72
  [data]
73
73
  )
74
74
 
75
+ useEnsureWindowOpenedAtAnchor({ conversation_id, reply_root_id, anchor })
76
+
75
77
  // Once nothing newer remains, the top of the window is the live edge. Without this,
76
78
  // a refetch would replay from the anchor and drop rows Jolt has added since.
77
79
  useEffect(() => {
@@ -82,8 +84,6 @@ export const useConversationMessages = (
82
84
  }
83
85
  }, [infiniteData, queryClient, queryKey])
84
86
 
85
- useEnsureWindowHoldsAnchor({ conversation_id, reply_root_id, anchor })
86
-
87
87
  return {
88
88
  messages,
89
89
  behind,
@@ -97,7 +97,7 @@ export const useConversationMessages = (
97
97
  }
98
98
  }
99
99
 
100
- const useEnsureWindowHoldsAnchor = ({ conversation_id, reply_root_id, anchor }: Options) => {
100
+ const useEnsureWindowOpenedAtAnchor = ({ conversation_id, reply_root_id, anchor }: Options) => {
101
101
  const queryClient = useQueryClient()
102
102
 
103
103
  useEffect(() => {
@@ -105,8 +105,10 @@ const useEnsureWindowHoldsAnchor = ({ conversation_id, reply_root_id, anchor }:
105
105
 
106
106
  const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })
107
107
  const cached = queryClient.getQueryData<MessagesWindow>(queryKey)
108
- const holdsAnchor = cached?.pages.some(page => page.data.some(m => m.id === anchor))
109
- if (cached && !holdsAnchor) {
108
+ if (!cached) return
109
+
110
+ const openedAtAnchor = cached.pageParams[0]?.where?.id_around === anchor
111
+ if (!openedAtAnchor) {
110
112
  queryClient.resetQueries({ queryKey, exact: true })
111
113
  }
112
114
  }, [anchor, conversation_id, reply_root_id, queryClient])
@@ -18,6 +18,7 @@ export const currentPersonRequestArgs = {
18
18
  'age_qualification_status',
19
19
  'direct_messages_disabled',
20
20
  'direct_messages_eligible',
21
+ 'can_browse_archived_conversations',
21
22
  'under_18',
22
23
  ],
23
24
  },
@@ -7,8 +7,9 @@ import {
7
7
  FetchSubscribeToken,
8
8
  JoltSubscription,
9
9
  } from '@planningcenter/jolt-client/dist/types/JoltSubscription'
10
- import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
10
+ import { QueryClient, useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
11
11
  import { useCallback, useEffect, useMemo } from 'react'
12
+ import { AppState, AppStateStatus } from 'react-native'
12
13
  import { useChatContext } from '../contexts/chat_context'
13
14
  import { ApiResource } from '../types'
14
15
  import type { JoltSubscriptionPattern } from '../types/jolt_events'
@@ -125,6 +126,61 @@ export const useJoltClient = (): JoltClient | undefined => {
125
126
  return joltClient
126
127
  }
127
128
 
129
+ const pingSubscribedJoltClients = (queryClient: QueryClient) => {
130
+ queryClient
131
+ .getQueryCache()
132
+ .findAll({ queryKey: ['jolt-client'] })
133
+ .forEach(query => {
134
+ const joltClient = query.state.data as JoltClient | undefined
135
+ if (!joltClient || joltClient.subscriptions.length === 0) return
136
+
137
+ try {
138
+ joltClient.ping()
139
+ } catch {}
140
+ })
141
+ }
142
+
143
+ const foregroundPingListeners = new Map<QueryClient, { mounts: number; remove: () => void }>()
144
+
145
+ const subscribeToForegroundPing = (queryClient: QueryClient) => {
146
+ const existing = foregroundPingListeners.get(queryClient)
147
+ if (existing) {
148
+ existing.mounts += 1
149
+ return
150
+ }
151
+
152
+ let previousState: AppStateStatus = AppState.currentState
153
+ const subscription = AppState.addEventListener('change', nextState => {
154
+ if (nextState === 'active' && previousState !== 'active') {
155
+ pingSubscribedJoltClients(queryClient)
156
+ }
157
+ previousState = nextState
158
+ })
159
+
160
+ foregroundPingListeners.set(queryClient, { mounts: 1, remove: () => subscription.remove() })
161
+ }
162
+
163
+ const unsubscribeFromForegroundPing = (queryClient: QueryClient) => {
164
+ const existing = foregroundPingListeners.get(queryClient)
165
+ if (!existing) return
166
+
167
+ existing.mounts -= 1
168
+ if (existing.mounts > 0) return
169
+
170
+ existing.remove()
171
+ foregroundPingListeners.delete(queryClient)
172
+ }
173
+
174
+ export const useJoltForegroundPing = () => {
175
+ const queryClient = useQueryClient()
176
+
177
+ useEffect(() => {
178
+ subscribeToForegroundPing(queryClient)
179
+
180
+ return () => unsubscribeFromForegroundPing(queryClient)
181
+ }, [queryClient])
182
+ }
183
+
128
184
  export function useJoltChannel(
129
185
  channelName: string,
130
186
  enabled: boolean = true
@@ -0,0 +1,10 @@
1
+ import { availableFeatures, useFeatures } from './use_features'
2
+
3
+ export function useManualArchivingEnabled() {
4
+ const { featureEnabled } = useFeatures()
5
+
6
+ return (
7
+ featureEnabled(availableFeatures.manual_archiving) ||
8
+ featureEnabled(availableFeatures.manual_archiving_rollout)
9
+ )
10
+ }
@@ -20,15 +20,16 @@ export function useMarkLatestMessageRead({ conversation, enabled = true }: Props
20
20
  const unreadCount = conversation.unreadCount
21
21
  const unreadReaction = conversation.unreadReaction
22
22
 
23
- const shouldMarkRead = Boolean(unreadCount >= 1 || unreadReaction || !firedOnce.current)
23
+ const shouldMarkRead =
24
+ !firedOnce.current || (enabled && Boolean(unreadCount >= 1 || unreadReaction))
24
25
  const appState = useAppState()
25
26
  const isActive = appState === 'active'
26
27
 
27
28
  useEffect(() => {
28
- if (!enabled || !isActive || !shouldMarkRead) return
29
+ if (!isActive || !shouldMarkRead) return
29
30
 
30
31
  firedOnce.current = true
31
32
 
32
33
  debouncedMarkRead(true)
33
- }, [debouncedMarkRead, enabled, isActive, shouldMarkRead, unreadReaction])
34
+ }, [debouncedMarkRead, isActive, shouldMarkRead, unreadReaction])
34
35
  }
@@ -0,0 +1,19 @@
1
+ import { useEffect, useState } from 'react'
2
+ import { AccessibilityInfo } from 'react-native'
3
+ import { useReducedMotion } from 'react-native-reanimated'
4
+
5
+ export const useReduceMotion = () => {
6
+ const [reduceMotion, setReduceMotion] = useState(useReducedMotion())
7
+
8
+ useEffect(() => {
9
+ AccessibilityInfo.isReduceMotionEnabled().then(setReduceMotion)
10
+
11
+ const subscription = AccessibilityInfo.addEventListener('reduceMotionChanged', setReduceMotion)
12
+
13
+ return () => {
14
+ subscription.remove()
15
+ }
16
+ }, [])
17
+
18
+ return reduceMotion
19
+ }
@@ -0,0 +1,24 @@
1
+ import { ConversationResource } from '../types'
2
+ import { isArchivedConversation } from '../utils/archived_conversation'
3
+ import { useConversationArchive } from './use_conversation'
4
+ import { availableFeatures, useFeatures } from './use_features'
5
+
6
+ export function useUnarchiveConversationAction(conversation: ConversationResource) {
7
+ const { featureEnabled } = useFeatures()
8
+ const { setArchived, isPending } = useConversationArchive({ conversation_id: conversation.id })
9
+ const manualArchivingEnabled =
10
+ featureEnabled(availableFeatures.manual_archiving) ||
11
+ featureEnabled(availableFeatures.manual_archiving_rollout)
12
+ const canUnarchive =
13
+ manualArchivingEnabled &&
14
+ isArchivedConversation(conversation) &&
15
+ !!conversation.memberAbility?.canUnarchive
16
+
17
+ if (!canUnarchive) return undefined
18
+
19
+ return {
20
+ label: 'Unarchive',
21
+ onPress: () => setArchived(false),
22
+ loading: isPending,
23
+ }
24
+ }