Skip to content

Commit dccbd7b

Browse files
committed
refactor streams data fetching with useAsync
1 parent 684ca71 commit dccbd7b

File tree

1 file changed

+40
-65
lines changed

1 file changed

+40
-65
lines changed

source/views/streaming/streams/list.tsx

Lines changed: 40 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {Moment} from 'moment-timezone'
1212
import {toLaxTitleCase as titleCase} from '@frogpond/titlecase'
1313
import type {StreamType} from './types'
1414
import {API} from '@frogpond/api'
15-
import {fetch} from '@frogpond/fetch'
15+
import {useFetch} from 'react-async'
1616

1717
const styles = StyleSheet.create({
1818
listContainer: {
@@ -23,52 +23,32 @@ const styles = StyleSheet.create({
2323
},
2424
})
2525

26-
export const StreamListView = (): JSX.Element => {
27-
let [error, setError] = React.useState<Error | null>(null)
28-
let [loading, setLoading] = React.useState(true)
29-
let [refreshing, setRefreshing] = React.useState(false)
30-
let [streams, setStreams] = React.useState<
31-
Array<{title: string; data: StreamType[]}>
32-
>([])
33-
34-
React.useEffect(() => {
35-
try {
36-
getStreams().then(() => {
37-
setLoading(false)
38-
})
39-
} catch (error) {
40-
if (error instanceof Error) {
41-
setError(error)
42-
} else {
43-
setError(new Error('unknown error - not an Error'))
44-
}
45-
return
46-
}
47-
}, [])
48-
49-
let refresh = async (): Promise<void> => {
50-
setRefreshing(true)
51-
await getStreams(true)
52-
setRefreshing(false)
53-
}
26+
const groupStreams = (entries: StreamType[]) => {
27+
let grouped = groupBy(entries, (j) => j.$groupBy)
28+
return toPairs(grouped).map(([title, data]) => ({title, data}))
29+
}
5430

55-
let getStreams = async (
56-
reload?: boolean,
57-
date: Moment = moment.tz(timezone()),
58-
) => {
59-
let dateFrom = date.format('YYYY-MM-DD')
60-
let dateTo = date.clone().add(2, 'month').format('YYYY-MM-DD')
31+
const useStreams = (date: Moment = moment.tz(timezone())) => {
32+
let dateFrom = date.format('YYYY-MM-DD')
33+
let dateTo = date.clone().add(2, 'month').format('YYYY-MM-DD')
34+
35+
return useFetch<StreamType[]>(
36+
API('/streams/upcoming', {
37+
sort: 'ascending',
38+
dateFrom,
39+
dateTo,
40+
}),
41+
{
42+
headers: {accept: 'application/json'},
43+
},
44+
)
45+
}
6146

62-
let data = await fetch(API('/streams/upcoming'), {
63-
searchParams: {
64-
sort: 'ascending',
65-
dateFrom,
66-
dateTo,
67-
},
68-
delay: reload ? 500 : 0,
69-
}).json<Array<StreamType>>()
47+
export const StreamListView = (): JSX.Element => {
48+
let {data = [], error, reload, isPending, isInitial, isLoading} = useStreams()
7049

71-
data = data
50+
let entries = React.useMemo(() => {
51+
return data
7252
.filter((stream) => stream.category !== 'athletics')
7353
.map((stream) => {
7454
let date: Moment = moment(stream.starttime)
@@ -84,38 +64,33 @@ export const StreamListView = (): JSX.Element => {
8464
$groupBy: group,
8565
}
8666
})
87-
88-
let grouped = groupBy(data, (j) => j.$groupBy)
89-
let mapped = toPairs(grouped).map(([title, data]) => ({title, data}))
90-
91-
setStreams(mapped)
92-
}
93-
94-
let keyExtractor = (item: StreamType) => item.eid
95-
96-
let renderItem = ({item}: {item: StreamType}) => <StreamRow stream={item} />
97-
98-
if (loading) {
99-
return <LoadingView />
100-
}
67+
}, [data])
10168

10269
if (error) {
103-
return <NoticeView text={`Error: ${error.message}`} />
70+
return (
71+
<NoticeView
72+
buttonText="Try Again"
73+
onPress={reload}
74+
text={`A problem occured while loading the streams. ${error.message}`}
75+
/>
76+
)
10477
}
10578

10679
return (
10780
<SectionList
10881
ItemSeparatorComponent={ListSeparator}
109-
ListEmptyComponent={<NoticeView text="No Streams" />}
82+
ListEmptyComponent={
83+
isLoading ? <LoadingView /> : <NoticeView text="No streams." />
84+
}
11085
contentContainerStyle={styles.contentContainer}
111-
keyExtractor={keyExtractor}
112-
onRefresh={refresh}
113-
refreshing={refreshing}
114-
renderItem={renderItem}
86+
keyExtractor={(item: StreamType) => item.eid}
87+
onRefresh={reload}
88+
refreshing={isPending && !isInitial}
89+
renderItem={({item}: {item: StreamType}) => <StreamRow stream={item} />}
11590
renderSectionHeader={({section: {title}}) => (
11691
<ListSectionHeader title={title} />
11792
)}
118-
sections={streams}
93+
sections={groupStreams(entries)}
11994
style={styles.listContainer}
12095
/>
12196
)

0 commit comments

Comments
 (0)