@planningcenter/chat-react-native 4.4.0-rc.6 → 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.
- package/build/components/conversation/jump_to_bottom_button.d.ts.map +1 -1
- package/build/components/conversation/jump_to_bottom_button.js +42 -40
- package/build/components/conversation/jump_to_bottom_button.js.map +1 -1
- package/build/components/conversation/message.d.ts +2 -1
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +3 -1
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +3 -1
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversation/message_list.d.ts.map +1 -1
- package/build/components/conversation/message_list.js +35 -31
- package/build/components/conversation/message_list.js.map +1 -1
- package/build/components/conversation/message_reaction.d.ts +2 -1
- package/build/components/conversation/message_reaction.d.ts.map +1 -1
- package/build/components/conversation/message_reaction.js +67 -60
- package/build/components/conversation/message_reaction.js.map +1 -1
- package/build/components/conversation/messages_disabled_banners.d.ts +7 -5
- package/build/components/conversation/messages_disabled_banners.d.ts.map +1 -1
- package/build/components/conversation/messages_disabled_banners.js +15 -14
- package/build/components/conversation/messages_disabled_banners.js.map +1 -1
- package/build/components/conversation/system_message.d.ts +2 -1
- package/build/components/conversation/system_message.d.ts.map +1 -1
- package/build/components/conversation/system_message.js +133 -100
- package/build/components/conversation/system_message.js.map +1 -1
- package/build/components/conversations/archived_results_footer.d.ts +6 -0
- package/build/components/conversations/archived_results_footer.d.ts.map +1 -0
- package/build/components/conversations/archived_results_footer.js +51 -0
- package/build/components/conversations/archived_results_footer.js.map +1 -0
- package/build/components/conversations/conversation_actions.d.ts.map +1 -1
- package/build/components/conversations/conversation_actions.js +241 -206
- package/build/components/conversations/conversation_actions.js.map +1 -1
- package/build/components/conversations/conversation_preview.d.ts.map +1 -1
- package/build/components/conversations/conversation_preview.js +102 -93
- package/build/components/conversations/conversation_preview.js.map +1 -1
- package/build/components/conversations/conversations.d.ts.map +1 -1
- package/build/components/conversations/conversations.js +66 -41
- package/build/components/conversations/conversations.js.map +1 -1
- package/build/components/conversations/conversations_blank_state.d.ts.map +1 -1
- package/build/components/conversations/conversations_blank_state.js +55 -12
- package/build/components/conversations/conversations_blank_state.js.map +1 -1
- package/build/components/conversations/filtered_results_footer.d.ts +2 -0
- package/build/components/conversations/filtered_results_footer.d.ts.map +1 -0
- package/build/components/conversations/filtered_results_footer.js +77 -0
- package/build/components/conversations/filtered_results_footer.js.map +1 -0
- package/build/components/display/action_button.d.ts.map +1 -1
- package/build/components/display/action_button.js +18 -16
- package/build/components/display/action_button.js.map +1 -1
- package/build/components/display/filter_dropdown.d.ts +14 -0
- package/build/components/display/filter_dropdown.d.ts.map +1 -0
- package/build/components/display/filter_dropdown.js +193 -0
- package/build/components/display/filter_dropdown.js.map +1 -0
- package/build/components/display/icon_tile.d.ts +13 -0
- package/build/components/display/icon_tile.d.ts.map +1 -0
- package/build/components/display/icon_tile.js +149 -0
- package/build/components/display/icon_tile.js.map +1 -0
- package/build/components/display/index.d.ts +2 -0
- package/build/components/display/index.d.ts.map +1 -1
- package/build/components/display/index.js +2 -0
- package/build/components/display/index.js.map +1 -1
- package/build/contexts/api_provider.d.ts.map +1 -1
- package/build/contexts/api_provider.js +21 -9
- package/build/contexts/api_provider.js.map +1 -1
- package/build/contexts/conversations_context.d.ts.map +1 -1
- package/build/contexts/conversations_context.js +21 -18
- package/build/contexts/conversations_context.js.map +1 -1
- package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +196 -16
- package/build/hooks/groups/use_group_members_for_new_conversation.d.ts.map +1 -1
- package/build/hooks/groups/use_group_members_for_new_conversation.js +72 -58
- package/build/hooks/groups/use_group_members_for_new_conversation.js.map +1 -1
- package/build/hooks/index.d.ts +3 -0
- package/build/hooks/index.d.ts.map +1 -1
- package/build/hooks/index.js +3 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/use_animated_message_background_color.d.ts.map +1 -1
- package/build/hooks/use_animated_message_background_color.js +5 -3
- package/build/hooks/use_animated_message_background_color.js.map +1 -1
- package/build/hooks/use_api.d.ts +3 -2
- package/build/hooks/use_api.d.ts.map +1 -1
- package/build/hooks/use_api.js.map +1 -1
- package/build/hooks/use_can_browse_archived_conversations.d.ts +2 -0
- package/build/hooks/use_can_browse_archived_conversations.d.ts.map +1 -0
- package/build/hooks/use_can_browse_archived_conversations.js +29 -0
- package/build/hooks/use_can_browse_archived_conversations.js.map +1 -0
- package/build/hooks/use_clear_conversation_filters.d.ts +2 -0
- package/build/hooks/use_clear_conversation_filters.d.ts.map +1 -0
- package/build/hooks/use_clear_conversation_filters.js +25 -0
- package/build/hooks/use_clear_conversation_filters.js.map +1 -0
- package/build/hooks/use_conversation.d.ts +73 -1
- package/build/hooks/use_conversation.d.ts.map +1 -1
- package/build/hooks/use_conversation.js +130 -3
- package/build/hooks/use_conversation.js.map +1 -1
- package/build/hooks/use_conversation_messages.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages.js +29 -26
- package/build/hooks/use_conversation_messages.js.map +1 -1
- package/build/hooks/use_current_person.d.ts.map +1 -1
- package/build/hooks/use_current_person.js +1 -1
- package/build/hooks/use_current_person.js.map +1 -1
- package/build/hooks/use_features.d.ts +2 -0
- package/build/hooks/use_features.d.ts.map +1 -1
- package/build/hooks/use_features.js +2 -0
- package/build/hooks/use_features.js.map +1 -1
- package/build/hooks/use_filter_dropdown_enabled.d.ts +2 -0
- package/build/hooks/use_filter_dropdown_enabled.d.ts.map +1 -0
- package/build/hooks/use_filter_dropdown_enabled.js +18 -0
- package/build/hooks/use_filter_dropdown_enabled.js.map +1 -0
- package/build/hooks/use_jolt.d.ts +1 -0
- package/build/hooks/use_jolt.d.ts.map +1 -1
- package/build/hooks/use_jolt.js +59 -0
- package/build/hooks/use_jolt.js.map +1 -1
- package/build/hooks/use_manual_archiving_enabled.d.ts +2 -0
- package/build/hooks/use_manual_archiving_enabled.d.ts.map +1 -0
- package/build/hooks/use_manual_archiving_enabled.js +18 -0
- package/build/hooks/use_manual_archiving_enabled.js.map +1 -0
- package/build/hooks/use_mark_latest_message_read.d.ts.map +1 -1
- package/build/hooks/use_mark_latest_message_read.js +3 -3
- package/build/hooks/use_mark_latest_message_read.js.map +1 -1
- package/build/hooks/use_reduce_motion.d.ts +2 -0
- package/build/hooks/use_reduce_motion.d.ts.map +1 -0
- package/build/hooks/use_reduce_motion.js +28 -0
- package/build/hooks/use_reduce_motion.js.map +1 -0
- package/build/hooks/use_unarchive_conversation_action.d.ts +7 -0
- package/build/hooks/use_unarchive_conversation_action.d.ts.map +1 -0
- package/build/hooks/use_unarchive_conversation_action.js +52 -0
- package/build/hooks/use_unarchive_conversation_action.js.map +1 -0
- package/build/screens/attachment_actions/attachment_actions_screen.d.ts.map +1 -1
- package/build/screens/attachment_actions/attachment_actions_screen.js +84 -61
- package/build/screens/attachment_actions/attachment_actions_screen.js.map +1 -1
- package/build/screens/conversation_details_screen.d.ts.map +1 -1
- package/build/screens/conversation_details_screen.js +490 -395
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_filters/components/conversation_filters.d.ts.map +1 -1
- package/build/screens/conversation_filters/components/conversation_filters.js +88 -18
- package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -1
- package/build/screens/conversation_filters/components/rows.d.ts +9 -0
- package/build/screens/conversation_filters/components/rows.d.ts.map +1 -1
- package/build/screens/conversation_filters/components/rows.js +93 -1
- package/build/screens/conversation_filters/components/rows.js.map +1 -1
- package/build/screens/conversation_filters/context/conversation_filter_context.d.ts.map +1 -1
- package/build/screens/conversation_filters/context/conversation_filter_context.js +8 -4
- package/build/screens/conversation_filters/context/conversation_filter_context.js.map +1 -1
- package/build/screens/conversation_filters/filter_types.d.ts +1 -0
- package/build/screens/conversation_filters/filter_types.d.ts.map +1 -1
- package/build/screens/conversation_filters/filter_types.js +1 -0
- package/build/screens/conversation_filters/filter_types.js.map +1 -1
- package/build/screens/conversation_filters/screen_props.d.ts +1 -0
- package/build/screens/conversation_filters/screen_props.d.ts.map +1 -1
- package/build/screens/conversation_filters/screen_props.js.map +1 -1
- package/build/screens/conversation_filters_screen.d.ts +1 -0
- package/build/screens/conversation_filters_screen.d.ts.map +1 -1
- package/build/screens/conversation_filters_screen.js +79 -48
- package/build/screens/conversation_filters_screen.js.map +1 -1
- package/build/screens/conversation_new/components/groups_form.d.ts.map +1 -1
- package/build/screens/conversation_new/components/groups_form.js +37 -34
- package/build/screens/conversation_new/components/groups_form.js.map +1 -1
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +13 -10
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts +2 -0
- package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts.map +1 -0
- package/build/screens/conversations/components/filter_dropdown_list_header_component.js +580 -0
- package/build/screens/conversations/components/filter_dropdown_list_header_component.js.map +1 -0
- package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
- package/build/screens/conversations/components/list_header_component.js +95 -90
- package/build/screens/conversations/components/list_header_component.js.map +1 -1
- package/build/screens/conversations/components/search_list_header_component.d.ts.map +1 -1
- package/build/screens/conversations/components/search_list_header_component.js +100 -95
- package/build/screens/conversations/components/search_list_header_component.js.map +1 -1
- package/build/screens/conversations/conversations_screen.d.ts +1 -0
- package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
- package/build/screens/conversations/conversations_screen.js +15 -2
- package/build/screens/conversations/conversations_screen.js.map +1 -1
- package/build/screens/design_system_screen.d.ts.map +1 -1
- package/build/screens/design_system_screen.js +275 -215
- package/build/screens/design_system_screen.js.map +1 -1
- package/build/screens/message_actions_screen.d.ts.map +1 -1
- package/build/screens/message_actions_screen.js +112 -92
- package/build/screens/message_actions_screen.js.map +1 -1
- package/build/screens/search/search_screen.d.ts.map +1 -1
- package/build/screens/search/search_screen.js +10 -2
- package/build/screens/search/search_screen.js.map +1 -1
- package/build/screens/send_giphy_screen.d.ts +1 -0
- package/build/screens/send_giphy_screen.d.ts.map +1 -1
- package/build/screens/send_giphy_screen.js +108 -106
- package/build/screens/send_giphy_screen.js.map +1 -1
- package/build/screens/team_conversation_screen.js +1 -1
- package/build/screens/team_conversation_screen.js.map +1 -1
- package/build/types/jolt_events/message_events.d.ts +2 -0
- package/build/types/jolt_events/message_events.d.ts.map +1 -1
- package/build/types/jolt_events/message_events.js.map +1 -1
- package/build/types/resources/conversation.d.ts +2 -2
- package/build/types/resources/conversation.d.ts.map +1 -1
- package/build/types/resources/conversation.js.map +1 -1
- package/build/types/resources/member_ability.d.ts +2 -0
- package/build/types/resources/member_ability.d.ts.map +1 -1
- package/build/types/resources/member_ability.js.map +1 -1
- package/build/types/resources/message.d.ts +2 -0
- package/build/types/resources/message.d.ts.map +1 -1
- package/build/types/resources/message.js.map +1 -1
- package/build/types/resources/person.d.ts +1 -0
- package/build/types/resources/person.d.ts.map +1 -1
- package/build/types/resources/person.js.map +1 -1
- package/build/utils/archived_conversation.d.ts +5 -0
- package/build/utils/archived_conversation.d.ts.map +1 -0
- package/build/utils/archived_conversation.js +5 -0
- package/build/utils/archived_conversation.js.map +1 -0
- package/build/utils/date.d.ts +1 -0
- package/build/utils/date.d.ts.map +1 -1
- package/build/utils/date.js +9 -0
- package/build/utils/date.js.map +1 -1
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js +1 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.d.ts.map +1 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.js +2 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.js.map +1 -1
- package/build/utils/native_adapters/configuration.d.ts +3 -0
- package/build/utils/native_adapters/configuration.d.ts.map +1 -1
- package/build/utils/native_adapters/configuration.js +3 -0
- package/build/utils/native_adapters/configuration.js.map +1 -1
- package/build/utils/native_adapters/index.d.ts +1 -0
- package/build/utils/native_adapters/index.d.ts.map +1 -1
- package/build/utils/native_adapters/index.js +1 -0
- package/build/utils/native_adapters/index.js.map +1 -1
- package/build/utils/native_adapters/menu.d.ts +41 -0
- package/build/utils/native_adapters/menu.d.ts.map +1 -0
- package/build/utils/native_adapters/menu.js +56 -0
- package/build/utils/native_adapters/menu.js.map +1 -0
- package/build/utils/request/conversation.d.ts +2 -1
- package/build/utils/request/conversation.d.ts.map +1 -1
- package/build/utils/request/conversation.js +4 -1
- package/build/utils/request/conversation.js.map +1 -1
- package/build/utils/request/messages_data_options.d.ts.map +1 -1
- package/build/utils/request/messages_data_options.js +1 -1
- package/build/utils/request/messages_data_options.js.map +1 -1
- package/build/utils/system_messages.d.ts +7 -5
- package/build/utils/system_messages.d.ts.map +1 -1
- package/build/utils/system_messages.js +10 -2
- package/build/utils/system_messages.js.map +1 -1
- package/build/vendor/font_awesome_pro_solid_icons.d.ts +1 -0
- package/build/vendor/font_awesome_pro_solid_icons.d.ts.map +1 -1
- package/build/vendor/font_awesome_pro_solid_icons.js +5 -0
- package/build/vendor/font_awesome_pro_solid_icons.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/hooks/use_can_browse_archived_conversations.test.tsx +98 -0
- package/src/__tests__/hooks/use_filter_dropdown_enabled.test.tsx +42 -0
- package/src/__tests__/screens/conversation_filters/components/conversation_filters.test.tsx +132 -0
- package/src/__tests__/screens/conversation_filters_screen.test.tsx +76 -0
- package/src/__tests__/screens/conversation_new/components/services_form.test.tsx +1 -0
- package/src/__tests__/screens/message_actions_screen.test.tsx +65 -2
- package/src/__tests__/screens/send_giphy_screen.test.tsx +102 -0
- package/src/__tests__/utils/system_messages.ts +19 -32
- package/src/components/conversation/__tests__/message_list.test.tsx +68 -2
- package/src/components/conversation/__tests__/system_message.test.tsx +106 -0
- package/src/components/conversation/jump_to_bottom_button.tsx +4 -3
- package/src/components/conversation/message.tsx +3 -0
- package/src/components/conversation/message_form.tsx +3 -1
- package/src/components/conversation/message_list.tsx +9 -1
- package/src/components/conversation/message_reaction.tsx +7 -2
- package/src/components/conversation/messages_disabled_banners.tsx +17 -18
- package/src/components/conversation/system_message.tsx +44 -16
- package/src/components/conversations/__tests__/conversation_actions.test.tsx +67 -0
- package/src/components/conversations/__tests__/conversation_preview.test.tsx +105 -0
- package/src/components/conversations/__tests__/conversations.test.tsx +93 -0
- package/src/components/conversations/__tests__/conversations_blank_state.test.tsx +73 -0
- package/src/components/conversations/archived_results_footer.tsx +36 -0
- package/src/components/conversations/conversation_actions.tsx +27 -19
- package/src/components/conversations/conversation_preview.tsx +39 -10
- package/src/components/conversations/conversations.tsx +26 -3
- package/src/components/conversations/conversations_blank_state.tsx +21 -0
- package/src/components/conversations/filtered_results_footer.tsx +38 -0
- package/src/components/display/__tests__/filter_dropdown.test.tsx +114 -0
- package/src/components/display/__tests__/icon_tile.test.tsx +16 -0
- package/src/components/display/action_button.tsx +4 -3
- package/src/components/display/filter_dropdown.tsx +124 -0
- package/src/components/display/icon_tile.tsx +67 -0
- package/src/components/display/index.ts +2 -0
- package/src/contexts/api_provider.tsx +8 -0
- package/src/contexts/conversations_context.tsx +2 -1
- package/src/hooks/__tests__/use_conversation_archive.test.tsx +152 -0
- package/src/hooks/__tests__/use_conversation_jolt_events.test.tsx +74 -0
- package/src/hooks/__tests__/use_conversation_messages.test.tsx +10 -2
- package/src/hooks/__tests__/use_jolt.test.tsx +100 -1
- package/src/hooks/__tests__/use_mark_latest_message_read.test.tsx +21 -7
- package/src/hooks/__tests__/use_reduce_motion.test.tsx +61 -0
- package/src/hooks/__tests__/use_unarchive_conversation_action.test.tsx +67 -0
- package/src/hooks/groups/use_group_members_for_new_conversation.ts +21 -16
- package/src/hooks/index.ts +3 -0
- package/src/hooks/use_animated_message_background_color.ts +6 -3
- package/src/hooks/use_api.ts +9 -2
- package/src/hooks/use_can_browse_archived_conversations.ts +17 -0
- package/src/hooks/use_clear_conversation_filters.ts +16 -0
- package/src/hooks/use_conversation.ts +44 -3
- package/src/hooks/use_conversation_messages.ts +7 -5
- package/src/hooks/use_current_person.ts +1 -0
- package/src/hooks/use_features.ts +2 -0
- package/src/hooks/use_filter_dropdown_enabled.ts +10 -0
- package/src/hooks/use_jolt.ts +57 -1
- package/src/hooks/use_manual_archiving_enabled.ts +10 -0
- package/src/hooks/use_mark_latest_message_read.ts +4 -3
- package/src/hooks/use_reduce_motion.ts +19 -0
- package/src/hooks/use_unarchive_conversation_action.ts +24 -0
- package/src/screens/__tests__/conversation_details_screen.test.tsx +305 -0
- package/src/screens/attachment_actions/__tests__/attachment_actions_screen.test.tsx +72 -0
- package/src/screens/attachment_actions/attachment_actions_screen.tsx +3 -1
- package/src/screens/conversation_details_screen.tsx +80 -16
- package/src/screens/conversation_filters/__tests__/conversation_filters.test.tsx +101 -0
- package/src/screens/conversation_filters/components/conversation_filters.tsx +40 -7
- package/src/screens/conversation_filters/components/rows.tsx +29 -1
- package/src/screens/conversation_filters/context/conversation_filter_context.tsx +4 -0
- package/src/screens/conversation_filters/filter_types.ts +1 -0
- package/src/screens/conversation_filters/screen_props.ts +1 -0
- package/src/screens/conversation_filters_screen.tsx +25 -5
- package/src/screens/conversation_new/components/groups_form.tsx +1 -0
- package/src/screens/conversation_screen.tsx +4 -2
- package/src/screens/conversations/__tests__/conversations_screen.test.tsx +52 -0
- package/src/screens/conversations/components/__tests__/filter_dropdown_list_header_component.test.tsx +259 -0
- package/src/screens/conversations/components/__tests__/list_header_component.test.tsx +21 -4
- package/src/screens/conversations/components/filter_dropdown_list_header_component.tsx +286 -0
- package/src/screens/conversations/components/list_header_component.tsx +17 -12
- package/src/screens/conversations/components/search_list_header_component.tsx +17 -12
- package/src/screens/conversations/conversations_screen.tsx +15 -2
- package/src/screens/design_system_screen.tsx +26 -0
- package/src/screens/message_actions_screen.tsx +29 -20
- package/src/screens/search/__tests__/search_screen.test.tsx +13 -1
- package/src/screens/search/search_screen.tsx +8 -2
- package/src/screens/send_giphy_screen.tsx +6 -3
- package/src/screens/team_conversation_screen.tsx +1 -1
- package/src/types/jolt_events/message_events.ts +2 -0
- package/src/types/resources/conversation.ts +2 -2
- package/src/types/resources/member_ability.ts +2 -0
- package/src/types/resources/message.ts +3 -0
- package/src/types/resources/person.ts +1 -0
- package/src/utils/__tests__/conversation.test.ts +1 -0
- package/src/utils/__tests__/date.test.ts +23 -0
- package/src/utils/__tests__/group_messages.test.ts +1 -0
- package/src/utils/archived_conversation.ts +13 -0
- package/src/utils/date.ts +8 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/jolt/__tests__/transform_message_event_data_to_message_resource.test.ts +35 -0
- package/src/utils/jolt/transform_message_event_data_to_message_resource.ts +1 -0
- package/src/utils/native_adapters/__tests__/menu.test.tsx +46 -0
- package/src/utils/native_adapters/configuration.ts +5 -0
- package/src/utils/native_adapters/index.ts +1 -0
- package/src/utils/native_adapters/menu.tsx +70 -0
- package/src/utils/request/conversation.ts +4 -0
- package/src/utils/request/messages_data_options.ts +1 -0
- package/src/utils/system_messages.ts +19 -10
- package/src/vendor/font_awesome_pro_solid_icons.ts +12 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { DefaultTheme, ThemeProvider } from '@react-navigation/native'
|
|
2
|
+
import { fireEvent, render, screen, waitFor } from '@testing-library/react-native'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Platform } from 'react-native'
|
|
5
|
+
import { SafeAreaProvider } from 'react-native-safe-area-context'
|
|
6
|
+
import { FilterContext } from '../../screens/conversation_filters/context/conversation_filter_context'
|
|
7
|
+
import { ConversationFiltersHeader } from '../../screens/conversation_filters_screen'
|
|
8
|
+
|
|
9
|
+
const mockGoBack = jest.fn()
|
|
10
|
+
|
|
11
|
+
jest.mock('@react-navigation/elements', () => ({
|
|
12
|
+
...jest.requireActual('@react-navigation/elements'),
|
|
13
|
+
useHeaderHeight: () => 0,
|
|
14
|
+
}))
|
|
15
|
+
jest.mock('@react-navigation/native', () => ({
|
|
16
|
+
...jest.requireActual('@react-navigation/native'),
|
|
17
|
+
useNavigation: () => ({ goBack: mockGoBack }),
|
|
18
|
+
useRoute: () => ({ params: {} }),
|
|
19
|
+
}))
|
|
20
|
+
jest.mock('../../hooks/use_filter_dropdown_enabled', () => ({
|
|
21
|
+
useFilterDropdownEnabled: () => true,
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
const safeAreaMetrics = {
|
|
25
|
+
frame: { x: 0, y: 0, width: 390, height: 844 },
|
|
26
|
+
insets: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const renderHeader = () =>
|
|
30
|
+
render(
|
|
31
|
+
<SafeAreaProvider initialMetrics={safeAreaMetrics}>
|
|
32
|
+
<ThemeProvider value={DefaultTheme}>
|
|
33
|
+
<FilterContext.Provider
|
|
34
|
+
value={{
|
|
35
|
+
params: {},
|
|
36
|
+
scrollOffset: 0,
|
|
37
|
+
setScrollOffset: jest.fn(),
|
|
38
|
+
setFormSheetHeaderHeight: jest.fn(),
|
|
39
|
+
resetFilter: jest.fn(),
|
|
40
|
+
setGroupFilter: jest.fn(),
|
|
41
|
+
setAppFilter: jest.fn(),
|
|
42
|
+
applyFilters: jest.fn(),
|
|
43
|
+
platformListPaddingBottom: 0,
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<ConversationFiltersHeader />
|
|
47
|
+
</FilterContext.Provider>
|
|
48
|
+
</ThemeProvider>
|
|
49
|
+
</SafeAreaProvider>
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
describe('ConversationFiltersHeader', () => {
|
|
53
|
+
afterEach(() => {
|
|
54
|
+
jest.restoreAllMocks()
|
|
55
|
+
mockGoBack.mockClear()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('shows a back button that dismisses the sheet on Android', async () => {
|
|
59
|
+
jest.replaceProperty(Platform, 'OS', 'android')
|
|
60
|
+
|
|
61
|
+
renderHeader()
|
|
62
|
+
|
|
63
|
+
fireEvent.press(screen.getByLabelText('Back'))
|
|
64
|
+
|
|
65
|
+
await waitFor(() => expect(mockGoBack).toHaveBeenCalledTimes(1))
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('does not show a back button on iOS', () => {
|
|
69
|
+
jest.replaceProperty(Platform, 'OS', 'ios')
|
|
70
|
+
|
|
71
|
+
renderHeader()
|
|
72
|
+
|
|
73
|
+
expect(screen.getByText('More filters')).toBeTruthy()
|
|
74
|
+
expect(screen.queryByLabelText('Back')).toBeNull()
|
|
75
|
+
})
|
|
76
|
+
})
|
|
@@ -9,6 +9,7 @@ import { ServicesForm } from '../../../../screens/conversation_new/components/se
|
|
|
9
9
|
jest.mock('react-native-reanimated', () => ({
|
|
10
10
|
...jest.requireActual('react-native-reanimated/mock'),
|
|
11
11
|
LayoutAnimationConfig: ({ children }: { children: React.ReactNode }) => children,
|
|
12
|
+
useReducedMotion: () => false,
|
|
12
13
|
}))
|
|
13
14
|
jest.mock('@react-navigation/native', () => ({
|
|
14
15
|
...jest.requireActual('@react-navigation/native'),
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
MessageActionsScreen,
|
|
10
10
|
MessageActionsScreenProps,
|
|
11
11
|
} from '../../screens/message_actions_screen'
|
|
12
|
-
import { MessageResource } from '../../types'
|
|
12
|
+
import { ConversationResource, MessageResource } from '../../types'
|
|
13
13
|
import {
|
|
14
14
|
AudioAdapter,
|
|
15
15
|
ChatAdapters,
|
|
@@ -36,7 +36,15 @@ const mockMessage: MessageResource = {
|
|
|
36
36
|
messageType: 'user',
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const myMessageWithLinkPreview = {
|
|
40
|
+
...mockMessage,
|
|
41
|
+
mine: true,
|
|
42
|
+
attachments: [{ type: 'ExpandedLink', id: '9' }],
|
|
43
|
+
} as MessageResource
|
|
44
|
+
|
|
39
45
|
let mockCurrentMessage = mockMessage
|
|
46
|
+
let mockConversation = { id: 1, disabled: false } as ConversationResource
|
|
47
|
+
let mockEnabledFeatures: string[] = []
|
|
40
48
|
|
|
41
49
|
const mockGoBack = jest.fn()
|
|
42
50
|
jest.mock('@react-navigation/native', () => ({
|
|
@@ -44,9 +52,15 @@ jest.mock('@react-navigation/native', () => ({
|
|
|
44
52
|
useNavigation: () => ({ navigate: jest.fn(), dispatch: jest.fn(), goBack: mockGoBack }),
|
|
45
53
|
}))
|
|
46
54
|
jest.mock('../../hooks/use_api_client', () => ({ useApiClient: () => ({}) }))
|
|
55
|
+
jest.mock('../../hooks/use_conversation', () => ({
|
|
56
|
+
useConversation: () => ({ data: mockConversation }),
|
|
57
|
+
}))
|
|
47
58
|
jest.mock('../../hooks/use_features', () => ({
|
|
48
59
|
...jest.requireActual('../../hooks/use_features'),
|
|
49
|
-
useFeatures: () => ({
|
|
60
|
+
useFeatures: () => ({
|
|
61
|
+
features: [],
|
|
62
|
+
featureEnabled: (name: string) => mockEnabledFeatures.includes(name),
|
|
63
|
+
}),
|
|
50
64
|
}))
|
|
51
65
|
jest.mock('../../hooks/use_message_reaction_toggle', () => ({
|
|
52
66
|
useMessageReactionToggle: () => ({ handleReactionToggle: jest.fn(), isPending: false }),
|
|
@@ -108,6 +122,55 @@ describe('MessageActionsScreen', () => {
|
|
|
108
122
|
beforeEach(() => {
|
|
109
123
|
jest.clearAllMocks()
|
|
110
124
|
mockCurrentMessage = mockMessage
|
|
125
|
+
mockConversation = { id: 1, disabled: false } as ConversationResource
|
|
126
|
+
mockEnabledFeatures = []
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('offers Delete on my own message', () => {
|
|
130
|
+
mockCurrentMessage = { ...mockMessage, mine: true }
|
|
131
|
+
const { getByText } = renderScreen()
|
|
132
|
+
|
|
133
|
+
expect(getByText('Delete message')).toBeTruthy()
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('hides Delete when the conversation is disabled', () => {
|
|
137
|
+
mockCurrentMessage = { ...mockMessage, mine: true }
|
|
138
|
+
mockConversation = { id: 1, disabled: true, disabledReason: 'locked' } as ConversationResource
|
|
139
|
+
const { queryByText, getByText } = renderScreen()
|
|
140
|
+
|
|
141
|
+
expect(queryByText('Delete message')).toBeNull()
|
|
142
|
+
expect(getByText('Copy text')).toBeTruthy()
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('offers reactions, reply, edit, and link preview removal on my message', () => {
|
|
146
|
+
mockCurrentMessage = myMessageWithLinkPreview
|
|
147
|
+
const { getByText } = renderScreen()
|
|
148
|
+
|
|
149
|
+
expect(getByText('👍')).toBeTruthy()
|
|
150
|
+
expect(getByText('Reply to message')).toBeTruthy()
|
|
151
|
+
expect(getByText('Edit message')).toBeTruthy()
|
|
152
|
+
expect(getByText('Remove link preview')).toBeTruthy()
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('hides reactions, reply, edit, and link preview removal when the conversation is disabled', () => {
|
|
156
|
+
mockCurrentMessage = myMessageWithLinkPreview
|
|
157
|
+
mockConversation = { id: 1, disabled: true, disabledReason: 'archived' } as ConversationResource
|
|
158
|
+
const { getByText, queryByText } = renderScreen()
|
|
159
|
+
|
|
160
|
+
expect(queryByText('👍')).toBeNull()
|
|
161
|
+
expect(queryByText('Reply to message')).toBeNull()
|
|
162
|
+
expect(queryByText('Edit message')).toBeNull()
|
|
163
|
+
expect(queryByText('Remove link preview')).toBeNull()
|
|
164
|
+
expect(getByText('Copy text')).toBeTruthy()
|
|
165
|
+
expect(getByText('View read receipts')).toBeTruthy()
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('keeps Report when the conversation is disabled', () => {
|
|
169
|
+
mockEnabledFeatures = ['ROLLOUT_MOBILE_message_reporting']
|
|
170
|
+
mockConversation = { id: 1, disabled: true, disabledReason: 'archived' } as ConversationResource
|
|
171
|
+
const { getByText } = renderScreen()
|
|
172
|
+
|
|
173
|
+
expect(getByText('Report message')).toBeTruthy()
|
|
111
174
|
})
|
|
112
175
|
|
|
113
176
|
it('copies the message text and gives success haptic feedback before closing', async () => {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { HeaderHeightContext } from '@react-navigation/elements'
|
|
2
|
+
import { DefaultTheme, ThemeProvider } from '@react-navigation/native'
|
|
3
|
+
import { QueryClientProvider, notifyManager } from '@tanstack/react-query'
|
|
4
|
+
import { act, fireEvent, render, screen } from '@testing-library/react-native'
|
|
5
|
+
import React from 'react'
|
|
6
|
+
import { SafeAreaProvider } from 'react-native-safe-area-context'
|
|
7
|
+
import { chatQueryClient } from '../../contexts/api_provider'
|
|
8
|
+
import { SendGiphyScreen, SendGiphyScreenProps } from '../../screens/send_giphy_screen'
|
|
9
|
+
|
|
10
|
+
jest.mock('../../contexts/api_provider', () => {
|
|
11
|
+
const { buildTestQueryClient } = require('../../__utils__/query_client')
|
|
12
|
+
return { chatQueryClient: buildTestQueryClient() }
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const mockPost = jest.fn()
|
|
16
|
+
jest.mock('../../hooks/use_api_client', () => ({
|
|
17
|
+
useApiClient: () => ({ chat: { post: mockPost, patch: jest.fn() } }),
|
|
18
|
+
}))
|
|
19
|
+
|
|
20
|
+
jest.mock('../../hooks/use_current_person', () => ({
|
|
21
|
+
useCurrentPerson: () => ({ type: 'Person', id: 1, name: 'Me', avatar: null }),
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
jest.mock('../../hooks/use_giphy', () => ({
|
|
25
|
+
useGiphy: () => ({
|
|
26
|
+
isSearching: false,
|
|
27
|
+
result: { type: 'giphy', title: 'cat', giphy: { fixed_width: { url: 'https://gif' } } },
|
|
28
|
+
nextResult: jest.fn(),
|
|
29
|
+
prevResult: jest.fn(),
|
|
30
|
+
}),
|
|
31
|
+
}))
|
|
32
|
+
|
|
33
|
+
const mockDispatch = jest.fn()
|
|
34
|
+
jest.mock('@react-navigation/native', () => ({
|
|
35
|
+
...jest.requireActual('@react-navigation/native'),
|
|
36
|
+
useNavigation: () => ({
|
|
37
|
+
dispatch: mockDispatch,
|
|
38
|
+
goBack: jest.fn(),
|
|
39
|
+
getState: () => ({
|
|
40
|
+
routes: [
|
|
41
|
+
{ name: 'Conversation', params: { conversation_id: 7 } },
|
|
42
|
+
{ name: 'ConversationReply', params: { conversation_id: 7, reply_root_id: '42' } },
|
|
43
|
+
{ name: 'SendGiphy' },
|
|
44
|
+
],
|
|
45
|
+
}),
|
|
46
|
+
}),
|
|
47
|
+
}))
|
|
48
|
+
|
|
49
|
+
notifyManager.setNotifyFunction(fn => act(fn))
|
|
50
|
+
|
|
51
|
+
const safeAreaMetrics = {
|
|
52
|
+
frame: { x: 0, y: 0, width: 390, height: 844 },
|
|
53
|
+
insets: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
describe('SendGiphyScreen', () => {
|
|
57
|
+
let finishSend: (value: unknown) => void
|
|
58
|
+
|
|
59
|
+
beforeEach(() => {
|
|
60
|
+
chatQueryClient.clear()
|
|
61
|
+
mockDispatch.mockReset()
|
|
62
|
+
mockPost.mockReset().mockReturnValue(new Promise(resolve => (finishSend = resolve)))
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
afterEach(async () => {
|
|
66
|
+
await act(async () => finishSend({ data: { type: 'Message', id: 'sent', mine: true } }))
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('sends from a reply thread as a reply and returns to the thread', async () => {
|
|
70
|
+
const route = {
|
|
71
|
+
params: { conversation_id: 7, reply_root_id: '42', search_term: 'cat' },
|
|
72
|
+
} as unknown as SendGiphyScreenProps['route']
|
|
73
|
+
|
|
74
|
+
render(
|
|
75
|
+
<QueryClientProvider client={chatQueryClient}>
|
|
76
|
+
<SafeAreaProvider initialMetrics={safeAreaMetrics}>
|
|
77
|
+
<ThemeProvider value={DefaultTheme}>
|
|
78
|
+
<HeaderHeightContext.Provider value={0}>
|
|
79
|
+
<SendGiphyScreen route={route} />
|
|
80
|
+
</HeaderHeightContext.Provider>
|
|
81
|
+
</ThemeProvider>
|
|
82
|
+
</SafeAreaProvider>
|
|
83
|
+
</QueryClientProvider>
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
await act(async () => {
|
|
87
|
+
fireEvent.press(screen.getByLabelText('Send Giphy'))
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const [{ data }] = mockPost.mock.calls[0]
|
|
91
|
+
expect(data.data.attributes.reply_root).toEqual({ id: '42' })
|
|
92
|
+
expect(mockDispatch).toHaveBeenCalledWith(
|
|
93
|
+
expect.objectContaining({
|
|
94
|
+
type: 'POP_TO',
|
|
95
|
+
payload: expect.objectContaining({
|
|
96
|
+
name: 'ConversationReply',
|
|
97
|
+
params: expect.objectContaining({ reply_root_id: '42', clear_input: true }),
|
|
98
|
+
}),
|
|
99
|
+
})
|
|
100
|
+
)
|
|
101
|
+
})
|
|
102
|
+
})
|
|
@@ -18,62 +18,49 @@ const makeMessage = (overrides: Partial<MessageResource> = {}): MessageResource
|
|
|
18
18
|
messageType: 'user',
|
|
19
19
|
personIdsForSystemEvent: null,
|
|
20
20
|
systemTextParts: null,
|
|
21
|
+
systemTextFormat: null,
|
|
21
22
|
...overrides,
|
|
22
23
|
})
|
|
23
24
|
|
|
25
|
+
const joinedParts = { names: ['Alice'], overflowCount: 0, action: 'joined the conversation' }
|
|
26
|
+
|
|
24
27
|
describe('isSystemMessage', () => {
|
|
25
|
-
it('returns true for
|
|
28
|
+
it('returns true for people messages with names and person ids', () => {
|
|
26
29
|
const message = makeMessage({
|
|
27
30
|
messageType: 'user_joined',
|
|
31
|
+
systemTextFormat: 'people',
|
|
28
32
|
personIdsForSystemEvent: [1],
|
|
29
|
-
systemTextParts:
|
|
33
|
+
systemTextParts: joinedParts,
|
|
30
34
|
})
|
|
31
35
|
expect(isSystemMessage(message)).toBe(true)
|
|
32
36
|
})
|
|
33
37
|
|
|
34
|
-
it('
|
|
38
|
+
it('returns true for actor messages of a type the client does not know', () => {
|
|
35
39
|
const message = makeMessage({
|
|
36
|
-
messageType: '
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
names: ['Alice', 'Bob'],
|
|
40
|
-
overflowCount: 0,
|
|
41
|
-
action: 'joined the conversation',
|
|
42
|
-
},
|
|
40
|
+
messageType: 'some_future_type',
|
|
41
|
+
systemTextFormat: 'actor',
|
|
42
|
+
text: 'This conversation was archived by Alice',
|
|
43
43
|
})
|
|
44
|
-
|
|
45
|
-
expect(message.systemTextParts.names).toEqual(['Alice', 'Bob'])
|
|
46
|
-
expect(message.personIdsForSystemEvent).toEqual([1, 2])
|
|
47
|
-
} else {
|
|
48
|
-
throw new Error('Expected isSystemMessage to return true')
|
|
49
|
-
}
|
|
44
|
+
expect(isSystemMessage(message)).toBe(true)
|
|
50
45
|
})
|
|
51
46
|
|
|
52
|
-
it('returns false for
|
|
53
|
-
const message = makeMessage({ messageType: '
|
|
47
|
+
it('returns false for messages without a system text format', () => {
|
|
48
|
+
const message = makeMessage({ messageType: 'user_joined', systemTextParts: joinedParts })
|
|
54
49
|
expect(isSystemMessage(message)).toBe(false)
|
|
55
50
|
})
|
|
56
51
|
|
|
57
|
-
it('returns false for
|
|
58
|
-
const message = makeMessage({
|
|
52
|
+
it('returns false for people messages without systemTextParts', () => {
|
|
53
|
+
const message = makeMessage({ systemTextFormat: 'people', personIdsForSystemEvent: [1] })
|
|
59
54
|
expect(isSystemMessage(message)).toBe(false)
|
|
60
55
|
})
|
|
61
56
|
|
|
62
|
-
it('returns false
|
|
63
|
-
const message = makeMessage({
|
|
64
|
-
messageType: 'user_joined',
|
|
65
|
-
personIdsForSystemEvent: [1],
|
|
66
|
-
systemTextParts: null,
|
|
67
|
-
})
|
|
57
|
+
it('returns false for people messages without personIdsForSystemEvent', () => {
|
|
58
|
+
const message = makeMessage({ systemTextFormat: 'people', systemTextParts: joinedParts })
|
|
68
59
|
expect(isSystemMessage(message)).toBe(false)
|
|
69
60
|
})
|
|
70
61
|
|
|
71
|
-
it('returns false
|
|
72
|
-
const message = makeMessage({
|
|
73
|
-
messageType: 'user_joined',
|
|
74
|
-
personIdsForSystemEvent: null,
|
|
75
|
-
systemTextParts: { names: ['Alice'], overflowCount: 0, action: 'joined the conversation' },
|
|
76
|
-
})
|
|
62
|
+
it.each([null, ''])('returns false for actor messages with text %p', text => {
|
|
63
|
+
const message = makeMessage({ systemTextFormat: 'actor', text })
|
|
77
64
|
expect(isSystemMessage(message)).toBe(false)
|
|
78
65
|
})
|
|
79
66
|
})
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
QueryClient,
|
|
6
6
|
QueryClientProvider,
|
|
7
7
|
} from '@tanstack/react-query'
|
|
8
|
-
import { act, render, screen } from '@testing-library/react-native'
|
|
8
|
+
import { act, fireEvent, render, screen } from '@testing-library/react-native'
|
|
9
9
|
import React from 'react'
|
|
10
10
|
import { FlatList } from 'react-native'
|
|
11
11
|
import { buildTestQueryClient } from '../../../__utils__/query_client'
|
|
@@ -37,9 +37,18 @@ jest.mock('../../../hooks/use_animated_message_background_color', () => ({
|
|
|
37
37
|
handleMessagePressOut: jest.fn(),
|
|
38
38
|
}),
|
|
39
39
|
}))
|
|
40
|
+
const mockNavigate = jest.fn()
|
|
40
41
|
jest.mock('@react-navigation/native', () => ({
|
|
41
42
|
...jest.requireActual('@react-navigation/native'),
|
|
42
|
-
useNavigation: () => ({ navigate:
|
|
43
|
+
useNavigation: () => ({ navigate: mockNavigate }),
|
|
44
|
+
}))
|
|
45
|
+
const mockToggleReaction = jest.fn()
|
|
46
|
+
jest.mock('../../../hooks/use_message_reaction_toggle', () => ({
|
|
47
|
+
useMessageReactionToggle: () => ({ handleReactionToggle: mockToggleReaction, isPending: false }),
|
|
48
|
+
}))
|
|
49
|
+
jest.mock('../../../utils/native_adapters', () => ({
|
|
50
|
+
...jest.requireActual('../../../utils/native_adapters'),
|
|
51
|
+
Haptic: { impactLight: jest.fn() },
|
|
43
52
|
}))
|
|
44
53
|
// Every row calls this hook on each render, so its calls count row renders.
|
|
45
54
|
jest.mock('../../../hooks/use_live_relative_time', () => {
|
|
@@ -293,6 +302,63 @@ describe('MessageList', () => {
|
|
|
293
302
|
expect(renderedRowIds()).toEqual([])
|
|
294
303
|
})
|
|
295
304
|
|
|
305
|
+
describe('in a disabled conversation', () => {
|
|
306
|
+
const reacted = buildMessage(1, {
|
|
307
|
+
reactionCounts: [
|
|
308
|
+
{
|
|
309
|
+
type: 'ReactionCount',
|
|
310
|
+
id: 'heart',
|
|
311
|
+
messageId: messageId(1),
|
|
312
|
+
value: 'heart',
|
|
313
|
+
count: 1,
|
|
314
|
+
mine: 0,
|
|
315
|
+
authorIds: [OTHER],
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
})
|
|
319
|
+
const archived = buildMessage(2, {
|
|
320
|
+
text: 'This conversation was archived by Ann',
|
|
321
|
+
systemTextFormat: 'actor',
|
|
322
|
+
})
|
|
323
|
+
const disable = () => act(() => setHarnessConversation({ ...conversation, disabled: true }))
|
|
324
|
+
|
|
325
|
+
it('toggles a reaction pill while the conversation is active', () => {
|
|
326
|
+
renderList([reacted])
|
|
327
|
+
|
|
328
|
+
fireEvent.press(screen.getByTestId(`reaction-${reacted.id}-heart`))
|
|
329
|
+
|
|
330
|
+
expect(mockToggleReaction).toHaveBeenCalledWith({ value: 'heart', mine: false })
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
it('keeps reaction pills read-only but still shows who reacted', () => {
|
|
334
|
+
renderList([reacted])
|
|
335
|
+
disable()
|
|
336
|
+
const pill = screen.getByTestId(`reaction-${reacted.id}-heart`)
|
|
337
|
+
|
|
338
|
+
fireEvent.press(pill)
|
|
339
|
+
fireEvent(pill, 'longPress')
|
|
340
|
+
|
|
341
|
+
expect(mockToggleReaction).not.toHaveBeenCalled()
|
|
342
|
+
expect(mockNavigate).toHaveBeenCalledWith('Reactions', expect.anything())
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
it('opens message actions on a system message only while the conversation is active', () => {
|
|
346
|
+
queryClient.setQueryData<MessagesQueryData>(messagesQueryKey, {
|
|
347
|
+
pages: [{ data: [archived], links: {}, meta: { count: 1, totalCount: 1 } }],
|
|
348
|
+
pageParams: [{}],
|
|
349
|
+
})
|
|
350
|
+
render(<Harness />, { wrapper: Wrapper })
|
|
351
|
+
fireEvent(screen.getByText(/archived by Ann/), 'longPress')
|
|
352
|
+
expect(mockNavigate).toHaveBeenCalledWith('MessageActions', expect.anything())
|
|
353
|
+
|
|
354
|
+
mockNavigate.mockClear()
|
|
355
|
+
disable()
|
|
356
|
+
fireEvent(screen.getByText(/archived by Ann/), 'longPress')
|
|
357
|
+
|
|
358
|
+
expect(mockNavigate).not.toHaveBeenCalled()
|
|
359
|
+
})
|
|
360
|
+
})
|
|
361
|
+
|
|
296
362
|
describe('opened at an anchor message', () => {
|
|
297
363
|
const anchor = messages[4]
|
|
298
364
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
2
|
+
import { render } from '@testing-library/react-native'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { buildTestQueryClient } from '../../../__utils__/query_client'
|
|
5
|
+
import { ChatProvider } from '../../../contexts/chat_context'
|
|
6
|
+
import type { PersonResource } from '../../../types/resources/person'
|
|
7
|
+
import type { SystemMessageResource } from '../../../utils/system_messages'
|
|
8
|
+
import { SystemMessage } from '../system_message'
|
|
9
|
+
|
|
10
|
+
jest.mock('@react-navigation/native', () => ({
|
|
11
|
+
useNavigation: () => ({ navigate: jest.fn() }),
|
|
12
|
+
}))
|
|
13
|
+
jest.mock('../../../hooks/use_animated_message_background_color', () => ({
|
|
14
|
+
useAnimatedMessageBackgroundColor: () => ({
|
|
15
|
+
animatedBackgroundColor: {},
|
|
16
|
+
handleMessagePressIn: jest.fn(),
|
|
17
|
+
handleMessagePressOut: jest.fn(),
|
|
18
|
+
}),
|
|
19
|
+
}))
|
|
20
|
+
|
|
21
|
+
const author = { id: 1, type: 'Person', name: 'Wes', avatar: null } as unknown as PersonResource
|
|
22
|
+
|
|
23
|
+
const systemMessage = (overrides: Partial<SystemMessageResource>): SystemMessageResource =>
|
|
24
|
+
({
|
|
25
|
+
type: 'Message',
|
|
26
|
+
id: '01',
|
|
27
|
+
text: null,
|
|
28
|
+
html: '',
|
|
29
|
+
createdAt: '2026-02-03T14:18:00',
|
|
30
|
+
deletedAt: null,
|
|
31
|
+
textEditedAt: null,
|
|
32
|
+
mine: false,
|
|
33
|
+
attachments: [],
|
|
34
|
+
author,
|
|
35
|
+
reactionCounts: [],
|
|
36
|
+
replyCount: 0,
|
|
37
|
+
replyRootId: null,
|
|
38
|
+
messageType: 'user_joined',
|
|
39
|
+
personIdsForSystemEvent: null,
|
|
40
|
+
systemTextParts: null,
|
|
41
|
+
...overrides,
|
|
42
|
+
}) as SystemMessageResource
|
|
43
|
+
|
|
44
|
+
let queryClient: QueryClient
|
|
45
|
+
|
|
46
|
+
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
47
|
+
<QueryClientProvider client={queryClient}>
|
|
48
|
+
<ChatProvider
|
|
49
|
+
value={{
|
|
50
|
+
token: {
|
|
51
|
+
access_token: '',
|
|
52
|
+
created_at: 0,
|
|
53
|
+
expires_in: 0,
|
|
54
|
+
scope: '',
|
|
55
|
+
refresh_token: '',
|
|
56
|
+
token_type: '',
|
|
57
|
+
},
|
|
58
|
+
onUnauthorizedResponse: () => {},
|
|
59
|
+
theme: { theme: { colors: { interaction: 'rgb(0, 0, 255)' } } },
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
</ChatProvider>
|
|
64
|
+
</QueryClientProvider>
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const renderSystemMessage = (message: SystemMessageResource) =>
|
|
68
|
+
render(<SystemMessage message={message} conversationId={1} conversationDisabled={false} />, {
|
|
69
|
+
wrapper: Wrapper,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
jest.useFakeTimers({ now: new Date(2026, 5, 15, 12, 0) })
|
|
74
|
+
queryClient = buildTestQueryClient()
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
afterEach(() => {
|
|
78
|
+
queryClient.clear()
|
|
79
|
+
jest.useRealTimers()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
describe('SystemMessage', () => {
|
|
83
|
+
it('renders actor messages as their text followed by the local date and time', () => {
|
|
84
|
+
const view = renderSystemMessage(
|
|
85
|
+
systemMessage({
|
|
86
|
+
messageType: 'conversation_archived',
|
|
87
|
+
systemTextFormat: 'actor',
|
|
88
|
+
text: 'This conversation was archived by Wes',
|
|
89
|
+
})
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
expect(view.getByText('This conversation was archived by Wes on Feb 3 at 2:18pm')).toBeTruthy()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('builds people messages from their names', () => {
|
|
96
|
+
const view = renderSystemMessage(
|
|
97
|
+
systemMessage({
|
|
98
|
+
systemTextFormat: 'people',
|
|
99
|
+
systemTextParts: { names: ['Ann', 'Bo'], overflowCount: 0, action: 'joined' },
|
|
100
|
+
personIdsForSystemEvent: [1, 2],
|
|
101
|
+
})
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
expect(view.getByText('Ann and Bo joined')).toBeTruthy()
|
|
105
|
+
})
|
|
106
|
+
})
|
|
@@ -8,7 +8,7 @@ import Animated, {
|
|
|
8
8
|
ReduceMotion,
|
|
9
9
|
withSpring,
|
|
10
10
|
} from 'react-native-reanimated'
|
|
11
|
-
import { useTheme } from '../../hooks'
|
|
11
|
+
import { useReduceMotion, useTheme } from '../../hooks'
|
|
12
12
|
import { platformFontWeightMedium } from '../../utils'
|
|
13
13
|
import { Icon, Text } from '../display'
|
|
14
14
|
|
|
@@ -20,6 +20,7 @@ interface JumpToBottomButtonProps {
|
|
|
20
20
|
export const JumpToBottomButton = ({ onPress, visible }: JumpToBottomButtonProps) => {
|
|
21
21
|
const styles = useStyles()
|
|
22
22
|
const progress = useSharedValue(0)
|
|
23
|
+
const reduceMotion = useReduceMotion()
|
|
23
24
|
|
|
24
25
|
useEffect(() => {
|
|
25
26
|
progress.value = withSpring(visible ? 1 : 0, {
|
|
@@ -27,9 +28,9 @@ export const JumpToBottomButton = ({ onPress, visible }: JumpToBottomButtonProps
|
|
|
27
28
|
damping: 16,
|
|
28
29
|
stiffness: 170,
|
|
29
30
|
overshootClamping: false,
|
|
30
|
-
reduceMotion: ReduceMotion.
|
|
31
|
+
reduceMotion: reduceMotion ? ReduceMotion.Always : ReduceMotion.Never,
|
|
31
32
|
})
|
|
32
|
-
}, [visible, progress])
|
|
33
|
+
}, [visible, progress, reduceMotion])
|
|
33
34
|
|
|
34
35
|
const animatedStyle = useAnimatedStyle(() => {
|
|
35
36
|
return {
|
|
@@ -43,6 +43,7 @@ import { TheirReplyConnector, MyReplyConnector, AVATAR_CONNECTOR_SPACING } from
|
|
|
43
43
|
*/
|
|
44
44
|
interface MessageProps extends MessageResource {
|
|
45
45
|
canDeleteNonAuthoredMessages: boolean
|
|
46
|
+
conversationDisabled: boolean
|
|
46
47
|
conversation_id: number
|
|
47
48
|
readByOthers?: boolean
|
|
48
49
|
inReplyScreen?: boolean
|
|
@@ -52,6 +53,7 @@ interface MessageProps extends MessageResource {
|
|
|
52
53
|
|
|
53
54
|
export const Message = memo(function MessageRow({
|
|
54
55
|
canDeleteNonAuthoredMessages,
|
|
56
|
+
conversationDisabled,
|
|
55
57
|
conversation_id,
|
|
56
58
|
readByOthers,
|
|
57
59
|
inReplyScreen,
|
|
@@ -296,6 +298,7 @@ export const Message = memo(function MessageRow({
|
|
|
296
298
|
onLongPress={handleReactionLongPress}
|
|
297
299
|
message={message}
|
|
298
300
|
conversationId={conversation_id}
|
|
301
|
+
disabled={conversationDisabled}
|
|
299
302
|
/>
|
|
300
303
|
))}
|
|
301
304
|
</View>
|
|
@@ -214,18 +214,20 @@ function MessageFormRoot({
|
|
|
214
214
|
if (!Keyboard.isVisible() || Platform.OS === 'ios') {
|
|
215
215
|
navigation.navigate('SendGiphy', {
|
|
216
216
|
conversation_id: conversation.id,
|
|
217
|
+
reply_root_id: replyRootId,
|
|
217
218
|
search_term: text,
|
|
218
219
|
})
|
|
219
220
|
} else {
|
|
220
221
|
const keyboardListener = Keyboard.addListener('keyboardDidHide', () => {
|
|
221
222
|
navigation.navigate('SendGiphy', {
|
|
222
223
|
conversation_id: conversation.id,
|
|
224
|
+
reply_root_id: replyRootId,
|
|
223
225
|
search_term: text,
|
|
224
226
|
})
|
|
225
227
|
keyboardListener?.remove()
|
|
226
228
|
})
|
|
227
229
|
}
|
|
228
|
-
}, [conversation.id, navigation, text])
|
|
230
|
+
}, [conversation.id, navigation, replyRootId, text])
|
|
229
231
|
|
|
230
232
|
const catchingUp = useRef(false)
|
|
231
233
|
|
|
@@ -72,6 +72,7 @@ export function MessageList({
|
|
|
72
72
|
const inReplyScreen = !!replyRootId
|
|
73
73
|
const canDeleteNonAuthoredMessages =
|
|
74
74
|
conversation.memberAbility?.canDeleteNonAuthoredMessages ?? false
|
|
75
|
+
const conversationDisabled = conversation.disabled ?? false
|
|
75
76
|
const latestRead = conversation.latestReadMessageSortKey
|
|
76
77
|
const messagesWithSeparators = groupMessages({ ms: messages, inReplyScreen })
|
|
77
78
|
const anchorIndex = anchorMessageId
|
|
@@ -193,7 +194,13 @@ export function MessageList({
|
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
if (isSystemMessage(item)) {
|
|
196
|
-
return
|
|
197
|
+
return (
|
|
198
|
+
<SystemMessage
|
|
199
|
+
message={item}
|
|
200
|
+
conversationId={conversationId}
|
|
201
|
+
conversationDisabled={conversationDisabled}
|
|
202
|
+
/>
|
|
203
|
+
)
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
const readByOthers = item.mine && !!latestRead && item.id <= latestRead
|
|
@@ -201,6 +208,7 @@ export function MessageList({
|
|
|
201
208
|
<Message
|
|
202
209
|
{...item}
|
|
203
210
|
canDeleteNonAuthoredMessages={canDeleteNonAuthoredMessages}
|
|
211
|
+
conversationDisabled={conversationDisabled}
|
|
204
212
|
conversation_id={conversationId}
|
|
205
213
|
readByOthers={readByOthers}
|
|
206
214
|
inReplyScreen={inReplyScreen}
|