Refactor notifications to use react-query (#1878)

* Move broadcast channel to lib

* Refactor view/com/post/Post and remove temporary 2 components

* Add useModerationOpts hook

* Refactor notifications to use react-query

* Fix: only trigger updates in useModerationOpts when the values have changed

* Implement unread notification tracking

* Add moderation filtering to notifications

* Handle native/push notifications

* Remove dead code

---------

Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
Paul Frazee 2023-11-12 18:13:11 -08:00 committed by GitHub
parent c584a3378d
commit b445c15cc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 941 additions and 1739 deletions

View file

@ -1,7 +1,7 @@
import React from 'react'
import {FlatList, View} from 'react-native'
import {useFocusEffect} from '@react-navigation/native'
import {observer} from 'mobx-react-lite'
import {useQueryClient} from '@tanstack/react-query'
import {
NativeStackScreenProps,
NotificationsTabNavigatorParams,
@ -13,21 +13,21 @@ import {TextLink} from 'view/com/util/Link'
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
import {useStores} from 'state/index'
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
import {useTabFocusEffect} from 'lib/hooks/useTabFocusEffect'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {s, colors} from 'lib/styles'
import {useAnalytics} from 'lib/analytics/analytics'
import {isWeb} from 'platform/detection'
import {logger} from '#/logger'
import {useSetMinimalShellMode} from '#/state/shell'
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed'
type Props = NativeStackScreenProps<
NotificationsTabNavigatorParams,
'Notifications'
>
export const NotificationsScreen = withAuthRequired(
observer(function NotificationsScreenImpl({}: Props) {
function NotificationsScreenImpl({}: Props) {
const store = useStores()
const setMinimalShellMode = useSetMinimalShellMode()
const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll()
@ -35,17 +35,12 @@ export const NotificationsScreen = withAuthRequired(
const {screen} = useAnalytics()
const pal = usePalette('default')
const {isDesktop} = useWebMediaQueries()
const hasNew =
store.me.notifications.hasNewLatest &&
!store.me.notifications.isRefreshing
const unreadNotifs = useUnreadNotifications()
const queryClient = useQueryClient()
const hasNew = !!unreadNotifs
// event handlers
// =
const onPressTryAgain = React.useCallback(() => {
store.me.notifications.refresh()
}, [store])
const scrollToTop = React.useCallback(() => {
scrollElRef.current?.scrollToOffset({offset: 0})
resetMainScroll()
@ -53,8 +48,8 @@ export const NotificationsScreen = withAuthRequired(
const onPressLoadLatest = React.useCallback(() => {
scrollToTop()
store.me.notifications.refresh()
}, [store, scrollToTop])
queryClient.invalidateQueries({queryKey: NOTIFS_RQKEY()})
}, [scrollToTop, queryClient])
// on-visible setup
// =
@ -63,42 +58,14 @@ export const NotificationsScreen = withAuthRequired(
setMinimalShellMode(false)
logger.debug('NotificationsScreen: Updating feed')
const softResetSub = store.onScreenSoftReset(onPressLoadLatest)
store.me.notifications.update()
screen('Notifications')
return () => {
softResetSub.remove()
store.me.notifications.markAllRead()
}
}, [store, screen, onPressLoadLatest, setMinimalShellMode]),
)
useTabFocusEffect(
'Notifications',
React.useCallback(
isInside => {
// on mobile:
// fires with `isInside=true` when the user navigates to the root tab
// but not when the user goes back to the screen by pressing back
// on web:
// essentially equivalent to useFocusEffect because we dont used tabbed
// navigation
if (isInside) {
if (isWeb) {
store.me.notifications.syncQueue()
} else {
if (store.me.notifications.unreadCount > 0) {
store.me.notifications.refresh()
} else {
store.me.notifications.syncQueue()
}
}
}
},
[store],
),
)
const ListHeaderComponent = React.useCallback(() => {
if (isDesktop) {
return (
@ -145,8 +112,6 @@ export const NotificationsScreen = withAuthRequired(
<View testID="notificationsScreen" style={s.hContentRegion}>
<ViewHeader title="Notifications" canGoBack={false} />
<Feed
view={store.me.notifications}
onPressTryAgain={onPressTryAgain}
onScroll={onMainScroll}
scrollElRef={scrollElRef}
ListHeaderComponent={ListHeaderComponent}
@ -160,5 +125,5 @@ export const NotificationsScreen = withAuthRequired(
)}
</View>
)
}),
},
)