Filter hidden replies from notifications using cache

This commit is contained in:
Eric Bailey
2024-08-14 11:02:02 -05:00
parent f8ae1014e7
commit ace8ea9daa
+43 -14
View File
@@ -16,7 +16,7 @@
* 3. Don't call this query's `refetch()` if you're trying to sync latest; call `checkUnread()` instead. * 3. Don't call this query's `refetch()` if you're trying to sync latest; call `checkUnread()` instead.
*/ */
import {useEffect, useRef} from 'react' import {useCallback, useEffect, useMemo, useRef} from 'react'
import {AppBskyActorDefs, AppBskyFeedDefs, AtUri} from '@atproto/api' import {AppBskyActorDefs, AppBskyFeedDefs, AtUri} from '@atproto/api'
import { import {
InfiniteData, InfiniteData,
@@ -27,6 +27,7 @@ import {
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
import {useThreadgateHiddenReplyUris} from '#/state/threadgate-hidden-replies'
import {useModerationOpts} from '../../preferences/moderation-opts' import {useModerationOpts} from '../../preferences/moderation-opts'
import {STALE} from '..' import {STALE} from '..'
import { import {
@@ -58,11 +59,18 @@ export function useNotificationFeedQuery(opts?: {
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
const unreads = useUnreadNotificationsApi() const unreads = useUnreadNotificationsApi()
const enabled = opts?.enabled !== false const enabled = opts?.enabled !== false
const {uris: hiddenReplyUris} = useThreadgateHiddenReplyUris()
// false: force showing all notifications // false: force showing all notifications
// undefined: let the server decide // undefined: let the server decide
const priority = opts?.overridePriorityNotifications ? false : undefined const priority = opts?.overridePriorityNotifications ? false : undefined
const selectArgs = useMemo(() => {
return {
hiddenReplyUris,
}
}, [hiddenReplyUris])
const query = useInfiniteQuery< const query = useInfiniteQuery<
FeedPage, FeedPage,
Error, Error,
@@ -101,20 +109,41 @@ export function useNotificationFeedQuery(opts?: {
initialPageParam: undefined, initialPageParam: undefined,
getNextPageParam: lastPage => lastPage.cursor, getNextPageParam: lastPage => lastPage.cursor,
enabled, enabled,
select(data: InfiniteData<FeedPage>) { select: useCallback(
// override 'isRead' using the first page's returned seenAt (data: InfiniteData<FeedPage>) => {
// we do this because the `markAllRead()` call above will const {hiddenReplyUris} = selectArgs
// 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 // 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)
}
}
data = {
...data,
pages: data.pages.map(page => {
return {
...page,
items: page.items.filter(item => {
const isHiddenReply =
item.type === 'reply' &&
item.subjectUri &&
hiddenReplyUris.includes(item.subjectUri)
return !isHiddenReply
}),
}
}),
}
return data
},
[selectArgs],
),
}) })
// The server may end up returning an empty page, a page with too few items, // The server may end up returning an empty page, a page with too few items,