@planningcenter/chat-react-native 4.4.1-qa-staging.32 → 4.4.1-qa-1036.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/build/components/conversation/message_list.d.ts.map +1 -1
  2. package/build/components/conversation/message_list.js +123 -155
  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 +0 -1
  6. package/build/components/conversations/conversations.js.map +1 -1
  7. package/build/components/display/keyboard_scroll_view.d.ts.map +1 -1
  8. package/build/components/display/keyboard_scroll_view.js +0 -1
  9. package/build/components/display/keyboard_scroll_view.js.map +1 -1
  10. package/build/components/page/page_error_boundary.d.ts +1 -9
  11. package/build/components/page/page_error_boundary.d.ts.map +1 -1
  12. package/build/components/page/page_error_boundary.js +31 -56
  13. package/build/components/page/page_error_boundary.js.map +1 -1
  14. package/build/navigation/index.d.ts.map +1 -1
  15. package/build/navigation/index.js +3 -11
  16. package/build/navigation/index.js.map +1 -1
  17. package/build/navigation/screenLayout.d.ts.map +1 -1
  18. package/build/navigation/screenLayout.js +6 -10
  19. package/build/navigation/screenLayout.js.map +1 -1
  20. package/build/screens/age_check/age_check_required_screen.d.ts.map +1 -1
  21. package/build/screens/age_check/age_check_required_screen.js +0 -1
  22. package/build/screens/age_check/age_check_required_screen.js.map +1 -1
  23. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  24. package/build/screens/conversation_details_screen.js +0 -1
  25. package/build/screens/conversation_details_screen.js.map +1 -1
  26. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.d.ts.map +1 -1
  27. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js +0 -1
  28. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js.map +1 -1
  29. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.d.ts.map +1 -1
  30. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js +291 -332
  31. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js.map +1 -1
  32. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.d.ts.map +1 -1
  33. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js +0 -1
  34. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js.map +1 -1
  35. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.d.ts.map +1 -1
  36. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js +0 -1
  37. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js.map +1 -1
  38. package/build/screens/get_help_screen.js +62 -56
  39. package/build/screens/get_help_screen.js.map +1 -1
  40. package/build/screens/group_notification_settings_screen.js +2 -3
  41. package/build/screens/group_notification_settings_screen.js.map +1 -1
  42. package/build/screens/notification_settings_screen.d.ts.map +1 -1
  43. package/build/screens/notification_settings_screen.js +0 -1
  44. package/build/screens/notification_settings_screen.js.map +1 -1
  45. package/build/screens/preferred_app_selection_screen.js +39 -45
  46. package/build/screens/preferred_app_selection_screen.js.map +1 -1
  47. package/build/screens/search/components/search_results_list.d.ts +1 -4
  48. package/build/screens/search/components/search_results_list.d.ts.map +1 -1
  49. package/build/screens/search/components/search_results_list.js +110 -136
  50. package/build/screens/search/components/search_results_list.js.map +1 -1
  51. package/build/screens/search/search_screen.d.ts.map +1 -1
  52. package/build/screens/search/search_screen.js +28 -21
  53. package/build/screens/search/search_screen.js.map +1 -1
  54. package/build/screens/settings_screen.d.ts.map +1 -1
  55. package/build/screens/settings_screen.js +6 -7
  56. package/build/screens/settings_screen.js.map +1 -1
  57. package/package.json +3 -3
  58. package/src/components/conversation/__tests__/message_list.test.tsx +0 -4
  59. package/src/components/conversation/message_list.tsx +0 -6
  60. package/src/components/conversations/conversations.tsx +0 -1
  61. package/src/components/display/keyboard_scroll_view.tsx +0 -1
  62. package/src/components/page/__tests__/page_error_boundary.test.tsx +0 -33
  63. package/src/components/page/page_error_boundary.tsx +12 -43
  64. package/src/navigation/index.tsx +2 -11
  65. package/src/navigation/screenLayout.tsx +1 -3
  66. package/src/screens/age_check/age_check_required_screen.tsx +1 -5
  67. package/src/screens/conversation_details_screen.tsx +0 -1
  68. package/src/screens/conversation_select_recipients/conversation_new_entry_screen.tsx +1 -4
  69. package/src/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.tsx +68 -78
  70. package/src/screens/conversation_select_recipients/conversation_select_group_recipients_screen.tsx +0 -1
  71. package/src/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.tsx +0 -1
  72. package/src/screens/get_help_screen.tsx +4 -4
  73. package/src/screens/group_notification_settings_screen.tsx +3 -3
  74. package/src/screens/notification_settings_screen.tsx +0 -1
  75. package/src/screens/preferred_app_selection_screen.tsx +4 -4
  76. package/src/screens/search/__tests__/search_screen.test.tsx +7 -5
  77. package/src/screens/search/components/__tests__/search_results_list.test.tsx +2 -6
  78. package/src/screens/search/components/search_results_list.tsx +13 -34
  79. package/src/screens/search/search_screen.tsx +18 -8
  80. package/src/screens/settings_screen.tsx +25 -25
  81. package/build/navigation/page_error_fallbacks.d.ts +0 -7
  82. package/build/navigation/page_error_fallbacks.d.ts.map +0 -1
  83. package/build/navigation/page_error_fallbacks.js +0 -7
  84. package/build/navigation/page_error_fallbacks.js.map +0 -1
  85. package/src/navigation/page_error_fallbacks.ts +0 -14
  86. package/src/screens/conversation_select_recipients/__tests__/conversation_select_direct_message_recipients_screen.test.tsx +0 -100
@@ -32,7 +32,6 @@ export const ConversationSelectTeamsILeadRecipientsScreen = ({
32
32
 
33
33
  return (
34
34
  <FlatList
35
- contentInsetAdjustmentBehavior="automatic"
36
35
  data={serviceTypes}
37
36
  keyExtractor={item => item.id.toString()}
38
37
  contentContainerStyle={styles.contentContainer}
@@ -1,6 +1,6 @@
1
1
  import { StaticScreenProps, useNavigation } from '@react-navigation/native'
2
2
  import { useCallback, useMemo } from 'react'
3
- import { Alert, Linking, ScrollView, StyleSheet, View } from 'react-native'
3
+ import { Alert, Linking, StyleSheet, View } from 'react-native'
4
4
  import { Heading, PressableRow, Text, TextInlineButton } from '../components'
5
5
  import { useApiGet, useTheme } from '../hooks'
6
6
  import { useAppName } from '../hooks/use_app_name'
@@ -56,7 +56,7 @@ export const GetHelpScreen = ({ route }: GetHelpScreenProps) => {
56
56
  }, [navigation])
57
57
 
58
58
  return (
59
- <ScrollView contentInsetAdjustmentBehavior="automatic" contentContainerStyle={styles.container}>
59
+ <View style={[styles.container]}>
60
60
  {appSpecificHelpUrls.length > 0 && (
61
61
  <Heading variant="h2" style={[styles.heading, styles.headingBottomBorder]}>
62
62
  How-to articles
@@ -90,7 +90,7 @@ export const GetHelpScreen = ({ route }: GetHelpScreenProps) => {
90
90
  to the development team.
91
91
  </Text>
92
92
  </View>
93
- </ScrollView>
93
+ </View>
94
94
  )
95
95
  }
96
96
 
@@ -145,7 +145,7 @@ const useStyles = () => {
145
145
 
146
146
  return StyleSheet.create({
147
147
  container: {
148
- flexGrow: 1,
148
+ flex: 1,
149
149
  },
150
150
  text: {
151
151
  paddingVertical: 4,
@@ -2,7 +2,7 @@ import { PlatformPressable } from '@react-navigation/elements'
2
2
  import { StaticScreenProps, useNavigation } from '@react-navigation/native'
3
3
  import type { NativeStackNavigationProp } from '@react-navigation/native-stack'
4
4
  import React, { useEffect } from 'react'
5
- import { Platform, ScrollView, StyleSheet, View } from 'react-native'
5
+ import { Platform, StyleSheet, View } from 'react-native'
6
6
  import { Heading, Icon, Text } from '../components'
7
7
  import { useTheme } from '../hooks'
8
8
  import { platformFontWeightBold } from '../utils/styles'
@@ -38,7 +38,7 @@ export function GroupNotificationSettingsScreen({ route }: GroupNotificationSett
38
38
  }
39
39
 
40
40
  return (
41
- <ScrollView contentInsetAdjustmentBehavior="automatic" style={styles.container}>
41
+ <View style={styles.container}>
42
42
  <View style={styles.sectionOuter}>
43
43
  <View style={styles.sectionInner}>
44
44
  <Heading variant="h2" style={styles.sectionHeading}>
@@ -76,7 +76,7 @@ export function GroupNotificationSettingsScreen({ route }: GroupNotificationSett
76
76
  )}
77
77
  </View>
78
78
  </PlatformPressable>
79
- </ScrollView>
79
+ </View>
80
80
  )
81
81
  }
82
82
 
@@ -123,7 +123,6 @@ export function NotificationSettingsScreen({}: NotificationSettingsScreenProps)
123
123
  return (
124
124
  <View style={styles.listContainer}>
125
125
  <FlatList
126
- contentInsetAdjustmentBehavior="automatic"
127
126
  data={listData as SectionListData}
128
127
  contentContainerStyle={styles.contentContainer}
129
128
  renderItem={({ item, index }) => {
@@ -2,7 +2,7 @@ import { PlatformPressable } from '@react-navigation/elements'
2
2
  import { StaticScreenProps } from '@react-navigation/native'
3
3
  import { useMutation } from '@tanstack/react-query'
4
4
  import React, { type PropsWithChildren } from 'react'
5
- import { Image, ScrollView, StyleSheet, View, type ViewStyle } from 'react-native'
5
+ import { Image, StyleSheet, View, type ViewStyle } from 'react-native'
6
6
  import { Heading, Icon, Text } from '../components'
7
7
  import { useApiClient, useTheme } from '../hooks'
8
8
  import { useAppName } from '../hooks/use_app_name'
@@ -45,7 +45,7 @@ export function PreferredAppSelectionScreen({ route }: PreferredAppSelectionScre
45
45
  const sectionTitle = chatType ? chatTypeLabel(chatType.title) : undefined
46
46
 
47
47
  return (
48
- <ScrollView contentInsetAdjustmentBehavior="automatic" contentContainerStyle={styles.container}>
48
+ <View style={styles.container}>
49
49
  <View style={styles.section}>
50
50
  <Heading variant="h2" style={styles.sectionHeading}>
51
51
  {sectionTitle}
@@ -64,7 +64,7 @@ export function PreferredAppSelectionScreen({ route }: PreferredAppSelectionScre
64
64
  </PressableRow>
65
65
  ))}
66
66
  </View>
67
- </ScrollView>
67
+ </View>
68
68
  )
69
69
  }
70
70
 
@@ -118,7 +118,7 @@ const PressableRow = ({
118
118
 
119
119
  const styles = StyleSheet.create({
120
120
  container: {
121
- flexGrow: 1,
121
+ flex: 1,
122
122
  },
123
123
  section: {
124
124
  paddingTop: 24,
@@ -106,13 +106,12 @@ describe('SearchScreen', () => {
106
106
  fireEvent.changeText(input, ' budget ')
107
107
 
108
108
  expect(view.getByText('Search chat')).toBeTruthy()
109
- const searchedTerms = () =>
110
- new Set(mockUseSearchResults.mock.calls.map(([term]) => term).filter(term => term.trim()))
111
- expect([...searchedTerms()]).toEqual([])
109
+ expect(mockUseSearchResults).not.toHaveBeenCalled()
112
110
 
113
111
  act(() => jest.advanceTimersByTime(200))
114
112
 
115
- expect([...searchedTerms()]).toEqual(['budget'])
113
+ const searchedTerms = new Set(mockUseSearchResults.mock.calls.map(([term]) => term))
114
+ expect([...searchedTerms]).toEqual(['budget'])
116
115
  expect(view.queryByText('Search chat')).toBeNull()
117
116
  expect(view.getByLabelText('Loading results')).toBeTruthy()
118
117
  })
@@ -122,7 +121,10 @@ describe('SearchScreen', () => {
122
121
 
123
122
  const scrollView = view.UNSAFE_getByType(ScrollView)
124
123
  expect(scrollView.props.keyboardShouldPersistTaps).toBe('handled')
125
- expect(scrollView.props.contentContainerStyle).toMatchObject({ flexGrow: 1 })
124
+ expect(scrollView.props.contentContainerStyle).toMatchObject({
125
+ flexGrow: 1,
126
+ justifyContent: 'center',
127
+ })
126
128
  expect(view.getByText('Search chat')).toBeTruthy()
127
129
  })
128
130
 
@@ -49,13 +49,9 @@ const messageResult = (id: string): MessageSearchResultResource => ({
49
49
  },
50
50
  })
51
51
 
52
- const slots = { header: <></>, prompt: <></> }
53
-
54
52
  const renderList = (state: Partial<SearchState>, onSettled = jest.fn()) => {
55
53
  mockUseSearchResults.mockReturnValue(searchState(state))
56
- const list = () => (
57
- <SearchResultsList term="potluck" onSelect={jest.fn()} onSettled={onSettled} {...slots} />
58
- )
54
+ const list = () => <SearchResultsList term="potluck" onSelect={jest.fn()} onSettled={onSettled} />
59
55
  const view = render(list())
60
56
  const rerenderWith = (next: Partial<SearchState>) => {
61
57
  mockUseSearchResults.mockReturnValue(searchState(next))
@@ -134,7 +130,7 @@ describe('SearchResultsList', () => {
134
130
  const results = [conversationResult('1'), messageResult('1'), messageResult('2')]
135
131
  mockUseSearchResults.mockReturnValue(searchState({ results }))
136
132
  const view = render(
137
- <SearchResultsList term="potluck" onSelect={onSelect} onSettled={jest.fn()} {...slots} />
133
+ <SearchResultsList term="potluck" onSelect={onSelect} onSettled={jest.fn()} />
138
134
  )
139
135
 
140
136
  fireEvent.press(view.getByLabelText(/^Message 2/))
@@ -1,4 +1,4 @@
1
- import React, { ReactElement, useEffect, useRef } from 'react'
1
+ import React, { useEffect, useRef } from 'react'
2
2
  import { FlatList, StyleSheet, View } from 'react-native'
3
3
  import { Banner, Spinner, Text, TextButton } from '../../../components'
4
4
  import { useSearchResults } from '../../../hooks/use_search_results'
@@ -23,17 +23,9 @@ interface SearchResultsListProps {
23
23
  term: string
24
24
  onSelect: (result: SearchResultResource, position: number) => void
25
25
  onSettled: (term: string, counts: SearchResultCounts) => void
26
- header: ReactElement
27
- prompt: ReactElement
28
26
  }
29
27
 
30
- export function SearchResultsList({
31
- term,
32
- onSelect,
33
- onSettled,
34
- header,
35
- prompt,
36
- }: SearchResultsListProps) {
28
+ export function SearchResultsList({ term, onSelect, onSettled }: SearchResultsListProps) {
37
29
  const {
38
30
  results,
39
31
  failedTypes,
@@ -44,10 +36,9 @@ export function SearchResultsList({
44
36
  hasNextPage,
45
37
  isFetchingNextPage,
46
38
  } = useSearchResults(term)
47
- const searching = term.trim().length > 0
48
- const conversationResults = searching ? results.filter(isConversationResult) : []
49
- const messageResults = searching ? results.filter(isMessageResult) : []
50
- const settled = searching && !isPending && !isError
39
+ const conversationResults = results.filter(isConversationResult)
40
+ const messageResults = results.filter(isMessageResult)
41
+ const settled = !isPending && !isError
51
42
 
52
43
  const settledTermRef = useRef<string | undefined>(undefined)
53
44
 
@@ -65,7 +56,6 @@ export function SearchResultsList({
65
56
  <FlatList
66
57
  data={messageResults}
67
58
  keyExtractor={item => item.id}
68
- contentInsetAdjustmentBehavior="automatic"
69
59
  keyboardShouldPersistTaps="handled"
70
60
  keyboardDismissMode="on-drag"
71
61
  contentContainerStyle={styles.content}
@@ -74,27 +64,20 @@ export function SearchResultsList({
74
64
  )}
75
65
  ListHeaderComponent={
76
66
  <>
77
- {header}
78
67
  {conversationResults.length > 0 && (
79
68
  <ConversationResults results={conversationResults} onSelect={onSelect} />
80
69
  )}
81
- {searching && failedTypes.includes('conversation') && (
82
- <SectionFailure type="conversation" />
83
- )}
70
+ {failedTypes.includes('conversation') && <SectionFailure type="conversation" />}
84
71
  {messageResults.length > 0 && <ResultsSection title="Messages" />}
85
72
  </>
86
73
  }
87
74
  ListEmptyComponent={
88
- searching ? (
89
- <ListEmpty
90
- term={term}
91
- isError={isError}
92
- isPending={isPending}
93
- noResults={results.length === 0 && failedTypes.length === 0}
94
- />
95
- ) : (
96
- <View style={styles.prompt}>{prompt}</View>
97
- )
75
+ <ListEmpty
76
+ term={term}
77
+ isError={isError}
78
+ isPending={isPending}
79
+ noResults={results.length === 0 && failedTypes.length === 0}
80
+ />
98
81
  }
99
82
  ListFooterComponent={
100
83
  <>
@@ -108,7 +91,7 @@ export function SearchResultsList({
108
91
  Try again
109
92
  </TextButton>
110
93
  )}
111
- {searching && failedTypes.includes('message') && <SectionFailure type="message" />}
94
+ {failedTypes.includes('message') && <SectionFailure type="message" />}
112
95
  </>
113
96
  }
114
97
  onEndReached={() => {
@@ -166,10 +149,6 @@ const styles = StyleSheet.create({
166
149
  content: {
167
150
  flexGrow: 1,
168
151
  },
169
- prompt: {
170
- flexGrow: 1,
171
- justifyContent: 'center',
172
- },
173
152
  banner: {
174
153
  margin: 16,
175
154
  },
@@ -4,7 +4,7 @@ import {
4
4
  NativeStackScreenProps,
5
5
  } from '@react-navigation/native-stack'
6
6
  import React, { useRef, useState } from 'react'
7
- import { Keyboard, StyleSheet, View } from 'react-native'
7
+ import { Keyboard, ScrollView, StyleSheet, View } from 'react-native'
8
8
  import { KeyboardView } from '../../components'
9
9
  import {
10
10
  composeOptions,
@@ -64,13 +64,19 @@ export function SearchScreen() {
64
64
  return (
65
65
  <KeyboardView>
66
66
  <View style={styles.container} testID="search-screen">
67
- <SearchResultsList
68
- term={debouncedTerm}
69
- onSelect={openResult}
70
- onSettled={publishSearch}
71
- header={<SearchField term={term} onChange={setTerm} />}
72
- prompt={<SearchPromptBlankState />}
73
- />
67
+ <SearchField term={term} onChange={setTerm} />
68
+ {debouncedTerm.length > 0 ? (
69
+ <SearchResultsList
70
+ key={debouncedTerm}
71
+ term={debouncedTerm}
72
+ onSelect={openResult}
73
+ onSettled={publishSearch}
74
+ />
75
+ ) : (
76
+ <ScrollView contentContainerStyle={styles.prompt} keyboardShouldPersistTaps="handled">
77
+ <SearchPromptBlankState />
78
+ </ScrollView>
79
+ )}
74
80
  </View>
75
81
  </KeyboardView>
76
82
  )
@@ -80,4 +86,8 @@ const styles = StyleSheet.create({
80
86
  container: {
81
87
  flex: 1,
82
88
  },
89
+ prompt: {
90
+ flexGrow: 1,
91
+ justifyContent: 'center',
92
+ },
83
93
  })
@@ -1,7 +1,7 @@
1
1
  import { PlatformPressable } from '@react-navigation/elements'
2
2
  import { StaticScreenProps, useNavigation } from '@react-navigation/native'
3
3
  import React, { useCallback } from 'react'
4
- import { Platform, ScrollView, StyleSheet, View } from 'react-native'
4
+ import { Platform, StyleSheet, View } from 'react-native'
5
5
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
6
6
  import { Heading, Icon, Text, VersionFooter } from '../components'
7
7
  import { Switch } from '../components/display/switch'
@@ -28,31 +28,29 @@ export function SettingsScreen({}: SettingsScreenProps) {
28
28
 
29
29
  return (
30
30
  <View style={styles.container}>
31
- <ScrollView contentInsetAdjustmentBehavior="automatic">
32
- <View style={styles.sectionOuter}>
33
- <View style={styles.sectionHeader}>
34
- <Heading variant="h2">Messages</Heading>
35
- </View>
36
- {directMessagesEligible && (
37
- <View style={styles.settingRow}>
38
- <View style={styles.settingRowText}>
39
- <Text>Allow direct messages</Text>
40
- <Text variant="tertiary">
41
- When off, you can't be added to new direct messages, and any you're already in
42
- will be turned off.
43
- </Text>
44
- </View>
45
- <Switch
46
- value={!directMessagesDisabled}
47
- onValueChange={enabled => setDirectMessagesDisabled(!enabled)}
48
- disabled={isMutating}
49
- />
50
- </View>
51
- )}
52
- <NavRow label="Notification settings" onPress={handleNotificationSettings} />
53
- {appName !== 'services' && <NavRow label="Get help" onPress={handleGetHelp} />}
31
+ <View style={styles.sectionOuter}>
32
+ <View style={styles.sectionHeader}>
33
+ <Heading variant="h2">Messages</Heading>
54
34
  </View>
55
- </ScrollView>
35
+ {directMessagesEligible && (
36
+ <View style={styles.settingRow}>
37
+ <View style={styles.settingRowText}>
38
+ <Text>Allow direct messages</Text>
39
+ <Text variant="tertiary">
40
+ When off, you can't be added to new direct messages, and any you're already in will
41
+ be turned off.
42
+ </Text>
43
+ </View>
44
+ <Switch
45
+ value={!directMessagesDisabled}
46
+ onValueChange={enabled => setDirectMessagesDisabled(!enabled)}
47
+ disabled={isMutating}
48
+ />
49
+ </View>
50
+ )}
51
+ <NavRow label="Notification settings" onPress={handleNotificationSettings} />
52
+ {appName !== 'services' && <NavRow label="Get help" onPress={handleGetHelp} />}
53
+ </View>
56
54
  <View style={styles.footer}>
57
55
  <VersionFooter />
58
56
  </View>
@@ -92,6 +90,8 @@ const useStyles = () => {
92
90
  flex: 1,
93
91
  },
94
92
  footer: {
93
+ flex: 1,
94
+ justifyContent: 'flex-end',
95
95
  paddingBottom: Math.max(insets.bottom, 8),
96
96
  },
97
97
  sectionOuter: {
@@ -1,7 +0,0 @@
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
- type RouteName = keyof ReactNavigation.RootParamList | keyof StaticParamList<typeof NewConversationStack>;
5
- export declare const PAGE_ERROR_FALLBACKS: Partial<Record<RouteName, PageErrorFallback>>;
6
- export {};
7
- //# sourceMappingURL=page_error_fallbacks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"page_error_fallbacks.d.ts","sourceRoot":"","sources":["../../src/navigation/page_error_fallbacks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AAC/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEnD,KAAK,SAAS,GACV,MAAM,eAAe,CAAC,aAAa,GACnC,MAAM,eAAe,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEtD,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAK9E,CAAA"}
@@ -1,7 +0,0 @@
1
- export const PAGE_ERROR_FALLBACKS = {
2
- ConversationSelectDirectMessageRecipients: {
3
- heading: "Couldn't load people right now",
4
- body: 'Try again.'
5
- }
6
- };
7
- //# sourceMappingURL=page_error_fallbacks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"page_error_fallbacks.js","names":["PAGE_ERROR_FALLBACKS","ConversationSelectDirectMessageRecipients","heading","body"],"sources":["../../src/navigation/page_error_fallbacks.ts"],"sourcesContent":["import type { StaticParamList } from '@react-navigation/native'\nimport type { PageErrorFallback } from '../components/page/page_error_boundary'\nimport type { NewConversationStack } from './index'\n\ntype RouteName =\n | keyof ReactNavigation.RootParamList\n | keyof StaticParamList<typeof NewConversationStack>\n\nexport const PAGE_ERROR_FALLBACKS: Partial<Record<RouteName, PageErrorFallback>> = {\n ConversationSelectDirectMessageRecipients: {\n heading: \"Couldn't load people right now\",\n body: 'Try again.',\n },\n}\n"],"mappings":"AAQA,OAAO,MAAMA,oBAAmE,GAAG;EACjFC,yCAAyC,EAAE;IACzCC,OAAO,EAAE,gCAAgC;IACzCC,IAAI,EAAE;EACR;AACF,CAAC","ignoreList":[]}
@@ -1,14 +0,0 @@
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,100 +0,0 @@
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
- })