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:
parent
c584a3378d
commit
b445c15cc9
29 changed files with 941 additions and 1739 deletions
|
@ -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>
|
||||
)
|
||||
}),
|
||||
},
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue