diff options
Diffstat (limited to 'src/state/queries/notifications/feed.ts')
-rw-r--r-- | src/state/queries/notifications/feed.ts | 44 |
1 files changed, 18 insertions, 26 deletions
diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts index 1610fc0bf..82eda06ea 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, useRef} from 'react' +import {useEffect} from 'react' import {AppBskyFeedDefs} from '@atproto/api' import { useInfiniteQuery, @@ -49,8 +49,6 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { const threadMutes = useMutedThreads() const unreads = useUnreadNotificationsApi() const enabled = opts?.enabled !== false - // state tracked across page fetches - const pageState = useRef({pageNum: 0, hasMarkedRead: false}) const query = useInfiniteQuery< FeedPage, @@ -66,8 +64,6 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { if (!pageParam) { // for the first page, we check the cached page held by the unread-checker first page = unreads.getCachedUnreadPage() - // reset the page state - pageState.current = {pageNum: 0, hasMarkedRead: false} } if (!page) { page = await fetchPage({ @@ -80,27 +76,9 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { }) } - // NOTE - // this section checks to see if we need to mark notifs read - // we want to wait until we've seen a read notification because - // of a timing challenge; marking read on the first page would - // cause subsequent pages of unread notifs to incorrectly come - // back as "read". we use page 6 as an abort condition, which means - // after ~180 notifs we give up on tracking unread state correctly - // -prf - if (!pageState.current.hasMarkedRead) { - let hasMarkedRead = false - if ( - pageState.current.pageNum > 5 || - page.items.some(item => item.notification.isRead) - ) { - unreads.markAllRead() - hasMarkedRead = true - } - pageState.current = { - pageNum: pageState.current.pageNum + 1, - hasMarkedRead, - } + // if the first page has an unread, mark all read + if (!pageParam && page.items[0] && !page.items[0].notification.isRead) { + unreads.markAllRead() } return page @@ -108,6 +86,20 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { initialPageParam: undefined, getNextPageParam: lastPage => lastPage.cursor, enabled, + select(data: InfiniteData<FeedPage>) { + // override 'isRead' using the first page's returned seenAt + // we do this because the `markAllRead()` call above will + // mark subsequent pages as read prematurely + const seenAt = data.pages[0]?.seenAt || new Date() + for (const page of data.pages) { + for (const item of page.items) { + item.notification.isRead = + seenAt > new Date(item.notification.indexedAt) + } + } + + return data + }, }) useEffect(() => { |