···1616 * 3. Don't call this query's `refetch()` if you're trying to sync latest; call `checkUnread()` instead.
1717 */
18181919-import {useEffect, useRef} from 'react'
1919+import {useEffect} from 'react'
2020import {AppBskyFeedDefs} from '@atproto/api'
2121import {
2222 useInfiniteQuery,
···4949 const threadMutes = useMutedThreads()
5050 const unreads = useUnreadNotificationsApi()
5151 const enabled = opts?.enabled !== false
5252- // state tracked across page fetches
5353- const pageState = useRef({pageNum: 0, hasMarkedRead: false})
54525553 const query = useInfiniteQuery<
5654 FeedPage,
···6664 if (!pageParam) {
6765 // for the first page, we check the cached page held by the unread-checker first
6866 page = unreads.getCachedUnreadPage()
6969- // reset the page state
7070- pageState.current = {pageNum: 0, hasMarkedRead: false}
7167 }
7268 if (!page) {
7369 page = await fetchPage({
···8076 })
8177 }
82788383- // NOTE
8484- // this section checks to see if we need to mark notifs read
8585- // we want to wait until we've seen a read notification because
8686- // of a timing challenge; marking read on the first page would
8787- // cause subsequent pages of unread notifs to incorrectly come
8888- // back as "read". we use page 6 as an abort condition, which means
8989- // after ~180 notifs we give up on tracking unread state correctly
9090- // -prf
9191- if (!pageState.current.hasMarkedRead) {
9292- let hasMarkedRead = false
9393- if (
9494- pageState.current.pageNum > 5 ||
9595- page.items.some(item => item.notification.isRead)
9696- ) {
9797- unreads.markAllRead()
9898- hasMarkedRead = true
9999- }
100100- pageState.current = {
101101- pageNum: pageState.current.pageNum + 1,
102102- hasMarkedRead,
103103- }
7979+ // if the first page has an unread, mark all read
8080+ if (!pageParam && page.items[0] && !page.items[0].notification.isRead) {
8181+ unreads.markAllRead()
10482 }
1058310684 return page
···10886 initialPageParam: undefined,
10987 getNextPageParam: lastPage => lastPage.cursor,
11088 enabled,
8989+ select(data: InfiniteData<FeedPage>) {
9090+ // override 'isRead' using the first page's returned seenAt
9191+ // we do this because the `markAllRead()` call above will
9292+ // mark subsequent pages as read prematurely
9393+ const seenAt = data.pages[0]?.seenAt || new Date()
9494+ for (const page of data.pages) {
9595+ for (const item of page.items) {
9696+ item.notification.isRead =
9797+ seenAt > new Date(item.notification.indexedAt)
9898+ }
9999+ }
100100+101101+ return data
102102+ },
111103 })
112104113105 useEffect(() => {