Search - extra tabs (#3408)

* add extra tab to search and translate tab names

* add feature gate

* flatten pager children

* Revert "flatten pager children"

This reverts commit 0050d42558c2c9b7bc4f2ad2df4ae2908fa26f65.

* have pager children as array

* move gate to custom hook

* bundle titles and pages together

* remove comment

* Fix a crash

* Use Views as children

---------

Co-authored-by: dan <dan.abramov@gmail.com>
zio/stable
Samuel Newman 2024-04-10 16:02:13 +01:00 committed by GitHub
parent b5f5777939
commit 353a963920
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 94 additions and 24 deletions

View File

@ -0,0 +1,3 @@
import {useGate} from './statsig'
export const useNewSearchGate = () => useGate('new_search')

View File

@ -10,12 +10,19 @@ import {getAgent} from '#/state/session'
import {embedViewRecordToPostView, getEmbeddedPost} from './util' import {embedViewRecordToPostView, getEmbeddedPost} from './util'
const searchPostsQueryKeyRoot = 'search-posts' const searchPostsQueryKeyRoot = 'search-posts'
const searchPostsQueryKey = ({query}: {query: string}) => [ const searchPostsQueryKey = ({query, sort}: {query: string; sort?: string}) => [
searchPostsQueryKeyRoot, searchPostsQueryKeyRoot,
query, query,
sort,
] ]
export function useSearchPostsQuery({query}: {query: string}) { export function useSearchPostsQuery({
query,
sort,
}: {
query: string
sort?: 'top' | 'latest'
}) {
return useInfiniteQuery< return useInfiniteQuery<
AppBskyFeedSearchPosts.OutputSchema, AppBskyFeedSearchPosts.OutputSchema,
Error, Error,
@ -23,14 +30,20 @@ export function useSearchPostsQuery({query}: {query: string}) {
QueryKey, QueryKey,
string | undefined string | undefined
>({ >({
queryKey: searchPostsQueryKey({query}), queryKey: searchPostsQueryKey({query, sort}),
queryFn: async ({pageParam}) => { queryFn: async ({pageParam}) => {
// waiting on new APIs
switch (sort) {
// case 'top':
// case 'latest':
default:
const res = await getAgent().app.bsky.feed.searchPosts({ const res = await getAgent().app.bsky.feed.searchPosts({
q: query, q: query,
limit: 25, limit: 25,
cursor: pageParam, cursor: pageParam,
}) })
return res.data return res.data
}
}, },
initialPageParam: undefined, initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor, getNextPageParam: lastPage => lastPage.cursor,

View File

@ -22,6 +22,7 @@ import {HITSLOP_10} from '#/lib/constants'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {MagnifyingGlassIcon} from '#/lib/icons' import {MagnifyingGlassIcon} from '#/lib/icons'
import {NavigationProp} from '#/lib/routes/types' import {NavigationProp} from '#/lib/routes/types'
import {useNewSearchGate} from '#/lib/statsig/gates'
import {augmentSearchQuery} from '#/lib/strings/helpers' import {augmentSearchQuery} from '#/lib/strings/helpers'
import {s} from '#/lib/styles' import {s} from '#/lib/styles'
import {logger} from '#/logger' import {logger} from '#/logger'
@ -191,7 +192,13 @@ type SearchResultSlice =
key: string key: string
} }
function SearchScreenPostResults({query}: {query: string}) { function SearchScreenPostResults({
query,
sort,
}: {
query: string
sort?: 'top' | 'latest'
}) {
const {_} = useLingui() const {_} = useLingui()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const [isPTR, setIsPTR] = React.useState(false) const [isPTR, setIsPTR] = React.useState(false)
@ -209,7 +216,7 @@ function SearchScreenPostResults({query}: {query: string}) {
fetchNextPage, fetchNextPage,
isFetchingNextPage, isFetchingNextPage,
hasNextPage, hasNextPage,
} = useSearchPostsQuery({query: augmentedQuery}) } = useSearchPostsQuery({query: augmentedQuery, sort})
const onPullToRefresh = React.useCallback(async () => { const onPullToRefresh = React.useCallback(async () => {
setIsPTR(true) setIsPTR(true)
@ -316,8 +323,6 @@ function SearchScreenUserResults({query}: {query: string}) {
) )
} }
const SECTIONS_LOGGEDOUT = ['Users']
const SECTIONS_LOGGEDIN = ['Posts', 'Users']
export function SearchScreenInner({ export function SearchScreenInner({
query, query,
primarySearch, primarySearch,
@ -330,6 +335,9 @@ export function SearchScreenInner({
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled() const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
const {hasSession} = useSession() const {hasSession} = useSession()
const {isDesktop} = useWebMediaQueries() const {isDesktop} = useWebMediaQueries()
const {_} = useLingui()
const isNewSearch = useNewSearchGate()
const onPageSelected = React.useCallback( const onPageSelected = React.useCallback(
(index: number) => { (index: number) => {
@ -339,6 +347,55 @@ export function SearchScreenInner({
[setDrawerSwipeDisabled, setMinimalShellMode], [setDrawerSwipeDisabled, setMinimalShellMode],
) )
const sections = React.useMemo(() => {
if (!query) return []
if (isNewSearch) {
if (hasSession) {
return [
{
title: _(msg`Top`),
component: <SearchScreenPostResults query={query} sort="top" />,
},
{
title: _(msg`Latest`),
component: <SearchScreenPostResults query={query} sort="latest" />,
},
{
title: _(msg`People`),
component: <SearchScreenUserResults query={query} />,
},
]
} else {
return [
{
title: _(msg`People`),
component: <SearchScreenUserResults query={query} />,
},
]
}
} else {
if (hasSession) {
return [
{
title: _(msg`Posts`),
component: <SearchScreenPostResults query={query} />,
},
{
title: _(msg`Users`),
component: <SearchScreenUserResults query={query} />,
},
]
} else {
return [
{
title: _(msg`Users`),
component: <SearchScreenUserResults query={query} />,
},
]
}
}
}, [hasSession, isNewSearch, _, query])
if (hasSession) { if (hasSession) {
return query ? ( return query ? (
<Pager <Pager
@ -347,16 +404,13 @@ export function SearchScreenInner({
<CenteredView <CenteredView
sideBorders sideBorders
style={[pal.border, pal.view, styles.tabBarContainer]}> style={[pal.border, pal.view, styles.tabBarContainer]}>
<TabBar items={SECTIONS_LOGGEDIN} {...props} /> <TabBar items={sections.map(section => section.title)} {...props} />
</CenteredView> </CenteredView>
)} )}
initialPage={0}> initialPage={0}>
<View> {sections.map((section, i) => (
<SearchScreenPostResults query={query} /> <View key={i}>{section.component}</View>
</View> ))}
<View>
<SearchScreenUserResults query={query} />
</View>
</Pager> </Pager>
) : ( ) : (
<View> <View>
@ -389,13 +443,13 @@ export function SearchScreenInner({
<CenteredView <CenteredView
sideBorders sideBorders
style={[pal.border, pal.view, styles.tabBarContainer]}> style={[pal.border, pal.view, styles.tabBarContainer]}>
<TabBar items={SECTIONS_LOGGEDOUT} {...props} /> <TabBar items={sections.map(section => section.title)} {...props} />
</CenteredView> </CenteredView>
)} )}
initialPage={0}> initialPage={0}>
<View> {sections.map((section, i) => (
<SearchScreenUserResults query={query} /> <View key={i}>{section.component}</View>
</View> ))}
</Pager> </Pager>
) : ( ) : (
<CenteredView sideBorders style={pal.border}> <CenteredView sideBorders style={pal.border}>