diff options
Diffstat (limited to 'src/view/screens/Home.tsx')
-rw-r--r-- | src/view/screens/Home.tsx | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 4222c7513..de7e61ba4 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -1,23 +1,24 @@ import React, {useEffect} from 'react' -import {View} from 'react-native' +import {FlatList, View} from 'react-native' import {observer} from 'mobx-react-lite' import useAppState from 'react-native-appstate-hook' import {ViewHeader} from '../com/util/ViewHeader' import {Feed} from '../com/posts/Feed' import {FAB} from '../com/util/FAB' import {LoadLatestBtn} from '../com/util/LoadLatestBtn' -import {useStores} from '../../state' +import {useStores} from 'state/index' import {ScreenParams} from '../routes' -import {s} from '../lib/styles' -import {useOnMainScroll} from '../lib/hooks/useOnMainScroll' +import {s} from 'lib/styles' +import {useOnMainScroll} from 'lib/hooks/useOnMainScroll' +import {useAnalytics} from 'lib/analytics' -export const Home = observer(function Home({ - navIdx, - visible, - scrollElRef, -}: ScreenParams) { +const HEADER_HEIGHT = 42 + +export const Home = observer(function Home({navIdx, visible}: ScreenParams) { const store = useStores() const onMainScroll = useOnMainScroll(store) + const {screen, track} = useAnalytics() + const scrollElRef = React.useRef<FlatList>(null) const [wasVisible, setWasVisible] = React.useState<boolean>(false) const {appState} = useAppState({ onForeground: () => doPoll(true), @@ -31,22 +32,31 @@ export const Home = observer(function Home({ if (store.me.mainFeed.isLoading) { return } - store.log.debug('Polling home feed') - store.me.mainFeed.checkForLatest().catch(e => { - store.log.error('Failed to poll feed', e) - }) + store.log.debug('HomeScreen: Polling for new posts') + store.me.mainFeed.checkForLatest() }, [appState, visible, store], ) + const scrollToTop = React.useCallback(() => { + // NOTE: the feed is offset by the height of the collapsing header, + // so we scroll to the negative of that height -prf + scrollElRef.current?.scrollToOffset({offset: -HEADER_HEIGHT}) + }, [scrollElRef]) + useEffect(() => { + const softResetSub = store.onScreenSoftReset(scrollToTop) const feedCleanup = store.me.mainFeed.registerListeners() - const pollInterval = setInterval(() => doPoll(), 15e3) + const pollInterval = setInterval(doPoll, 15e3) const cleanup = () => { clearInterval(pollInterval) + softResetSub.remove() feedCleanup() } + // guard to only continue when transitioning from !visible -> visible + // TODO is this 100% needed? depends on if useEffect() is getting refired + // for reasons other than `visible` changing -prf if (!visible) { setWasVisible(false) return cleanup @@ -55,17 +65,20 @@ export const Home = observer(function Home({ } setWasVisible(true) + // just became visible + screen('Feed') store.nav.setTitle(navIdx, 'Home') - store.log.debug('Updating home feed') + store.log.debug('HomeScreen: Updating feed') if (store.me.mainFeed.hasContent) { store.me.mainFeed.update() } else { store.me.mainFeed.setup() } return cleanup - }, [visible, store, navIdx, doPoll, wasVisible]) + }, [visible, store, store.me.mainFeed, navIdx, doPoll, wasVisible, scrollToTop, screen]) const onPressCompose = (imagesOpen?: boolean) => { + track('Home:ComposeButtonPressed') store.shell.openComposer({imagesOpen}) } const onPressTryAgain = () => { @@ -73,26 +86,31 @@ export const Home = observer(function Home({ } const onPressLoadLatest = () => { store.me.mainFeed.refresh() - scrollElRef?.current?.scrollToOffset({offset: 0}) + scrollToTop() } return ( <View style={s.h100pct}> - <ViewHeader title="Bluesky" subtitle="Private Beta" canGoBack={false} /> <Feed testID="homeFeed" key="default" feed={store.me.mainFeed} scrollElRef={scrollElRef} style={s.h100pct} - onPressCompose={onPressCompose} onPressTryAgain={onPressTryAgain} + onPressCompose={onPressCompose} onScroll={onMainScroll} + headerOffset={HEADER_HEIGHT} /> + <ViewHeader title="Bluesky" canGoBack={false} hideOnScroll /> {store.me.mainFeed.hasNewLatest && !store.me.mainFeed.isRefreshing && ( <LoadLatestBtn onPress={onPressLoadLatest} /> )} - <FAB icon="pen-nib" onPress={() => onPressCompose(false)} /> + <FAB + testID="composeFAB" + icon="plus" + onPress={() => onPressCompose(false)} + /> </View> ) }) |