@planningcenter/chat-react-native 4.4.1-qa-1036.2 → 4.4.1-qa-staging.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/build/components/conversation/message_list.d.ts.map +1 -1
  2. package/build/components/conversation/message_list.js +155 -123
  3. package/build/components/conversation/message_list.js.map +1 -1
  4. package/build/components/conversations/conversations.d.ts.map +1 -1
  5. package/build/components/conversations/conversations.js +1 -0
  6. package/build/components/conversations/conversations.js.map +1 -1
  7. package/build/components/display/filter_dropdown.d.ts +1 -0
  8. package/build/components/display/filter_dropdown.d.ts.map +1 -1
  9. package/build/components/display/filter_dropdown.js.map +1 -1
  10. package/build/components/display/keyboard_scroll_view.d.ts.map +1 -1
  11. package/build/components/display/keyboard_scroll_view.js +1 -0
  12. package/build/components/display/keyboard_scroll_view.js.map +1 -1
  13. package/build/components/page/page_error_boundary.d.ts +9 -1
  14. package/build/components/page/page_error_boundary.d.ts.map +1 -1
  15. package/build/components/page/page_error_boundary.js +56 -31
  16. package/build/components/page/page_error_boundary.js.map +1 -1
  17. package/build/navigation/index.d.ts.map +1 -1
  18. package/build/navigation/index.js +11 -3
  19. package/build/navigation/index.js.map +1 -1
  20. package/build/navigation/page_error_fallbacks.d.ts +7 -0
  21. package/build/navigation/page_error_fallbacks.d.ts.map +1 -0
  22. package/build/navigation/page_error_fallbacks.js +7 -0
  23. package/build/navigation/page_error_fallbacks.js.map +1 -0
  24. package/build/navigation/screenLayout.d.ts.map +1 -1
  25. package/build/navigation/screenLayout.js +21 -13
  26. package/build/navigation/screenLayout.js.map +1 -1
  27. package/build/screens/age_check/age_check_required_screen.d.ts.map +1 -1
  28. package/build/screens/age_check/age_check_required_screen.js +1 -0
  29. package/build/screens/age_check/age_check_required_screen.js.map +1 -1
  30. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  31. package/build/screens/conversation_details_screen.js +1 -0
  32. package/build/screens/conversation_details_screen.js.map +1 -1
  33. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.d.ts.map +1 -1
  34. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js +1 -0
  35. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js.map +1 -1
  36. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.d.ts.map +1 -1
  37. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js +332 -291
  38. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js.map +1 -1
  39. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.d.ts.map +1 -1
  40. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js +1 -0
  41. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js.map +1 -1
  42. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.d.ts.map +1 -1
  43. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js +1 -0
  44. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js.map +1 -1
  45. package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts.map +1 -1
  46. package/build/screens/conversations/components/filter_dropdown_list_header_component.js +22 -7
  47. package/build/screens/conversations/components/filter_dropdown_list_header_component.js.map +1 -1
  48. package/build/screens/get_help_screen.js +56 -62
  49. package/build/screens/get_help_screen.js.map +1 -1
  50. package/build/screens/group_notification_settings_screen.js +3 -2
  51. package/build/screens/group_notification_settings_screen.js.map +1 -1
  52. package/build/screens/notification_settings_screen.d.ts.map +1 -1
  53. package/build/screens/notification_settings_screen.js +1 -0
  54. package/build/screens/notification_settings_screen.js.map +1 -1
  55. package/build/screens/preferred_app_selection_screen.js +45 -39
  56. package/build/screens/preferred_app_selection_screen.js.map +1 -1
  57. package/build/screens/search/components/search_results_list.d.ts +4 -1
  58. package/build/screens/search/components/search_results_list.d.ts.map +1 -1
  59. package/build/screens/search/components/search_results_list.js +136 -110
  60. package/build/screens/search/components/search_results_list.js.map +1 -1
  61. package/build/screens/search/search_screen.d.ts.map +1 -1
  62. package/build/screens/search/search_screen.js +21 -28
  63. package/build/screens/search/search_screen.js.map +1 -1
  64. package/build/screens/settings_screen.d.ts.map +1 -1
  65. package/build/screens/settings_screen.js +7 -6
  66. package/build/screens/settings_screen.js.map +1 -1
  67. package/package.json +3 -3
  68. package/src/__tests__/navigation/screen_layout.test.tsx +55 -0
  69. package/src/components/conversation/__tests__/message_list.test.tsx +4 -0
  70. package/src/components/conversation/message_list.tsx +6 -0
  71. package/src/components/conversations/conversations.tsx +1 -0
  72. package/src/components/display/filter_dropdown.tsx +1 -0
  73. package/src/components/display/keyboard_scroll_view.tsx +1 -0
  74. package/src/components/page/__tests__/page_error_boundary.test.tsx +33 -0
  75. package/src/components/page/page_error_boundary.tsx +43 -12
  76. package/src/navigation/index.tsx +11 -2
  77. package/src/navigation/page_error_fallbacks.ts +14 -0
  78. package/src/navigation/screenLayout.tsx +6 -3
  79. package/src/screens/age_check/age_check_required_screen.tsx +5 -1
  80. package/src/screens/conversation_details_screen.tsx +1 -0
  81. package/src/screens/conversation_select_recipients/__tests__/conversation_select_direct_message_recipients_screen.test.tsx +100 -0
  82. package/src/screens/conversation_select_recipients/conversation_new_entry_screen.tsx +4 -1
  83. package/src/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.tsx +78 -68
  84. package/src/screens/conversation_select_recipients/conversation_select_group_recipients_screen.tsx +1 -0
  85. package/src/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.tsx +1 -0
  86. package/src/screens/conversations/components/__tests__/filter_dropdown_list_header_component.test.tsx +59 -1
  87. package/src/screens/conversations/components/filter_dropdown_list_header_component.tsx +24 -9
  88. package/src/screens/get_help_screen.tsx +4 -4
  89. package/src/screens/group_notification_settings_screen.tsx +3 -3
  90. package/src/screens/notification_settings_screen.tsx +1 -0
  91. package/src/screens/preferred_app_selection_screen.tsx +4 -4
  92. package/src/screens/search/__tests__/search_screen.test.tsx +5 -7
  93. package/src/screens/search/components/__tests__/search_results_list.test.tsx +6 -2
  94. package/src/screens/search/components/search_results_list.tsx +34 -13
  95. package/src/screens/search/search_screen.tsx +8 -18
  96. package/src/screens/settings_screen.tsx +25 -25
@@ -1 +1 @@
1
- {"version":3,"file":"settings_screen.js","names":["PlatformPressable","useNavigation","React","useCallback","Platform","StyleSheet","View","useSafeAreaInsets","Heading","Icon","Text","VersionFooter","Switch","useDirectMessagesEligible","useTheme","useAppName","usePersonSettings","jsx","_jsx","jsxs","_jsxs","SettingsScreen","t0","$","_c","styles","useStyles","directMessagesDisabled","setDirectMessagesDisabled","isMutating","directMessagesEligible","appName","navigation","t1","navigate","handleNotificationSettings","t2","type","handleGetHelp","t3","Symbol","for","variant","children","t4","sectionHeader","style","t5","settingRow","settingRowText","value","onValueChange","enabled","t6","NavRow","label","t7","t8","sectionOuter","t9","t10","footer","t11","container","onPress","useNavRowStyles","chevron","OS","name","size","inner","accessibilityRole","colors","insets","borderColorDefaultBase","bottom","create","flex","justifyContent","paddingBottom","Math","max","paddingLeft","paddingRight","paddingTop","borderBottomWidth","borderBottomColor","flexDirection","alignItems","paddingVertical","gap","iconColorDefaultDisabled","color"],"sources":["../../src/screens/settings_screen.tsx"],"sourcesContent":["import { PlatformPressable } from '@react-navigation/elements'\nimport { StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport React, { useCallback } from 'react'\nimport { Platform, StyleSheet, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Heading, Icon, Text, VersionFooter } from '../components'\nimport { Switch } from '../components/display/switch'\nimport { useDirectMessagesEligible, useTheme } from '../hooks'\nimport { useAppName } from '../hooks/use_app_name'\nimport { usePersonSettings } from '../hooks/use_person_settings'\n\nexport type SettingsScreenProps = StaticScreenProps<{}>\n\nexport function SettingsScreen({}: SettingsScreenProps) {\n const styles = useStyles()\n const { directMessagesDisabled, setDirectMessagesDisabled, isMutating } = usePersonSettings()\n const directMessagesEligible = useDirectMessagesEligible()\n const appName = useAppName()\n const navigation = useNavigation()\n\n const handleNotificationSettings = useCallback(() => {\n navigation.navigate('NotificationSettings', {})\n }, [navigation])\n\n const handleGetHelp = useCallback(() => {\n navigation.navigate('GetHelp', { type: 'chat' })\n }, [navigation])\n\n return (\n <View style={styles.container}>\n <View style={styles.sectionOuter}>\n <View style={styles.sectionHeader}>\n <Heading variant=\"h2\">Messages</Heading>\n </View>\n {directMessagesEligible && (\n <View style={styles.settingRow}>\n <View style={styles.settingRowText}>\n <Text>Allow direct messages</Text>\n <Text variant=\"tertiary\">\n When off, you can't be added to new direct messages, and any you're already in will\n be turned off.\n </Text>\n </View>\n <Switch\n value={!directMessagesDisabled}\n onValueChange={enabled => setDirectMessagesDisabled(!enabled)}\n disabled={isMutating}\n />\n </View>\n )}\n <NavRow label=\"Notification settings\" onPress={handleNotificationSettings} />\n {appName !== 'services' && <NavRow label=\"Get help\" onPress={handleGetHelp} />}\n </View>\n <View style={styles.footer}>\n <VersionFooter />\n </View>\n </View>\n )\n}\n\ninterface NavRowProps {\n label: string\n onPress: () => void\n}\n\nfunction NavRow({ label, onPress }: NavRowProps) {\n const styles = useNavRowStyles()\n return (\n <PlatformPressable\n style={styles.container}\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n >\n <View style={styles.inner}>\n <Text>{label}</Text>\n {Platform.OS === 'ios' && (\n <Icon name=\"general.rightChevron\" size={16} style={styles.chevron} />\n )}\n </View>\n </PlatformPressable>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const insets = useSafeAreaInsets()\n return StyleSheet.create({\n container: {\n flex: 1,\n },\n footer: {\n flex: 1,\n justifyContent: 'flex-end',\n paddingBottom: Math.max(insets.bottom, 8),\n },\n sectionOuter: {\n paddingLeft: 16,\n },\n sectionHeader: {\n paddingRight: 16,\n paddingTop: 24,\n paddingBottom: 12,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultBase,\n },\n settingRow: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n paddingRight: 16,\n paddingVertical: 12,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultBase,\n },\n settingRowText: {\n flex: 1,\n gap: 8,\n },\n })\n}\n\nconst useNavRowStyles = () => {\n const { colors } = useTheme()\n return StyleSheet.create({\n container: {\n paddingLeft: 0,\n },\n inner: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingRight: 16,\n paddingVertical: 14,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultBase,\n },\n chevron: {\n color: colors.iconColorDefaultDisabled,\n },\n })\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"settings_screen.js","names":["PlatformPressable","useNavigation","React","useCallback","Platform","ScrollView","StyleSheet","View","useSafeAreaInsets","Heading","Icon","Text","VersionFooter","Switch","useDirectMessagesEligible","useTheme","useAppName","usePersonSettings","jsx","_jsx","jsxs","_jsxs","SettingsScreen","t0","$","_c","styles","useStyles","directMessagesDisabled","setDirectMessagesDisabled","isMutating","directMessagesEligible","appName","navigation","t1","navigate","handleNotificationSettings","t2","type","handleGetHelp","t3","Symbol","for","variant","children","t4","sectionHeader","style","t5","settingRow","settingRowText","value","onValueChange","enabled","t6","NavRow","label","t7","t8","sectionOuter","contentInsetAdjustmentBehavior","t9","t10","footer","t11","container","onPress","useNavRowStyles","chevron","OS","name","size","inner","accessibilityRole","colors","insets","borderColorDefaultBase","bottom","create","flex","paddingBottom","Math","max","paddingLeft","paddingRight","paddingTop","borderBottomWidth","borderBottomColor","flexDirection","alignItems","justifyContent","paddingVertical","gap","iconColorDefaultDisabled","color"],"sources":["../../src/screens/settings_screen.tsx"],"sourcesContent":["import { PlatformPressable } from '@react-navigation/elements'\nimport { StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport React, { useCallback } from 'react'\nimport { Platform, ScrollView, StyleSheet, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Heading, Icon, Text, VersionFooter } from '../components'\nimport { Switch } from '../components/display/switch'\nimport { useDirectMessagesEligible, useTheme } from '../hooks'\nimport { useAppName } from '../hooks/use_app_name'\nimport { usePersonSettings } from '../hooks/use_person_settings'\n\nexport type SettingsScreenProps = StaticScreenProps<{}>\n\nexport function SettingsScreen({}: SettingsScreenProps) {\n const styles = useStyles()\n const { directMessagesDisabled, setDirectMessagesDisabled, isMutating } = usePersonSettings()\n const directMessagesEligible = useDirectMessagesEligible()\n const appName = useAppName()\n const navigation = useNavigation()\n\n const handleNotificationSettings = useCallback(() => {\n navigation.navigate('NotificationSettings', {})\n }, [navigation])\n\n const handleGetHelp = useCallback(() => {\n navigation.navigate('GetHelp', { type: 'chat' })\n }, [navigation])\n\n return (\n <View style={styles.container}>\n <ScrollView contentInsetAdjustmentBehavior=\"automatic\">\n <View style={styles.sectionOuter}>\n <View style={styles.sectionHeader}>\n <Heading variant=\"h2\">Messages</Heading>\n </View>\n {directMessagesEligible && (\n <View style={styles.settingRow}>\n <View style={styles.settingRowText}>\n <Text>Allow direct messages</Text>\n <Text variant=\"tertiary\">\n When off, you can't be added to new direct messages, and any you're already in\n will be turned off.\n </Text>\n </View>\n <Switch\n value={!directMessagesDisabled}\n onValueChange={enabled => setDirectMessagesDisabled(!enabled)}\n disabled={isMutating}\n />\n </View>\n )}\n <NavRow label=\"Notification settings\" onPress={handleNotificationSettings} />\n {appName !== 'services' && <NavRow label=\"Get help\" onPress={handleGetHelp} />}\n </View>\n </ScrollView>\n <View style={styles.footer}>\n <VersionFooter />\n </View>\n </View>\n )\n}\n\ninterface NavRowProps {\n label: string\n onPress: () => void\n}\n\nfunction NavRow({ label, onPress }: NavRowProps) {\n const styles = useNavRowStyles()\n return (\n <PlatformPressable\n style={styles.container}\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n >\n <View style={styles.inner}>\n <Text>{label}</Text>\n {Platform.OS === 'ios' && (\n <Icon name=\"general.rightChevron\" size={16} style={styles.chevron} />\n )}\n </View>\n </PlatformPressable>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const insets = useSafeAreaInsets()\n return StyleSheet.create({\n container: {\n flex: 1,\n },\n footer: {\n paddingBottom: Math.max(insets.bottom, 8),\n },\n sectionOuter: {\n paddingLeft: 16,\n },\n sectionHeader: {\n paddingRight: 16,\n paddingTop: 24,\n paddingBottom: 12,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultBase,\n },\n settingRow: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n paddingRight: 16,\n paddingVertical: 12,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultBase,\n },\n settingRowText: {\n flex: 1,\n gap: 8,\n },\n })\n}\n\nconst useNavRowStyles = () => {\n const { colors } = useTheme()\n return StyleSheet.create({\n container: {\n paddingLeft: 0,\n },\n inner: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingRight: 16,\n paddingVertical: 14,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultBase,\n },\n chevron: {\n color: colors.iconColorDefaultDisabled,\n },\n })\n}\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "4.4.1-qa-1036.2",
3
+ "version": "4.4.1-qa-staging.41",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "@fortawesome/fontawesome-svg-core": "^7.2.0",
35
35
  "@fortawesome/react-native-fontawesome": "^0.3.2",
36
- "@planningcenter/emoji-keyboard": "4.4.1-qa-1036.2",
36
+ "@planningcenter/emoji-keyboard": "4.4.1-qa-staging.41",
37
37
  "lodash-inflection": "^1.5.0"
38
38
  },
39
39
  "peerDependencies": {
@@ -84,5 +84,5 @@
84
84
  "sf-symbols-typescript": "^2.2.0",
85
85
  "typescript": "~6.0.3"
86
86
  },
87
- "gitHead": "d60eb48469e8b60f337efc8cb83c3e9cf6666fab"
87
+ "gitHead": "382bfa092bf544d43feca8879e595cebe31446de"
88
88
  }
@@ -0,0 +1,55 @@
1
+ import { render } from '@testing-library/react-native'
2
+ import React, { useEffect } from 'react'
3
+ import { ScreenLayout } from '../../navigation/screenLayout'
4
+
5
+ jest.mock('react-native', () => {
6
+ const actual = jest.requireActual('react-native')
7
+ return Object.defineProperty(actual, 'useWindowDimensions', {
8
+ value: jest.fn(),
9
+ configurable: true,
10
+ })
11
+ })
12
+ jest.mock('@react-navigation/native', () => ({ useRoute: () => ({ name: 'Conversations' }) }))
13
+ jest.mock('react-native-safe-area-context', () => ({
14
+ useSafeAreaInsets: () => ({ top: 0, right: 0, bottom: 0, left: 0 }),
15
+ }))
16
+ jest.mock('../../components/page/page_error_boundary', () => ({
17
+ PageErrorBoundary: ({ children }: { children: React.ReactNode }) => children,
18
+ }))
19
+
20
+ const mockUseWindowDimensions = require('react-native').useWindowDimensions
21
+ const onMount = jest.fn()
22
+
23
+ function Child() {
24
+ useEffect(() => {
25
+ onMount()
26
+ }, [])
27
+ return null
28
+ }
29
+
30
+ describe('ScreenLayout', () => {
31
+ afterEach(() => jest.clearAllMocks())
32
+
33
+ test('remounts its screen when the font scale changes, and only then', () => {
34
+ mockUseWindowDimensions.mockReturnValue({ fontScale: 1 })
35
+ const screen = render(
36
+ <ScreenLayout>
37
+ <Child />
38
+ </ScreenLayout>
39
+ )
40
+ screen.rerender(
41
+ <ScreenLayout>
42
+ <Child />
43
+ </ScreenLayout>
44
+ )
45
+ expect(onMount).toHaveBeenCalledTimes(1)
46
+
47
+ mockUseWindowDimensions.mockReturnValue({ fontScale: 1.2 })
48
+ screen.rerender(
49
+ <ScreenLayout>
50
+ <Child />
51
+ </ScreenLayout>
52
+ )
53
+ expect(onMount).toHaveBeenCalledTimes(2)
54
+ })
55
+ })
@@ -27,6 +27,10 @@ import { addRecordInPagesData, deleteRecordInPagesData } from '../../../utils/ca
27
27
  import { getMessagesQueryKey } from '../../../utils/request/get_messages'
28
28
  import { MessageList } from '../message_list'
29
29
 
30
+ jest.mock('@react-navigation/elements', () => ({
31
+ ...jest.requireActual('@react-navigation/elements'),
32
+ useHeaderHeight: () => 0,
33
+ }))
30
34
  jest.mock('../../../hooks/use_api_client')
31
35
  const mockFlash = jest.fn()
32
36
  jest.mock('../../../hooks/use_animated_message_background_color', () => ({
@@ -1,4 +1,5 @@
1
1
  import { date as formatDate } from '@planningcenter/datetime-fmt'
2
+ import { useHeaderHeight } from '@react-navigation/elements'
2
3
  import { noop } from 'lodash'
3
4
  import React, { RefObject, useCallback, useEffect, useRef, useState } from 'react'
4
5
  import { FlatList, FlatListProps, StyleSheet, View } from 'react-native'
@@ -7,6 +8,7 @@ import { ConversationResource } from '../../types/resources/conversation'
7
8
  import { MessageResource } from '../../types/resources/message'
8
9
  import { getRelativeDateStatus } from '../../utils/date'
9
10
  import { groupMessages, type DateSeparator, type EnrichedMessage } from '../../utils/group_messages'
11
+ import { isLiquidGlassEnabled } from '../../utils/liquid_glass'
10
12
  import { CONVERSATION_MESSAGE_LIST_PADDING_HORIZONTAL } from '../../utils/styles'
11
13
  import { isSystemMessage } from '../../utils/system_messages'
12
14
  import { Text } from '../display'
@@ -69,6 +71,8 @@ export function MessageList({
69
71
  onMomentumScrollEnd,
70
72
  }: MessageListProps) {
71
73
  const styles = useStyles()
74
+ const headerHeight = useHeaderHeight()
75
+ const glassHeaderInset = isLiquidGlassEnabled() ? headerHeight : 0
72
76
  const inReplyScreen = !!replyRootId
73
77
  const canDeleteNonAuthoredMessages =
74
78
  conversation.memberAbility?.canDeleteNonAuthoredMessages ?? false
@@ -155,6 +159,8 @@ export function MessageList({
155
159
  inverted
156
160
  ref={listRef}
157
161
  contentContainerStyle={styles.listContainer}
162
+ contentInset={{ bottom: glassHeaderInset }}
163
+ scrollIndicatorInsets={{ bottom: glassHeaderInset }}
158
164
  data={messagesWithSeparators}
159
165
  keyExtractor={item => item.id}
160
166
  onScroll={onScroll}
@@ -79,6 +79,7 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
79
79
  data={data}
80
80
  keyExtractor={item => item.id.toString()}
81
81
  contentContainerStyle={styles.contentContainer}
82
+ contentInsetAdjustmentBehavior="automatic"
82
83
  onRefresh={refetch}
83
84
  refreshing={!isFetched && isRefetching}
84
85
  ListHeaderComponent={ListHeaderComponent}
@@ -102,6 +102,7 @@ export interface FilterDropdownTriggerProps {
102
102
  accessibilityElementsHidden?: boolean
103
103
  importantForAccessibility?: 'no-hide-descendants'
104
104
  onLayout?: (event: LayoutChangeEvent) => void
105
+ testID?: string
105
106
  }
106
107
 
107
108
  /**
@@ -43,6 +43,7 @@ export function KeyboardScrollView({ children, contentContainerStyle }: Keyboard
43
43
  <KeyboardView>
44
44
  <ScrollView
45
45
  ref={scrollViewRef}
46
+ contentInsetAdjustmentBehavior="automatic"
46
47
  contentContainerStyle={contentContainerStyle}
47
48
  onLayout={scrollFocusedInputIntoView}
48
49
  onContentSizeChange={scrollFocusedInputIntoView}
@@ -4,6 +4,7 @@ import { render } from '@testing-library/react-native'
4
4
  import React from 'react'
5
5
  import { buildTestQueryClient } from '../../../__utils__/query_client'
6
6
  import { Log } from '../../../utils/native_adapters/configuration'
7
+ import { ResponseError } from '../../../utils/response_error'
7
8
  import { PageErrorBoundary } from '../page_error_boundary'
8
9
 
9
10
  jest.mock('../../primitive/blank_state_primitive', () => {
@@ -74,4 +75,36 @@ describe('PageErrorBoundary', () => {
74
75
  expect(getByText('Oops!')).toBeTruthy()
75
76
  expect(getByText('Something unexpected happened.')).toBeTruthy()
76
77
  })
78
+
79
+ describe('with a generic fallback override', () => {
80
+ const genericFallback = { heading: 'Nothing here', body: 'Come back later.' }
81
+ const responseError = (status: number) =>
82
+ new ResponseError({ status, statusText: 'x', errors: [] } as never)
83
+
84
+ it.each([
85
+ ['a plain error', new Error('boom')],
86
+ ['an unhandled status', responseError(500)],
87
+ ])('replaces the Oops copy for %s', (_label, thrown) => {
88
+ const { getByText, queryByText } = renderWithProviders(
89
+ <PageErrorBoundary genericFallback={genericFallback}>
90
+ <Boom thrown={thrown} />
91
+ </PageErrorBoundary>
92
+ )
93
+
94
+ expect(getByText('Nothing here')).toBeTruthy()
95
+ expect(getByText('Come back later.')).toBeTruthy()
96
+ expect(queryByText('Oops!')).toBeNull()
97
+ })
98
+
99
+ it('leaves a known status alone', () => {
100
+ const { getByText, queryByText } = renderWithProviders(
101
+ <PageErrorBoundary genericFallback={genericFallback}>
102
+ <Boom thrown={responseError(403)} />
103
+ </PageErrorBoundary>
104
+ )
105
+
106
+ expect(getByText('Permission required')).toBeTruthy()
107
+ expect(queryByText('Nothing here')).toBeNull()
108
+ })
109
+ })
77
110
  })
@@ -6,11 +6,26 @@ import { ResponseError } from '../../utils/response_error'
6
6
  import BlankState from '../primitive/blank_state_primitive'
7
7
  import { ErrorBoundary, ErrorBoundaryFallback, ErrorBoundaryProps } from './error_boundary'
8
8
 
9
- const renderPageFallback: ErrorBoundaryFallback = (error, reset) => (
10
- <ErrorView error={error} reset={reset} />
11
- )
9
+ export type PageErrorFallback = { heading: string; body: string }
10
+
11
+ const GENERIC_FALLBACK: PageErrorFallback = {
12
+ heading: 'Oops!',
13
+ body: 'Something unexpected happened.',
14
+ }
15
+
16
+ type PageErrorBoundaryProps = PropsWithChildren<
17
+ ErrorBoundaryProps & { genericFallback?: PageErrorFallback }
18
+ >
19
+
20
+ export function PageErrorBoundary({
21
+ children,
22
+ genericFallback = GENERIC_FALLBACK,
23
+ ...props
24
+ }: PageErrorBoundaryProps) {
25
+ const renderPageFallback: ErrorBoundaryFallback = (error, reset) => (
26
+ <ErrorView error={error} reset={reset} generic={genericFallback} />
27
+ )
12
28
 
13
- export function PageErrorBoundary({ children, ...props }: PropsWithChildren<ErrorBoundaryProps>) {
14
29
  return (
15
30
  <ErrorBoundary scope="screen" fallback={renderPageFallback} {...props}>
16
31
  {children}
@@ -18,7 +33,15 @@ export function PageErrorBoundary({ children, ...props }: PropsWithChildren<Erro
18
33
  )
19
34
  }
20
35
 
21
- function ErrorView({ error, reset }: { error: Error; reset: () => void }) {
36
+ function ErrorView({
37
+ error,
38
+ reset,
39
+ generic,
40
+ }: {
41
+ error: Error
42
+ reset: () => void
43
+ generic: PageErrorFallback
44
+ }) {
22
45
  const { reset: resetQueries } = useQueryErrorResetBoundary()
23
46
 
24
47
  const handleReset = useCallback(() => {
@@ -29,7 +52,7 @@ function ErrorView({ error, reset }: { error: Error; reset: () => void }) {
29
52
  useEffect(() => handleReset, [handleReset])
30
53
 
31
54
  if (error instanceof ResponseError) {
32
- return <ResponseErrorView response={error.response} onReset={handleReset} />
55
+ return <ResponseErrorView response={error.response} onReset={handleReset} generic={generic} />
33
56
  }
34
57
 
35
58
  if (isNetworkError(error)) {
@@ -41,7 +64,7 @@ function ErrorView({ error, reset }: { error: Error; reset: () => void }) {
41
64
  )
42
65
  }
43
66
 
44
- return <ErrorContent heading={'Oops!'} body={'Something unexpected happened.'} />
67
+ return <ErrorContent heading={generic.heading} body={generic.body} />
45
68
  }
46
69
 
47
70
  function isNetworkError(error: Error) {
@@ -54,7 +77,15 @@ function isNetworkError(error: Error) {
54
77
  return new RegExp(networkFailedMessages.join('|'), 'i').test(error.message)
55
78
  }
56
79
 
57
- function ResponseErrorView({ response, onReset }: { response: Response; onReset: () => void }) {
80
+ function ResponseErrorView({
81
+ response,
82
+ onReset,
83
+ generic,
84
+ }: {
85
+ response: Response
86
+ onReset: () => void
87
+ generic: PageErrorFallback
88
+ }) {
58
89
  const { status } = response
59
90
 
60
91
  const heading = useMemo(() => {
@@ -64,9 +95,9 @@ function ResponseErrorView({ response, onReset }: { response: Response; onReset:
64
95
  case 404:
65
96
  return 'Content not found'
66
97
  default:
67
- return 'Oops!'
98
+ return generic.heading
68
99
  }
69
- }, [status])
100
+ }, [status, generic.heading])
70
101
 
71
102
  const body = useMemo(() => {
72
103
  switch (status) {
@@ -75,9 +106,9 @@ function ResponseErrorView({ response, onReset }: { response: Response; onReset:
75
106
  case 404:
76
107
  return 'If you believe something should be here, please reach out to your administrator.'
77
108
  default:
78
- return 'Something unexpected happened.'
109
+ return generic.body
79
110
  }
80
- }, [status])
111
+ }, [status, generic.body])
81
112
 
82
113
  useEffect(() => {
83
114
  if (status !== 401) return
@@ -83,9 +83,12 @@ import { TeamConversationScreen } from '../screens/team_conversation_screen'
83
83
  import { isLiquidGlassEnabled } from '../utils/liquid_glass'
84
84
  import { ScreenLayoutWithChatAccessGate } from './screenLayout'
85
85
 
86
+ const conversationGlassHeader = (): NativeStackNavigationOptions =>
87
+ isLiquidGlassEnabled() ? { headerBlurEffect: 'systemChromeMaterial' } : {}
88
+
86
89
  const globalScreenOptions: () => NativeStackNavigationOptions = () => ({
87
90
  headerBackButtonDisplayMode: 'minimal',
88
- ...(isLiquidGlassEnabled() ? { headerShadowVisible: false } : {}),
91
+ ...(isLiquidGlassEnabled() ? { headerShadowVisible: false, headerTransparent: true } : {}),
89
92
  })
90
93
 
91
94
  export const NewConversationStack = createNativeStackNavigator({
@@ -151,6 +154,7 @@ export const NewConversationStack = createNativeStackNavigator({
151
154
  {
152
155
  title: 'New conversation',
153
156
  headerLeft: () => null,
157
+ headerTransparent: false,
154
158
  },
155
159
  withRightClose({
156
160
  onPress: () => {
@@ -196,6 +200,7 @@ export const ChatStack = createNativeStackNavigator({
196
200
  options: ({ route, navigation }) =>
197
201
  composeOptions(
198
202
  {
203
+ ...conversationGlassHeader(),
199
204
  headerTitle: (props: NativeStackHeaderRightProps) => {
200
205
  const { conversation_id, title, badge, deleted, muted } =
201
206
  route.params as ConversationRouteProps
@@ -232,7 +237,10 @@ export const ChatStack = createNativeStackNavigator({
232
237
  screen: ConversationScreen,
233
238
  options: ({ route, navigation }) =>
234
239
  composeOptions(
235
- { title: (route.params as ConversationRouteProps)?.title ?? 'Reply' },
240
+ {
241
+ ...conversationGlassHeader(),
242
+ title: (route.params as ConversationRouteProps)?.title ?? 'Reply',
243
+ },
236
244
  withMinimalBack({ onPress: navigation.goBack })
237
245
  ),
238
246
  },
@@ -325,6 +333,7 @@ export const ChatStack = createNativeStackNavigator({
325
333
  {
326
334
  title: 'New conversation',
327
335
  headerLeft: () => null,
336
+ headerTransparent: false,
328
337
  },
329
338
  withRightClose({ onPress: () => navigation.getParent()?.goBack() })
330
339
  ),
@@ -0,0 +1,14 @@
1
+ import type { StaticParamList } from '@react-navigation/native'
2
+ import type { PageErrorFallback } from '../components/page/page_error_boundary'
3
+ import type { NewConversationStack } from './index'
4
+
5
+ type RouteName =
6
+ | keyof ReactNavigation.RootParamList
7
+ | keyof StaticParamList<typeof NewConversationStack>
8
+
9
+ export const PAGE_ERROR_FALLBACKS: Partial<Record<RouteName, PageErrorFallback>> = {
10
+ ConversationSelectDirectMessageRecipients: {
11
+ heading: "Couldn't load people right now",
12
+ body: 'Try again.',
13
+ },
14
+ }
@@ -1,19 +1,22 @@
1
1
  import { useRoute } from '@react-navigation/native'
2
2
  import React from 'react'
3
3
  import { Suspense } from 'react'
4
- import { StyleSheet, View } from 'react-native'
4
+ import { StyleSheet, useWindowDimensions, View } from 'react-native'
5
5
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
6
6
  import { DefaultLoading } from '../components/page/loading'
7
7
  import { PageErrorBoundary } from '../components/page/page_error_boundary'
8
8
  import { ChatAccessGate } from './chat_access_gate'
9
+ import { PAGE_ERROR_FALLBACKS } from './page_error_fallbacks'
9
10
 
10
11
  export function ScreenLayout({ children }: { children: React.ReactElement }) {
11
12
  const route = useRoute()
13
+ const genericFallback = PAGE_ERROR_FALLBACKS[route.name as keyof typeof PAGE_ERROR_FALLBACKS]
12
14
  const styles = useStyles()
15
+ const { fontScale } = useWindowDimensions()
13
16
 
14
17
  return (
15
- <PageErrorBoundary screenName={route.name}>
16
- <View style={styles.screen}>
18
+ <PageErrorBoundary screenName={route.name} genericFallback={genericFallback}>
19
+ <View key={fontScale} style={styles.screen}>
17
20
  <Suspense fallback={<DefaultLoading />}>{children}</Suspense>
18
21
  </View>
19
22
  </PageErrorBoundary>
@@ -58,7 +58,11 @@ export function AgeCheckRequiredScreen() {
58
58
 
59
59
  return (
60
60
  <>
61
- <ScrollView style={styles.scrollView} contentContainerStyle={styles.container}>
61
+ <ScrollView
62
+ contentInsetAdjustmentBehavior="automatic"
63
+ style={styles.scrollView}
64
+ contentContainerStyle={styles.container}
65
+ >
62
66
  <View style={styles.header}>
63
67
  <View style={styles.heading}>
64
68
  <Icon name="general.exclamationTriangle" size={20} style={styles.warningIcon} />
@@ -427,6 +427,7 @@ export function ConversationDetailsScreen({ route }: ConversationDetailsScreenPr
427
427
  return (
428
428
  <View style={styles.listContainer}>
429
429
  <FlatList
430
+ contentInsetAdjustmentBehavior="automatic"
430
431
  data={listData as SectionListData}
431
432
  contentContainerStyle={styles.contentContainer}
432
433
  renderItem={({ item, index }) => {
@@ -0,0 +1,100 @@
1
+ import { fireEvent, render } from '@testing-library/react-native'
2
+ import React from 'react'
3
+ import { SafeAreaProvider } from 'react-native-safe-area-context'
4
+ import { ScreenLayout } from '../../../navigation/screenLayout'
5
+ import { Log } from '../../../utils/native_adapters/configuration'
6
+ import { ResponseError } from '../../../utils/response_error'
7
+ import { ConversationSelectDirectMessageRecipientsScreen } from '../conversation_select_direct_message_recipients_screen'
8
+
9
+ jest.mock('@react-navigation/native', () => ({
10
+ ...jest.requireActual('@react-navigation/native'),
11
+ useNavigation: () => ({ getParent: jest.fn(), goBack: jest.fn(), navigate: jest.fn() }),
12
+ useRoute: () => ({ name: 'ConversationSelectDirectMessageRecipients' }),
13
+ }))
14
+ jest.mock('../../../hooks/use_features', () => ({
15
+ ...jest.requireActual('../../../hooks/use_features'),
16
+ useFeatures: () => ({ featureEnabled: () => false }),
17
+ }))
18
+ jest.mock('../../../hooks/use_debounced_search_term', () => ({
19
+ useDebouncedSearchTerm: (term: string) => term,
20
+ }))
21
+ jest.mock('../../../hooks/direct_messages/use_direct_message_conversation_validate', () => ({
22
+ useDirectMessageConversationValidate: () => ({ warnings: [], validationPending: false }),
23
+ }))
24
+ jest.mock('../../../hooks/direct_messages/use_find_or_create_direct_message_conversation', () => ({
25
+ useFindOrCreateDirectMessageConversation: () => ({
26
+ findOrCreateConversation: jest.fn(),
27
+ directMessageExists: false,
28
+ isFinding: false,
29
+ isError: false,
30
+ }),
31
+ }))
32
+ jest.mock('../../../hooks/direct_messages/use_direct_message_affiliations', () => ({
33
+ useDirectMessageAffiliations: () => ({
34
+ groups: new Map(),
35
+ teams: new Map(),
36
+ resultsDescription: null,
37
+ }),
38
+ }))
39
+ let mockSearchFailure: Error = new TypeError('Network request failed')
40
+ jest.mock('../../../hooks/direct_messages/use_direct_message_candidates', () => ({
41
+ useDirectMessageCandidates: (term: string) => {
42
+ if (term) throw mockSearchFailure
43
+ return { data: undefined, isFetching: false }
44
+ },
45
+ }))
46
+ jest.mock('../../../components/display/action_button', () => ({ ActionButton: () => null }))
47
+ jest.mock('../../../components/display/keyboard_view', () => ({
48
+ ...jest.requireActual('../../../components/display/keyboard_view'),
49
+ KeyboardView: ({ children }: { children: React.ReactNode }) => children,
50
+ }))
51
+
52
+ const renderScreen = () =>
53
+ render(
54
+ <SafeAreaProvider
55
+ initialMetrics={{
56
+ frame: { x: 0, y: 0, width: 390, height: 844 },
57
+ insets: { top: 0, left: 0, right: 0, bottom: 0 },
58
+ }}
59
+ >
60
+ <ScreenLayout>
61
+ <ConversationSelectDirectMessageRecipientsScreen route={{ params: {} } as never} />
62
+ </ScreenLayout>
63
+ </SafeAreaProvider>
64
+ )
65
+
66
+ describe('ConversationSelectDirectMessageRecipientsScreen', () => {
67
+ let reportError: jest.SpyInstance
68
+ let consoleError: jest.SpyInstance
69
+
70
+ beforeEach(() => {
71
+ reportError = jest.spyOn(Log, 'reportError').mockImplementation(() => {})
72
+ consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
73
+ })
74
+
75
+ afterEach(() => {
76
+ reportError.mockRestore()
77
+ consoleError.mockRestore()
78
+ })
79
+
80
+ it('hands a failed search to the page error view', () => {
81
+ mockSearchFailure = new TypeError('Network request failed')
82
+ const view = renderScreen()
83
+
84
+ fireEvent.changeText(view.getByPlaceholderText('Search'), 'pi')
85
+
86
+ expect(view.getByText('Problem connecting!')).toBeTruthy()
87
+ expect(view.queryByPlaceholderText('Search')).toBeNull()
88
+ expect(reportError).toHaveBeenCalledTimes(1)
89
+ })
90
+
91
+ it("uses the screen's own wording when the search fails for no known reason", () => {
92
+ mockSearchFailure = new ResponseError({ status: 500, statusText: 'x', errors: [] } as never)
93
+ const view = renderScreen()
94
+
95
+ fireEvent.changeText(view.getByPlaceholderText('Search'), 'pi')
96
+
97
+ expect(view.getByText("Couldn't load people right now")).toBeTruthy()
98
+ expect(view.queryByText('Oops!')).toBeNull()
99
+ })
100
+ })
@@ -59,7 +59,10 @@ export const ConversationNewEntryScreen = ({ route }: ConversationSelectRecipien
59
59
  }
60
60
 
61
61
  return (
62
- <ScrollView contentContainerStyle={styles.contentContainer}>
62
+ <ScrollView
63
+ contentInsetAdjustmentBehavior="automatic"
64
+ contentContainerStyle={styles.contentContainer}
65
+ >
63
66
  <View style={styles.header}>
64
67
  <Heading variant="h2">Start a conversation by</Heading>
65
68
  </View>