Filter mute words from search

This commit is contained in:
Eric Bailey
2024-10-03 16:46:09 -05:00
parent eb3b01d0ad
commit 939b07155b
+74 -1
View File
@@ -1,3 +1,4 @@
import React from 'react'
import {
AppBskyActorDefs,
AppBskyFeedDefs,
@@ -11,6 +12,8 @@ import {
useInfiniteQuery,
} from '@tanstack/react-query'
import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useAgent} from '#/state/session'
import {
didOrHandleUriMatches,
@@ -35,6 +38,19 @@ export function useSearchPostsQuery({
enabled?: boolean
}) {
const agent = useAgent()
const moderationOpts = useModerationOpts()
const selectArgs = React.useMemo(
() => ({
moderationOpts,
}),
[moderationOpts],
)
const lastRun = React.useRef<{
data: InfiniteData<AppBskyFeedSearchPosts.OutputSchema>
args: typeof selectArgs
result: InfiniteData<AppBskyFeedSearchPosts.OutputSchema>
} | null>(null)
return useInfiniteQuery<
AppBskyFeedSearchPosts.OutputSchema,
Error,
@@ -54,7 +70,64 @@ export function useSearchPostsQuery({
},
initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor,
enabled,
enabled: enabled ?? !!moderationOpts,
select: React.useCallback(
(data: InfiniteData<AppBskyFeedSearchPosts.OutputSchema>) => {
const {moderationOpts} = selectArgs
// Keep track of the last run and whether we can reuse
// some already selected pages from there.
let reusedPages = []
if (lastRun.current) {
const {
data: lastData,
args: lastArgs,
result: lastResult,
} = lastRun.current
let canReuse = true
for (let key in selectArgs) {
if (selectArgs.hasOwnProperty(key)) {
if ((selectArgs as any)[key] !== (lastArgs as any)[key]) {
// Can't do reuse anything if any input has changed.
canReuse = false
break
}
}
}
if (canReuse) {
for (let i = 0; i < data.pages.length; i++) {
if (data.pages[i] && lastData.pages[i] === data.pages[i]) {
reusedPages.push(lastResult.pages[i])
continue
}
// Stop as soon as pages stop matching up.
break
}
}
}
const result = {
...data,
pages: [
...reusedPages,
...data.pages.slice(reusedPages.length).map(page => {
return {
...page,
posts: page.posts.filter(post => {
const mod = moderatePost(post, moderationOpts!)
return !mod.ui('contentList').filter
}),
}
}),
],
}
lastRun.current = {data, result, args: selectArgs}
return result
},
[selectArgs],
),
})
}