fix scrollToTop for web
parent
58a0489ce3
commit
9673225f78
|
@ -18,6 +18,7 @@ import {OnScrollCb, onMomentumScrollEndCb} from 'lib/hooks/useOnMainScroll'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {useAnalytics} from 'lib/analytics'
|
import {useAnalytics} from 'lib/analytics'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {useTheme} from 'lib/ThemeContext'
|
||||||
|
|
||||||
const LOADING_ITEM = {_reactKey: '__loading__'}
|
const LOADING_ITEM = {_reactKey: '__loading__'}
|
||||||
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
|
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
|
||||||
|
@ -54,6 +55,7 @@ export const Feed = observer(function Feed({
|
||||||
extraData?: any
|
extraData?: any
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
const theme = useTheme()
|
||||||
const {track} = useAnalytics()
|
const {track} = useAnalytics()
|
||||||
const [isRefreshing, setIsRefreshing] = React.useState(false)
|
const [isRefreshing, setIsRefreshing] = React.useState(false)
|
||||||
|
|
||||||
|
@ -186,6 +188,7 @@ export const Feed = observer(function Feed({
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
scrollEventThrottle={scrollEventThrottle}
|
scrollEventThrottle={scrollEventThrottle}
|
||||||
onMomentumScrollEnd={onMomentumScrollEnd}
|
onMomentumScrollEnd={onMomentumScrollEnd}
|
||||||
|
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
onEndReachedThreshold={0.6}
|
onEndReachedThreshold={0.6}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
|
|
|
@ -20,15 +20,13 @@ import {ViewHeader} from 'view/com/util/ViewHeader'
|
||||||
import {Button} from 'view/com/util/forms/Button'
|
import {Button} from 'view/com/util/forms/Button'
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
import * as Toast from 'view/com/util/Toast'
|
import * as Toast from 'view/com/util/Toast'
|
||||||
import {isDesktopWeb} from 'platform/detection'
|
import {isDesktopWeb, isWeb} from 'platform/detection'
|
||||||
import {useSetTitle} from 'lib/hooks/useSetTitle'
|
import {useSetTitle} from 'lib/hooks/useSetTitle'
|
||||||
import {shareUrl} from 'lib/sharing'
|
import {shareUrl} from 'lib/sharing'
|
||||||
import {toShareUrl} from 'lib/strings/url-helpers'
|
import {toShareUrl} from 'lib/strings/url-helpers'
|
||||||
import {Haptics} from 'lib/haptics'
|
import {Haptics} from 'lib/haptics'
|
||||||
import { LoadLatestBtn } from 'view/com/util/load-latest/LoadLatestBtn'
|
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
|
||||||
import { onMomentumScrollEndCb } from 'lib/hooks/useOnMainScroll'
|
import {OnScrollCb, onMomentumScrollEndCb} from 'lib/hooks/useOnMainScroll'
|
||||||
|
|
||||||
const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5}
|
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'CustomFeed'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'CustomFeed'>
|
||||||
export const CustomFeedScreen = withAuthRequired(
|
export const CustomFeedScreen = withAuthRequired(
|
||||||
|
@ -257,23 +255,38 @@ export const CustomFeedScreen = withAuthRequired(
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}, [
|
}, [
|
||||||
store.me.did,
|
|
||||||
pal,
|
pal,
|
||||||
currentFeed,
|
currentFeed,
|
||||||
onToggleLiked,
|
store.me.did,
|
||||||
onToggleSaved,
|
onToggleSaved,
|
||||||
|
onToggleLiked,
|
||||||
onPressShare,
|
onPressShare,
|
||||||
name,
|
name,
|
||||||
rkey,
|
rkey,
|
||||||
isPinned,
|
isPinned,
|
||||||
|
onTogglePinned,
|
||||||
])
|
])
|
||||||
|
|
||||||
const onMomentumScrollEnd: onMomentumScrollEndCb = React.useCallback((event) => {
|
const onMomentumScrollEnd: onMomentumScrollEndCb = React.useCallback(
|
||||||
if (event.nativeEvent.contentOffset.y > 200) {
|
event => {
|
||||||
|
console.log('onMomentumScrollEnd')
|
||||||
|
if (event.nativeEvent.contentOffset.y > s.window.height * 3) {
|
||||||
setAllowScrollToTop(true)
|
setAllowScrollToTop(true)
|
||||||
} else {
|
} else {
|
||||||
setAllowScrollToTop(false)
|
setAllowScrollToTop(false)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
const onScroll: OnScrollCb = React.useCallback(event => {
|
||||||
|
// since onMomentumScrollEnd is not supported in react-native-web, we have to use onScroll which fires more often so is not desirable on mobile
|
||||||
|
if (isWeb) {
|
||||||
|
if (event.nativeEvent.contentOffset.y > s.window.height * 2) {
|
||||||
|
setAllowScrollToTop(true)
|
||||||
|
} else {
|
||||||
|
setAllowScrollToTop(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -283,14 +296,18 @@ export const CustomFeedScreen = withAuthRequired(
|
||||||
scrollElRef={scrollElRef}
|
scrollElRef={scrollElRef}
|
||||||
feed={algoFeed}
|
feed={algoFeed}
|
||||||
onMomentumScrollEnd={onMomentumScrollEnd}
|
onMomentumScrollEnd={onMomentumScrollEnd}
|
||||||
|
onScroll={onScroll} // same logic as onMomentumScrollEnd but for web
|
||||||
ListHeaderComponent={renderListHeaderComponent}
|
ListHeaderComponent={renderListHeaderComponent}
|
||||||
extraData={[uri, isPinned]}
|
extraData={[uri, isPinned]}
|
||||||
/>
|
/>
|
||||||
{allowScrollToTop ? <LoadLatestBtn onPress={() => {
|
{allowScrollToTop ? (
|
||||||
|
<LoadLatestBtn
|
||||||
|
onPress={() => {
|
||||||
scrollElRef.current?.scrollToOffset({offset: 0, animated: true})
|
scrollElRef.current?.scrollToOffset({offset: 0, animated: true})
|
||||||
}}
|
}}
|
||||||
label='Scroll to top'
|
label="Scroll to top"
|
||||||
/> : null}
|
/>
|
||||||
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in New Issue