Multiple notifications fixes (#2154)

* Dont reset notifications feed on push notification event

* Dont separate notifications by read state to avoid jank

* On notifications screen focus, check latest and only rerender if not scrolled down

* Reuse the cached notifs page when its not stale

* Bump ios build number

* Improve comments

* Change the 'mark all read' condition to avoid firing too early
zio/stable
Paul Frazee 2023-12-09 15:09:31 -08:00 committed by GitHub
parent d854e88218
commit 6b3eb401b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 162 additions and 146 deletions

View File

@ -9,7 +9,7 @@ module.exports = function () {
/**
* iOS build number. Must be incremented for each TestFlight version.
*/
const IOS_BUILD_NUMBER = '12'
const IOS_BUILD_NUMBER = '13'
/**
* Android build number. Must be incremented for each release.

View File

@ -81,6 +81,7 @@ export function registerTokenChangeHandler(
export function init(queryClient: QueryClient) {
// handle notifications that are received, both in the foreground or background
// NOTE: currently just here for debug logging
Notifications.addNotificationReceivedListener(event => {
logger.debug(
'Notifications: received',
@ -88,8 +89,6 @@ export function init(queryClient: QueryClient) {
logger.DebugContext.notifications,
)
if (event.request.trigger.type === 'push') {
// refresh notifications in the background
truncateAndInvalidate(queryClient, RQKEY_NOTIFS())
// handle payload-based deeplinks
let payload
if (isIOS) {

View File

@ -38,12 +38,12 @@ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite
msgstr ""
#: src/view/screens/Settings.tsx:407
#: src/view/shell/Drawer.tsx:648
#: src/view/shell/Drawer.tsx:640
msgid "{invitesAvailable} invite code available"
msgstr ""
#: src/view/screens/Settings.tsx:409
#: src/view/shell/Drawer.tsx:650
#: src/view/shell/Drawer.tsx:642
msgid "{invitesAvailable} invite codes available"
msgstr ""
@ -830,16 +830,16 @@ msgid "Feed Preferences"
msgstr ""
#: src/view/shell/desktop/RightNav.tsx:64
#: src/view/shell/Drawer.tsx:300
#: src/view/shell/Drawer.tsx:292
msgid "Feedback"
msgstr ""
#: src/view/screens/Feeds.tsx:475
#: src/view/screens/Profile.tsx:164
#: src/view/shell/bottom-bar/BottomBar.tsx:168
#: src/view/shell/desktop/LeftNav.tsx:341
#: src/view/shell/Drawer.tsx:463
#: src/view/shell/Drawer.tsx:464
#: src/view/shell/bottom-bar/BottomBar.tsx:160
#: src/view/shell/desktop/LeftNav.tsx:333
#: src/view/shell/Drawer.tsx:455
#: src/view/shell/Drawer.tsx:456
msgid "Feeds"
msgstr ""
@ -928,7 +928,7 @@ msgstr ""
#: src/view/com/auth/LoggedOut.tsx:68
#: src/view/com/auth/LoggedOut.tsx:69
#: src/view/com/util/moderation/ScreenHider.tsx:105
#: src/view/shell/desktop/LeftNav.tsx:106
#: src/view/shell/desktop/LeftNav.tsx:103
msgid "Go back"
msgstr ""
@ -950,7 +950,7 @@ msgid "Handle"
msgstr ""
#: src/view/shell/desktop/RightNav.tsx:93
#: src/view/shell/Drawer.tsx:310
#: src/view/shell/Drawer.tsx:302
msgid "Help"
msgstr ""
@ -994,10 +994,10 @@ msgstr ""
#~ msgid "Hmmm, we're having trouble finding this feed. It may have been deleted."
#~ msgstr ""
#: src/view/shell/bottom-bar/BottomBar.tsx:124
#: src/view/shell/desktop/LeftNav.tsx:305
#: src/view/shell/Drawer.tsx:387
#: src/view/shell/Drawer.tsx:388
#: src/view/shell/bottom-bar/BottomBar.tsx:116
#: src/view/shell/desktop/LeftNav.tsx:297
#: src/view/shell/Drawer.tsx:379
#: src/view/shell/Drawer.tsx:380
msgid "Home"
msgstr ""
@ -1063,7 +1063,7 @@ msgstr ""
msgid "Invite code not accepted. Check that you input it correctly and try again."
msgstr ""
#: src/view/shell/Drawer.tsx:629
#: src/view/shell/Drawer.tsx:621
msgid "Invite codes: {invitesAvailable} available"
msgstr ""
@ -1162,9 +1162,9 @@ msgid "List Name"
msgstr ""
#: src/view/screens/Profile.tsx:165
#: src/view/shell/desktop/LeftNav.tsx:381
#: src/view/shell/Drawer.tsx:479
#: src/view/shell/Drawer.tsx:480
#: src/view/shell/desktop/LeftNav.tsx:373
#: src/view/shell/Drawer.tsx:471
#: src/view/shell/Drawer.tsx:472
msgid "Lists"
msgstr ""
@ -1173,7 +1173,7 @@ msgstr ""
msgid "Load more posts"
msgstr ""
#: src/view/screens/Notifications.tsx:130
#: src/view/screens/Notifications.tsx:141
msgid "Load new notifications"
msgstr ""
@ -1224,9 +1224,9 @@ msgstr ""
#: src/view/screens/Moderation.tsx:63
#: src/view/screens/Settings.tsx:563
#: src/view/shell/desktop/LeftNav.tsx:399
#: src/view/shell/Drawer.tsx:498
#: src/view/shell/Drawer.tsx:499
#: src/view/shell/desktop/LeftNav.tsx:391
#: src/view/shell/Drawer.tsx:490
#: src/view/shell/Drawer.tsx:491
msgid "Moderation"
msgstr ""
@ -1300,7 +1300,7 @@ msgstr ""
msgid "My Feeds"
msgstr ""
#: src/view/shell/desktop/LeftNav.tsx:67
#: src/view/shell/desktop/LeftNav.tsx:64
msgid "My Profile"
msgstr ""
@ -1328,11 +1328,11 @@ msgstr ""
#: src/view/screens/ProfileFeed.tsx:451
#: src/view/screens/ProfileList.tsx:212
#: src/view/screens/ProfileList.tsx:244
#: src/view/shell/desktop/LeftNav.tsx:254
#: src/view/shell/desktop/LeftNav.tsx:246
msgid "New post"
msgstr ""
#: src/view/shell/desktop/LeftNav.tsx:264
#: src/view/shell/desktop/LeftNav.tsx:256
msgid "New Post"
msgstr ""
@ -1402,12 +1402,12 @@ msgstr ""
#~ msgid "Note: Third-party apps that display Bluesky content may not respect this setting."
#~ msgstr ""
#: src/view/screens/Notifications.tsx:97
#: src/view/screens/Notifications.tsx:121
#: src/view/shell/bottom-bar/BottomBar.tsx:195
#: src/view/shell/desktop/LeftNav.tsx:363
#: src/view/shell/Drawer.tsx:424
#: src/view/shell/Drawer.tsx:425
#: src/view/screens/Notifications.tsx:108
#: src/view/screens/Notifications.tsx:132
#: src/view/shell/bottom-bar/BottomBar.tsx:187
#: src/view/shell/desktop/LeftNav.tsx:355
#: src/view/shell/Drawer.tsx:416
#: src/view/shell/Drawer.tsx:417
msgid "Notifications"
msgstr ""
@ -1432,7 +1432,7 @@ msgid "Opens configurable language settings"
msgstr ""
#: src/view/shell/desktop/RightNav.tsx:146
#: src/view/shell/Drawer.tsx:630
#: src/view/shell/Drawer.tsx:622
msgid "Opens list of invite codes"
msgstr ""
@ -1592,10 +1592,10 @@ msgstr ""
msgid "Processing..."
msgstr ""
#: src/view/shell/bottom-bar/BottomBar.tsx:237
#: src/view/shell/Drawer.tsx:72
#: src/view/shell/Drawer.tsx:533
#: src/view/shell/Drawer.tsx:534
#: src/view/shell/bottom-bar/BottomBar.tsx:229
#: src/view/shell/Drawer.tsx:69
#: src/view/shell/Drawer.tsx:525
#: src/view/shell/Drawer.tsx:526
msgid "Profile"
msgstr ""
@ -1813,12 +1813,12 @@ msgstr ""
#: src/view/com/util/forms/SearchInput.tsx:64
#: src/view/screens/Search/Search.tsx:381
#: src/view/screens/Search/Search.tsx:533
#: src/view/shell/bottom-bar/BottomBar.tsx:146
#: src/view/shell/desktop/LeftNav.tsx:323
#: src/view/shell/bottom-bar/BottomBar.tsx:138
#: src/view/shell/desktop/LeftNav.tsx:315
#: src/view/shell/desktop/Search.tsx:161
#: src/view/shell/desktop/Search.tsx:170
#: src/view/shell/Drawer.tsx:351
#: src/view/shell/Drawer.tsx:352
#: src/view/shell/Drawer.tsx:343
#: src/view/shell/Drawer.tsx:344
msgid "Search"
msgstr ""
@ -1870,8 +1870,8 @@ msgstr ""
msgid "Send Email"
msgstr ""
#: src/view/shell/Drawer.tsx:284
#: src/view/shell/Drawer.tsx:305
#: src/view/shell/Drawer.tsx:276
#: src/view/shell/Drawer.tsx:297
msgid "Send feedback"
msgstr ""
@ -1904,9 +1904,9 @@ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your f
msgstr ""
#: src/view/screens/Settings.tsx:277
#: src/view/shell/desktop/LeftNav.tsx:435
#: src/view/shell/Drawer.tsx:554
#: src/view/shell/Drawer.tsx:555
#: src/view/shell/desktop/LeftNav.tsx:427
#: src/view/shell/Drawer.tsx:546
#: src/view/shell/Drawer.tsx:547
msgid "Settings"
msgstr ""
@ -2447,7 +2447,7 @@ msgstr ""
#: src/view/screens/Settings.tsx:402
#: src/view/shell/desktop/RightNav.tsx:127
#: src/view/shell/Drawer.tsx:644
#: src/view/shell/Drawer.tsx:636
msgid "Your invite codes are hidden when logged in using an App Password"
msgstr ""

View File

@ -38,12 +38,12 @@ msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite
msgstr ""
#: src/view/screens/Settings.tsx:407
#: src/view/shell/Drawer.tsx:648
#: src/view/shell/Drawer.tsx:640
msgid "{invitesAvailable} invite code available"
msgstr ""
#: src/view/screens/Settings.tsx:409
#: src/view/shell/Drawer.tsx:650
#: src/view/shell/Drawer.tsx:642
msgid "{invitesAvailable} invite codes available"
msgstr ""
@ -826,16 +826,16 @@ msgid "Feed Preferences"
msgstr "फ़ीड प्राथमिकता"
#: src/view/shell/desktop/RightNav.tsx:64
#: src/view/shell/Drawer.tsx:300
#: src/view/shell/Drawer.tsx:292
msgid "Feedback"
msgstr "प्रतिक्रिया"
#: src/view/screens/Feeds.tsx:475
#: src/view/screens/Profile.tsx:164
#: src/view/shell/bottom-bar/BottomBar.tsx:168
#: src/view/shell/desktop/LeftNav.tsx:341
#: src/view/shell/Drawer.tsx:463
#: src/view/shell/Drawer.tsx:464
#: src/view/shell/bottom-bar/BottomBar.tsx:160
#: src/view/shell/desktop/LeftNav.tsx:333
#: src/view/shell/Drawer.tsx:455
#: src/view/shell/Drawer.tsx:456
msgid "Feeds"
msgstr "सभी फ़ीड"
@ -920,7 +920,7 @@ msgstr "प्रारंभ करें"
#: src/view/com/auth/LoggedOut.tsx:68
#: src/view/com/auth/LoggedOut.tsx:69
#: src/view/com/util/moderation/ScreenHider.tsx:105
#: src/view/shell/desktop/LeftNav.tsx:106
#: src/view/shell/desktop/LeftNav.tsx:103
msgid "Go back"
msgstr "वापस जाओ"
@ -942,7 +942,7 @@ msgid "Handle"
msgstr "हैंडल"
#: src/view/shell/desktop/RightNav.tsx:93
#: src/view/shell/Drawer.tsx:310
#: src/view/shell/Drawer.tsx:302
msgid "Help"
msgstr "सहायता"
@ -986,10 +986,10 @@ msgstr ""
#~ msgid "Hmmm, we're having trouble finding this feed. It may have been deleted."
#~ msgstr ""
#: src/view/shell/bottom-bar/BottomBar.tsx:124
#: src/view/shell/desktop/LeftNav.tsx:305
#: src/view/shell/Drawer.tsx:387
#: src/view/shell/Drawer.tsx:388
#: src/view/shell/bottom-bar/BottomBar.tsx:116
#: src/view/shell/desktop/LeftNav.tsx:297
#: src/view/shell/Drawer.tsx:379
#: src/view/shell/Drawer.tsx:380
msgid "Home"
msgstr "होम फीड"
@ -1055,7 +1055,7 @@ msgstr "आमंत्रण कोड"
msgid "Invite code not accepted. Check that you input it correctly and try again."
msgstr ""
#: src/view/shell/Drawer.tsx:629
#: src/view/shell/Drawer.tsx:621
msgid "Invite codes: {invitesAvailable} available"
msgstr ""
@ -1154,9 +1154,9 @@ msgid "List Name"
msgstr "सूची का नाम"
#: src/view/screens/Profile.tsx:165
#: src/view/shell/desktop/LeftNav.tsx:381
#: src/view/shell/Drawer.tsx:479
#: src/view/shell/Drawer.tsx:480
#: src/view/shell/desktop/LeftNav.tsx:373
#: src/view/shell/Drawer.tsx:471
#: src/view/shell/Drawer.tsx:472
msgid "Lists"
msgstr "सूची"
@ -1165,7 +1165,7 @@ msgstr "सूची"
msgid "Load more posts"
msgstr "अधिक पोस्ट लोड करें"
#: src/view/screens/Notifications.tsx:130
#: src/view/screens/Notifications.tsx:141
msgid "Load new notifications"
msgstr "नई सूचनाएं लोड करें"
@ -1216,9 +1216,9 @@ msgstr ""
#: src/view/screens/Moderation.tsx:63
#: src/view/screens/Settings.tsx:563
#: src/view/shell/desktop/LeftNav.tsx:399
#: src/view/shell/Drawer.tsx:498
#: src/view/shell/Drawer.tsx:499
#: src/view/shell/desktop/LeftNav.tsx:391
#: src/view/shell/Drawer.tsx:490
#: src/view/shell/Drawer.tsx:491
msgid "Moderation"
msgstr "मॉडरेशन"
@ -1292,7 +1292,7 @@ msgstr "जन्मदिन"
msgid "My Feeds"
msgstr "मेरी फ़ीड"
#: src/view/shell/desktop/LeftNav.tsx:67
#: src/view/shell/desktop/LeftNav.tsx:64
msgid "My Profile"
msgstr "मेरी प्रोफाइल"
@ -1320,11 +1320,11 @@ msgstr "नया"
#: src/view/screens/ProfileFeed.tsx:451
#: src/view/screens/ProfileList.tsx:212
#: src/view/screens/ProfileList.tsx:244
#: src/view/shell/desktop/LeftNav.tsx:254
#: src/view/shell/desktop/LeftNav.tsx:246
msgid "New post"
msgstr "नई पोस्ट"
#: src/view/shell/desktop/LeftNav.tsx:264
#: src/view/shell/desktop/LeftNav.tsx:256
msgid "New Post"
msgstr "नई पोस्ट"
@ -1394,12 +1394,12 @@ msgstr ""
#~ msgid "Note: Third-party apps that display Bluesky content may not respect this setting."
#~ msgstr ""
#: src/view/screens/Notifications.tsx:97
#: src/view/screens/Notifications.tsx:121
#: src/view/shell/bottom-bar/BottomBar.tsx:195
#: src/view/shell/desktop/LeftNav.tsx:363
#: src/view/shell/Drawer.tsx:424
#: src/view/shell/Drawer.tsx:425
#: src/view/screens/Notifications.tsx:108
#: src/view/screens/Notifications.tsx:132
#: src/view/shell/bottom-bar/BottomBar.tsx:187
#: src/view/shell/desktop/LeftNav.tsx:355
#: src/view/shell/Drawer.tsx:416
#: src/view/shell/Drawer.tsx:417
msgid "Notifications"
msgstr "सूचनाएं"
@ -1424,7 +1424,7 @@ msgid "Opens configurable language settings"
msgstr "भाषा सेटिंग्स खोलें"
#: src/view/shell/desktop/RightNav.tsx:146
#: src/view/shell/Drawer.tsx:630
#: src/view/shell/Drawer.tsx:622
msgid "Opens list of invite codes"
msgstr ""
@ -1584,10 +1584,10 @@ msgstr "गोपनीयता नीति"
msgid "Processing..."
msgstr "प्रसंस्करण..."
#: src/view/shell/bottom-bar/BottomBar.tsx:237
#: src/view/shell/Drawer.tsx:72
#: src/view/shell/Drawer.tsx:533
#: src/view/shell/Drawer.tsx:534
#: src/view/shell/bottom-bar/BottomBar.tsx:229
#: src/view/shell/Drawer.tsx:69
#: src/view/shell/Drawer.tsx:525
#: src/view/shell/Drawer.tsx:526
msgid "Profile"
msgstr "प्रोफ़ाइल"
@ -1805,12 +1805,12 @@ msgstr "सहेजे गए फ़ीड"
#: src/view/com/util/forms/SearchInput.tsx:64
#: src/view/screens/Search/Search.tsx:381
#: src/view/screens/Search/Search.tsx:533
#: src/view/shell/bottom-bar/BottomBar.tsx:146
#: src/view/shell/desktop/LeftNav.tsx:323
#: src/view/shell/bottom-bar/BottomBar.tsx:138
#: src/view/shell/desktop/LeftNav.tsx:315
#: src/view/shell/desktop/Search.tsx:161
#: src/view/shell/desktop/Search.tsx:170
#: src/view/shell/Drawer.tsx:351
#: src/view/shell/Drawer.tsx:352
#: src/view/shell/Drawer.tsx:343
#: src/view/shell/Drawer.tsx:344
msgid "Search"
msgstr "खोज"
@ -1862,8 +1862,8 @@ msgstr "ईमेल भेजें"
msgid "Send Email"
msgstr "ईमेल भेजें"
#: src/view/shell/Drawer.tsx:284
#: src/view/shell/Drawer.tsx:305
#: src/view/shell/Drawer.tsx:276
#: src/view/shell/Drawer.tsx:297
msgid "Send feedback"
msgstr "प्रतिक्रिया भेजें"
@ -1896,9 +1896,9 @@ msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your f
msgstr "इस सेटिंग को अपने निम्नलिखित फ़ीड में अपने सहेजे गए फ़ीड के नमूने दिखाने के लिए \"हाँ\" पर सेट करें। यह एक प्रयोगात्मक विशेषता है।।"
#: src/view/screens/Settings.tsx:277
#: src/view/shell/desktop/LeftNav.tsx:435
#: src/view/shell/Drawer.tsx:554
#: src/view/shell/Drawer.tsx:555
#: src/view/shell/desktop/LeftNav.tsx:427
#: src/view/shell/Drawer.tsx:546
#: src/view/shell/Drawer.tsx:547
msgid "Settings"
msgstr "सेटिंग्स"
@ -2439,7 +2439,7 @@ msgstr "आपका होस्टिंग प्रदाता"
#: src/view/screens/Settings.tsx:402
#: src/view/shell/desktop/RightNav.tsx:127
#: src/view/shell/Drawer.tsx:644
#: src/view/shell/Drawer.tsx:636
msgid "Your invite codes are hidden when logged in using an App Password"
msgstr ""

View File

@ -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,8 @@ 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,
@ -60,17 +62,44 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) {
staleTime: STALE.INFINITY,
queryKey: RQKEY(),
async queryFn({pageParam}: {pageParam: RQPageParam}) {
let page = await fetchPage({
limit: PAGE_SIZE,
cursor: pageParam,
queryClient,
moderationOpts,
threadMutes,
})
let page
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({
limit: PAGE_SIZE,
cursor: pageParam,
queryClient,
moderationOpts,
threadMutes,
})
}
// if the first page has an unread, mark all read
if (!pageParam && page.items[0] && !page.items[0].notification.isRead) {
unreads.markAllRead()
// 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,
}
}
return page

View File

@ -28,7 +28,10 @@ export interface FeedPage {
}
export interface CachedFeedPage {
sessDid: string // used to invalidate on session changes
/**
* if true, the cached page is recent enough to use as the response
*/
usableInFeed: boolean
syncedAt: Date
data: FeedPage | undefined
}

View File

@ -37,7 +37,7 @@ const apiContext = React.createContext<ApiContext>({
})
export function Provider({children}: React.PropsWithChildren<{}>) {
const {hasSession, currentAccount} = useSession()
const {hasSession} = useSession()
const queryClient = useQueryClient()
const moderationOpts = useModerationOpts()
const threadMutes = useMutedThreads()
@ -46,7 +46,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const checkUnreadRef = React.useRef<ApiContext['checkUnread'] | null>(null)
const cacheRef = React.useRef<CachedFeedPage>({
sessDid: currentAccount?.did || '',
usableInFeed: false,
syncedAt: new Date(),
data: undefined,
})
@ -65,7 +65,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
React.useEffect(() => {
const listener = ({data}: MessageEvent) => {
cacheRef.current = {
sessDid: currentAccount?.did || '',
usableInFeed: false,
syncedAt: new Date(),
data: undefined,
}
@ -75,7 +75,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
return () => {
broadcast.removeEventListener('message', listener)
}
}, [setNumUnread, currentAccount])
}, [setNumUnread])
// create API
const api = React.useMemo<ApiContext>(() => {
@ -119,7 +119,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const lastIndexed =
page.items[0] && new Date(page.items[0].notification.indexedAt)
cacheRef.current = {
sessDid: currentAccount?.did || '',
usableInFeed: !!invalidate, // will be used immediately
data: page,
syncedAt: !lastIndexed || now > lastIndexed ? now : lastIndexed,
}
@ -136,14 +136,13 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
},
getCachedUnreadPage() {
// return cached page if was for the current user
// (protects against session changes serving data from the past session)
if (cacheRef.current.sessDid === currentAccount?.did) {
// return cached page if it's marked as fresh enough
if (cacheRef.current.usableInFeed) {
return cacheRef.current.data
}
},
}
}, [setNumUnread, queryClient, moderationOpts, threadMutes, currentAccount])
}, [setNumUnread, queryClient, moderationOpts, threadMutes])
checkUnreadRef.current = api.checkUnread
return (

View File

@ -119,8 +119,7 @@ function groupNotifications(
Math.abs(ts2 - ts) < MS_2DAY &&
notif.reason === groupedNotif.notification.reason &&
notif.reasonSubject === groupedNotif.notification.reasonSubject &&
notif.author.did !== groupedNotif.notification.author.did &&
notif.isRead === groupedNotif.notification.isRead
notif.author.did !== groupedNotif.notification.author.did
) {
groupedNotif.additional = groupedNotif.additional || []
groupedNotif.additional.push(notif)

View File

@ -37,6 +37,7 @@ export function NotificationsScreen({}: Props) {
const setMinimalShellMode = useSetMinimalShellMode()
const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll()
const scrollElRef = React.useRef<FlatList>(null)
const checkLatestRef = React.useRef<() => void | null>()
const {screen} = useAnalytics()
const pal = usePalette('default')
const {isDesktop} = useWebMediaQueries()
@ -63,16 +64,26 @@ export function NotificationsScreen({}: Props) {
}
}, [scrollToTop, queryClient, unreadApi, hasNew])
const onFocusCheckLatest = React.useCallback(() => {
// on focus, check for latest, but only invalidate if the user
// isnt scrolled down to avoid moving content underneath them
unreadApi.checkUnread({invalidate: !isScrolledDown})
}, [unreadApi, isScrolledDown])
checkLatestRef.current = onFocusCheckLatest
// on-visible setup
// =
useFocusEffect(
React.useCallback(() => {
setMinimalShellMode(false)
logger.debug('NotificationsScreen: Updating feed')
logger.debug('NotificationsScreen: Focus')
screen('Notifications')
return listenSoftReset(onPressLoadLatest)
}, [screen, onPressLoadLatest, setMinimalShellMode]),
checkLatestRef.current?.()
}, [screen, setMinimalShellMode]),
)
React.useEffect(() => {
return listenSoftReset(onPressLoadLatest)
}, [onPressLoadLatest])
const ListHeaderComponent = React.useCallback(() => {
if (isDesktop) {

View File

@ -14,7 +14,6 @@ import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {useQueryClient} from '@tanstack/react-query'
import {s, colors} from 'lib/styles'
import {FEEDBACK_FORM_URL, HELP_DESK_URL} from 'lib/constants'
import {
@ -51,9 +50,7 @@ import {useProfileQuery} from '#/state/queries/profile'
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {emitSoftReset} from '#/state/events'
import {useInviteCodesQuery} from '#/state/queries/invites'
import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed'
import {NavSignupCard} from '#/view/shell/NavSignupCard'
import {truncateAndInvalidate} from '#/state/queries/util'
let DrawerProfileCard = ({
account,
@ -109,7 +106,6 @@ export {DrawerProfileCard}
let DrawerContent = ({}: {}): React.ReactNode => {
const theme = useTheme()
const pal = usePalette('default')
const queryClient = useQueryClient()
const setDrawerOpen = useSetDrawerOpen()
const navigation = useNavigation<NavigationProp>()
const {track} = useAnalytics()
@ -140,16 +136,12 @@ let DrawerContent = ({}: {}): React.ReactNode => {
} else if (tabState === TabState.Inside) {
navigation.dispatch(StackActions.popToTop())
} else {
if (tab === 'Notifications') {
// fetch new notifs on view
truncateAndInvalidate(queryClient, NOTIFS_RQKEY())
}
// @ts-ignore must be Home, Search, Notifications, or MyProfile
navigation.navigate(`${tab}Tab`)
}
}
},
[track, navigation, setDrawerOpen, currentAccount, queryClient],
[track, navigation, setDrawerOpen, currentAccount],
)
const onPressHome = React.useCallback(() => onPressTab('Home'), [onPressTab])

View File

@ -1,7 +1,6 @@
import React, {ComponentProps} from 'react'
import {GestureResponderEvent, TouchableOpacity, View} from 'react-native'
import Animated from 'react-native-reanimated'
import {useQueryClient} from '@tanstack/react-query'
import {StackActions} from '@react-navigation/native'
import {BottomTabBarProps} from '@react-navigation/bottom-tabs'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
@ -31,8 +30,6 @@ import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {emitSoftReset} from '#/state/events'
import {useSession} from '#/state/session'
import {useProfileQuery} from '#/state/queries/profile'
import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed'
import {truncateAndInvalidate} from '#/state/queries/util'
type TabOptions = 'Home' | 'Search' | 'Notifications' | 'MyProfile' | 'Feeds'
@ -41,7 +38,6 @@ export function BottomBar({navigation}: BottomTabBarProps) {
const {hasSession, currentAccount} = useSession()
const pal = usePalette('default')
const {_} = useLingui()
const queryClient = useQueryClient()
const safeAreaInsets = useSafeAreaInsets()
const {track} = useAnalytics()
const {footerHeight} = useShellLayout()
@ -61,14 +57,10 @@ export function BottomBar({navigation}: BottomTabBarProps) {
} else if (tabState === TabState.Inside) {
navigation.dispatch(StackActions.popToTop())
} else {
if (tab === 'Notifications') {
// fetch new notifs on view
truncateAndInvalidate(queryClient, NOTIFS_RQKEY())
}
navigation.navigate(`${tab}Tab`)
}
},
[track, navigation, queryClient],
[track, navigation],
)
const onPressHome = React.useCallback(() => onPressTab('Home'), [onPressTab])
const onPressSearch = React.useCallback(

View File

@ -45,10 +45,7 @@ import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {useComposerControls} from '#/state/shell/composer'
import {useFetchHandle} from '#/state/queries/handle'
import {emitSoftReset} from '#/state/events'
import {useQueryClient} from '@tanstack/react-query'
import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed'
import {NavSignupCard} from '#/view/shell/NavSignupCard'
import {truncateAndInvalidate} from '#/state/queries/util'
function ProfileCard() {
const {currentAccount} = useSession()
@ -123,7 +120,6 @@ interface NavItemProps {
}
function NavItem({count, href, icon, iconFilled, label}: NavItemProps) {
const pal = usePalette('default')
const queryClient = useQueryClient()
const {currentAccount} = useSession()
const {isDesktop, isTablet} = useWebMediaQueries()
const [pathName] = React.useMemo(() => router.matchPath(href), [href])
@ -149,14 +145,10 @@ function NavItem({count, href, icon, iconFilled, label}: NavItemProps) {
if (isCurrent) {
emitSoftReset()
} else {
if (href === '/notifications') {
// fetch new notifs on view
truncateAndInvalidate(queryClient, NOTIFS_RQKEY())
}
onPress()
}
},
[onPress, isCurrent, queryClient, href],
[onPress, isCurrent],
)
return (