Files
bsky-social-app/src/state/queries/trending/useGetTrendsQuery.ts
T
2026-07-22 14:23:01 -07:00

83 lines
2.3 KiB
TypeScript

import {useCallback, useMemo} from 'react'
import {type AppBskyUnspeccedGetTrends, hasMutedWord} from '@atproto/api'
import {useQuery} from '@tanstack/react-query'
import {
aggregateUserInterests,
createBskyTopicsHeader,
} from '#/lib/api/feed/utils'
import {logger} from '#/logger'
import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences'
import {useAgent} from '#/state/session'
export const DEFAULT_LIMIT = 5
type QueryProps = {
limit?: number
refetchOnWindowFocus?: boolean
}
function dedupe<T extends {link: string}>(trends: T[]): T[] {
const seen = new Set<string>()
return trends.filter(trend => {
if (seen.has(trend.link)) return false
seen.add(trend.link)
return true
})
}
export const createGetTrendsQueryKey = (limit?: number) =>
limit === undefined ? ['trends'] : ['trends', {limit}]
export function useGetTrendsQuery(props: QueryProps = {}) {
const agent = useAgent()
const {data: preferences} = usePreferencesQuery()
const limit = props.limit ?? DEFAULT_LIMIT
const mutedWords = useMemo(() => {
return preferences?.moderationPrefs?.mutedWords || []
}, [preferences?.moderationPrefs])
return useQuery({
enabled: !!preferences,
refetchOnWindowFocus: props.refetchOnWindowFocus,
staleTime: STALE.MINUTES.THREE,
queryKey: createGetTrendsQueryKey(limit),
queryFn: async () => {
const contentLangs = getContentLanguages().join(',')
const {data} = await agent.app.bsky.unspecced.getTrends(
{
limit,
},
{
headers: {
...createBskyTopicsHeader(aggregateUserInterests(preferences)),
'Accept-Language': contentLangs,
},
},
)
if (!data.recIdStr) {
logger.debug('useGetTrendsQuery response missing recIdStr')
}
return data
},
select: useCallback(
(data: AppBskyUnspeccedGetTrends.OutputSchema) => {
return {
recId: data.recIdStr,
trends: dedupe(
(data.trends ?? []).filter(t => {
return !hasMutedWord({
mutedWords,
text: `${t.topic} ${t.displayName} ${t.category}`,
})
}),
),
}
},
[mutedWords],
),
})
}