Port pager to use onScrolledDownChange

This commit is contained in:
Dan Abramov
2023-12-13 04:18:54 +00:00
parent b4de3dda7d
commit b93ab428c3
5 changed files with 23 additions and 66 deletions
+3
View File
@@ -35,6 +35,7 @@ export function ListMembers({
style,
scrollElRef,
onScroll,
onScrolledDownChange,
onPressTryAgain,
renderHeader,
renderEmptyState,
@@ -47,6 +48,7 @@ export function ListMembers({
style?: StyleProp<ViewStyle>
scrollElRef?: ListRef
onScroll: OnScrollHandler
onScrolledDownChange: (isScrolledDown: boolean) => void
onPressTryAgain?: () => void
renderHeader: () => JSX.Element
renderEmptyState: () => JSX.Element
@@ -234,6 +236,7 @@ export function ListMembers({
}}
style={{paddingTop: headerOffset}}
onScroll={scrollHandler}
onScrolledDownChange={onScrolledDownChange}
onEndReached={onEndReached}
onEndReachedThreshold={0.6}
scrollEventThrottle={scrollEventThrottle}
-16
View File
@@ -23,13 +23,10 @@ import {OnScrollHandler} from 'lib/hooks/useOnMainScroll'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {ListMethods} from '../util/List'
const SCROLLED_DOWN_LIMIT = 200
export interface PagerWithHeaderChildParams {
headerHeight: number
isFocused: boolean
onScroll: OnScrollHandler
isScrolledDown: boolean
scrollElRef: React.MutableRefObject<ListMethods | ScrollView | null>
}
@@ -62,7 +59,6 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
const [currentPage, setCurrentPage] = React.useState(0)
const [tabBarHeight, setTabBarHeight] = React.useState(0)
const [headerOnlyHeight, setHeaderOnlyHeight] = React.useState(0)
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const scrollY = useSharedValue(0)
const headerHeight = headerOnlyHeight + tabBarHeight
@@ -155,15 +151,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
if (!throttleTimeout.current) {
throttleTimeout.current = setTimeout(() => {
throttleTimeout.current = null
runOnUI(adjustScrollForOtherPages)()
const nextIsScrolledDown = scrollY.value > SCROLLED_DOWN_LIMIT
if (isScrolledDown !== nextIsScrolledDown) {
React.startTransition(() => {
setIsScrolledDown(nextIsScrolledDown)
})
}
}, 80 /* Sync often enough you're unlikely to catch it unsynced */)
}
})
@@ -211,7 +199,6 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
index={i}
isReady={isReady}
isFocused={i === currentPage}
isScrolledDown={isScrolledDown}
onScrollWorklet={i === currentPage ? onScrollWorklet : noop}
registerRef={registerRef}
renderTab={child}
@@ -293,7 +280,6 @@ function PagerItem({
index,
isReady,
isFocused,
isScrolledDown,
onScrollWorklet,
renderTab,
registerRef,
@@ -302,7 +288,6 @@ function PagerItem({
index: number
isFocused: boolean
isReady: boolean
isScrolledDown: boolean
registerRef: (scrollRef: AnimatedRef<any> | null, atIndex: number) => void
onScrollWorklet: (e: NativeScrollEvent) => void
renderTab: ((props: PagerWithHeaderChildParams) => JSX.Element) | null
@@ -328,7 +313,6 @@ function PagerItem({
return renderTab({
headerHeight,
isFocused,
isScrolledDown,
onScroll: scrollHandler,
scrollElRef: scrollElRef as React.MutableRefObject<
ListMethods | ScrollView | null
+7 -30
View File
@@ -278,65 +278,49 @@ function ProfileScreenLoaded({
onPageSelected={onPageSelected}
onCurrentPageSelected={onCurrentPageSelected}
renderHeader={renderHeader}>
{({onScroll, headerHeight, isFocused, isScrolledDown, scrollElRef}) => (
{({onScroll, headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={postsSectionRef}
feed={`author|${profile.did}|posts_and_author_threads`}
onScroll={onScroll}
headerHeight={headerHeight}
isFocused={isFocused}
isScrolledDown={isScrolledDown}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
)}
{showRepliesTab
? ({
onScroll,
headerHeight,
isFocused,
isScrolledDown,
scrollElRef,
}) => (
? ({onScroll, headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={repliesSectionRef}
feed={`author|${profile.did}|posts_with_replies`}
onScroll={onScroll}
headerHeight={headerHeight}
isFocused={isFocused}
isScrolledDown={isScrolledDown}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
)
: null}
{({onScroll, headerHeight, isFocused, isScrolledDown, scrollElRef}) => (
{({onScroll, headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={mediaSectionRef}
feed={`author|${profile.did}|posts_with_media`}
onScroll={onScroll}
headerHeight={headerHeight}
isFocused={isFocused}
isScrolledDown={isScrolledDown}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
)}
{showLikesTab
? ({
onScroll,
headerHeight,
isFocused,
isScrolledDown,
scrollElRef,
}) => (
? ({onScroll, headerHeight, isFocused, scrollElRef}) => (
<FeedSection
ref={likesSectionRef}
feed={`likes|${profile.did}`}
onScroll={onScroll}
headerHeight={headerHeight}
isFocused={isFocused}
isScrolledDown={isScrolledDown}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
/>
@@ -388,25 +372,17 @@ interface FeedSectionProps {
onScroll: OnScrollHandler
headerHeight: number
isFocused: boolean
isScrolledDown: boolean
scrollElRef: ListRef
ignoreFilterFor?: string
}
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
function FeedSectionImpl(
{
feed,
onScroll,
headerHeight,
isFocused,
isScrolledDown,
scrollElRef,
ignoreFilterFor,
},
{feed, onScroll, headerHeight, isFocused, scrollElRef, ignoreFilterFor},
ref,
) {
const queryClient = useQueryClient()
const [hasNew, setHasNew] = React.useState(false)
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const onScrollToTop = React.useCallback(() => {
scrollElRef.current?.scrollToOffset({
@@ -433,6 +409,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
scrollElRef={scrollElRef}
onHasNew={setHasNew}
onScroll={onScroll}
onScrolledDownChange={setIsScrolledDown}
scrollEventThrottle={1}
renderEmptyState={renderPostsEmpty}
headerOffset={headerHeight}
+4 -4
View File
@@ -398,14 +398,13 @@ export function ProfileFeedScreenInner({
isHeaderReady={true}
renderHeader={renderHeader}
onCurrentPageSelected={onCurrentPageSelected}>
{({onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused}) =>
{({onScroll, headerHeight, scrollElRef, isFocused}) =>
isPublicResponse?.isPublic ? (
<FeedSection
ref={feedSectionRef}
feed={`feedgen|${feedInfo.uri}`}
onScroll={onScroll}
headerHeight={headerHeight}
isScrolledDown={isScrolledDown}
scrollElRef={scrollElRef as ListRef}
isFocused={isFocused}
/>
@@ -492,16 +491,16 @@ interface FeedSectionProps {
feed: FeedDescriptor
onScroll: OnScrollHandler
headerHeight: number
isScrolledDown: boolean
scrollElRef: ListRef
isFocused: boolean
}
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
function FeedSectionImpl(
{feed, onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused},
{feed, onScroll, headerHeight, scrollElRef, isFocused},
ref,
) {
const [hasNew, setHasNew] = React.useState(false)
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const queryClient = useQueryClient()
const onScrollToTop = useCallback(() => {
@@ -530,6 +529,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
scrollElRef={scrollElRef}
onHasNew={setHasNew}
onScroll={onScroll}
onScrolledDownChange={setIsScrolledDown}
scrollEventThrottle={5}
renderEmptyState={renderPostsEmpty}
headerOffset={headerHeight}
+9 -16
View File
@@ -160,24 +160,17 @@ function ProfileListScreenLoaded({
isHeaderReady={true}
renderHeader={renderHeader}
onCurrentPageSelected={onCurrentPageSelected}>
{({
onScroll,
headerHeight,
isScrolledDown,
scrollElRef,
isFocused,
}) => (
{({onScroll, headerHeight, scrollElRef, isFocused}) => (
<FeedSection
ref={feedSectionRef}
feed={`list|${uri}`}
scrollElRef={scrollElRef as ListRef}
onScroll={onScroll}
headerHeight={headerHeight}
isScrolledDown={isScrolledDown}
isFocused={isFocused}
/>
)}
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
{({onScroll, headerHeight, scrollElRef}) => (
<AboutSection
ref={aboutSectionRef}
scrollElRef={scrollElRef as ListRef}
@@ -185,7 +178,6 @@ function ProfileListScreenLoaded({
onPressAddUser={onPressAddUser}
onScroll={onScroll}
headerHeight={headerHeight}
isScrolledDown={isScrolledDown}
/>
)}
</PagerWithHeader>
@@ -212,14 +204,13 @@ function ProfileListScreenLoaded({
items={SECTION_TITLES_MOD}
isHeaderReady={true}
renderHeader={renderHeader}>
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
{({onScroll, headerHeight, scrollElRef}) => (
<AboutSection
list={list}
scrollElRef={scrollElRef as ListRef}
onPressAddUser={onPressAddUser}
onScroll={onScroll}
headerHeight={headerHeight}
isScrolledDown={isScrolledDown}
/>
)}
</PagerWithHeader>
@@ -606,17 +597,17 @@ interface FeedSectionProps {
feed: FeedDescriptor
onScroll: OnScrollHandler
headerHeight: number
isScrolledDown: boolean
scrollElRef: ListRef
isFocused: boolean
}
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
function FeedSectionImpl(
{feed, scrollElRef, onScroll, headerHeight, isScrolledDown, isFocused},
{feed, scrollElRef, onScroll, headerHeight, isFocused},
ref,
) {
const queryClient = useQueryClient()
const [hasNew, setHasNew] = React.useState(false)
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({
@@ -644,6 +635,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
scrollElRef={scrollElRef}
onHasNew={setHasNew}
onScroll={onScroll}
onScrolledDownChange={setIsScrolledDown}
scrollEventThrottle={1}
renderEmptyState={renderPostsEmpty}
headerOffset={headerHeight}
@@ -665,18 +657,18 @@ interface AboutSectionProps {
onPressAddUser: () => void
onScroll: OnScrollHandler
headerHeight: number
isScrolledDown: boolean
scrollElRef: ListRef
}
const AboutSection = React.forwardRef<SectionRef, AboutSectionProps>(
function AboutSectionImpl(
{list, onPressAddUser, onScroll, headerHeight, isScrolledDown, scrollElRef},
{list, onPressAddUser, onScroll, headerHeight, scrollElRef},
ref,
) {
const pal = usePalette('default')
const {_} = useLingui()
const {isMobile} = useWebMediaQueries()
const {currentAccount} = useSession()
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const isCurateList = list.purpose === 'app.bsky.graph.defs#curatelist'
const isOwner = list.creator.did === currentAccount?.did
@@ -807,6 +799,7 @@ const AboutSection = React.forwardRef<SectionRef, AboutSectionProps>(
renderEmptyState={renderEmptyState}
headerOffset={headerHeight}
onScroll={onScroll}
onScrolledDownChange={setIsScrolledDown}
scrollEventThrottle={1}
/>
{isScrolledDown && (