@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.
- package/build/components/conversation/message_list.d.ts.map +1 -1
- package/build/components/conversation/message_list.js +123 -155
- package/build/components/conversation/message_list.js.map +1 -1
- package/build/components/conversations/conversations.d.ts.map +1 -1
- package/build/components/conversations/conversations.js +0 -1
- package/build/components/conversations/conversations.js.map +1 -1
- package/build/components/display/keyboard_scroll_view.d.ts.map +1 -1
- package/build/components/display/keyboard_scroll_view.js +0 -1
- package/build/components/display/keyboard_scroll_view.js.map +1 -1
- package/build/components/page/page_error_boundary.d.ts +1 -9
- package/build/components/page/page_error_boundary.d.ts.map +1 -1
- package/build/components/page/page_error_boundary.js +31 -56
- package/build/components/page/page_error_boundary.js.map +1 -1
- package/build/navigation/index.d.ts.map +1 -1
- package/build/navigation/index.js +3 -11
- package/build/navigation/index.js.map +1 -1
- package/build/navigation/screenLayout.d.ts.map +1 -1
- package/build/navigation/screenLayout.js +6 -10
- package/build/navigation/screenLayout.js.map +1 -1
- package/build/screens/age_check/age_check_required_screen.d.ts.map +1 -1
- package/build/screens/age_check/age_check_required_screen.js +0 -1
- package/build/screens/age_check/age_check_required_screen.js.map +1 -1
- package/build/screens/conversation_details_screen.d.ts.map +1 -1
- package/build/screens/conversation_details_screen.js +0 -1
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_new_entry_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js +0 -1
- package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js +291 -332
- package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js +0 -1
- package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js +0 -1
- package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js.map +1 -1
- package/build/screens/get_help_screen.js +62 -56
- package/build/screens/get_help_screen.js.map +1 -1
- package/build/screens/group_notification_settings_screen.js +2 -3
- package/build/screens/group_notification_settings_screen.js.map +1 -1
- package/build/screens/notification_settings_screen.d.ts.map +1 -1
- package/build/screens/notification_settings_screen.js +0 -1
- package/build/screens/notification_settings_screen.js.map +1 -1
- package/build/screens/preferred_app_selection_screen.js +39 -45
- package/build/screens/preferred_app_selection_screen.js.map +1 -1
- package/build/screens/search/components/search_results_list.d.ts +1 -4
- package/build/screens/search/components/search_results_list.d.ts.map +1 -1
- package/build/screens/search/components/search_results_list.js +110 -136
- package/build/screens/search/components/search_results_list.js.map +1 -1
- package/build/screens/search/search_screen.d.ts.map +1 -1
- package/build/screens/search/search_screen.js +28 -21
- package/build/screens/search/search_screen.js.map +1 -1
- package/build/screens/settings_screen.d.ts.map +1 -1
- package/build/screens/settings_screen.js +6 -7
- package/build/screens/settings_screen.js.map +1 -1
- package/package.json +3 -3
- package/src/components/conversation/__tests__/message_list.test.tsx +0 -4
- package/src/components/conversation/message_list.tsx +0 -6
- package/src/components/conversations/conversations.tsx +0 -1
- package/src/components/display/keyboard_scroll_view.tsx +0 -1
- package/src/components/page/__tests__/page_error_boundary.test.tsx +0 -33
- package/src/components/page/page_error_boundary.tsx +12 -43
- package/src/navigation/index.tsx +2 -11
- package/src/navigation/screenLayout.tsx +1 -3
- package/src/screens/age_check/age_check_required_screen.tsx +1 -5
- package/src/screens/conversation_details_screen.tsx +0 -1
- package/src/screens/conversation_select_recipients/conversation_new_entry_screen.tsx +1 -4
- package/src/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.tsx +68 -78
- package/src/screens/conversation_select_recipients/conversation_select_group_recipients_screen.tsx +0 -1
- package/src/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.tsx +0 -1
- package/src/screens/get_help_screen.tsx +4 -4
- package/src/screens/group_notification_settings_screen.tsx +3 -3
- package/src/screens/notification_settings_screen.tsx +0 -1
- package/src/screens/preferred_app_selection_screen.tsx +4 -4
- package/src/screens/search/__tests__/search_screen.test.tsx +7 -5
- package/src/screens/search/components/__tests__/search_results_list.test.tsx +2 -6
- package/src/screens/search/components/search_results_list.tsx +13 -34
- package/src/screens/search/search_screen.tsx +18 -8
- package/src/screens/settings_screen.tsx +25 -25
- package/build/navigation/page_error_fallbacks.d.ts +0 -7
- package/build/navigation/page_error_fallbacks.d.ts.map +0 -1
- package/build/navigation/page_error_fallbacks.js +0 -7
- package/build/navigation/page_error_fallbacks.js.map +0 -1
- package/src/navigation/page_error_fallbacks.ts +0 -14
- package/src/screens/conversation_select_recipients/__tests__/conversation_select_direct_message_recipients_screen.test.tsx +0 -100
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StaticScreenProps, useNavigation } from '@react-navigation/native'
|
|
2
2
|
import { useCallback, useMemo } from 'react'
|
|
3
|
-
import { Alert, Linking,
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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
|
-
|
|
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,
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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,
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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()}
|
|
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, {
|
|
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
|
|
48
|
-
const
|
|
49
|
-
const
|
|
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
|
-
{
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
{
|
|
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
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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,
|
|
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
|
-
<
|
|
32
|
-
<View style={styles.
|
|
33
|
-
<
|
|
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
|
-
|
|
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 +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
|
-
})
|