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:
parent
fa3ccafa80
commit
7fd7970237
26 changed files with 280 additions and 354 deletions
|
@ -1,4 +1,4 @@
|
|||
import React, {MutableRefObject} from 'react'
|
||||
import React from 'react'
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Dimensions,
|
||||
|
@ -8,7 +8,7 @@ import {
|
|||
ViewStyle,
|
||||
} from 'react-native'
|
||||
import {AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api'
|
||||
import {FlatList} from '../util/Views'
|
||||
import {List, ListRef} from '../util/List'
|
||||
import {ProfileCardFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
||||
|
@ -18,10 +18,8 @@ import {useAnalytics} from 'lib/analytics/analytics'
|
|||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {useListMembersQuery} from '#/state/queries/list-members'
|
||||
import {OnScrollHandler} from 'lib/hooks/useOnMainScroll'
|
||||
import {logger} from '#/logger'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
|
||||
import {useSession} from '#/state/session'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
|
||||
|
@ -34,24 +32,22 @@ export function ListMembers({
|
|||
list,
|
||||
style,
|
||||
scrollElRef,
|
||||
onScroll,
|
||||
onScrolledDownChange,
|
||||
onPressTryAgain,
|
||||
renderHeader,
|
||||
renderEmptyState,
|
||||
testID,
|
||||
scrollEventThrottle,
|
||||
headerOffset = 0,
|
||||
desktopFixedHeightOffset,
|
||||
}: {
|
||||
list: string
|
||||
style?: StyleProp<ViewStyle>
|
||||
scrollElRef?: MutableRefObject<FlatList<any> | null>
|
||||
onScroll: OnScrollHandler
|
||||
scrollElRef?: ListRef
|
||||
onScrolledDownChange: (isScrolledDown: boolean) => void
|
||||
onPressTryAgain?: () => void
|
||||
renderHeader: () => JSX.Element
|
||||
renderEmptyState: () => JSX.Element
|
||||
testID?: string
|
||||
scrollEventThrottle?: number
|
||||
headerOffset?: number
|
||||
desktopFixedHeightOffset?: number
|
||||
}) {
|
||||
|
@ -209,10 +205,9 @@ export function ListMembers({
|
|||
[isFetching],
|
||||
)
|
||||
|
||||
const scrollHandler = useAnimatedScrollHandler(onScroll)
|
||||
return (
|
||||
<View testID={testID} style={style}>
|
||||
<FlatList
|
||||
<List
|
||||
testID={testID ? `${testID}-flatlist` : undefined}
|
||||
ref={scrollElRef}
|
||||
data={items}
|
||||
|
@ -233,10 +228,9 @@ export function ListMembers({
|
|||
minHeight: Dimensions.get('window').height * 1.5,
|
||||
}}
|
||||
style={{paddingTop: headerOffset}}
|
||||
onScroll={scrollHandler}
|
||||
onScrolledDownChange={onScrolledDownChange}
|
||||
onEndReached={onEndReached}
|
||||
onEndReachedThreshold={0.6}
|
||||
scrollEventThrottle={scrollEventThrottle}
|
||||
removeClippedSubviews={true}
|
||||
contentOffset={{x: 0, y: headerOffset * -1}}
|
||||
// @ts-ignore our .web version only -prf
|
||||
|
|
|
@ -15,7 +15,7 @@ import {ErrorMessage} from '../util/error/ErrorMessage'
|
|||
import {Text} from '../util/text/Text'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {FlatList} from '../util/Views'
|
||||
import {List} from '../util/List'
|
||||
import {s} from 'lib/styles'
|
||||
import {logger} from '#/logger'
|
||||
import {Trans} from '@lingui/macro'
|
||||
|
@ -119,7 +119,7 @@ export function MyLists({
|
|||
[error, onRefresh, renderItem, pal],
|
||||
)
|
||||
|
||||
const FlatListCom = inline ? RNFlatList : FlatList
|
||||
const FlatListCom = inline ? RNFlatList : List
|
||||
return (
|
||||
<View testID={testID} style={style}>
|
||||
{items.length > 0 && (
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, {MutableRefObject} from 'react'
|
||||
import React from 'react'
|
||||
import {
|
||||
Dimensions,
|
||||
RefreshControl,
|
||||
|
@ -8,7 +8,7 @@ import {
|
|||
ViewStyle,
|
||||
} from 'react-native'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
import {FlatList} from '../util/Views'
|
||||
import {List, ListRef} from '../util/List'
|
||||
import {ListCard} from './ListCard'
|
||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
||||
|
@ -16,11 +16,9 @@ import {Text} from '../util/text/Text'
|
|||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useProfileListsQuery, RQKEY} from '#/state/queries/profile-lists'
|
||||
import {OnScrollHandler} from '#/lib/hooks/useOnMainScroll'
|
||||
import {logger} from '#/logger'
|
||||
import {Trans} from '@lingui/macro'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
|
||||
import {useTheme} from '#/lib/ThemeContext'
|
||||
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||
import {isNative} from '#/platform/detection'
|
||||
|
@ -36,9 +34,7 @@ interface SectionRef {
|
|||
|
||||
interface ProfileListsProps {
|
||||
did: string
|
||||
scrollElRef: MutableRefObject<FlatList<any> | null>
|
||||
onScroll?: OnScrollHandler
|
||||
scrollEventThrottle?: number
|
||||
scrollElRef: ListRef
|
||||
headerOffset: number
|
||||
enabled?: boolean
|
||||
style?: StyleProp<ViewStyle>
|
||||
|
@ -47,16 +43,7 @@ interface ProfileListsProps {
|
|||
|
||||
export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
|
||||
function ProfileListsImpl(
|
||||
{
|
||||
did,
|
||||
scrollElRef,
|
||||
onScroll,
|
||||
scrollEventThrottle,
|
||||
headerOffset,
|
||||
enabled,
|
||||
style,
|
||||
testID,
|
||||
},
|
||||
{did, scrollElRef, headerOffset, enabled, style, testID},
|
||||
ref,
|
||||
) {
|
||||
const pal = usePalette('default')
|
||||
|
@ -187,10 +174,9 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
|
|||
[error, refetch, onPressRetryLoadMore, pal],
|
||||
)
|
||||
|
||||
const scrollHandler = useAnimatedScrollHandler(onScroll || {})
|
||||
return (
|
||||
<View testID={testID} style={style}>
|
||||
<FlatList
|
||||
<List
|
||||
testID={testID ? `${testID}-flatlist` : undefined}
|
||||
ref={scrollElRef}
|
||||
data={items}
|
||||
|
@ -209,8 +195,6 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
|
|||
minHeight: Dimensions.get('window').height * 1.5,
|
||||
}}
|
||||
style={{paddingTop: headerOffset}}
|
||||
onScroll={onScroll != null ? scrollHandler : undefined}
|
||||
scrollEventThrottle={scrollEventThrottle}
|
||||
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
||||
removeClippedSubviews={true}
|
||||
contentOffset={{x: 0, y: headerOffset * -1}}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue