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/notifications/feed.ts34
-rw-r--r--src/state/queries/notifications/settings.ts9
-rw-r--r--src/state/queries/notifications/unread.tsx16
-rw-r--r--src/state/queries/notifications/util.ts5
-rw-r--r--src/state/queries/util.ts4
5 files changed, 45 insertions, 23 deletions
diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts
index 19a92fc3c..72100a624 100644
--- a/src/state/queries/notifications/feed.ts
+++ b/src/state/queries/notifications/feed.ts
@@ -52,25 +52,22 @@ const PAGE_SIZE = 30
 type RQPageParam = string | undefined
 
 const RQKEY_ROOT = 'notification-feed'
-export function RQKEY(priority?: false) {
-  return [RQKEY_ROOT, priority]
+export function RQKEY(filter: 'all' | 'mentions') {
+  return [RQKEY_ROOT, filter]
 }
 
-export function useNotificationFeedQuery(opts?: {
+export function useNotificationFeedQuery(opts: {
   enabled?: boolean
-  overridePriorityNotifications?: boolean
+  filter: 'all' | 'mentions'
 }) {
   const agent = useAgent()
   const queryClient = useQueryClient()
   const moderationOpts = useModerationOpts()
   const unreads = useUnreadNotificationsApi()
-  const enabled = opts?.enabled !== false
+  const enabled = opts.enabled !== false
+  const filter = opts.filter
   const {uris: hiddenReplyUris} = useThreadgateHiddenReplyUris()
 
-  // false: force showing all notifications
-  // undefined: let the server decide
-  const priority = opts?.overridePriorityNotifications ? false : undefined
-
   const selectArgs = useMemo(() => {
     return {
       moderationOpts,
@@ -91,14 +88,23 @@ export function useNotificationFeedQuery(opts?: {
     RQPageParam
   >({
     staleTime: STALE.INFINITY,
-    queryKey: RQKEY(priority),
+    queryKey: RQKEY(filter),
     async queryFn({pageParam}: {pageParam: RQPageParam}) {
       let page
-      if (!pageParam) {
+      if (filter === 'all' && !pageParam) {
         // for the first page, we check the cached page held by the unread-checker first
         page = unreads.getCachedUnreadPage()
       }
       if (!page) {
+        let reasons: string[] = []
+        if (filter === 'mentions') {
+          reasons = [
+            // Anything that's a post
+            'mention',
+            'reply',
+            'quote',
+          ]
+        }
         const {page: fetchedPage} = await fetchPage({
           agent,
           limit: PAGE_SIZE,
@@ -106,13 +112,13 @@ export function useNotificationFeedQuery(opts?: {
           queryClient,
           moderationOpts,
           fetchAdditionalData: true,
-          priority,
+          reasons,
         })
         page = fetchedPage
       }
 
-      // if the first page has an unread, mark all read
-      if (!pageParam) {
+      if (filter === 'all' && !pageParam) {
+        // if the first page has an unread, mark all read
         unreads.markAllRead()
       }
 
diff --git a/src/state/queries/notifications/settings.ts b/src/state/queries/notifications/settings.ts
index a17fce832..e552b6520 100644
--- a/src/state/queries/notifications/settings.ts
+++ b/src/state/queries/notifications/settings.ts
@@ -45,7 +45,8 @@ export function useNotificationSettingsMutation() {
     },
     onSettled: () => {
       invalidateCachedUnreadPage()
-      queryClient.invalidateQueries({queryKey: RQKEY_NOTIFS()})
+      queryClient.invalidateQueries({queryKey: RQKEY_NOTIFS('all')})
+      queryClient.invalidateQueries({queryKey: RQKEY_NOTIFS('mentions')})
     },
   })
 }
@@ -54,7 +55,7 @@ function eagerlySetCachedPriority(
   queryClient: ReturnType<typeof useQueryClient>,
   enabled: boolean,
 ) {
-  queryClient.setQueryData(RQKEY_NOTIFS(), (old: any) => {
+  function updateData(old: any) {
     if (!old) return old
     return {
       ...old,
@@ -65,5 +66,7 @@ function eagerlySetCachedPriority(
         }
       }),
     }
-  })
+  }
+  queryClient.setQueryData(RQKEY_NOTIFS('all'), updateData)
+  queryClient.setQueryData(RQKEY_NOTIFS('mentions'), updateData)
 }
diff --git a/src/state/queries/notifications/unread.tsx b/src/state/queries/notifications/unread.tsx
index 2ade04246..ba2377a78 100644
--- a/src/state/queries/notifications/unread.tsx
+++ b/src/state/queries/notifications/unread.tsx
@@ -2,7 +2,7 @@
  * A kind of companion API to ./feed.ts. See that file for more info.
  */
 
-import React from 'react'
+import React, {useRef} from 'react'
 import {AppState} from 'react-native'
 import {useQueryClient} from '@tanstack/react-query'
 import EventEmitter from 'eventemitter3'
@@ -105,6 +105,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
     }
   }, [setNumUnread])
 
+  const isFetchingRef = useRef(false)
+
   // create API
   const api = React.useMemo<ApiContext>(() => {
     return {
@@ -138,6 +140,12 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
             }
           }
 
+          if (isFetchingRef.current) {
+            return
+          }
+          // Do not move this without ensuring it gets a symmetrical reset in the finally block.
+          isFetchingRef.current = true
+
           // count
           const {page, indexedAt: lastIndexed} = await fetchPage({
             agent,
@@ -145,6 +153,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
             limit: 40,
             queryClient,
             moderationOpts,
+            reasons: [],
 
             // only fetch subjects when the page is going to be used
             // in the notifications query, otherwise skip it
@@ -174,11 +183,14 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
           // update & broadcast
           setNumUnread(unreadCountStr)
           if (invalidate) {
-            truncateAndInvalidate(queryClient, RQKEY_NOTIFS())
+            truncateAndInvalidate(queryClient, RQKEY_NOTIFS('all'))
+            truncateAndInvalidate(queryClient, RQKEY_NOTIFS('mentions'))
           }
           broadcast.postMessage({event: unreadCountStr})
         } catch (e) {
           logger.warn('Failed to check unread notifications', {error: e})
+        } finally {
+          isFetchingRef.current = false
         }
       },
 
diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts
index a251d170e..0d72e9e92 100644
--- a/src/state/queries/notifications/util.ts
+++ b/src/state/queries/notifications/util.ts
@@ -31,6 +31,7 @@ export async function fetchPage({
   queryClient,
   moderationOpts,
   fetchAdditionalData,
+  reasons,
 }: {
   agent: BskyAgent
   cursor: string | undefined
@@ -38,7 +39,7 @@ export async function fetchPage({
   queryClient: QueryClient
   moderationOpts: ModerationOpts | undefined
   fetchAdditionalData: boolean
-  priority?: boolean
+  reasons: string[]
 }): Promise<{
   page: FeedPage
   indexedAt: string | undefined
@@ -46,7 +47,7 @@ export async function fetchPage({
   const res = await agent.listNotifications({
     limit,
     cursor,
-    // priority,
+    reasons,
   })
 
   const indexedAt = res.data.notifications[0]?.indexedAt
diff --git a/src/state/queries/util.ts b/src/state/queries/util.ts
index 0d6a8e99a..887c1df0a 100644
--- a/src/state/queries/util.ts
+++ b/src/state/queries/util.ts
@@ -8,7 +8,7 @@ import {
 } from '@atproto/api'
 import {InfiniteData, QueryClient, QueryKey} from '@tanstack/react-query'
 
-export function truncateAndInvalidate<T = any>(
+export async function truncateAndInvalidate<T = any>(
   queryClient: QueryClient,
   queryKey: QueryKey,
 ) {
@@ -21,7 +21,7 @@ export function truncateAndInvalidate<T = any>(
     }
     return data
   })
-  queryClient.invalidateQueries({queryKey})
+  return queryClient.invalidateQueries({queryKey})
 }
 
 // Given an AtUri, this function will check if the AtUri matches a