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

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 (95) 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/filter_dropdown.d.ts +0 -1
  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 +0 -1
  12. package/build/components/display/keyboard_scroll_view.js.map +1 -1
  13. package/build/components/page/page_error_boundary.d.ts +1 -9
  14. package/build/components/page/page_error_boundary.d.ts.map +1 -1
  15. package/build/components/page/page_error_boundary.js +31 -56
  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 +3 -11
  19. package/build/navigation/index.js.map +1 -1
  20. package/build/navigation/screenLayout.d.ts.map +1 -1
  21. package/build/navigation/screenLayout.js +6 -10
  22. package/build/navigation/screenLayout.js.map +1 -1
  23. package/build/screens/age_check/age_check_required_screen.d.ts.map +1 -1
  24. package/build/screens/age_check/age_check_required_screen.js +0 -1
  25. package/build/screens/age_check/age_check_required_screen.js.map +1 -1
  26. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  27. package/build/screens/conversation_details_screen.js +0 -1
  28. package/build/screens/conversation_details_screen.js.map +1 -1
  29. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.d.ts.map +1 -1
  30. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js +0 -1
  31. package/build/screens/conversation_select_recipients/conversation_new_entry_screen.js.map +1 -1
  32. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.d.ts.map +1 -1
  33. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js +291 -332
  34. package/build/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.js.map +1 -1
  35. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.d.ts.map +1 -1
  36. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js +0 -1
  37. package/build/screens/conversation_select_recipients/conversation_select_group_recipients_screen.js.map +1 -1
  38. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.d.ts.map +1 -1
  39. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js +0 -1
  40. package/build/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.js.map +1 -1
  41. package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts.map +1 -1
  42. package/build/screens/conversations/components/filter_dropdown_list_header_component.js +7 -22
  43. package/build/screens/conversations/components/filter_dropdown_list_header_component.js.map +1 -1
  44. package/build/screens/get_help_screen.js +62 -56
  45. package/build/screens/get_help_screen.js.map +1 -1
  46. package/build/screens/group_notification_settings_screen.js +2 -3
  47. package/build/screens/group_notification_settings_screen.js.map +1 -1
  48. package/build/screens/notification_settings_screen.d.ts.map +1 -1
  49. package/build/screens/notification_settings_screen.js +0 -1
  50. package/build/screens/notification_settings_screen.js.map +1 -1
  51. package/build/screens/preferred_app_selection_screen.js +39 -45
  52. package/build/screens/preferred_app_selection_screen.js.map +1 -1
  53. package/build/screens/search/components/search_results_list.d.ts +1 -4
  54. package/build/screens/search/components/search_results_list.d.ts.map +1 -1
  55. package/build/screens/search/components/search_results_list.js +110 -136
  56. package/build/screens/search/components/search_results_list.js.map +1 -1
  57. package/build/screens/search/search_screen.d.ts.map +1 -1
  58. package/build/screens/search/search_screen.js +28 -21
  59. package/build/screens/search/search_screen.js.map +1 -1
  60. package/build/screens/settings_screen.d.ts.map +1 -1
  61. package/build/screens/settings_screen.js +6 -7
  62. package/build/screens/settings_screen.js.map +1 -1
  63. package/package.json +3 -3
  64. package/src/components/conversation/__tests__/message_list.test.tsx +0 -4
  65. package/src/components/conversation/message_list.tsx +0 -6
  66. package/src/components/conversations/conversations.tsx +0 -1
  67. package/src/components/display/filter_dropdown.tsx +0 -1
  68. package/src/components/display/keyboard_scroll_view.tsx +0 -1
  69. package/src/components/page/__tests__/page_error_boundary.test.tsx +0 -33
  70. package/src/components/page/page_error_boundary.tsx +12 -43
  71. package/src/navigation/index.tsx +2 -11
  72. package/src/navigation/screenLayout.tsx +1 -3
  73. package/src/screens/age_check/age_check_required_screen.tsx +1 -5
  74. package/src/screens/conversation_details_screen.tsx +0 -1
  75. package/src/screens/conversation_select_recipients/conversation_new_entry_screen.tsx +1 -4
  76. package/src/screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen.tsx +68 -78
  77. package/src/screens/conversation_select_recipients/conversation_select_group_recipients_screen.tsx +0 -1
  78. package/src/screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen.tsx +0 -1
  79. package/src/screens/conversations/components/__tests__/filter_dropdown_list_header_component.test.tsx +1 -59
  80. package/src/screens/conversations/components/filter_dropdown_list_header_component.tsx +9 -24
  81. package/src/screens/get_help_screen.tsx +4 -4
  82. package/src/screens/group_notification_settings_screen.tsx +3 -3
  83. package/src/screens/notification_settings_screen.tsx +0 -1
  84. package/src/screens/preferred_app_selection_screen.tsx +4 -4
  85. package/src/screens/search/__tests__/search_screen.test.tsx +7 -5
  86. package/src/screens/search/components/__tests__/search_results_list.test.tsx +2 -6
  87. package/src/screens/search/components/search_results_list.tsx +13 -34
  88. package/src/screens/search/search_screen.tsx +18 -8
  89. package/src/screens/settings_screen.tsx +25 -25
  90. package/build/navigation/page_error_fallbacks.d.ts +0 -7
  91. package/build/navigation/page_error_fallbacks.d.ts.map +0 -1
  92. package/build/navigation/page_error_fallbacks.js +0 -7
  93. package/build/navigation/page_error_fallbacks.js.map +0 -1
  94. package/src/navigation/page_error_fallbacks.ts +0 -14
  95. package/src/screens/conversation_select_recipients/__tests__/conversation_select_direct_message_recipients_screen.test.tsx +0 -100
@@ -60,7 +60,6 @@ export const ConversationSelectGroupRecipientsScreen = ({
60
60
 
61
61
  return (
62
62
  <SectionList<GroupsGroupResource, GroupsSection>
63
- contentInsetAdjustmentBehavior="automatic"
64
63
  sections={sections}
65
64
  keyExtractor={item => item.id.toString()}
66
65
  stickySectionHeadersEnabled={false}
@@ -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 { fireEvent, render, screen } from '@testing-library/react-native'
2
2
  import React from 'react'
3
- import { Pressable, StyleSheet, Text } from 'react-native'
3
+ import { Pressable, Text } from 'react-native'
4
4
  import {
5
5
  AudioAdapter,
6
6
  ChatAdapters,
@@ -115,25 +115,6 @@ const setRouteParams = (params: Record<string, unknown>) => {
115
115
  const menuItemNames = () =>
116
116
  screen.getAllByRole('menuitem').map(item => item.props.accessibilityLabel)
117
117
 
118
- const ROW_WIDTH = 360
119
- const ROW_CONTENT_WIDTH = ROW_WIDTH - 16 * 2
120
- const HEADING_ROW_GAP = 12
121
- const WIDEST_LABEL_WIDTH = 150
122
-
123
- const layOut = (testID: string, width: number) =>
124
- fireEvent(screen.getByTestId(testID, { includeHiddenElements: true }), 'layout', {
125
- nativeEvent: { layout: { width } },
126
- })
127
-
128
- const layOutHeader = ({ actionsWidth }: { actionsWidth: number }) => {
129
- layOut('conversations-filter-heading-row', ROW_WIDTH)
130
- layOut('conversations-filter-widest-label', WIDEST_LABEL_WIDTH)
131
- layOut('conversations-filter-heading-actions', actionsWidth)
132
- }
133
-
134
- const triggerMaxWidth = (): number =>
135
- StyleSheet.flatten(screen.getByRole('button', { name: 'All conversations' }).props.style).maxWidth
136
-
137
118
  describe('FilterDropdownListHeaderComponent', () => {
138
119
  beforeEach(() => {
139
120
  mockNavigate.mockClear()
@@ -305,45 +286,6 @@ describe('FilterDropdownListHeaderComponent', () => {
305
286
  )
306
287
  })
307
288
 
308
- it('caps the trigger short of the room beside the actions so a full label never wraps them', () => {
309
- render(<FilterDropdownListHeaderComponent />)
310
-
311
- layOutHeader({ actionsWidth: 120.4 })
312
-
313
- expect(triggerMaxWidth()).toBeGreaterThanOrEqual(WIDEST_LABEL_WIDTH)
314
- expect(triggerMaxWidth() + HEADING_ROW_GAP + 120.4).toBeLessThan(ROW_CONTENT_WIDTH)
315
- })
316
-
317
- it('holds the cap when the actions remeasure by less than a point', () => {
318
- render(<FilterDropdownListHeaderComponent />)
319
-
320
- layOutHeader({ actionsWidth: 120.4 })
321
- const capBefore = triggerMaxWidth()
322
-
323
- layOut('conversations-filter-heading-actions', 120.9)
324
-
325
- expect(triggerMaxWidth()).toBe(capBefore)
326
- })
327
-
328
- it('recomputes the cap when the actions grow by a button', () => {
329
- render(<FilterDropdownListHeaderComponent />)
330
-
331
- layOutHeader({ actionsWidth: 120.4 })
332
- const capBefore = triggerMaxWidth()
333
-
334
- layOut('conversations-filter-heading-actions', 160)
335
-
336
- expect(triggerMaxWidth()).toBeLessThan(capBefore)
337
- })
338
-
339
- it('caps the trigger to the row once All conversations no longer fits beside the actions', () => {
340
- render(<FilterDropdownListHeaderComponent />)
341
-
342
- layOutHeader({ actionsWidth: 200 })
343
-
344
- expect(triggerMaxWidth()).toBe(ROW_CONTENT_WIDTH)
345
- })
346
-
347
289
  it('shows the search button only when search is enabled', () => {
348
290
  mockSearchEnabled.mockReturnValue(false)
349
291
  const view = render(<FilterDropdownListHeaderComponent />)
@@ -30,8 +30,6 @@ import { ListHeaderActionButton } from './list_header_action_button'
30
30
 
31
31
  const ROW_PADDING_HORIZONTAL = 16
32
32
  const HEADING_ROW_GAP = 12
33
- const TRIGGER_CAP_SLACK = 2
34
- const LAYOUT_JITTER = 1
35
33
  const ALL_CONVERSATIONS_LABEL = 'All conversations'
36
34
  const ARCHIVED_LABEL = 'Archived'
37
35
 
@@ -44,9 +42,6 @@ enum FilterTypes {
44
42
  More = 'More',
45
43
  }
46
44
 
47
- const holdSubPointJitter = (previous: number | undefined, next: number) =>
48
- previous !== undefined && Math.abs(next - previous) < LAYOUT_JITTER ? previous : next
49
-
50
45
  const FILTER_PARAMS: Record<Exclude<FilterTypes, FilterTypes.More>, ConversationFiltersParams> = {
51
46
  [FilterTypes.All]: {},
52
47
  [FilterTypes.Groups]: { group_source_app_name: 'Groups' },
@@ -222,14 +217,14 @@ export const FilterDropdownListHeaderComponent = () => {
222
217
  const [rowWidth, setRowWidth] = useState<number>()
223
218
  const [actionsWidth, setActionsWidth] = useState<number>()
224
219
  const [widestFixedLabelWidth, setWidestFixedLabelWidth] = useState<number>()
225
- const handleRowLayout = useCallback(({ nativeEvent }: LayoutChangeEvent) => {
226
- setRowWidth(previous => holdSubPointJitter(previous, nativeEvent.layout.width))
220
+ const handleRowLayout = useCallback((event: LayoutChangeEvent) => {
221
+ setRowWidth(event.nativeEvent.layout.width)
227
222
  }, [])
228
- const handleActionsLayout = useCallback(({ nativeEvent }: LayoutChangeEvent) => {
229
- setActionsWidth(previous => holdSubPointJitter(previous, nativeEvent.layout.width))
223
+ const handleActionsLayout = useCallback((event: LayoutChangeEvent) => {
224
+ setActionsWidth(event.nativeEvent.layout.width)
230
225
  }, [])
231
- const handleWidestFixedLabelLayout = useCallback(({ nativeEvent }: LayoutChangeEvent) => {
232
- setWidestFixedLabelWidth(previous => holdSubPointJitter(previous, nativeEvent.layout.width))
226
+ const handleWidestFixedLabelLayout = useCallback((event: LayoutChangeEvent) => {
227
+ setWidestFixedLabelWidth(event.nativeEvent.layout.width)
233
228
  }, [])
234
229
  const triggerMaxWidth = useMemo(() => {
235
230
  if (rowWidth === undefined) return undefined
@@ -237,8 +232,7 @@ export const FilterDropdownListHeaderComponent = () => {
237
232
  const rowContentWidth = rowWidth - ROW_PADDING_HORIZONTAL * 2
238
233
  if (actionsWidth === undefined || widestFixedLabelWidth === undefined) return rowContentWidth
239
234
 
240
- const roomBesideActions =
241
- Math.floor(rowContentWidth - actionsWidth - HEADING_ROW_GAP) - TRIGGER_CAP_SLACK
235
+ const roomBesideActions = rowContentWidth - actionsWidth - HEADING_ROW_GAP
242
236
  return roomBesideActions >= widestFixedLabelWidth ? roomBesideActions : rowContentWidth
243
237
  }, [rowWidth, actionsWidth, widestFixedLabelWidth])
244
238
 
@@ -248,16 +242,11 @@ export const FilterDropdownListHeaderComponent = () => {
248
242
  <FilterDropdownTrigger
249
243
  label={ALL_CONVERSATIONS_LABEL}
250
244
  onLayout={handleWidestFixedLabelLayout}
251
- testID="conversations-filter-widest-label"
252
245
  accessibilityElementsHidden
253
246
  importantForAccessibility="no-hide-descendants"
254
247
  />
255
248
  </View>
256
- <View
257
- style={styles.headingRow}
258
- onLayout={handleRowLayout}
259
- testID="conversations-filter-heading-row"
260
- >
249
+ <View style={styles.headingRow} onLayout={handleRowLayout}>
261
250
  <View style={styles.titleContainer}>
262
251
  <FilterDropdown
263
252
  options={options}
@@ -269,11 +258,7 @@ export const FilterDropdownListHeaderComponent = () => {
269
258
  maxWidth={triggerMaxWidth}
270
259
  />
271
260
  </View>
272
- <View
273
- style={styles.actionsContainer}
274
- onLayout={handleActionsLayout}
275
- testID="conversations-filter-heading-actions"
276
- >
261
+ <View style={styles.actionsContainer} onLayout={handleActionsLayout}>
277
262
  <ListHeaderActionButton
278
263
  name="general.cog"
279
264
  onPress={handleChatSettings}
@@ -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
- }