Fix home feed positioning (closes #189) (#195)

* Fix home feed positioning for floating header

* Fix positioning of errors in home feed

* Fix lint
This commit is contained in:
Paul Frazee
2023-02-14 15:33:36 -06:00
committed by GitHub
parent 6f98bf8aa5
commit 7d162c8101
2 changed files with 26 additions and 24 deletions
+15 -16
View File
@@ -17,8 +17,8 @@ import {OnScrollCb} from '../../lib/hooks/useOnMainScroll'
import {s} from '../../lib/styles'
import {useAnalytics} from '@segment/analytics-react-native'
const HEADER_SPACER_ITEM = {_reactKey: '__spacer__'}
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
const ERROR_FEED_ITEM = {_reactKey: '__error__'}
export const Feed = observer(function Feed({
feed,
@@ -27,7 +27,7 @@ export const Feed = observer(function Feed({
onPressTryAgain,
onScroll,
testID,
headerSpacer,
headerOffset = 0,
}: {
feed: FeedModel
style?: StyleProp<ViewStyle>
@@ -35,7 +35,7 @@ export const Feed = observer(function Feed({
onPressTryAgain?: () => void
onScroll?: OnScrollCb
testID?: string
headerSpacer?: boolean
headerOffset?: number
}) {
const {screen, track} = useAnalytics()
@@ -56,13 +56,13 @@ export const Feed = observer(function Feed({
style={styles.emptyState}
/>
)
} else if (item === ERROR_FEED_ITEM) {
return (
<ErrorMessage message={feed.error} onPressTryAgain={onPressTryAgain} />
)
}
if (item === HEADER_SPACER_ITEM) {
return <View style={styles.headerSpacer} />
} else {
return <FeedItem item={item} />
}
}
const onRefresh = () => {
track('Feed:onRefresh')
feed
@@ -77,13 +77,13 @@ export const Feed = observer(function Feed({
.loadMore()
.catch(err => feed.rootStore.log.error('Failed to load more posts', err))
}
let data = []
if (headerSpacer) {
data.push(HEADER_SPACER_ITEM)
let data: any[] = []
if (feed.hasError) {
data = data.concat([ERROR_FEED_ITEM])
}
if (feed.hasLoaded) {
if (feed.isEmpty) {
data.push(EMPTY_FEED_ITEM)
data = data.concat([EMPTY_FEED_ITEM])
} else {
data = data.concat(feed.feed)
}
@@ -99,10 +99,7 @@ export const Feed = observer(function Feed({
return (
<View testID={testID} style={style}>
{feed.isLoading && !data && <PostFeedLoadingPlaceholder />}
{feed.hasError && (
<ErrorMessage message={feed.error} onPressTryAgain={onPressTryAgain} />
)}
{feed.hasLoaded && data && (
{data && (
<FlatList
ref={scrollElRef}
data={data}
@@ -115,6 +112,9 @@ export const Feed = observer(function Feed({
onRefresh={onRefresh}
onEndReached={onEndReached}
removeClippedSubviews={true}
contentInset={{top: headerOffset}}
contentOffset={{x: 0, y: headerOffset * -1}}
progressViewOffset={headerOffset}
/>
)}
</View>
@@ -122,7 +122,6 @@ export const Feed = observer(function Feed({
})
const styles = StyleSheet.create({
headerSpacer: {height: 42},
feedFooter: {paddingTop: 20},
emptyState: {paddingVertical: 40},
})
+10 -7
View File
@@ -15,6 +15,7 @@ import {useOnMainScroll} from '../lib/hooks/useOnMainScroll'
import {clamp} from 'lodash'
import {useAnalytics} from '@segment/analytics-react-native'
const HEADER_HEIGHT = 42
const HITSLOP = {left: 20, top: 20, right: 20, bottom: 20}
export const Home = observer(function Home({navIdx, visible}: ScreenParams) {
@@ -42,12 +43,14 @@ export const Home = observer(function Home({navIdx, visible}: ScreenParams) {
[appState, visible, store],
)
const onSoftReset = () => {
scrollElRef.current?.scrollToOffset({offset: 0})
}
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(onSoftReset)
const softResetSub = store.onScreenSoftReset(scrollToTop)
const feedCleanup = store.me.mainFeed.registerListeners()
const pollInterval = setInterval(() => doPoll(), 15e3)
const cleanup = () => {
@@ -72,7 +75,7 @@ export const Home = observer(function Home({navIdx, visible}: ScreenParams) {
store.me.mainFeed.setup()
}
return cleanup
}, [visible, store, store.me.mainFeed, navIdx, doPoll, wasVisible])
}, [visible, store, store.me.mainFeed, navIdx, doPoll, wasVisible, scrollToTop])
const onPressCompose = (imagesOpen?: boolean) => {
track('Home:ComposeButtonPressed')
@@ -83,7 +86,7 @@ export const Home = observer(function Home({navIdx, visible}: ScreenParams) {
}
const onPressLoadLatest = () => {
store.me.mainFeed.refresh()
scrollElRef?.current?.scrollToOffset({offset: 0})
scrollToTop()
}
return (
@@ -96,7 +99,7 @@ export const Home = observer(function Home({navIdx, visible}: ScreenParams) {
style={s.h100pct}
onPressTryAgain={onPressTryAgain}
onScroll={onMainScroll}
headerSpacer
headerOffset={HEADER_HEIGHT}
/>
<ViewHeader title="Bluesky" canGoBack={false} hideOnScroll />
{store.me.mainFeed.hasNewLatest && !store.me.mainFeed.isRefreshing ? (