Use getSuggestions endpoint behind the gate (#3499)

* Move suggested follows out of the component

* Add new suggestions implementation

* Put new endpoint behind the gate

* Make bottom less weird
zio/stable
dan 2024-04-12 13:02:15 +01:00 committed by GitHub
parent e3e8f10538
commit bedb0c3fbd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 5 deletions

View File

@ -7,3 +7,4 @@ export type Gate =
| 'new_search' | 'new_search'
| 'show_follow_back_label' | 'show_follow_back_label'
| 'start_session_with_following' | 'start_session_with_following'
| 'use_new_suggestions_endpoint'

View File

@ -82,7 +82,10 @@ export function useGate(gateName: Gate): boolean {
// This should not happen because of waitForInitialization={true}. // This should not happen because of waitForInitialization={true}.
console.error('Did not expected isLoading to ever be true.') console.error('Did not expected isLoading to ever be true.')
} }
return value // This shouldn't technically be necessary but let's get a strong
// guarantee that a gate value can never change while mounted.
const [initialValue] = React.useState(value)
return initialValue
} }
function toStatsigUser(did: string | undefined) { function toStatsigUser(did: string | undefined) {

View File

@ -32,7 +32,10 @@ import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
import {useActorSearch} from '#/state/queries/actor-search' import {useActorSearch} from '#/state/queries/actor-search'
import {useModerationOpts} from '#/state/queries/preferences' import {useModerationOpts} from '#/state/queries/preferences'
import {useSearchPostsQuery} from '#/state/queries/search-posts' import {useSearchPostsQuery} from '#/state/queries/search-posts'
import {useGetSuggestedFollowersByActor} from '#/state/queries/suggested-follows' import {
useGetSuggestedFollowersByActor,
useSuggestedFollowsQuery,
} from '#/state/queries/suggested-follows'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useSetDrawerOpen} from '#/state/shell' import {useSetDrawerOpen} from '#/state/shell'
import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell' import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell'
@ -118,8 +121,10 @@ function EmptyState({message, error}: {message: string; error?: string}) {
) )
} }
function SearchScreenSuggestedFollows() { function useSuggestedFollowsV1(): [
const pal = usePalette('default') AppBskyActorDefs.ProfileViewBasic[],
() => void,
] {
const {currentAccount} = useSession() const {currentAccount} = useSession()
const [suggestions, setSuggestions] = React.useState< const [suggestions, setSuggestions] = React.useState<
AppBskyActorDefs.ProfileViewBasic[] AppBskyActorDefs.ProfileViewBasic[]
@ -162,6 +167,56 @@ function SearchScreenSuggestedFollows() {
} }
}, [currentAccount, setSuggestions, getSuggestedFollowsByActor]) }, [currentAccount, setSuggestions, getSuggestedFollowsByActor])
return [suggestions, () => {}]
}
function useSuggestedFollowsV2(): [
AppBskyActorDefs.ProfileViewBasic[],
() => void,
] {
const {
data: suggestions,
hasNextPage,
isFetchingNextPage,
isError,
fetchNextPage,
} = useSuggestedFollowsQuery()
const onEndReached = React.useCallback(async () => {
if (isFetchingNextPage || !hasNextPage || isError) return
try {
await fetchNextPage()
} catch (err) {
logger.error('Failed to load more suggested follows', {message: err})
}
}, [isFetchingNextPage, hasNextPage, isError, fetchNextPage])
const items: AppBskyActorDefs.ProfileViewBasic[] = []
if (suggestions) {
// Currently the responses contain duplicate items.
// Needs to be fixed on backend, but let's dedupe to be safe.
let seen = new Set()
for (const page of suggestions.pages) {
for (const actor of page.actors) {
if (!seen.has(actor.did)) {
seen.add(actor.did)
items.push(actor)
}
}
}
}
return [items, onEndReached]
}
function SearchScreenSuggestedFollows() {
const pal = usePalette('default')
const useSuggestedFollows = useGate('use_new_suggestions_endpoint')
? // Conditional hook call here is *only* OK because useGate()
// result won't change until a remount.
useSuggestedFollowsV2
: useSuggestedFollowsV1
const [suggestions, onEndReached] = useSuggestedFollows()
return suggestions.length ? ( return suggestions.length ? (
<List <List
data={suggestions} data={suggestions}
@ -169,9 +224,11 @@ function SearchScreenSuggestedFollows() {
keyExtractor={item => item.did} keyExtractor={item => item.did}
// @ts-ignore web only -prf // @ts-ignore web only -prf
desktopFixedHeight desktopFixedHeight
contentContainerStyle={{paddingBottom: 1200}} contentContainerStyle={{paddingBottom: 200}}
keyboardShouldPersistTaps="handled" keyboardShouldPersistTaps="handled"
keyboardDismissMode="on-drag" keyboardDismissMode="on-drag"
onEndReached={onEndReached}
onEndReachedThreshold={2}
/> />
) : ( ) : (
<CenteredView sideBorders style={[pal.border, s.hContentRegion]}> <CenteredView sideBorders style={[pal.border, s.hContentRegion]}>