about summary refs log tree commit diff
path: root/src/state/queries
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/queries')
-rw-r--r--src/state/queries/feed.ts45
-rw-r--r--src/state/queries/notifications/feed.ts29
-rw-r--r--src/state/queries/post-feed.ts35
-rw-r--r--src/state/queries/profile.ts4
4 files changed, 38 insertions, 75 deletions
diff --git a/src/state/queries/feed.ts b/src/state/queries/feed.ts
index e431643e7..c9d81bc17 100644
--- a/src/state/queries/feed.ts
+++ b/src/state/queries/feed.ts
@@ -161,51 +161,6 @@ export function useFeedSourceInfoQuery({uri}: {uri: string}) {
   })
 }
 
-export const isFeedPublicQueryKey = ({uri}: {uri: string}) => [
-  'isFeedPublic',
-  uri,
-]
-
-export function useIsFeedPublicQuery({uri}: {uri: string}) {
-  return useQuery({
-    queryKey: isFeedPublicQueryKey({uri}),
-    queryFn: async ({queryKey}) => {
-      const [, uri] = queryKey
-      try {
-        const res = await getAgent().app.bsky.feed.getFeed({
-          feed: uri,
-          limit: 1,
-        })
-        return {
-          isPublic: Boolean(res.data.feed),
-          error: undefined,
-        }
-      } catch (e: any) {
-        /**
-         * This should be an `XRPCError`, but I can't safely import from
-         * `@atproto/xrpc` due to a depdency on node's `crypto` module.
-         *
-         * @see https://github.com/bluesky-social/atproto/blob/c17971a2d8e424cc7f10c071d97c07c08aa319cf/packages/xrpc/src/client.ts#L126
-         */
-        if (e?.status === 401) {
-          return {
-            isPublic: false,
-            error: e,
-          }
-        }
-
-        /*
-         * Non-401 response means something else went wrong on the server
-         */
-        return {
-          isPublic: true,
-          error: e,
-        }
-      }
-    },
-  })
-}
-
 export const useGetPopularFeedsQueryKey = ['getPopularFeeds']
 
 export function useGetPopularFeedsQuery() {
diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts
index dc206df79..d652f493d 100644
--- a/src/state/queries/notifications/feed.ts
+++ b/src/state/queries/notifications/feed.ts
@@ -16,7 +16,7 @@
  * 3. Don't call this query's `refetch()` if you're trying to sync latest; call `checkUnread()` instead.
  */
 
-import {useEffect} from 'react'
+import {useEffect, useRef} from 'react'
 import {AppBskyFeedDefs} from '@atproto/api'
 import {
   useInfiniteQuery,
@@ -49,6 +49,7 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) {
   const threadMutes = useMutedThreads()
   const unreads = useUnreadNotificationsApi()
   const enabled = opts?.enabled !== false
+  const lastPageCountRef = useRef(0)
 
   const query = useInfiniteQuery<
     FeedPage,
@@ -104,24 +105,26 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) {
 
   useEffect(() => {
     const {isFetching, hasNextPage, data} = query
+    if (isFetching || !hasNextPage) {
+      return
+    }
+
+    // avoid double-fires of fetchNextPage()
+    if (
+      lastPageCountRef.current !== 0 &&
+      lastPageCountRef.current === data?.pages?.length
+    ) {
+      return
+    }
 
+    // fetch next page if we haven't gotten a full page of content
     let count = 0
-    let numEmpties = 0
     for (const page of data?.pages || []) {
-      if (!page.items.length) {
-        numEmpties++
-      }
       count += page.items.length
     }
-
-    if (
-      !isFetching &&
-      hasNextPage &&
-      count < PAGE_SIZE &&
-      numEmpties < 3 &&
-      (data?.pages.length || 0) < 6
-    ) {
+    if (count < PAGE_SIZE && (data?.pages.length || 0) < 6) {
       query.fetchNextPage()
+      lastPageCountRef.current = data?.pages?.length || 0
     }
   }, [query])
 
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index 423de4ae8..b91af372f 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -1,4 +1,4 @@
-import React, {useCallback, useEffect} from 'react'
+import React, {useCallback, useEffect, useRef} from 'react'
 import {
   AppBskyFeedDefs,
   AppBskyFeedPost,
@@ -78,6 +78,7 @@ export interface FeedPageUnselected {
   api: FeedAPI
   cursor: string | undefined
   feed: AppBskyFeedDefs.FeedViewPost[]
+  fetchedAt: number
 }
 
 export interface FeedPage {
@@ -85,6 +86,7 @@ export interface FeedPage {
   tuner: FeedTuner | NoopFeedTuner
   cursor: string | undefined
   slices: FeedPostSlice[]
+  fetchedAt: number
 }
 
 const PAGE_SIZE = 30
@@ -98,11 +100,12 @@ export function usePostFeedQuery(
   const feedTuners = useFeedTuners(feedDesc)
   const moderationOpts = useModerationOpts()
   const enabled = opts?.enabled !== false && Boolean(moderationOpts)
-  const lastRun = React.useRef<{
+  const lastRun = useRef<{
     data: InfiniteData<FeedPageUnselected>
     args: typeof selectArgs
     result: InfiniteData<FeedPage>
   } | null>(null)
+  const lastPageCountRef = useRef(0)
 
   // Make sure this doesn't invalidate unless really needed.
   const selectArgs = React.useMemo(
@@ -152,6 +155,7 @@ export function usePostFeedQuery(
         api,
         cursor: res.cursor,
         feed: res.feed,
+        fetchedAt: Date.now(),
       }
     },
     initialPageParam: undefined,
@@ -214,6 +218,7 @@ export function usePostFeedQuery(
               api: page.api,
               tuner,
               cursor: page.cursor,
+              fetchedAt: page.fetchedAt,
               slices: tuner
                 .tune(page.feed)
                 .map(slice => {
@@ -279,26 +284,28 @@ export function usePostFeedQuery(
 
   useEffect(() => {
     const {isFetching, hasNextPage, data} = query
+    if (isFetching || !hasNextPage) {
+      return
+    }
+
+    // avoid double-fires of fetchNextPage()
+    if (
+      lastPageCountRef.current !== 0 &&
+      lastPageCountRef.current === data?.pages?.length
+    ) {
+      return
+    }
 
+    // fetch next page if we haven't gotten a full page of content
     let count = 0
-    let numEmpties = 0
     for (const page of data?.pages || []) {
-      if (page.slices.length === 0) {
-        numEmpties++
-      }
       for (const slice of page.slices) {
         count += slice.items.length
       }
     }
-
-    if (
-      !isFetching &&
-      hasNextPage &&
-      count < PAGE_SIZE &&
-      numEmpties < 3 &&
-      (data?.pages.length || 0) < 6
-    ) {
+    if (count < PAGE_SIZE && (data?.pages.length || 0) < 6) {
       query.fetchNextPage()
+      lastPageCountRef.current = data?.pages?.length || 0
     }
   }, [query])
 
diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts
index 5fd0b4e34..40ba0653c 100644
--- a/src/state/queries/profile.ts
+++ b/src/state/queries/profile.ts
@@ -35,9 +35,7 @@ export function useProfileQuery({did}: {did: string | undefined}) {
     // if you remove it, the UI infinite-loops
     // -prf
     staleTime: isCurrentAccount ? STALE.SECONDS.THIRTY : STALE.MINUTES.FIVE,
-    refetchInterval: isCurrentAccount
-      ? STALE.SECONDS.THIRTY
-      : STALE.MINUTES.FIVE,
+    refetchInterval: STALE.MINUTES.FIVE,
     queryKey: RQKEY(did || ''),
     queryFn: async () => {
       const res = await getAgent().getProfile({actor: did || ''})