Make scroll handling contextual (#2200)

* Add an intermediate List component

* Fix type

* Add onScrolledDownChange

* Port pager to use onScrolledDownChange

* Fix on mobile

* Don't pass down onScroll (replacement TBD)

* Remove resetMainScroll

* Replace onMainScroll with MainScrollProvider

* Hook ScrollProvider to pager

* Fix the remaining special case

* Optimize a bit

* Enforce that onScroll cannot be passed

* Keep value updated even if no handler

* Also memo it
This commit is contained in:
dan 2023-12-14 02:48:20 +00:00 committed by GitHub
parent fa3ccafa80
commit 7fd7970237
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 280 additions and 354 deletions

View file

@ -1,5 +1,5 @@
import React from 'react'
import {FlatList, View} from 'react-native'
import {View} from 'react-native'
import {useFocusEffect} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {
@ -9,8 +9,9 @@ import {
import {ViewHeader} from '../com/util/ViewHeader'
import {Feed} from '../com/notifications/Feed'
import {TextLink} from 'view/com/util/Link'
import {ListMethods} from 'view/com/util/List'
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
import {MainScrollProvider} from '../com/util/MainScrollProvider'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {s, colors} from 'lib/styles'
@ -35,8 +36,8 @@ type Props = NativeStackScreenProps<
export function NotificationsScreen({}: Props) {
const {_} = useLingui()
const setMinimalShellMode = useSetMinimalShellMode()
const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll()
const scrollElRef = React.useRef<FlatList>(null)
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const scrollElRef = React.useRef<ListMethods>(null)
const checkLatestRef = React.useRef<() => void | null>()
const {screen} = useAnalytics()
const pal = usePalette('default')
@ -50,8 +51,8 @@ export function NotificationsScreen({}: Props) {
// =
const scrollToTop = React.useCallback(() => {
scrollElRef.current?.scrollToOffset({animated: isNative, offset: 0})
resetMainScroll()
}, [scrollElRef, resetMainScroll])
setMinimalShellMode(false)
}, [scrollElRef, setMinimalShellMode])
const onPressLoadLatest = React.useCallback(() => {
scrollToTop()
@ -130,11 +131,13 @@ export function NotificationsScreen({}: Props) {
return (
<View testID="notificationsScreen" style={s.hContentRegion}>
<ViewHeader title={_(msg`Notifications`)} canGoBack={false} />
<Feed
onScroll={onMainScroll}
scrollElRef={scrollElRef}
ListHeaderComponent={ListHeaderComponent}
/>
<MainScrollProvider>
<Feed
onScrolledDownChange={setIsScrolledDown}
scrollElRef={scrollElRef}
ListHeaderComponent={ListHeaderComponent}
/>
</MainScrollProvider>
{(isScrolledDown || hasNew) && (
<LoadLatestBtn
onPress={onPressLoadLatest}