mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at rm-broken-strings 173 lines 4.8 kB view raw
1import { 2 AppBskyActorDefs, 3 AppBskyActorGetSuggestions, 4 AppBskyGraphGetSuggestedFollowsByActor, 5 moderateProfile, 6} from '@atproto/api' 7import { 8 InfiniteData, 9 QueryClient, 10 QueryKey, 11 useInfiniteQuery, 12 useQuery, 13} from '@tanstack/react-query' 14 15import { 16 aggregateUserInterests, 17 createBskyTopicsHeader, 18} from '#/lib/api/feed/utils' 19import {getContentLanguages} from '#/state/preferences/languages' 20import {STALE} from '#/state/queries' 21import {usePreferencesQuery} from '#/state/queries/preferences' 22import {useAgent, useSession} from '#/state/session' 23import {useModerationOpts} from '../preferences/moderation-opts' 24 25const suggestedFollowsQueryKeyRoot = 'suggested-follows' 26const suggestedFollowsQueryKey = (options?: SuggestedFollowsOptions) => [ 27 suggestedFollowsQueryKeyRoot, 28 options, 29] 30 31const suggestedFollowsByActorQueryKeyRoot = 'suggested-follows-by-actor' 32const suggestedFollowsByActorQueryKey = (did: string) => [ 33 suggestedFollowsByActorQueryKeyRoot, 34 did, 35] 36 37type SuggestedFollowsOptions = {limit?: number; subsequentPageLimit?: number} 38 39export function useSuggestedFollowsQuery(options?: SuggestedFollowsOptions) { 40 const {currentAccount} = useSession() 41 const agent = useAgent() 42 const moderationOpts = useModerationOpts() 43 const {data: preferences} = usePreferencesQuery() 44 const limit = options?.limit || 25 45 46 return useInfiniteQuery< 47 AppBskyActorGetSuggestions.OutputSchema, 48 Error, 49 InfiniteData<AppBskyActorGetSuggestions.OutputSchema>, 50 QueryKey, 51 string | undefined 52 >({ 53 enabled: !!moderationOpts && !!preferences, 54 staleTime: STALE.HOURS.ONE, 55 queryKey: suggestedFollowsQueryKey(options), 56 queryFn: async ({pageParam}) => { 57 const contentLangs = getContentLanguages().join(',') 58 const maybeDifferentLimit = 59 options?.subsequentPageLimit && pageParam 60 ? options.subsequentPageLimit 61 : limit 62 const res = await agent.app.bsky.actor.getSuggestions( 63 { 64 limit: maybeDifferentLimit, 65 cursor: pageParam, 66 }, 67 { 68 headers: { 69 ...createBskyTopicsHeader(aggregateUserInterests(preferences)), 70 'Accept-Language': contentLangs, 71 }, 72 }, 73 ) 74 75 res.data.actors = res.data.actors 76 .filter( 77 actor => 78 !moderateProfile(actor, moderationOpts!).ui('profileList').filter, 79 ) 80 .filter(actor => { 81 const viewer = actor.viewer 82 if (viewer) { 83 if ( 84 viewer.following || 85 viewer.muted || 86 viewer.mutedByList || 87 viewer.blockedBy || 88 viewer.blocking 89 ) { 90 return false 91 } 92 } 93 if (actor.did === currentAccount?.did) { 94 return false 95 } 96 return true 97 }) 98 99 return res.data 100 }, 101 initialPageParam: undefined, 102 getNextPageParam: lastPage => lastPage.cursor, 103 }) 104} 105 106export function useSuggestedFollowsByActorQuery({did}: {did: string}) { 107 const agent = useAgent() 108 return useQuery({ 109 queryKey: suggestedFollowsByActorQueryKey(did), 110 queryFn: async () => { 111 const res = await agent.app.bsky.graph.getSuggestedFollowsByActor({ 112 actor: did, 113 }) 114 const suggestions = res.data.isFallback 115 ? [] 116 : res.data.suggestions.filter(profile => !profile.viewer?.following) 117 return {suggestions} 118 }, 119 }) 120} 121 122export function* findAllProfilesInQueryData( 123 queryClient: QueryClient, 124 did: string, 125): Generator<AppBskyActorDefs.ProfileView, void> { 126 yield* findAllProfilesInSuggestedFollowsQueryData(queryClient, did) 127 yield* findAllProfilesInSuggestedFollowsByActorQueryData(queryClient, did) 128} 129 130function* findAllProfilesInSuggestedFollowsQueryData( 131 queryClient: QueryClient, 132 did: string, 133) { 134 const queryDatas = queryClient.getQueriesData< 135 InfiniteData<AppBskyActorGetSuggestions.OutputSchema> 136 >({ 137 queryKey: [suggestedFollowsQueryKeyRoot], 138 }) 139 for (const [_queryKey, queryData] of queryDatas) { 140 if (!queryData?.pages) { 141 continue 142 } 143 for (const page of queryData?.pages) { 144 for (const actor of page.actors) { 145 if (actor.did === did) { 146 yield actor 147 } 148 } 149 } 150 } 151} 152 153function* findAllProfilesInSuggestedFollowsByActorQueryData( 154 queryClient: QueryClient, 155 did: string, 156) { 157 const queryDatas = 158 queryClient.getQueriesData<AppBskyGraphGetSuggestedFollowsByActor.OutputSchema>( 159 { 160 queryKey: [suggestedFollowsByActorQueryKeyRoot], 161 }, 162 ) 163 for (const [_queryKey, queryData] of queryDatas) { 164 if (!queryData) { 165 continue 166 } 167 for (const suggestion of queryData.suggestions) { 168 if (suggestion.did === did) { 169 yield suggestion 170 } 171 } 172 } 173}