Fix: correctly identify if the screen is focused when handling soft resets on post feeds (#2100)
parent
3c8036587e
commit
826b841e10
|
@ -1,5 +1,15 @@
|
||||||
|
import {NavigationProp} from '@react-navigation/native'
|
||||||
import {State, RouteParams} from './types'
|
import {State, RouteParams} from './types'
|
||||||
|
|
||||||
|
export function getRootNavigation<T>(
|
||||||
|
nav: NavigationProp<T>,
|
||||||
|
): NavigationProp<T> {
|
||||||
|
while (nav.getParent()) {
|
||||||
|
nav = nav.getParent()
|
||||||
|
}
|
||||||
|
return nav
|
||||||
|
}
|
||||||
|
|
||||||
export function getCurrentRoute(state: State) {
|
export function getCurrentRoute(state: State) {
|
||||||
let node = state.routes[state.index || 0]
|
let node = state.routes[state.index || 0]
|
||||||
while (node.state?.routes && typeof node.state?.index === 'number') {
|
while (node.state?.routes && typeof node.state?.index === 'number') {
|
||||||
|
|
|
@ -98,7 +98,7 @@ export function usePostFeedQuery(
|
||||||
staleTime: STALE.INFINITY,
|
staleTime: STALE.INFINITY,
|
||||||
queryKey: RQKEY(feedDesc, params),
|
queryKey: RQKEY(feedDesc, params),
|
||||||
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
||||||
logger.debug('usePostFeedQuery', {feedDesc, pageParam})
|
logger.debug('usePostFeedQuery', {feedDesc, cursor: pageParam?.cursor})
|
||||||
|
|
||||||
const {api, cursor} = pageParam
|
const {api, cursor} = pageParam
|
||||||
? pageParam
|
? pageParam
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
import React from 'react'
|
||||||
import {
|
import {
|
||||||
FontAwesomeIcon,
|
FontAwesomeIcon,
|
||||||
FontAwesomeIconStyle,
|
FontAwesomeIconStyle,
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
import {useIsFocused} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
import {useAnalytics} from '@segment/analytics-react-native'
|
import {useAnalytics} from '@segment/analytics-react-native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
|
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
|
||||||
|
@ -12,7 +13,6 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||||
import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
|
import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
|
||||||
import {ComposeIcon2} from 'lib/icons'
|
import {ComposeIcon2} from 'lib/icons'
|
||||||
import {colors, s} from 'lib/styles'
|
import {colors, s} from 'lib/styles'
|
||||||
import React from 'react'
|
|
||||||
import {FlatList, View, useWindowDimensions} from 'react-native'
|
import {FlatList, View, useWindowDimensions} from 'react-native'
|
||||||
import {Feed} from '../posts/Feed'
|
import {Feed} from '../posts/Feed'
|
||||||
import {TextLink} from '../util/Link'
|
import {TextLink} from '../util/Link'
|
||||||
|
@ -24,6 +24,7 @@ import {useSession} from '#/state/session'
|
||||||
import {useComposerControls} from '#/state/shell/composer'
|
import {useComposerControls} from '#/state/shell/composer'
|
||||||
import {listenSoftReset, emitSoftReset} from '#/state/events'
|
import {listenSoftReset, emitSoftReset} from '#/state/events'
|
||||||
import {truncateAndInvalidate} from '#/state/queries/util'
|
import {truncateAndInvalidate} from '#/state/queries/util'
|
||||||
|
import {TabState, getTabState, getRootNavigation} from '#/lib/routes/helpers'
|
||||||
|
|
||||||
const POLL_FREQ = 30e3 // 30sec
|
const POLL_FREQ = 30e3 // 30sec
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ export function FeedPage({
|
||||||
const {isSandbox, hasSession} = useSession()
|
const {isSandbox, hasSession} = useSession()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
const navigation = useNavigation()
|
||||||
const {isDesktop} = useWebMediaQueries()
|
const {isDesktop} = useWebMediaQueries()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const {openComposer} = useComposerControls()
|
const {openComposer} = useComposerControls()
|
||||||
|
@ -52,7 +54,6 @@ export function FeedPage({
|
||||||
const {screen, track} = useAnalytics()
|
const {screen, track} = useAnalytics()
|
||||||
const headerOffset = useHeaderOffset()
|
const headerOffset = useHeaderOffset()
|
||||||
const scrollElRef = React.useRef<FlatList>(null)
|
const scrollElRef = React.useRef<FlatList>(null)
|
||||||
const isScreenFocused = useIsFocused()
|
|
||||||
const [hasNew, setHasNew] = React.useState(false)
|
const [hasNew, setHasNew] = React.useState(false)
|
||||||
|
|
||||||
const scrollToTop = React.useCallback(() => {
|
const scrollToTop = React.useCallback(() => {
|
||||||
|
@ -61,21 +62,24 @@ export function FeedPage({
|
||||||
}, [headerOffset, resetMainScroll])
|
}, [headerOffset, resetMainScroll])
|
||||||
|
|
||||||
const onSoftReset = React.useCallback(() => {
|
const onSoftReset = React.useCallback(() => {
|
||||||
if (isPageFocused) {
|
const isScreenFocused =
|
||||||
|
getTabState(getRootNavigation(navigation).getState(), 'Home') ===
|
||||||
|
TabState.InsideAtRoot
|
||||||
|
if (isScreenFocused && isPageFocused) {
|
||||||
scrollToTop()
|
scrollToTop()
|
||||||
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
|
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
|
||||||
setHasNew(false)
|
setHasNew(false)
|
||||||
}
|
}
|
||||||
}, [isPageFocused, scrollToTop, queryClient, feed, setHasNew])
|
}, [navigation, isPageFocused, scrollToTop, queryClient, feed, setHasNew])
|
||||||
|
|
||||||
// fires when page within screen is activated/deactivated
|
// fires when page within screen is activated/deactivated
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!isPageFocused || !isScreenFocused) {
|
if (!isPageFocused) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
screen('Feed')
|
screen('Feed')
|
||||||
return listenSoftReset(onSoftReset)
|
return listenSoftReset(onSoftReset)
|
||||||
}, [onSoftReset, screen, isPageFocused, isScreenFocused])
|
}, [onSoftReset, screen, isPageFocused])
|
||||||
|
|
||||||
const onPressCompose = React.useCallback(() => {
|
const onPressCompose = React.useCallback(() => {
|
||||||
track('HomeScreen:PressCompose')
|
track('HomeScreen:PressCompose')
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View, ActivityIndicator, StyleSheet} from 'react-native'
|
import {View, ActivityIndicator, StyleSheet} from 'react-native'
|
||||||
import {useFocusEffect, useIsFocused} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
|
||||||
import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
|
import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
|
||||||
import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
|
import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
|
||||||
|
@ -65,7 +65,6 @@ function HomeScreenReady({
|
||||||
const {hasSession} = useSession()
|
const {hasSession} = useSession()
|
||||||
const setMinimalShellMode = useSetMinimalShellMode()
|
const setMinimalShellMode = useSetMinimalShellMode()
|
||||||
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
|
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
|
||||||
const isPageFocused = useIsFocused()
|
|
||||||
const [selectedPage, setSelectedPage] = React.useState<string>(initialPage)
|
const [selectedPage, setSelectedPage] = React.useState<string>(initialPage)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,7 +174,7 @@ function HomeScreenReady({
|
||||||
<FeedPage
|
<FeedPage
|
||||||
key="1"
|
key="1"
|
||||||
testID="followingFeedPage"
|
testID="followingFeedPage"
|
||||||
isPageFocused={selectedPageIndex === 0 && isPageFocused}
|
isPageFocused={selectedPageIndex === 0}
|
||||||
feed={homeFeedParams.mergeFeedEnabled ? 'home' : 'following'}
|
feed={homeFeedParams.mergeFeedEnabled ? 'home' : 'following'}
|
||||||
feedParams={homeFeedParams}
|
feedParams={homeFeedParams}
|
||||||
renderEmptyState={renderFollowingEmptyState}
|
renderEmptyState={renderFollowingEmptyState}
|
||||||
|
@ -186,7 +185,7 @@ function HomeScreenReady({
|
||||||
<FeedPage
|
<FeedPage
|
||||||
key={f}
|
key={f}
|
||||||
testID="customFeedPage"
|
testID="customFeedPage"
|
||||||
isPageFocused={selectedPageIndex === 1 + index && isPageFocused}
|
isPageFocused={selectedPageIndex === 1 + index}
|
||||||
feed={f}
|
feed={f}
|
||||||
renderEmptyState={renderCustomFeedEmptyState}
|
renderEmptyState={renderCustomFeedEmptyState}
|
||||||
/>
|
/>
|
||||||
|
@ -202,7 +201,7 @@ function HomeScreenReady({
|
||||||
tabBarPosition="top">
|
tabBarPosition="top">
|
||||||
<FeedPage
|
<FeedPage
|
||||||
testID="customFeedPage"
|
testID="customFeedPage"
|
||||||
isPageFocused={isPageFocused}
|
isPageFocused={true}
|
||||||
feed={`feedgen|at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot`}
|
feed={`feedgen|at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot`}
|
||||||
renderEmptyState={renderCustomFeedEmptyState}
|
renderEmptyState={renderCustomFeedEmptyState}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue