@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.
- 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_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__/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_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
|
@@ -4,10 +4,13 @@ import { FlatList } from 'react-native-gesture-handler'
|
|
|
4
4
|
import { Heading } from '../../../components'
|
|
5
5
|
import {
|
|
6
6
|
useAtFontScaleBreakpoint,
|
|
7
|
+
useCanBrowseArchivedConversations,
|
|
7
8
|
useDirectMessagesEligible,
|
|
8
9
|
useHasDirectMessages,
|
|
9
10
|
useTheme,
|
|
10
11
|
} from '../../../hooks'
|
|
12
|
+
import { useFilterDropdownEnabled } from '../../../hooks/use_filter_dropdown_enabled'
|
|
13
|
+
import { faBoxArchive } from '../../../vendor/font_awesome_pro_solid_icons'
|
|
11
14
|
import { FilterContext, useFilterContext } from '../context/conversation_filter_context'
|
|
12
15
|
import { FilterTypes } from '../filter_types'
|
|
13
16
|
import { useGroupsToFilter, useTeamsToFilter } from '../hooks/filters'
|
|
@@ -16,6 +19,8 @@ import {
|
|
|
16
19
|
FilterRow,
|
|
17
20
|
GroupRow,
|
|
18
21
|
GroupRowProps,
|
|
22
|
+
OtherRow,
|
|
23
|
+
OtherRowProps,
|
|
19
24
|
TeamRow,
|
|
20
25
|
TeamRowProps,
|
|
21
26
|
ViewMore,
|
|
@@ -32,6 +37,7 @@ enum SectionTypes {
|
|
|
32
37
|
header,
|
|
33
38
|
hidden,
|
|
34
39
|
more,
|
|
40
|
+
other,
|
|
35
41
|
teams,
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -41,6 +47,7 @@ type SectionListData = Array<
|
|
|
41
47
|
| DataItem<HeaderProps, SectionTypes.header>
|
|
42
48
|
| DataItem<any, SectionTypes.hidden>
|
|
43
49
|
| DataItem<ViewMoreRowProps, SectionTypes.more>
|
|
50
|
+
| DataItem<OtherRowProps, SectionTypes.other>
|
|
44
51
|
| DataItem<TeamRowProps, SectionTypes.teams>
|
|
45
52
|
>
|
|
46
53
|
|
|
@@ -57,11 +64,18 @@ interface DataItem<T, TName extends SectionTypes> {
|
|
|
57
64
|
export const ConversationFilters = () => {
|
|
58
65
|
const styles = useStyles()
|
|
59
66
|
const { setScrollOffset, params } = useContext(FilterContext)
|
|
60
|
-
const {
|
|
67
|
+
const {
|
|
68
|
+
chat_group_graph_id,
|
|
69
|
+
group_source_app_name = '',
|
|
70
|
+
show_direct_messages,
|
|
71
|
+
show_archived,
|
|
72
|
+
} = params
|
|
61
73
|
|
|
74
|
+
const filterDropdownEnabled = useFilterDropdownEnabled()
|
|
62
75
|
const directMessagesEligible = useDirectMessagesEligible()
|
|
63
76
|
const hasDirectMessages = useHasDirectMessages()
|
|
64
77
|
const canFilterByDMs = directMessagesEligible && hasDirectMessages
|
|
78
|
+
const canFilterByArchived = useCanBrowseArchivedConversations()
|
|
65
79
|
|
|
66
80
|
const activeFilter: FilterTypes = useMemo(() => {
|
|
67
81
|
if (chat_group_graph_id) {
|
|
@@ -72,10 +86,12 @@ export const ConversationFilters = () => {
|
|
|
72
86
|
return FilterTypes.Teams
|
|
73
87
|
} else if (show_direct_messages) {
|
|
74
88
|
return FilterTypes.DirectMessages
|
|
89
|
+
} else if (show_archived) {
|
|
90
|
+
return FilterTypes.Archived
|
|
75
91
|
}
|
|
76
92
|
|
|
77
93
|
return FilterTypes.All
|
|
78
|
-
}, [chat_group_graph_id, group_source_app_name, show_direct_messages])
|
|
94
|
+
}, [chat_group_graph_id, group_source_app_name, show_direct_messages, show_archived])
|
|
79
95
|
|
|
80
96
|
const { groups = [] } = useGroupsToFilter()
|
|
81
97
|
const { teams = [] } = useTeamsToFilter()
|
|
@@ -101,8 +117,9 @@ export const ConversationFilters = () => {
|
|
|
101
117
|
const groupItemData = selectActiveWithFirst(5)(groupItems)
|
|
102
118
|
const teamItemData = selectActiveWithFirst(5)(teamItems)
|
|
103
119
|
|
|
104
|
-
const
|
|
105
|
-
const
|
|
120
|
+
const showAppFilters = !filterDropdownEnabled && groupItems.length > 0 && teamItems.length > 0
|
|
121
|
+
const showDMFilter = !filterDropdownEnabled && canFilterByDMs
|
|
122
|
+
const showGeneralFilters = showAppFilters || showDMFilter
|
|
106
123
|
|
|
107
124
|
const listData: SectionListData = [
|
|
108
125
|
{
|
|
@@ -114,7 +131,7 @@ export const ConversationFilters = () => {
|
|
|
114
131
|
data: { filter: FilterTypes.All, isActive: activeFilter === FilterTypes.All },
|
|
115
132
|
},
|
|
116
133
|
{
|
|
117
|
-
type:
|
|
134
|
+
type: showAppFilters ? SectionTypes.filter : SectionTypes.hidden,
|
|
118
135
|
data: {
|
|
119
136
|
filter: FilterTypes.Groups,
|
|
120
137
|
group_source_app_name: 'groups',
|
|
@@ -122,7 +139,7 @@ export const ConversationFilters = () => {
|
|
|
122
139
|
},
|
|
123
140
|
},
|
|
124
141
|
{
|
|
125
|
-
type:
|
|
142
|
+
type: showAppFilters ? SectionTypes.filter : SectionTypes.hidden,
|
|
126
143
|
data: {
|
|
127
144
|
filter: FilterTypes.Teams,
|
|
128
145
|
group_source_app_name: 'services',
|
|
@@ -130,7 +147,7 @@ export const ConversationFilters = () => {
|
|
|
130
147
|
},
|
|
131
148
|
},
|
|
132
149
|
{
|
|
133
|
-
type:
|
|
150
|
+
type: showDMFilter ? SectionTypes.filter : SectionTypes.hidden,
|
|
134
151
|
data: {
|
|
135
152
|
filter: FilterTypes.DirectMessages,
|
|
136
153
|
show_direct_messages: true,
|
|
@@ -155,6 +172,20 @@ export const ConversationFilters = () => {
|
|
|
155
172
|
type: teamItems.length > 5 ? SectionTypes.more : SectionTypes.hidden,
|
|
156
173
|
data: { routeName: 'TeamFilters' },
|
|
157
174
|
},
|
|
175
|
+
{
|
|
176
|
+
type: canFilterByArchived ? SectionTypes.header : SectionTypes.hidden,
|
|
177
|
+
data: { title: 'Other', style: styles.extraHeaderScalableSpace },
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
type: canFilterByArchived ? SectionTypes.other : SectionTypes.hidden,
|
|
181
|
+
data: {
|
|
182
|
+
filter: FilterTypes.Archived,
|
|
183
|
+
description: 'Archived for everybody',
|
|
184
|
+
icon: faBoxArchive,
|
|
185
|
+
show_archived: true,
|
|
186
|
+
isActive: activeFilter === FilterTypes.Archived,
|
|
187
|
+
},
|
|
188
|
+
},
|
|
158
189
|
]
|
|
159
190
|
|
|
160
191
|
return (
|
|
@@ -175,6 +206,8 @@ export const ConversationFilters = () => {
|
|
|
175
206
|
return <TeamRow {...item.data} />
|
|
176
207
|
case SectionTypes.more:
|
|
177
208
|
return <ViewMore {...item.data} />
|
|
209
|
+
case SectionTypes.other:
|
|
210
|
+
return <OtherRow {...item.data} />
|
|
178
211
|
default:
|
|
179
212
|
return null
|
|
180
213
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core'
|
|
1
2
|
import { PlatformPressable } from '@react-navigation/elements'
|
|
2
3
|
import { NavigationProp, useNavigation } from '@react-navigation/native'
|
|
3
4
|
import React, { PropsWithChildren, useContext } from 'react'
|
|
4
5
|
import { StyleSheet, View, ViewStyle } from 'react-native'
|
|
5
|
-
import { Heading, Icon, Image, Text, TextButton } from '../../../components'
|
|
6
|
+
import { Heading, Icon, IconTile, Image, Text, TextButton } from '../../../components'
|
|
6
7
|
import {
|
|
7
8
|
useAtFontScaleBreakpoint,
|
|
8
9
|
useFontScale,
|
|
@@ -115,6 +116,33 @@ export const TeamRow = ({ team }: TeamRowProps) => {
|
|
|
115
116
|
)
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
export type OtherRowProps = {
|
|
120
|
+
show_archived?: boolean
|
|
121
|
+
isActive: boolean
|
|
122
|
+
filter: FilterTypes
|
|
123
|
+
description: string
|
|
124
|
+
icon: IconDefinition
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const OtherRow = ({ show_archived, isActive, filter, description, icon }: OtherRowProps) => {
|
|
128
|
+
const styles = useRowStyles()
|
|
129
|
+
const { setAppFilter } = useContext(FilterContext)
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<PressableRow onPress={() => setAppFilter({ show_archived })} isActive={isActive}>
|
|
133
|
+
<IconTile icon={icon} shape="square" size="lg" />
|
|
134
|
+
<View style={styles.rowTextContainer}>
|
|
135
|
+
<Heading variant="h3" style={styles.rowTitle}>
|
|
136
|
+
{filter}
|
|
137
|
+
</Heading>
|
|
138
|
+
<Text variant="footnote" style={styles.rowSubtitle}>
|
|
139
|
+
{description}
|
|
140
|
+
</Text>
|
|
141
|
+
</View>
|
|
142
|
+
</PressableRow>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
118
146
|
export type ViewMoreRowProps = { routeName: keyof ConversationFilterStackParamList }
|
|
119
147
|
|
|
120
148
|
export const ViewMore = ({ routeName }: ViewMoreRowProps) => {
|
|
@@ -22,6 +22,7 @@ export const FilterContext = createContext<{
|
|
|
22
22
|
chat_group_graph_id: undefined,
|
|
23
23
|
group_source_app_name: undefined,
|
|
24
24
|
show_direct_messages: undefined,
|
|
25
|
+
show_archived: undefined,
|
|
25
26
|
},
|
|
26
27
|
scrollOffset: 0,
|
|
27
28
|
setScrollOffset: () => {},
|
|
@@ -57,6 +58,7 @@ export const FilterProvider = ({ children }: PropsWithChildren) => {
|
|
|
57
58
|
chat_group_graph_id: undefined,
|
|
58
59
|
group_source_app_name: undefined,
|
|
59
60
|
show_direct_messages: undefined,
|
|
61
|
+
show_archived: undefined,
|
|
60
62
|
})
|
|
61
63
|
)
|
|
62
64
|
},
|
|
@@ -65,6 +67,7 @@ export const FilterProvider = ({ children }: PropsWithChildren) => {
|
|
|
65
67
|
chat_group_graph_id: params.chat_group_graph_id,
|
|
66
68
|
group_source_app_name: undefined,
|
|
67
69
|
show_direct_messages: undefined,
|
|
70
|
+
show_archived: undefined,
|
|
68
71
|
})
|
|
69
72
|
},
|
|
70
73
|
setAppFilter: (params: Omit<ConversationFiltersParams, 'chat_group_graph_id'>) => {
|
|
@@ -72,6 +75,7 @@ export const FilterProvider = ({ children }: PropsWithChildren) => {
|
|
|
72
75
|
chat_group_graph_id: undefined,
|
|
73
76
|
group_source_app_name: params.group_source_app_name,
|
|
74
77
|
show_direct_messages: params.show_direct_messages,
|
|
78
|
+
show_archived: params.show_archived,
|
|
75
79
|
})
|
|
76
80
|
},
|
|
77
81
|
applyFilters: (params: ConversationFiltersParams) => {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { useHeaderHeight } from '@react-navigation/elements'
|
|
1
|
+
import { HeaderBackButton, useHeaderHeight } from '@react-navigation/elements'
|
|
2
2
|
import * as ReactNavigationNative from '@react-navigation/native'
|
|
3
|
-
import { RouteProp, useRoute } from '@react-navigation/native'
|
|
3
|
+
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native'
|
|
4
4
|
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
|
5
5
|
import React, { useCallback } from 'react'
|
|
6
6
|
import { LayoutChangeEvent, Platform, StyleSheet, useWindowDimensions, View } from 'react-native'
|
|
7
7
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
8
8
|
import FormSheet, { getFormSheetScreenOptions } from '../components/primitive/form_sheet'
|
|
9
|
+
import { useTheme } from '../hooks'
|
|
10
|
+
import { useFilterDropdownEnabled } from '../hooks/use_filter_dropdown_enabled'
|
|
9
11
|
import { ConversationFilters } from './conversation_filters/components/conversation_filters'
|
|
10
12
|
import {
|
|
11
13
|
FilterProvider,
|
|
@@ -86,16 +88,19 @@ export const ConversationFiltersScreen = (_props: ConversationFiltersScreenProps
|
|
|
86
88
|
return (
|
|
87
89
|
<FilterProvider>
|
|
88
90
|
<FormSheet.Root contentStyle={styles.contentContainer} showAndroidSheetGrabber={false}>
|
|
89
|
-
<
|
|
91
|
+
<ConversationFiltersHeader />
|
|
90
92
|
<Filters />
|
|
91
93
|
</FormSheet.Root>
|
|
92
94
|
</FilterProvider>
|
|
93
95
|
)
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
const
|
|
98
|
+
export const ConversationFiltersHeader = () => {
|
|
97
99
|
const { resetFilter, applyFilters, setFormSheetHeaderHeight } = useFilterContext()
|
|
100
|
+
const navigation = useNavigation()
|
|
98
101
|
const route = useRoute<RouteProp<ConversationFiltersScreenProps['route']>>()
|
|
102
|
+
const filterDropdownEnabled = useFilterDropdownEnabled()
|
|
103
|
+
const { colors } = useTheme()
|
|
99
104
|
const styles = useStyles()
|
|
100
105
|
|
|
101
106
|
const handleFormSheetHeaderLayout = useCallback(
|
|
@@ -108,7 +113,18 @@ const FormSheetHeaderWithContext = () => {
|
|
|
108
113
|
return (
|
|
109
114
|
<View onLayout={handleFormSheetHeaderLayout}>
|
|
110
115
|
<FormSheet.Header style={styles.header}>
|
|
111
|
-
|
|
116
|
+
{Platform.OS === 'android' && (
|
|
117
|
+
<HeaderBackButton
|
|
118
|
+
displayMode="minimal"
|
|
119
|
+
accessibilityLabel="Back"
|
|
120
|
+
tintColor={colors.iconColorDefaultPrimary}
|
|
121
|
+
onPress={navigation.goBack}
|
|
122
|
+
style={styles.backButton}
|
|
123
|
+
/>
|
|
124
|
+
)}
|
|
125
|
+
<FormSheet.HeaderTitle>
|
|
126
|
+
{filterDropdownEnabled ? 'More filters' : 'Filters'}
|
|
127
|
+
</FormSheet.HeaderTitle>
|
|
112
128
|
<FormSheet.HeaderActions>
|
|
113
129
|
<FormSheet.HeaderTextButton onPress={resetFilter}>Reset</FormSheet.HeaderTextButton>
|
|
114
130
|
<FormSheet.HeaderButton title="Apply" onPress={() => applyFilters(route.params)} />
|
|
@@ -141,5 +157,9 @@ const useStyles = () => {
|
|
|
141
157
|
// separator the way the non-scrolling reaction sheet does.
|
|
142
158
|
borderBottomWidth: 0,
|
|
143
159
|
},
|
|
160
|
+
backButton: {
|
|
161
|
+
marginLeft: -3,
|
|
162
|
+
marginRight: 8,
|
|
163
|
+
},
|
|
144
164
|
})
|
|
145
165
|
}
|
|
@@ -125,6 +125,7 @@ export const GroupsForm = ({ groupId, chat_group_graph_id, avatarSelection }: Gr
|
|
|
125
125
|
memberData={groupMemberships.adultMembers}
|
|
126
126
|
loadingMore={groupMemberships.isFetchingNextPage}
|
|
127
127
|
onEndReached={groupMemberships.fetchNextPage}
|
|
128
|
+
listEmptyText={groupMemberships.isLoading ? 'Loading members...' : undefined}
|
|
128
129
|
FormContent={
|
|
129
130
|
<FormContent
|
|
130
131
|
group={group}
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
usePublishProductAnalyticsEvent,
|
|
41
41
|
} from '../hooks/use_product_analytics'
|
|
42
42
|
import { useRestAwayFromDismissEdge } from '../hooks/use_rest_away_from_dismiss_edge'
|
|
43
|
+
import { useUnarchiveConversationAction } from '../hooks/use_unarchive_conversation_action'
|
|
43
44
|
import { useVideoModerationJoltEvents } from '../hooks/use_video_moderation_jolt_events'
|
|
44
45
|
import { ConversationResource } from '../types/resources/conversation'
|
|
45
46
|
import { ConversationBadgeResource } from '../types/resources/conversation_badge'
|
|
@@ -158,7 +159,7 @@ function ConversationScreenContent({ route }: ConversationScreenProps) {
|
|
|
158
159
|
})
|
|
159
160
|
} else {
|
|
160
161
|
navigation.setParams({
|
|
161
|
-
title: title,
|
|
162
|
+
title: title ?? undefined,
|
|
162
163
|
badge: badges?.[0],
|
|
163
164
|
deleted: conversation?.deleted,
|
|
164
165
|
muted,
|
|
@@ -265,12 +266,13 @@ function ConversationBottomBar({
|
|
|
265
266
|
onBeforeSubmit,
|
|
266
267
|
}: ConversationBottomBarProps) {
|
|
267
268
|
const messageLink = useMessageAvailableMembersAction(conversation)
|
|
269
|
+
const unarchiveAction = useUnarchiveConversationAction(conversation)
|
|
268
270
|
|
|
269
271
|
if (conversation.disabled)
|
|
270
272
|
return (
|
|
271
273
|
<ConversationDisabledBanner
|
|
272
274
|
message={conversation.disabledMessage ?? null}
|
|
273
|
-
|
|
275
|
+
action={unarchiveAction ?? messageLink}
|
|
274
276
|
/>
|
|
275
277
|
)
|
|
276
278
|
if (!canReply) return <MemberMessagesDisabledBanner />
|
|
@@ -2,6 +2,14 @@ import { QueryClientProvider } from '@tanstack/react-query'
|
|
|
2
2
|
import { render } from '@testing-library/react-native'
|
|
3
3
|
import React, { Suspense } from 'react'
|
|
4
4
|
import { buildTestQueryClient } from '../../../__utils__/query_client'
|
|
5
|
+
import {
|
|
6
|
+
AudioAdapter,
|
|
7
|
+
ChatAdapters,
|
|
8
|
+
ClipboardAdapter,
|
|
9
|
+
ImagePickerAdapter,
|
|
10
|
+
MenuAdapter,
|
|
11
|
+
VideoAdapter,
|
|
12
|
+
} from '../../../utils/native_adapters'
|
|
5
13
|
import { ConversationsScreen } from '../conversations_screen'
|
|
6
14
|
|
|
7
15
|
const mockGet = jest.fn()
|
|
@@ -28,6 +36,26 @@ jest.mock('../components/search_list_header_component', () => {
|
|
|
28
36
|
const { Text } = require('react-native')
|
|
29
37
|
return { SearchListHeaderComponent: () => <Text>Search header</Text> }
|
|
30
38
|
})
|
|
39
|
+
jest.mock('../components/filter_dropdown_list_header_component', () => {
|
|
40
|
+
const { Text } = require('react-native')
|
|
41
|
+
return { FilterDropdownListHeaderComponent: () => <Text>Filter dropdown header</Text> }
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const configureAdapters = ({ menu }: { menu: boolean }) => {
|
|
45
|
+
ChatAdapters.configure({
|
|
46
|
+
clipboard: new ClipboardAdapter({
|
|
47
|
+
getStringAsync: async () => '',
|
|
48
|
+
setStringAsync: async () => {},
|
|
49
|
+
}),
|
|
50
|
+
audio: new AudioAdapter({ useAudio: () => ({}) as any }),
|
|
51
|
+
video: new VideoAdapter({ Player: (() => null) as any }),
|
|
52
|
+
imagePicker: new ImagePickerAdapter({
|
|
53
|
+
openCameraAsync: async () => ({ canceled: true, assets: null }),
|
|
54
|
+
openImageLibraryAsync: async () => ({ canceled: true, assets: null }),
|
|
55
|
+
}),
|
|
56
|
+
...(menu ? { menu: new MenuAdapter({ View: () => null }) } : {}),
|
|
57
|
+
})
|
|
58
|
+
}
|
|
31
59
|
|
|
32
60
|
const renderWithFeatures = (enabledFeatures: string[]) => {
|
|
33
61
|
mockGet.mockResolvedValue({
|
|
@@ -51,6 +79,10 @@ const renderWithFeatures = (enabledFeatures: string[]) => {
|
|
|
51
79
|
}
|
|
52
80
|
|
|
53
81
|
describe('ConversationsScreen header gating', () => {
|
|
82
|
+
beforeEach(() => {
|
|
83
|
+
configureAdapters({ menu: true })
|
|
84
|
+
})
|
|
85
|
+
|
|
54
86
|
it('shows the search header with only the QA flag on', async () => {
|
|
55
87
|
const view = renderWithFeatures(['QA_MOBILE_search'])
|
|
56
88
|
|
|
@@ -63,6 +95,26 @@ describe('ConversationsScreen header gating', () => {
|
|
|
63
95
|
expect(await view.findByText('Search header')).toBeTruthy()
|
|
64
96
|
})
|
|
65
97
|
|
|
98
|
+
it('shows the filter dropdown header over the search header when its flag is on', async () => {
|
|
99
|
+
const view = renderWithFeatures(['QA_MOBILE_filter_dropdown', 'ROLLOUT_MOBILE_search'])
|
|
100
|
+
|
|
101
|
+
expect(await view.findByText('Filter dropdown header')).toBeTruthy()
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('shows the filter dropdown header with only its rollout flag on', async () => {
|
|
105
|
+
const view = renderWithFeatures(['ROLLOUT_MOBILE_filter_dropdown'])
|
|
106
|
+
|
|
107
|
+
expect(await view.findByText('Filter dropdown header')).toBeTruthy()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('falls back to the search header when the host has no menu adapter', async () => {
|
|
111
|
+
configureAdapters({ menu: false })
|
|
112
|
+
|
|
113
|
+
const view = renderWithFeatures(['QA_MOBILE_filter_dropdown', 'ROLLOUT_MOBILE_search'])
|
|
114
|
+
|
|
115
|
+
expect(await view.findByText('Search header')).toBeTruthy()
|
|
116
|
+
})
|
|
117
|
+
|
|
66
118
|
it('shows the default header with neither flag on', async () => {
|
|
67
119
|
const view = renderWithFeatures(['ROLLOUT_WEB_search'])
|
|
68
120
|
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react-native'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { Pressable, Text } from 'react-native'
|
|
4
|
+
import {
|
|
5
|
+
AudioAdapter,
|
|
6
|
+
ChatAdapters,
|
|
7
|
+
ClipboardAdapter,
|
|
8
|
+
ImagePickerAdapter,
|
|
9
|
+
MenuAction,
|
|
10
|
+
MenuAdapter,
|
|
11
|
+
MenuViewProps,
|
|
12
|
+
VideoAdapter,
|
|
13
|
+
} from '../../../../utils/native_adapters'
|
|
14
|
+
import { FilterDropdownListHeaderComponent } from '../filter_dropdown_list_header_component'
|
|
15
|
+
|
|
16
|
+
const mockNavigate = jest.fn()
|
|
17
|
+
const mockSetParams = jest.fn()
|
|
18
|
+
const mockRouteParams: Record<string, unknown> = {}
|
|
19
|
+
const mockCanDisplayGroups = jest.fn()
|
|
20
|
+
const mockSearchEnabled = jest.fn()
|
|
21
|
+
const mockCanBrowseArchived = jest.fn()
|
|
22
|
+
const mockGroupsByGraphId: Record<string, { name: string }> = {}
|
|
23
|
+
|
|
24
|
+
jest.mock('@react-navigation/native', () => ({
|
|
25
|
+
...jest.requireActual('@react-navigation/native'),
|
|
26
|
+
useNavigation: () => ({ setParams: mockSetParams, navigate: mockNavigate }),
|
|
27
|
+
useRoute: () => ({ params: mockRouteParams }),
|
|
28
|
+
}))
|
|
29
|
+
|
|
30
|
+
jest.mock('../../../../hooks/use_api', () => ({
|
|
31
|
+
useApiGet: ({ url }: { url: string }, { enabled }: { enabled: boolean }) => ({
|
|
32
|
+
data: enabled ? mockGroupsByGraphId[url.replace('/me/groups/', '')] : undefined,
|
|
33
|
+
}),
|
|
34
|
+
}))
|
|
35
|
+
jest.mock('../../../../hooks/use_groups', () => ({
|
|
36
|
+
useCanDisplayGroups: (args: { source_type: string }) => mockCanDisplayGroups(args),
|
|
37
|
+
}))
|
|
38
|
+
jest.mock('../../../../hooks/use_direct_messages_eligible', () => ({
|
|
39
|
+
useDirectMessagesEligible: () => true,
|
|
40
|
+
}))
|
|
41
|
+
jest.mock('../../../../hooks/use_has_direct_messages', () => ({
|
|
42
|
+
useHasDirectMessages: () => true,
|
|
43
|
+
}))
|
|
44
|
+
jest.mock('../../../../hooks/use_can_browse_archived_conversations', () => ({
|
|
45
|
+
useCanBrowseArchivedConversations: () => mockCanBrowseArchived(),
|
|
46
|
+
}))
|
|
47
|
+
jest.mock('../../../../hooks/use_chat_permissions', () => ({
|
|
48
|
+
useCanCreateConversations: () => true,
|
|
49
|
+
}))
|
|
50
|
+
jest.mock('../../../../hooks/use_new_conversation_entry', () => ({
|
|
51
|
+
useNewConversationEntry: () => 'select_type',
|
|
52
|
+
}))
|
|
53
|
+
jest.mock('../../../../hooks/use_current_person', () => ({
|
|
54
|
+
useCurrentPersonCache: () => ({ update: jest.fn() }),
|
|
55
|
+
}))
|
|
56
|
+
jest.mock('../../../../hooks/use_conversations_actions', () => ({
|
|
57
|
+
useMarkAllRead: () => ({ markAllRead: jest.fn(), isPending: false }),
|
|
58
|
+
}))
|
|
59
|
+
jest.mock('../../../../hooks/use_new_conversation_from_filter', () => ({
|
|
60
|
+
useNewConversationFromFilter: () => undefined,
|
|
61
|
+
}))
|
|
62
|
+
jest.mock('../../../../hooks/use_search_enabled', () => ({
|
|
63
|
+
useSearchEnabled: () => mockSearchEnabled(),
|
|
64
|
+
}))
|
|
65
|
+
|
|
66
|
+
const FakeMenuView = ({ actions, onPressAction, children }: MenuViewProps) => {
|
|
67
|
+
const flatten = (items: MenuAction[]): MenuAction[] =>
|
|
68
|
+
items.flatMap(item => (item.displayInline && item.subactions ? item.subactions : [item]))
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<>
|
|
72
|
+
{children}
|
|
73
|
+
{flatten(actions).map(action => (
|
|
74
|
+
<Pressable
|
|
75
|
+
key={action.id}
|
|
76
|
+
accessibilityRole="menuitem"
|
|
77
|
+
accessibilityLabel={action.title}
|
|
78
|
+
accessibilityState={{ selected: action.state === 'on' }}
|
|
79
|
+
onPress={() => onPressAction?.({ nativeEvent: { event: action.id ?? action.title } })}
|
|
80
|
+
>
|
|
81
|
+
<Text>{action.title}</Text>
|
|
82
|
+
</Pressable>
|
|
83
|
+
))}
|
|
84
|
+
</>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
beforeAll(() => {
|
|
89
|
+
ChatAdapters.configure({
|
|
90
|
+
clipboard: new ClipboardAdapter({
|
|
91
|
+
getStringAsync: async () => '',
|
|
92
|
+
setStringAsync: async () => {},
|
|
93
|
+
}),
|
|
94
|
+
audio: new AudioAdapter({ useAudio: () => ({}) as any }),
|
|
95
|
+
video: new VideoAdapter({ Player: (() => null) as any }),
|
|
96
|
+
imagePicker: new ImagePickerAdapter({
|
|
97
|
+
openCameraAsync: async () => ({ canceled: true, assets: null }),
|
|
98
|
+
openImageLibraryAsync: async () => ({ canceled: true, assets: null }),
|
|
99
|
+
}),
|
|
100
|
+
menu: new MenuAdapter({ View: FakeMenuView }),
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const setCapabilities = ({ groups, teams }: { groups: boolean; teams: boolean }) => {
|
|
105
|
+
mockCanDisplayGroups.mockImplementation(({ source_type }: { source_type: string }) =>
|
|
106
|
+
source_type === 'Group' ? groups : teams
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const setRouteParams = (params: Record<string, unknown>) => {
|
|
111
|
+
Object.keys(mockRouteParams).forEach(key => delete mockRouteParams[key])
|
|
112
|
+
Object.assign(mockRouteParams, params)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const menuItemNames = () =>
|
|
116
|
+
screen.getAllByRole('menuitem').map(item => item.props.accessibilityLabel)
|
|
117
|
+
|
|
118
|
+
describe('FilterDropdownListHeaderComponent', () => {
|
|
119
|
+
beforeEach(() => {
|
|
120
|
+
mockNavigate.mockClear()
|
|
121
|
+
mockSetParams.mockClear()
|
|
122
|
+
mockSearchEnabled.mockReturnValue(true)
|
|
123
|
+
mockCanBrowseArchived.mockReturnValue(false)
|
|
124
|
+
setCapabilities({ groups: true, teams: true })
|
|
125
|
+
setRouteParams({})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
it('offers every filter the person can use, then More filters', () => {
|
|
129
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
130
|
+
|
|
131
|
+
expect(menuItemNames()).toEqual(['All', 'Groups', 'Teams', 'DMs', 'More filters'])
|
|
132
|
+
expect(screen.getByRole('button', { name: 'All conversations' })).toBeTruthy()
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('leaves out Teams and More filters when only DMs are filterable', () => {
|
|
136
|
+
setCapabilities({ groups: false, teams: false })
|
|
137
|
+
|
|
138
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
139
|
+
|
|
140
|
+
expect(menuItemNames()).toEqual(['All', 'DMs'])
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('selecting Groups filters to group conversations', () => {
|
|
144
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
145
|
+
|
|
146
|
+
fireEvent.press(screen.getByRole('menuitem', { name: 'Groups' }))
|
|
147
|
+
|
|
148
|
+
expect(mockSetParams).toHaveBeenCalledWith(
|
|
149
|
+
expect.objectContaining({ group_source_app_name: 'Groups', show_direct_messages: undefined })
|
|
150
|
+
)
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
it('labels the trigger with the active filter and checks it', () => {
|
|
154
|
+
setRouteParams({ group_source_app_name: 'Services' })
|
|
155
|
+
|
|
156
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
157
|
+
|
|
158
|
+
expect(screen.getByRole('button', { name: 'Teams' })).toBeTruthy()
|
|
159
|
+
expect(screen.getByRole('menuitem', { name: 'Teams' }).props.accessibilityState.selected).toBe(
|
|
160
|
+
true
|
|
161
|
+
)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it("labels the trigger with the group's name when filtered to one group from More filters", () => {
|
|
165
|
+
mockGroupsByGraphId['Group/1'] = { name: 'Youth Group' }
|
|
166
|
+
setRouteParams({ chat_group_graph_id: 'Group/1' })
|
|
167
|
+
|
|
168
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
169
|
+
|
|
170
|
+
expect(screen.getByRole('button', { name: 'Youth Group' })).toBeTruthy()
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('falls back to the route title while the group is still loading', () => {
|
|
174
|
+
delete mockGroupsByGraphId['Group/2']
|
|
175
|
+
setRouteParams({ chat_group_graph_id: 'Group/2', title: 'Youth Group' })
|
|
176
|
+
|
|
177
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
178
|
+
|
|
179
|
+
expect(screen.getByRole('button', { name: 'Youth Group' })).toBeTruthy()
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('offers More filters when archived conversations are the only extra filter', () => {
|
|
183
|
+
setCapabilities({ groups: false, teams: false })
|
|
184
|
+
mockCanBrowseArchived.mockReturnValue(true)
|
|
185
|
+
|
|
186
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
187
|
+
|
|
188
|
+
expect(menuItemNames()).toEqual(['All', 'DMs', 'More filters'])
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it('labels the archived list and carries it into More filters', () => {
|
|
192
|
+
setRouteParams({ show_archived: true })
|
|
193
|
+
|
|
194
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
195
|
+
|
|
196
|
+
expect(screen.getByRole('button', { name: 'Archived' })).toBeTruthy()
|
|
197
|
+
|
|
198
|
+
fireEvent.press(screen.getByRole('menuitem', { name: 'More filters' }))
|
|
199
|
+
|
|
200
|
+
expect(mockNavigate).toHaveBeenCalledWith(
|
|
201
|
+
'ConversationFilters',
|
|
202
|
+
expect.objectContaining({ show_archived: true })
|
|
203
|
+
)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
it('hides Mark all read on the archived list', () => {
|
|
207
|
+
const view = render(<FilterDropdownListHeaderComponent />)
|
|
208
|
+
|
|
209
|
+
expect(view.getByText('Mark all read')).toBeTruthy()
|
|
210
|
+
|
|
211
|
+
setRouteParams({ show_archived: true })
|
|
212
|
+
view.rerender(<FilterDropdownListHeaderComponent />)
|
|
213
|
+
|
|
214
|
+
expect(view.queryByText('Mark all read')).toBeNull()
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
it('leaves the archived list when another filter is picked', () => {
|
|
218
|
+
setRouteParams({ show_archived: true })
|
|
219
|
+
|
|
220
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
221
|
+
|
|
222
|
+
fireEvent.press(screen.getByRole('menuitem', { name: 'Groups' }))
|
|
223
|
+
|
|
224
|
+
expect(mockSetParams).toHaveBeenCalledWith(
|
|
225
|
+
expect.objectContaining({ group_source_app_name: 'Groups', show_archived: undefined })
|
|
226
|
+
)
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
it('More filters opens the filters sheet', () => {
|
|
230
|
+
render(<FilterDropdownListHeaderComponent />)
|
|
231
|
+
|
|
232
|
+
fireEvent.press(screen.getByRole('menuitem', { name: 'More filters' }))
|
|
233
|
+
|
|
234
|
+
expect(mockNavigate).toHaveBeenCalledWith('ConversationFilters', expect.any(Object))
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
it('shows the search button only when search is enabled', () => {
|
|
238
|
+
mockSearchEnabled.mockReturnValue(false)
|
|
239
|
+
const view = render(<FilterDropdownListHeaderComponent />)
|
|
240
|
+
|
|
241
|
+
expect(view.queryByTestId('conversations-search-button')).toBeNull()
|
|
242
|
+
|
|
243
|
+
mockSearchEnabled.mockReturnValue(true)
|
|
244
|
+
view.rerender(<FilterDropdownListHeaderComponent />)
|
|
245
|
+
|
|
246
|
+
fireEvent.press(view.getByTestId('conversations-search-button'))
|
|
247
|
+
|
|
248
|
+
expect(mockNavigate).toHaveBeenCalledWith('Search')
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
it('renders the search button after the other actions', () => {
|
|
252
|
+
const view = render(<FilterDropdownListHeaderComponent />)
|
|
253
|
+
|
|
254
|
+
const buttons = view.getAllByRole('button').map(button => button.props.accessibilityLabel)
|
|
255
|
+
|
|
256
|
+
expect(buttons.indexOf('Search')).toBeGreaterThan(buttons.indexOf('Chat settings'))
|
|
257
|
+
expect(buttons.indexOf('Search')).toBeGreaterThan(buttons.indexOf('New conversation'))
|
|
258
|
+
})
|
|
259
|
+
})
|