An ATproto social media client -- with an independent Appview.
1import React from 'react'
2import {type AppBskyUnspeccedGetTrends, hasMutedWord} from '@atproto/api'
3import {useQuery} from '@tanstack/react-query'
4
5import {
6 aggregateUserInterests,
7 createBskyTopicsHeader,
8} from '#/lib/api/feed/utils'
9import {getContentLanguages} from '#/state/preferences/languages'
10import {STALE} from '#/state/queries'
11import {usePreferencesQuery} from '#/state/queries/preferences'
12import {useAgent} from '#/state/session'
13
14export const DEFAULT_LIMIT = 5
15
16export const createGetTrendsQueryKey = () => ['trends']
17
18export function useGetTrendsQuery() {
19 const agent = useAgent()
20 const {data: preferences} = usePreferencesQuery()
21 const mutedWords = React.useMemo(() => {
22 return preferences?.moderationPrefs?.mutedWords || []
23 }, [preferences?.moderationPrefs])
24
25 return useQuery({
26 enabled: !!preferences,
27 staleTime: STALE.MINUTES.THREE,
28 queryKey: createGetTrendsQueryKey(),
29 queryFn: async () => {
30 const contentLangs = getContentLanguages().join(',')
31 const {data} = await agent.app.bsky.unspecced.getTrends(
32 {
33 limit: DEFAULT_LIMIT,
34 },
35 {
36 headers: {
37 ...createBskyTopicsHeader(aggregateUserInterests(preferences)),
38 'Accept-Language': contentLangs,
39 },
40 },
41 )
42 return data
43 },
44 select: React.useCallback(
45 (data: AppBskyUnspeccedGetTrends.OutputSchema) => {
46 return {
47 trends: (data.trends ?? []).filter(t => {
48 return !hasMutedWord({
49 mutedWords,
50 text: t.topic + ' ' + t.displayName + ' ' + t.category,
51 })
52 }),
53 }
54 },
55 [mutedWords],
56 ),
57 })
58}