Skip to content

Commit

Permalink
Fix wrong feed being shown (#3015)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon authored Feb 28, 2024
1 parent 88c66c4 commit 0dd3f94
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 86 deletions.
129 changes: 51 additions & 78 deletions src/state/queries/feed.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from 'react'
import {
useQuery,
useInfiniteQuery,
InfiniteData,
QueryKey,
useMutation,
useQueryClient,
} from '@tanstack/react-query'
import {
AtUri,
Expand All @@ -15,7 +13,6 @@ import {
AppBskyUnspeccedGetPopularFeedGenerators,
} from '@atproto/api'

import {logger} from '#/logger'
import {router} from '#/routes'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
Expand Down Expand Up @@ -219,83 +216,59 @@ const FOLLOWING_FEED_STUB: FeedSourceInfo = {
likeUri: '',
}

export function usePinnedFeedsInfos(): {
feeds: FeedSourceInfo[]
hasPinnedCustom: boolean
isLoading: boolean
} {
const queryClient = useQueryClient()
const [tabs, setTabs] = React.useState<FeedSourceInfo[]>([
FOLLOWING_FEED_STUB,
])
const [isLoading, setLoading] = React.useState(true)
const {data: preferences} = usePreferencesQuery()
export function usePinnedFeedsInfos() {
const {data: preferences, isLoading: isLoadingPrefs} = usePreferencesQuery()
const pinnedUris = preferences?.feeds?.pinned ?? []

const hasPinnedCustom = React.useMemo<boolean>(() => {
return tabs.some(tab => tab !== FOLLOWING_FEED_STUB)
}, [tabs])

React.useEffect(() => {
if (!preferences?.feeds?.pinned) return
const uris = preferences.feeds.pinned

async function fetchFeedInfo() {
const reqs = []

for (const uri of uris) {
const cached = queryClient.getQueryData<FeedSourceInfo>(
feedSourceInfoQueryKey({uri}),
)

if (cached) {
reqs.push(cached)
} else {
reqs.push(
(async () => {
// these requests can fail, need to filter those out
try {
return await queryClient.fetchQuery({
staleTime: STALE.SECONDS.FIFTEEN,
queryKey: feedSourceInfoQueryKey({uri}),
queryFn: async () => {
const type = getFeedTypeFromUri(uri)
return useQuery({
staleTime: STALE.INFINITY,
enabled: !isLoadingPrefs,
queryKey: ['pinnedFeedsInfos', pinnedUris.join(',')],
queryFn: async () => {
let resolved = new Map()

// Get all feeds. We can do this in a batch.
const feedUris = pinnedUris.filter(
uri => getFeedTypeFromUri(uri) === 'feed',
)
let feedsPromise = Promise.resolve()
if (feedUris.length > 0) {
feedsPromise = getAgent()
.app.bsky.feed.getFeedGenerators({
feeds: feedUris,
})
.then(res => {
for (let feedView of res.data.feeds) {
resolved.set(feedView.uri, hydrateFeedGenerator(feedView))
}
})
}

if (type === 'feed') {
const res =
await getAgent().app.bsky.feed.getFeedGenerator({
feed: uri,
})
return hydrateFeedGenerator(res.data.view)
} else {
const res = await getAgent().app.bsky.graph.getList({
list: uri,
limit: 1,
})
return hydrateList(res.data.list)
}
},
})
} catch (e) {
// expected failure
logger.info(`usePinnedFeedsInfos: failed to fetch ${uri}`, {
error: e,
})
}
})(),
)
// Get all lists. This currently has to be done individually.
const listUris = pinnedUris.filter(
uri => getFeedTypeFromUri(uri) === 'list',
)
const listsPromises = listUris.map(listUri =>
getAgent()
.app.bsky.graph.getList({
list: listUri,
limit: 1,
})
.then(res => {
const listView = res.data.list
resolved.set(listView.uri, hydrateList(listView))
}),
)

// The returned result will have the original order.
const result = [FOLLOWING_FEED_STUB]
await Promise.allSettled([feedsPromise, ...listsPromises])
for (let pinnedUri of pinnedUris) {
if (resolved.has(pinnedUri)) {
result.push(resolved.get(pinnedUri))
}
}

const views = (await Promise.all(reqs)).filter(
Boolean,
) as FeedSourceInfo[]

setTabs([FOLLOWING_FEED_STUB].concat(views))
setLoading(false)
}

fetchFeedInfo()
}, [queryClient, setTabs, preferences?.feeds?.pinned])

return {feeds: tabs, hasPinnedCustom, isLoading}
return result
},
})
}
15 changes: 11 additions & 4 deletions src/view/com/home/HomeHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
import React from 'react'
import {RenderTabBarFnProps} from 'view/com/pager/Pager'
import {HomeHeaderLayout} from './HomeHeaderLayout'
import {usePinnedFeedsInfos} from '#/state/queries/feed'
import {FeedSourceInfo} from '#/state/queries/feed'
import {useNavigation} from '@react-navigation/native'
import {NavigationProp} from 'lib/routes/types'
import {isWeb} from 'platform/detection'
import {TabBar} from '../pager/TabBar'
import {usePalette} from '#/lib/hooks/usePalette'

export function HomeHeader(
props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void},
props: RenderTabBarFnProps & {
testID?: string
onPressSelected: () => void
feeds: FeedSourceInfo[]
},
) {
const {feeds} = props
const navigation = useNavigation<NavigationProp>()
const {feeds, hasPinnedCustom} = usePinnedFeedsInfos()
const pal = usePalette('default')

const hasPinnedCustom = React.useMemo<boolean>(() => {
return feeds.some(tab => tab.uri !== '')
}, [feeds])

const items = React.useMemo(() => {
const pinnedNames = feeds.map(f => f.displayName)

if (!hasPinnedCustom) {
return pinnedNames.concat('Feeds ✨')
}
Expand Down
5 changes: 3 additions & 2 deletions src/view/screens/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed'
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
export function HomeScreen(props: Props) {
const {data: preferences} = usePreferencesQuery()
const {feeds: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} =
const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} =
usePinnedFeedsInfos()
if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) {
return (
Expand Down Expand Up @@ -124,10 +124,11 @@ function HomeScreenReady({
onSelect={props.onSelect}
testID="homeScreenFeedTabs"
onPressSelected={onPressSelected}
feeds={pinnedFeedInfos}
/>
)
},
[onPressSelected],
[onPressSelected, pinnedFeedInfos],
)

const renderFollowingEmptyState = React.useCallback(() => {
Expand Down
6 changes: 4 additions & 2 deletions src/view/shell/desktop/Feeds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {emitSoftReset} from '#/state/events'
export function DesktopFeeds() {
const pal = usePalette('default')
const {_} = useLingui()
const {feeds: pinnedFeedInfos} = usePinnedFeedsInfos()
const {data: pinnedFeedInfos} = usePinnedFeedsInfos()
const selectedFeed = useSelectedFeed()
const setSelectedFeed = useSetSelectedFeed()
const navigation = useNavigation<NavigationProp>()
Expand All @@ -25,7 +25,9 @@ export function DesktopFeeds() {
}
return getCurrentRoute(state)
})

if (!pinnedFeedInfos) {
return null
}
return (
<View style={[styles.container, pal.view]}>
{pinnedFeedInfos.map(feedInfo => {
Expand Down

0 comments on commit 0dd3f94

Please sign in to comment.