An ATproto social media client -- with an independent Appview.
7
fork

Configure Feed

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

at main 67 lines 1.8 kB view raw
1import { 2 type AppBskyFeedGetActorFeeds, 3 moderateFeedGenerator, 4} from '@atproto/api' 5import { 6 type InfiniteData, 7 type QueryKey, 8 useInfiniteQuery, 9} from '@tanstack/react-query' 10 11import {useAgent} from '#/state/session' 12import {useModerationOpts} from '../preferences/moderation-opts' 13 14const PAGE_SIZE = 50 15type RQPageParam = string | undefined 16 17// TODO refactor invalidate on mutate? 18export const RQKEY_ROOT = 'profile-feedgens' 19export const RQKEY = (did: string) => [RQKEY_ROOT, did] 20 21export function useProfileFeedgensQuery( 22 did: string, 23 opts?: {enabled?: boolean}, 24) { 25 const moderationOpts = useModerationOpts() 26 const enabled = opts?.enabled !== false && Boolean(moderationOpts) 27 const agent = useAgent() 28 return useInfiniteQuery< 29 AppBskyFeedGetActorFeeds.OutputSchema, 30 Error, 31 InfiniteData<AppBskyFeedGetActorFeeds.OutputSchema>, 32 QueryKey, 33 RQPageParam 34 >({ 35 queryKey: RQKEY(did), 36 async queryFn({pageParam}: {pageParam: RQPageParam}) { 37 const res = await agent.app.bsky.feed.getActorFeeds({ 38 actor: did, 39 limit: PAGE_SIZE, 40 cursor: pageParam, 41 }) 42 res.data.feeds.sort((a, b) => { 43 return (b.likeCount || 0) - (a.likeCount || 0) 44 }) 45 return res.data 46 }, 47 initialPageParam: undefined, 48 getNextPageParam: lastPage => lastPage.cursor, 49 enabled, 50 select(data) { 51 return { 52 ...data, 53 pages: data.pages.map(page => { 54 return { 55 ...page, 56 feeds: page.feeds 57 // filter by labels 58 .filter(list => { 59 const decision = moderateFeedGenerator(list, moderationOpts!) 60 return !decision.ui('contentList').filter 61 }), 62 } 63 }), 64 } 65 }, 66 }) 67}