about summary refs log tree commit diff
path: root/src/state/queries/post-feed.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/queries/post-feed.ts')
-rw-r--r--src/state/queries/post-feed.ts145
1 files changed, 74 insertions, 71 deletions
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index 113e6f2fb..74c0c064e 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -1,5 +1,4 @@
-import {useCallback, useMemo} from 'react'
-import {AppBskyFeedDefs, AppBskyFeedPost, moderatePost} from '@atproto/api'
+import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api'
 import {
   useInfiniteQuery,
   InfiniteData,
@@ -7,9 +6,8 @@ import {
   QueryClient,
   useQueryClient,
 } from '@tanstack/react-query'
-import {getAgent} from '../session'
 import {useFeedTuners} from '../preferences/feed-tuners'
-import {FeedTuner, NoopFeedTuner} from 'lib/api/feed-manip'
+import {FeedTuner, FeedTunerFn, NoopFeedTuner} from 'lib/api/feed-manip'
 import {FeedAPI, ReasonFeedSource} from 'lib/api/feed/types'
 import {FollowingFeedAPI} from 'lib/api/feed/following'
 import {AuthorFeedAPI} from 'lib/api/feed/author'
@@ -17,7 +15,6 @@ import {LikesFeedAPI} from 'lib/api/feed/likes'
 import {CustomFeedAPI} from 'lib/api/feed/custom'
 import {ListFeedAPI} from 'lib/api/feed/list'
 import {MergeFeedAPI} from 'lib/api/feed/merge'
-import {useModerationOpts} from '#/state/queries/preferences'
 import {logger} from '#/logger'
 import {STALE} from '#/state/queries'
 import {precacheFeedPosts as precacheResolvedUris} from './resolve-uri'
@@ -42,7 +39,9 @@ export interface FeedParams {
   mergeFeedSources?: string[]
 }
 
-type RQPageParam = string | undefined
+type RQPageParam =
+  | {cursor: string | undefined; api: FeedAPI; tuner: FeedTuner | NoopFeedTuner}
+  | undefined
 
 export function RQKEY(feedDesc: FeedDescriptor, params?: FeedParams) {
   return ['post-feed', feedDesc, params || {}]
@@ -64,6 +63,8 @@ export interface FeedPostSlice {
 }
 
 export interface FeedPage {
+  api: FeedAPI
+  tuner: FeedTuner | NoopFeedTuner
   cursor: string | undefined
   slices: FeedPostSlice[]
 }
@@ -76,65 +77,8 @@ export function usePostFeedQuery(
   const queryClient = useQueryClient()
   const feedTuners = useFeedTuners(feedDesc)
   const enabled = opts?.enabled !== false
-  const moderationOpts = useModerationOpts()
-  const agent = getAgent()
 
-  const api: FeedAPI = useMemo(() => {
-    if (feedDesc === 'home') {
-      return new MergeFeedAPI(agent, params || {}, feedTuners)
-    } else if (feedDesc === 'following') {
-      return new FollowingFeedAPI(agent)
-    } else if (feedDesc.startsWith('author')) {
-      const [_, actor, filter] = feedDesc.split('|')
-      return new AuthorFeedAPI(agent, {actor, filter})
-    } else if (feedDesc.startsWith('likes')) {
-      const [_, actor] = feedDesc.split('|')
-      return new LikesFeedAPI(agent, {actor})
-    } else if (feedDesc.startsWith('feedgen')) {
-      const [_, feed] = feedDesc.split('|')
-      return new CustomFeedAPI(agent, {feed})
-    } else if (feedDesc.startsWith('list')) {
-      const [_, list] = feedDesc.split('|')
-      return new ListFeedAPI(agent, {list})
-    } else {
-      // shouldnt happen
-      return new FollowingFeedAPI(agent)
-    }
-  }, [feedDesc, params, feedTuners, agent])
-
-  const disableTuner = !!params?.disableTuner
-  const tuner = useMemo(
-    () => (disableTuner ? new NoopFeedTuner() : new FeedTuner()),
-    [disableTuner],
-  )
-
-  const pollLatest = useCallback(async () => {
-    if (!enabled) {
-      return false
-    }
-
-    logger.debug('usePostFeedQuery: pollLatest')
-
-    const post = await api.peekLatest()
-
-    if (post && moderationOpts) {
-      const slices = tuner.tune([post], feedTuners, {
-        dryRun: true,
-        maintainOrder: true,
-      })
-      if (slices[0]) {
-        if (
-          !moderatePost(slices[0].items[0].post, moderationOpts).content.filter
-        ) {
-          return true
-        }
-      }
-    }
-
-    return false
-  }, [api, tuner, feedTuners, moderationOpts, enabled])
-
-  const out = useInfiniteQuery<
+  return useInfiniteQuery<
     FeedPage,
     Error,
     InfiniteData<FeedPage>,
@@ -145,13 +89,23 @@ export function usePostFeedQuery(
     queryKey: RQKEY(feedDesc, params),
     async queryFn({pageParam}: {pageParam: RQPageParam}) {
       logger.debug('usePostFeedQuery', {feedDesc, pageParam})
-      if (!pageParam) {
-        tuner.reset()
-      }
-      const res = await api.fetch({cursor: pageParam, limit: 30})
+
+      const {api, tuner, cursor} = pageParam
+        ? pageParam
+        : {
+            api: createApi(feedDesc, params || {}, feedTuners),
+            tuner: params?.disableTuner
+              ? new NoopFeedTuner()
+              : new FeedTuner(feedTuners),
+            cursor: undefined,
+          }
+
+      const res = await api.fetch({cursor, limit: 30})
       precacheResolvedUris(queryClient, res.feed) // precache the handle->did resolution
-      const slices = tuner.tune(res.feed, feedTuners)
+      const slices = tuner.tune(res.feed)
       return {
+        api,
+        tuner,
         cursor: res.cursor,
         slices: slices.map(slice => ({
           _reactKey: slice._reactKey,
@@ -182,11 +136,60 @@ export function usePostFeedQuery(
       }
     },
     initialPageParam: undefined,
-    getNextPageParam: lastPage => lastPage.cursor,
+    getNextPageParam: lastPage => ({
+      api: lastPage.api,
+      tuner: lastPage.tuner,
+      cursor: lastPage.cursor,
+    }),
     enabled,
   })
+}
+
+export async function pollLatest(page: FeedPage | undefined) {
+  if (!page) {
+    return false
+  }
+
+  logger.debug('usePostFeedQuery: pollLatest')
+  const post = await page.api.peekLatest()
+  if (post) {
+    const slices = page.tuner.tune([post], {
+      dryRun: true,
+      maintainOrder: true,
+    })
+    if (slices[0]) {
+      return true
+    }
+  }
+
+  return false
+}
 
-  return {...out, pollLatest}
+function createApi(
+  feedDesc: FeedDescriptor,
+  params: FeedParams,
+  feedTuners: FeedTunerFn[],
+) {
+  if (feedDesc === 'home') {
+    return new MergeFeedAPI(params, feedTuners)
+  } else if (feedDesc === 'following') {
+    return new FollowingFeedAPI()
+  } else if (feedDesc.startsWith('author')) {
+    const [_, actor, filter] = feedDesc.split('|')
+    return new AuthorFeedAPI({actor, filter})
+  } else if (feedDesc.startsWith('likes')) {
+    const [_, actor] = feedDesc.split('|')
+    return new LikesFeedAPI({actor})
+  } else if (feedDesc.startsWith('feedgen')) {
+    const [_, feed] = feedDesc.split('|')
+    return new CustomFeedAPI({feed})
+  } else if (feedDesc.startsWith('list')) {
+    const [_, list] = feedDesc.split('|')
+    return new ListFeedAPI({list})
+  } else {
+    // shouldnt happen
+    return new FollowingFeedAPI()
+  }
 }
 
 /**