Only poll feed when feed page is focused (#2064)
* Do no poll when screen is not focused * Avoid polling unless focused * Handle homepage in background * Fix the intl:check to ignore comments in diffs --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com>zio/stable
parent
f80bd30ef4
commit
9dec9d7276
|
@ -30,7 +30,7 @@
|
||||||
"perf:test:results": "NODE_ENV=test flashlight report .perf/results.json",
|
"perf:test:results": "NODE_ENV=test flashlight report .perf/results.json",
|
||||||
"perf:measure": "NODE_ENV=test flashlight measure",
|
"perf:measure": "NODE_ENV=test flashlight measure",
|
||||||
"intl:build": "yarn intl:check && yarn intl:compile",
|
"intl:build": "yarn intl:check && yarn intl:compile",
|
||||||
"intl:check": "yarn intl:extract && git diff-index --quiet HEAD || (echo '\n⚠️ i18n detected un-extracted translations\n' && exit 1)",
|
"intl:check": "yarn intl:extract && git diff-index -G'(^[^\\*# /])|(^#\\w)|(^\\s+[^\\*#/])' HEAD || (echo '\n⚠️ i18n detected un-extracted translations\n' && exit 1)",
|
||||||
"intl:extract": "lingui extract",
|
"intl:extract": "lingui extract",
|
||||||
"intl:compile": "lingui compile"
|
"intl:compile": "lingui compile"
|
||||||
},
|
},
|
||||||
|
|
|
@ -158,9 +158,9 @@ export function FeedPage({
|
||||||
<View testID={testID} style={s.h100pct}>
|
<View testID={testID} style={s.h100pct}>
|
||||||
<Feed
|
<Feed
|
||||||
testID={testID ? `${testID}-feed` : undefined}
|
testID={testID ? `${testID}-feed` : undefined}
|
||||||
|
enabled={isPageFocused}
|
||||||
feed={feed}
|
feed={feed}
|
||||||
feedParams={feedParams}
|
feedParams={feedParams}
|
||||||
enabled={isPageFocused}
|
|
||||||
pollInterval={POLL_FREQ}
|
pollInterval={POLL_FREQ}
|
||||||
scrollElRef={scrollElRef}
|
scrollElRef={scrollElRef}
|
||||||
onScroll={onMainScroll}
|
onScroll={onMainScroll}
|
||||||
|
|
|
@ -89,7 +89,7 @@ let Feed = ({
|
||||||
const isEmpty = !isFetching && !data?.pages[0]?.slices.length
|
const isEmpty = !isFetching && !data?.pages[0]?.slices.length
|
||||||
|
|
||||||
const checkForNew = React.useCallback(async () => {
|
const checkForNew = React.useCallback(async () => {
|
||||||
if (!data?.pages[0] || isFetching || !onHasNew) {
|
if (!data?.pages[0] || isFetching || !onHasNew || !enabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -99,7 +99,7 @@ let Feed = ({
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('Poll latest failed', {feed, error: String(e)})
|
logger.error('Poll latest failed', {feed, error: String(e)})
|
||||||
}
|
}
|
||||||
}, [feed, data, isFetching, onHasNew])
|
}, [feed, data, isFetching, onHasNew, enabled])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// we store the interval handler in a ref to avoid needless
|
// we store the interval handler in a ref to avoid needless
|
||||||
|
|
|
@ -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} from '@react-navigation/native'
|
import {useFocusEffect, useIsFocused} 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'
|
||||||
|
@ -39,6 +39,7 @@ function HomeScreenReady({
|
||||||
const setMinimalShellMode = useSetMinimalShellMode()
|
const setMinimalShellMode = useSetMinimalShellMode()
|
||||||
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
|
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
|
||||||
const [selectedPage, setSelectedPage] = React.useState(0)
|
const [selectedPage, setSelectedPage] = React.useState(0)
|
||||||
|
const isPageFocused = useIsFocused()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to ensure that we re-compute `customFeeds` AND force a re-render of
|
* Used to ensure that we re-compute `customFeeds` AND force a re-render of
|
||||||
|
@ -132,7 +133,7 @@ function HomeScreenReady({
|
||||||
<FeedPage
|
<FeedPage
|
||||||
key="1"
|
key="1"
|
||||||
testID="followingFeedPage"
|
testID="followingFeedPage"
|
||||||
isPageFocused={selectedPage === 0}
|
isPageFocused={selectedPage === 0 && isPageFocused}
|
||||||
feed={homeFeedParams.mergeFeedEnabled ? 'home' : 'following'}
|
feed={homeFeedParams.mergeFeedEnabled ? 'home' : 'following'}
|
||||||
feedParams={homeFeedParams}
|
feedParams={homeFeedParams}
|
||||||
renderEmptyState={renderFollowingEmptyState}
|
renderEmptyState={renderFollowingEmptyState}
|
||||||
|
@ -143,7 +144,7 @@ function HomeScreenReady({
|
||||||
<FeedPage
|
<FeedPage
|
||||||
key={f}
|
key={f}
|
||||||
testID="customFeedPage"
|
testID="customFeedPage"
|
||||||
isPageFocused={selectedPage === 1 + index}
|
isPageFocused={selectedPage === 1 + index && isPageFocused}
|
||||||
feed={f}
|
feed={f}
|
||||||
renderEmptyState={renderCustomFeedEmptyState}
|
renderEmptyState={renderCustomFeedEmptyState}
|
||||||
/>
|
/>
|
||||||
|
@ -159,7 +160,7 @@ function HomeScreenReady({
|
||||||
tabBarPosition="top">
|
tabBarPosition="top">
|
||||||
<FeedPage
|
<FeedPage
|
||||||
testID="customFeedPage"
|
testID="customFeedPage"
|
||||||
isPageFocused
|
isPageFocused={isPageFocused}
|
||||||
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}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -420,6 +420,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
||||||
<View>
|
<View>
|
||||||
<Feed
|
<Feed
|
||||||
testID="postsFeed"
|
testID="postsFeed"
|
||||||
|
enabled={isFocused}
|
||||||
feed={feed}
|
feed={feed}
|
||||||
pollInterval={30e3}
|
pollInterval={30e3}
|
||||||
scrollElRef={scrollElRef}
|
scrollElRef={scrollElRef}
|
||||||
|
@ -428,7 +429,6 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
||||||
scrollEventThrottle={1}
|
scrollEventThrottle={1}
|
||||||
renderEmptyState={renderPostsEmpty}
|
renderEmptyState={renderPostsEmpty}
|
||||||
headerOffset={headerHeight}
|
headerOffset={headerHeight}
|
||||||
enabled={isFocused}
|
|
||||||
/>
|
/>
|
||||||
{(isScrolledDown || hasNew) && (
|
{(isScrolledDown || hasNew) && (
|
||||||
<LoadLatestBtn
|
<LoadLatestBtn
|
||||||
|
|
|
@ -402,7 +402,7 @@ export function ProfileFeedScreenInner({
|
||||||
isHeaderReady={true}
|
isHeaderReady={true}
|
||||||
renderHeader={renderHeader}
|
renderHeader={renderHeader}
|
||||||
onCurrentPageSelected={onCurrentPageSelected}>
|
onCurrentPageSelected={onCurrentPageSelected}>
|
||||||
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) =>
|
{({onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused}) =>
|
||||||
isPublic ? (
|
isPublic ? (
|
||||||
<FeedSection
|
<FeedSection
|
||||||
ref={feedSectionRef}
|
ref={feedSectionRef}
|
||||||
|
@ -413,6 +413,7 @@ export function ProfileFeedScreenInner({
|
||||||
scrollElRef={
|
scrollElRef={
|
||||||
scrollElRef as React.MutableRefObject<FlatList<any> | null>
|
scrollElRef as React.MutableRefObject<FlatList<any> | null>
|
||||||
}
|
}
|
||||||
|
isFocused={isFocused}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CenteredView sideBorders style={[{paddingTop: headerHeight}]}>
|
<CenteredView sideBorders style={[{paddingTop: headerHeight}]}>
|
||||||
|
@ -492,10 +493,11 @@ interface FeedSectionProps {
|
||||||
headerHeight: number
|
headerHeight: number
|
||||||
isScrolledDown: boolean
|
isScrolledDown: boolean
|
||||||
scrollElRef: React.MutableRefObject<FlatList<any> | null>
|
scrollElRef: React.MutableRefObject<FlatList<any> | null>
|
||||||
|
isFocused: boolean
|
||||||
}
|
}
|
||||||
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
||||||
function FeedSectionImpl(
|
function FeedSectionImpl(
|
||||||
{feed, onScroll, headerHeight, isScrolledDown, scrollElRef},
|
{feed, onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused},
|
||||||
ref,
|
ref,
|
||||||
) {
|
) {
|
||||||
const [hasNew, setHasNew] = React.useState(false)
|
const [hasNew, setHasNew] = React.useState(false)
|
||||||
|
@ -518,6 +520,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<Feed
|
<Feed
|
||||||
|
enabled={isFocused}
|
||||||
feed={feed}
|
feed={feed}
|
||||||
pollInterval={30e3}
|
pollInterval={30e3}
|
||||||
scrollElRef={scrollElRef}
|
scrollElRef={scrollElRef}
|
||||||
|
|
|
@ -159,7 +159,13 @@ function ProfileListScreenLoaded({
|
||||||
isHeaderReady={true}
|
isHeaderReady={true}
|
||||||
renderHeader={renderHeader}
|
renderHeader={renderHeader}
|
||||||
onCurrentPageSelected={onCurrentPageSelected}>
|
onCurrentPageSelected={onCurrentPageSelected}>
|
||||||
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
|
{({
|
||||||
|
onScroll,
|
||||||
|
headerHeight,
|
||||||
|
isScrolledDown,
|
||||||
|
scrollElRef,
|
||||||
|
isFocused,
|
||||||
|
}) => (
|
||||||
<FeedSection
|
<FeedSection
|
||||||
ref={feedSectionRef}
|
ref={feedSectionRef}
|
||||||
feed={`list|${uri}`}
|
feed={`list|${uri}`}
|
||||||
|
@ -169,6 +175,7 @@ function ProfileListScreenLoaded({
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
headerHeight={headerHeight}
|
headerHeight={headerHeight}
|
||||||
isScrolledDown={isScrolledDown}
|
isScrolledDown={isScrolledDown}
|
||||||
|
isFocused={isFocused}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
|
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
|
||||||
|
@ -519,10 +526,11 @@ interface FeedSectionProps {
|
||||||
headerHeight: number
|
headerHeight: number
|
||||||
isScrolledDown: boolean
|
isScrolledDown: boolean
|
||||||
scrollElRef: React.MutableRefObject<FlatList<any> | null>
|
scrollElRef: React.MutableRefObject<FlatList<any> | null>
|
||||||
|
isFocused: boolean
|
||||||
}
|
}
|
||||||
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
||||||
function FeedSectionImpl(
|
function FeedSectionImpl(
|
||||||
{feed, scrollElRef, onScroll, headerHeight, isScrolledDown},
|
{feed, scrollElRef, onScroll, headerHeight, isScrolledDown, isFocused},
|
||||||
ref,
|
ref,
|
||||||
) {
|
) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
@ -545,6 +553,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
|
||||||
<View>
|
<View>
|
||||||
<Feed
|
<Feed
|
||||||
testID="listFeed"
|
testID="listFeed"
|
||||||
|
enabled={isFocused}
|
||||||
feed={feed}
|
feed={feed}
|
||||||
pollInterval={30e3}
|
pollInterval={30e3}
|
||||||
scrollElRef={scrollElRef}
|
scrollElRef={scrollElRef}
|
||||||
|
|
Loading…
Reference in New Issue