Respect labels on feeds and lists (#4818)

* Prep

* Pass in optional moderation to FeedCard

* Compute moderation decision, filter contentList contexts, pass into card

* Let's go a different route

* Filter from within search queries

* Use same search query for starter packs

* Filter lists from profile tabs

* Cleanup

* Filter from profile feeds

* Moderate post embeds

* Memoize

* Use ScreenHider on lists

* Hide both list types

* Fix crash on iOS in screen hider, fix lineheight

* Memoize renderItem

* Reuse objects to prevent re-renders
This commit is contained in:
Eric Bailey
2024-08-02 13:05:33 -05:00
committed by GitHub
parent 293ac6fab2
commit c3d8beee6d
9 changed files with 261 additions and 145 deletions
+33 -20
View File
@@ -5,6 +5,7 @@ import {
AppBskyGraphDefs,
AppBskyUnspeccedGetPopularFeedGenerators,
AtUri,
moderateFeedGenerator,
RichText,
} from '@atproto/api'
import {
@@ -26,6 +27,7 @@ import {RQKEY as listQueryKey} from '#/state/queries/list'
import {usePreferencesQuery} from '#/state/queries/preferences'
import {useAgent, useSession} from '#/state/session'
import {router} from '#/routes'
import {useModerationOpts} from '../preferences/moderation-opts'
import {FeedDescriptor} from './post-feed'
import {precacheResolvedUri} from './resolve-uri'
@@ -207,14 +209,16 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) {
const limit = options?.limit || 10
const {data: preferences} = usePreferencesQuery()
const queryClient = useQueryClient()
const moderationOpts = useModerationOpts()
// Make sure this doesn't invalidate unless really needed.
const selectArgs = useMemo(
() => ({
hasSession,
savedFeeds: preferences?.savedFeeds || [],
moderationOpts,
}),
[hasSession, preferences?.savedFeeds],
[hasSession, preferences?.savedFeeds, moderationOpts],
)
const lastPageCountRef = useRef(0)
@@ -225,6 +229,7 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) {
QueryKey,
string | undefined
>({
enabled: Boolean(moderationOpts),
queryKey: createGetPopularFeedsQueryKey(options),
queryFn: async ({pageParam}) => {
const res = await agent.app.bsky.unspecced.getPopularFeedGenerators({
@@ -246,7 +251,11 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) {
(
data: InfiniteData<AppBskyUnspeccedGetPopularFeedGenerators.OutputSchema>,
) => {
const {savedFeeds, hasSession: hasSessionInner} = selectArgs
const {
savedFeeds,
hasSession: hasSessionInner,
moderationOpts,
} = selectArgs
return {
...data,
pages: data.pages.map(page => {
@@ -264,7 +273,8 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) {
return f.value === feed.uri
}),
)
return !alreadySaved
const decision = moderateFeedGenerator(feed, moderationOpts!)
return !alreadySaved && !decision.ui('contentList').filter
}),
}
}),
@@ -304,6 +314,8 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) {
export function useSearchPopularFeedsMutation() {
const agent = useAgent()
const moderationOpts = useModerationOpts()
return useMutation({
mutationFn: async (query: string) => {
const res = await agent.app.bsky.unspecced.getPopularFeedGenerators({
@@ -311,24 +323,15 @@ export function useSearchPopularFeedsMutation() {
query: query,
})
return res.data.feeds
},
})
}
export function useSearchPopularFeedsQuery({q}: {q: string}) {
const agent = useAgent()
return useQuery({
queryKey: ['searchPopularFeeds', q],
queryFn: async () => {
const res = await agent.app.bsky.unspecced.getPopularFeedGenerators({
limit: 15,
query: q,
})
if (moderationOpts) {
return res.data.feeds.filter(feed => {
const decision = moderateFeedGenerator(feed, moderationOpts)
return !decision.ui('contentList').filter
})
}
return res.data.feeds
},
placeholderData: keepPreviousData,
})
}
@@ -346,17 +349,27 @@ export function usePopularFeedsSearch({
enabled?: boolean
}) {
const agent = useAgent()
const moderationOpts = useModerationOpts()
const enabledInner = enabled ?? Boolean(moderationOpts)
return useQuery({
enabled,
enabled: enabledInner,
queryKey: createPopularFeedsSearchQueryKey(query),
queryFn: async () => {
const res = await agent.app.bsky.unspecced.getPopularFeedGenerators({
limit: 10,
limit: 15,
query: query,
})
return res.data.feeds
},
placeholderData: keepPreviousData,
select(data) {
return data.filter(feed => {
const decision = moderateFeedGenerator(feed, moderationOpts!)
return !decision.ui('contentList').filter
})
},
})
}