Reduce home polling to the currently active page; also reuse some code

zio/stable
Paul Frazee 2023-03-17 15:14:17 -05:00
parent 93b334cce4
commit 201c21df6d
1 changed files with 100 additions and 183 deletions

View File

@ -36,6 +36,12 @@ export const HomeScreen = withAuthRequired((_opts: Props) => {
const store = useStores() const store = useStores()
const [selectedPage, setSelectedPage] = React.useState(0) const [selectedPage, setSelectedPage] = React.useState(0)
const algoFeed = React.useMemo(() => {
const feed = new FeedModel(store, 'goodstuff', {})
feed.setup()
return feed
}, [store])
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
store.shell.setIsDrawerSwipeDisabled(selectedPage > 0) store.shell.setIsDrawerSwipeDisabled(selectedPage > 0)
@ -62,10 +68,12 @@ export const HomeScreen = withAuthRequired((_opts: Props) => {
onPageSelected={onPageSelected} onPageSelected={onPageSelected}
renderTabBar={renderTabBar} renderTabBar={renderTabBar}
tabBarPosition="bottom"> tabBarPosition="bottom">
<AlgoView key="1" /> <FeedPage key="1" isPageFocused={selectedPage === 0} feed={algoFeed} />
<View key="2"> <FeedPage
<FollowingView /> key="2"
</View> isPageFocused={selectedPage === 1}
feed={store.me.mainFeed}
/>
</Pager> </Pager>
) )
}) })
@ -110,194 +118,103 @@ const FloatingTabBar = observer((props: TabBarProps) => {
) )
}) })
const AlgoView = observer(() => { const FeedPage = observer(
const store = useStores() ({isPageFocused, feed}: {feed: FeedModel; isPageFocused: boolean}) => {
const onMainScroll = useOnMainScroll(store) const store = useStores()
const {screen, track} = useAnalytics() const onMainScroll = useOnMainScroll(store)
const scrollElRef = React.useRef<FlatList>(null) const {screen, track} = useAnalytics()
const {appState} = useAppState({ const scrollElRef = React.useRef<FlatList>(null)
onForeground: () => doPoll(true), const {appState} = useAppState({
}) onForeground: () => doPoll(true),
const isFocused = useIsFocused() })
const winDim = useWindowDimensions() const isScreenFocused = useIsFocused()
const containerStyle = React.useMemo( const winDim = useWindowDimensions()
() => ({height: winDim.height - TAB_BAR_HEIGHT}), const containerStyle = React.useMemo(
[winDim], () => ({height: winDim.height - TAB_BAR_HEIGHT}),
) [winDim],
const algoFeed = React.useMemo(() => { )
const feed = new FeedModel(store, 'goodstuff', {})
feed.setup()
return feed
}, [store])
const doPoll = React.useCallback( const doPoll = React.useCallback(
(knownActive = false) => { (knownActive = false) => {
if ((!knownActive && appState !== 'active') || !isFocused) { if (
return (!knownActive && appState !== 'active') ||
} !isScreenFocused ||
if (algoFeed.isLoading) { !isPageFocused
return ) {
} return
store.log.debug('HomeScreen: Polling for new posts') }
algoFeed.checkForLatest() if (feed.isLoading) {
}, return
[appState, isFocused, store, algoFeed], }
) store.log.debug('HomeScreen: Polling for new posts')
feed.checkForLatest()
},
[appState, isScreenFocused, isPageFocused, store, feed],
)
const scrollToTop = React.useCallback(() => { const scrollToTop = React.useCallback(() => {
scrollElRef.current?.scrollToOffset({offset: 0}) scrollElRef.current?.scrollToOffset({offset: 0})
}, [scrollElRef]) }, [scrollElRef])
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
const softResetSub = store.onScreenSoftReset(scrollToTop) const softResetSub = store.onScreenSoftReset(scrollToTop)
const feedCleanup = algoFeed.registerListeners() const feedCleanup = feed.registerListeners()
const pollInterval = setInterval(doPoll, 15e3) const pollInterval = setInterval(doPoll, 15e3)
screen('Feed') screen('Feed')
store.log.debug('HomeScreen: Updating feed') store.log.debug('HomeScreen: Updating feed')
if (algoFeed.hasContent) { if (feed.hasContent) {
algoFeed.update() feed.update()
} }
return () => { return () => {
clearInterval(pollInterval) clearInterval(pollInterval)
softResetSub.remove() softResetSub.remove()
feedCleanup() feedCleanup()
} }
}, [store, doPoll, scrollToTop, screen, algoFeed]), }, [store, doPoll, scrollToTop, screen, feed]),
) )
const onPressCompose = React.useCallback(() => { const onPressCompose = React.useCallback(() => {
track('HomeScreen:PressCompose') track('HomeScreen:PressCompose')
store.shell.openComposer({}) store.shell.openComposer({})
}, [store, track]) }, [store, track])
const onPressTryAgain = React.useCallback(() => { const onPressTryAgain = React.useCallback(() => {
algoFeed.refresh() feed.refresh()
}, [algoFeed]) }, [feed])
const onPressLoadLatest = React.useCallback(() => { const onPressLoadLatest = React.useCallback(() => {
algoFeed.refresh() feed.refresh()
scrollToTop() scrollToTop()
}, [algoFeed, scrollToTop]) }, [feed, scrollToTop])
return ( return (
<View style={containerStyle}> <View style={containerStyle}>
{store.shell.isOnboarding && <WelcomeBanner />} {store.shell.isOnboarding && <WelcomeBanner />}
<Feed <Feed
testID="homeFeed" testID="homeFeed"
key="default" key="default"
feed={algoFeed} feed={feed}
scrollElRef={scrollElRef} scrollElRef={scrollElRef}
style={s.hContentRegion} style={s.hContentRegion}
showPostFollowBtn showPostFollowBtn
onPressTryAgain={onPressTryAgain} onPressTryAgain={onPressTryAgain}
onScroll={onMainScroll} onScroll={onMainScroll}
/> />
{algoFeed.hasNewLatest && !algoFeed.isRefreshing && ( {feed.hasNewLatest && !feed.isRefreshing && (
<LoadLatestBtn onPress={onPressLoadLatest} /> <LoadLatestBtn onPress={onPressLoadLatest} />
)} )}
<FAB <FAB
testID="composeFAB" testID="composeFAB"
onPress={onPressCompose} onPress={onPressCompose}
icon={<ComposeIcon2 strokeWidth={1.5} size={29} style={s.white} />} icon={<ComposeIcon2 strokeWidth={1.5} size={29} style={s.white} />}
/> />
</View> </View>
) )
}) },
)
const FollowingView = observer(() => {
const store = useStores()
const onMainScroll = useOnMainScroll(store)
const {screen, track} = useAnalytics()
const scrollElRef = React.useRef<FlatList>(null)
const {appState} = useAppState({
onForeground: () => doPoll(true),
})
const isFocused = useIsFocused()
const winDim = useWindowDimensions()
const containerStyle = React.useMemo(
() => ({height: winDim.height - TAB_BAR_HEIGHT}),
[winDim],
)
const doPoll = React.useCallback(
(knownActive = false) => {
if ((!knownActive && appState !== 'active') || !isFocused) {
return
}
if (store.me.mainFeed.isLoading) {
return
}
store.log.debug('HomeScreen: Polling for new posts')
store.me.mainFeed.checkForLatest()
},
[appState, isFocused, store],
)
const scrollToTop = React.useCallback(() => {
scrollElRef.current?.scrollToOffset({offset: 0})
}, [scrollElRef])
useFocusEffect(
React.useCallback(() => {
const softResetSub = store.onScreenSoftReset(scrollToTop)
const feedCleanup = store.me.mainFeed.registerListeners()
const pollInterval = setInterval(doPoll, 15e3)
screen('Feed')
store.log.debug('HomeScreen: Updating feed')
if (store.me.mainFeed.hasContent) {
store.me.mainFeed.update()
}
return () => {
clearInterval(pollInterval)
softResetSub.remove()
feedCleanup()
}
}, [store, doPoll, scrollToTop, screen]),
)
const onPressCompose = React.useCallback(() => {
track('HomeScreen:PressCompose')
store.shell.openComposer({})
}, [store, track])
const onPressTryAgain = React.useCallback(() => {
store.me.mainFeed.refresh()
}, [store])
const onPressLoadLatest = React.useCallback(() => {
store.me.mainFeed.refresh()
scrollToTop()
}, [store, scrollToTop])
return (
<View style={containerStyle}>
{store.shell.isOnboarding && <WelcomeBanner />}
<Feed
testID="homeFeed"
key="default"
feed={store.me.mainFeed}
scrollElRef={scrollElRef}
style={s.hContentRegion}
showPostFollowBtn
onPressTryAgain={onPressTryAgain}
onScroll={onMainScroll}
/>
{store.me.mainFeed.hasNewLatest && !store.me.mainFeed.isRefreshing && (
<LoadLatestBtn onPress={onPressLoadLatest} />
)}
<FAB
testID="composeFAB"
onPress={onPressCompose}
icon={<ComposeIcon2 strokeWidth={1.5} size={29} style={s.white} />}
/>
</View>
)
})
const styles = StyleSheet.create({ const styles = StyleSheet.create({
tabBar: { tabBar: {