Fix: correctly identify if the screen is focused when handling soft resets on post feeds (#2100)

zio/stable
Paul Frazee 2023-12-05 18:01:08 -08:00 committed by GitHub
parent 3c8036587e
commit 826b841e10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 13 deletions

View File

@ -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') {

View File

@ -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

View File

@ -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')

View File

@ -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}
/> />