add React Query and hook up to existing functionality (#1358)
* add React Query and hook up to existing functionality * wire in remote data, add error message * remove hard-coded feeds * oops fix logic * add loading state * fix loading on mobile --------- Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
parent
84b7edd9db
commit
188d4893f9
8 changed files with 108 additions and 153 deletions
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import {FlatList, StyleSheet, View} from 'react-native'
|
||||
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {TabletOrDesktop, Mobile} from 'view/com/util/layouts/Breakpoints'
|
||||
|
@ -10,7 +10,10 @@ import {Button} from 'view/com/util/forms/Button'
|
|||
import {RecommendedFeedsItem} from './RecommendedFeedsItem'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {RECOMMENDED_FEEDS} from 'lib/constants'
|
||||
import {useQuery} from '@tanstack/react-query'
|
||||
import {useStores} from 'state/index'
|
||||
import {CustomFeedModel} from 'state/models/feeds/custom-feed'
|
||||
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
||||
|
||||
type Props = {
|
||||
next: () => void
|
||||
|
@ -18,8 +21,31 @@ type Props = {
|
|||
export const RecommendedFeeds = observer(function RecommendedFeedsImpl({
|
||||
next,
|
||||
}: Props) {
|
||||
const store = useStores()
|
||||
const pal = usePalette('default')
|
||||
const {isTabletOrMobile} = useWebMediaQueries()
|
||||
const {isLoading, data: recommendedFeeds} = useQuery({
|
||||
staleTime: Infinity, // fixed list rn, never refetch
|
||||
queryKey: ['onboarding', 'recommended_feeds'],
|
||||
async queryFn() {
|
||||
try {
|
||||
const {
|
||||
data: {feeds},
|
||||
success,
|
||||
} = await store.agent.app.bsky.feed.getSuggestedFeeds()
|
||||
|
||||
if (!success) return
|
||||
|
||||
return (feeds.length ? feeds : []).map(feed => {
|
||||
return new CustomFeedModel(store, feed)
|
||||
})
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const hasFeeds = recommendedFeeds && recommendedFeeds.length
|
||||
|
||||
const title = (
|
||||
<>
|
||||
|
@ -86,12 +112,20 @@ export const RecommendedFeeds = observer(function RecommendedFeedsImpl({
|
|||
horizontal
|
||||
titleStyle={isTabletOrMobile ? undefined : {minWidth: 470}}
|
||||
contentStyle={{paddingHorizontal: 0}}>
|
||||
<FlatList
|
||||
data={RECOMMENDED_FEEDS}
|
||||
renderItem={({item}) => <RecommendedFeedsItem {...item} />}
|
||||
keyExtractor={item => item.did + item.rkey}
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
{hasFeeds ? (
|
||||
<FlatList
|
||||
data={recommendedFeeds}
|
||||
renderItem={({item}) => <RecommendedFeedsItem item={item} />}
|
||||
keyExtractor={item => item.uri}
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
) : isLoading ? (
|
||||
<View>
|
||||
<ActivityIndicator size="large" />
|
||||
</View>
|
||||
) : (
|
||||
<ErrorMessage message="Failed to load recommended feeds" />
|
||||
)}
|
||||
</TitleColumnLayout>
|
||||
</TabletOrDesktop>
|
||||
<Mobile>
|
||||
|
@ -106,12 +140,20 @@ export const RecommendedFeeds = observer(function RecommendedFeedsImpl({
|
|||
pinned feeds.
|
||||
</Text>
|
||||
|
||||
<FlatList
|
||||
data={RECOMMENDED_FEEDS}
|
||||
renderItem={({item}) => <RecommendedFeedsItem {...item} />}
|
||||
keyExtractor={item => item.did + item.rkey}
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
{hasFeeds ? (
|
||||
<FlatList
|
||||
data={recommendedFeeds}
|
||||
renderItem={({item}) => <RecommendedFeedsItem item={item} />}
|
||||
keyExtractor={item => item.uri}
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
) : isLoading ? (
|
||||
<View>
|
||||
<ActivityIndicator size="large" />
|
||||
</View>
|
||||
) : (
|
||||
<ErrorMessage message="Failed to load recommended feeds" />
|
||||
)}
|
||||
|
||||
<Button
|
||||
onPress={next}
|
||||
|
|
|
@ -8,22 +8,17 @@ import {UserAvatar} from 'view/com/util/UserAvatar'
|
|||
import * as Toast from 'view/com/util/Toast'
|
||||
import {HeartIcon} from 'lib/icons'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useCustomFeed} from 'lib/hooks/useCustomFeed'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||
import {sanitizeHandle} from 'lib/strings/handles'
|
||||
import {CustomFeedModel} from 'state/models/feeds/custom-feed'
|
||||
|
||||
export const RecommendedFeedsItem = observer(function RecommendedFeedsItemImpl({
|
||||
did,
|
||||
rkey,
|
||||
item,
|
||||
}: {
|
||||
did: string
|
||||
rkey: string
|
||||
item: CustomFeedModel
|
||||
}) {
|
||||
const {isMobile} = useWebMediaQueries()
|
||||
const pal = usePalette('default')
|
||||
const uri = makeRecordUri(did, 'app.bsky.feed.generator', rkey)
|
||||
const item = useCustomFeed(uri)
|
||||
if (!item) return null
|
||||
const onToggle = async () => {
|
||||
if (item.isSaved) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue