Skip to content

Commit e198276

Browse files
committed
update api tester list to separaate concerns
1 parent ef9b892 commit e198276

File tree

1 file changed

+93
-110
lines changed
  • source/views/settings/screens/api-test

1 file changed

+93
-110
lines changed
Lines changed: 93 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,122 @@
1-
import * as c from '@frogpond/colors'
1+
import React from 'react'
2+
import {View, SectionList, SafeAreaView, StyleSheet} from 'react-native'
3+
4+
import {ListRow, ListSectionHeader, ListSeparator, Title} from '@frogpond/lists'
5+
import {Column} from '@frogpond/layout'
26
import {LoadingView, NoticeView} from '@frogpond/notice'
3-
import {SearchButton} from '@frogpond/navigation-buttons'
7+
import * as c from '@frogpond/colors'
48
import {debounceSearch} from '@frogpond/use-debounce'
9+
import {NetworkLoggerButton} from '@frogpond/navigation-buttons'
10+
11+
import {ServerRoute, useServerRoutes} from './query'
12+
import {ChangeTextEvent} from '../../../../navigation/types'
513
import {useNavigation} from '@react-navigation/native'
614
import {NativeStackNavigationOptions} from '@react-navigation/native-stack'
7-
import {fromPairs} from 'lodash'
8-
import * as React from 'react'
9-
import {ScrollView, StyleSheet, View} from 'react-native'
10-
import {ChangeTextEvent} from '../../../navigation/types'
11-
import {useAppSelector} from '../../../redux'
12-
import {
13-
selectRecentFilters,
14-
selectRecentSearches,
15-
} from '../../../redux/parts/courses'
16-
import {RecentItemsList} from '../components/recents-list'
17-
import {useFilters} from './lib/build-filters'
18-
19-
export const NavigationOptions: NativeStackNavigationOptions = {
20-
title: 'Course Catalog',
21-
}
2215

23-
export const CourseSearchView = (): JSX.Element => {
16+
export const APITestView = (): JSX.Element => {
2417
let navigation = useNavigation()
2518

26-
let {data: basicFilters = [], isLoading, error} = useFilters()
19+
let [filterPath, setFilterPath] = React.useState<string>('')
2720

28-
let recentFilters = useAppSelector(selectRecentFilters)
29-
let recentSearches = useAppSelector(selectRecentSearches)
30-
31-
let [typedQuery, setTypedQuery] = React.useState('')
21+
let {
22+
data: groupedRoutes = [],
23+
error: routesError,
24+
isLoading: isRoutesLoading,
25+
isError: isRoutesError,
26+
refetch: routesRefetch,
27+
} = useServerRoutes()
3228

3329
React.useLayoutEffect(() => {
3430
navigation.setOptions({
35-
headerRight: () => (
36-
<SearchButton
37-
onPress={() =>
38-
navigation.navigate('CourseSearchResults', {initialQuery: ''})
39-
}
40-
title="Browse"
41-
/>
42-
),
4331
headerSearchBarOptions: {
44-
barTintColor: c.quaternarySystemFill,
45-
onChangeText: (event: ChangeTextEvent) => {
46-
setTypedQuery(event.nativeEvent.text)
47-
},
32+
autoCapitalize: 'none',
33+
barTintColor: c.systemFill,
34+
// android-only
35+
autoFocus: true,
36+
hideNavigationBar: false,
37+
hideWhenScrolling: false,
38+
onChangeText: (event: ChangeTextEvent) =>
39+
setFilterPath(event.nativeEvent.text),
40+
placeholder: '/path/to/uri',
4841
},
42+
headerRight: () => <NetworkLoggerButton />,
4943
})
50-
}, [navigation, typedQuery])
51-
52-
let showSearchResult = React.useCallback(
53-
(query: string) => {
54-
navigation.navigate('CourseSearchResults', {initialQuery: query})
55-
},
56-
[navigation],
57-
)
58-
59-
React.useEffect(() => {
60-
debounceSearch(typedQuery, () => {
61-
showSearchResult(typedQuery)
44+
}, [navigation])
45+
46+
let showSearchResult = React.useCallback(() => {
47+
navigation.navigate('APITestDetail', {
48+
query: {
49+
displayName: filterPath,
50+
path: filterPath,
51+
params: [],
52+
},
6253
})
63-
}, [showSearchResult, typedQuery])
64-
65-
let onRecentFilterPress = React.useCallback(
66-
(text: string) => {
67-
let selectedFilterCombo = recentFilters.find(
68-
(f) => f.description === text,
69-
)
54+
}, [filterPath, navigation])
7055

71-
let selectedFilters = basicFilters
72-
if (selectedFilterCombo) {
73-
let filterLookup = fromPairs(
74-
selectedFilterCombo.filters.map((f) => [f.key, f]),
75-
)
76-
selectedFilters = basicFilters.map((f) => filterLookup[f.key] || f)
77-
}
78-
79-
navigation.navigate('CourseSearchResults', {
80-
initialFilters: selectedFilters,
81-
})
82-
},
83-
[basicFilters, navigation, recentFilters],
56+
React.useEffect(() => {
57+
debounceSearch(filterPath, () => showSearchResult())
58+
}, [filterPath, navigation, showSearchResult])
59+
60+
const renderItem = React.useCallback(
61+
(item: ServerRoute) => (
62+
<SafeAreaView>
63+
<ListRow
64+
fullWidth={false}
65+
onPress={() => navigation.navigate('APITestDetail', {query: item})}
66+
style={styles.serverRouteRow}
67+
>
68+
<Column flex={1}>
69+
<Title lines={1}>{item.displayName}</Title>
70+
</Column>
71+
</ListRow>
72+
</SafeAreaView>
73+
),
74+
[navigation],
8475
)
8576

86-
if (isLoading) {
87-
return <LoadingView text="Loading Course Data…" />
88-
}
89-
90-
if (error) {
91-
return (
92-
<NoticeView
93-
buttonText="Try Again"
94-
// onPress={refetch} // TODO: implement refetch here
95-
text={`A problem occured while loading: ${error}`}
96-
/>
97-
)
98-
}
99-
100-
let recentFilterDescriptions = recentFilters.map((f) => f.description)
101-
10277
return (
103-
<View style={[styles.container, styles.common]}>
104-
<ScrollView
105-
// needed for handling native searchbar alignment
106-
contentInsetAdjustmentBehavior="automatic"
107-
keyboardDismissMode="interactive"
108-
style={[styles.common, styles.bottomContainer]}
109-
>
110-
<RecentItemsList
111-
emptyHeader="No recent searches"
112-
emptyText="Your recent searches will appear here."
113-
items={recentSearches}
114-
onItemPress={showSearchResult}
115-
title="Recent"
78+
<View style={styles.serverRouteContainer}>
79+
{isRoutesLoading ? (
80+
<LoadingView />
81+
) : isRoutesError && routesError instanceof Error ? (
82+
<NoticeView
83+
buttonText="Try Again"
84+
onPress={routesRefetch}
85+
text={`A problem occured while loading: ${routesError}`}
11686
/>
117-
<RecentItemsList
118-
emptyHeader="No recent filter combinations"
119-
emptyText="Your recent filter combinations will appear here."
120-
items={recentFilterDescriptions}
121-
onItemPress={onRecentFilterPress}
122-
title="Browse"
87+
) : !groupedRoutes ? (
88+
<NoticeView text="No routes were found." />
89+
) : (
90+
<SectionList
91+
ItemSeparatorComponent={ListSeparator}
92+
contentInsetAdjustmentBehavior="automatic"
93+
keyExtractor={(item, index) => `${item.path}-${index}`}
94+
keyboardDismissMode="on-drag"
95+
keyboardShouldPersistTaps="never"
96+
onRefresh={routesRefetch}
97+
refreshing={isRoutesLoading}
98+
renderItem={({item}) => renderItem(item)}
99+
renderSectionHeader={({section: {title}}) => (
100+
<ListSectionHeader title={title} />
101+
)}
102+
sections={groupedRoutes}
123103
/>
124-
</ScrollView>
104+
)}
125105
</View>
126106
)
127107
}
128108

129-
let styles = StyleSheet.create({
130-
bottomContainer: {
131-
paddingTop: 12,
132-
},
133-
container: {
109+
const styles = StyleSheet.create({
110+
serverRouteContainer: {
134111
flex: 1,
135-
},
136-
common: {
137112
backgroundColor: c.systemBackground,
138113
},
114+
serverRouteRow: {
115+
flexDirection: 'row',
116+
alignItems: 'center',
117+
},
139118
})
119+
120+
export const NavigationOptions: NativeStackNavigationOptions = {
121+
title: 'API Tester',
122+
}

0 commit comments

Comments
 (0)