Scroll sync in the pager without jumps (#1863)

This commit is contained in:
dan 2023-11-10 19:54:33 +00:00 committed by GitHub
parent 65def37165
commit 91f8a23fbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 160 additions and 87 deletions

View file

@ -1,5 +1,11 @@
import React, {useMemo, useCallback} from 'react'
import {FlatList, StyleSheet, View, ActivityIndicator} from 'react-native'
import {
Dimensions,
StyleSheet,
View,
ActivityIndicator,
FlatList,
} from 'react-native'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
import {useNavigation} from '@react-navigation/native'
import {usePalette} from 'lib/hooks/usePalette'
@ -343,16 +349,19 @@ export const ProfileFeedScreenInner = observer(
isHeaderReady={feedInfo?.hasLoaded ?? false}
renderHeader={renderHeader}
onCurrentPageSelected={onCurrentPageSelected}>
{({onScroll, headerHeight, isScrolledDown}) => (
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
<FeedSection
ref={feedSectionRef}
feed={feed}
onScroll={onScroll}
headerHeight={headerHeight}
isScrolledDown={isScrolledDown}
scrollElRef={
scrollElRef as React.MutableRefObject<FlatList<any> | null>
}
/>
)}
{({onScroll, headerHeight}) => (
{({onScroll, headerHeight, scrollElRef}) => (
<AboutSection
feedOwnerDid={feedOwnerDid}
feedRkey={rkey}
@ -360,6 +369,9 @@ export const ProfileFeedScreenInner = observer(
headerHeight={headerHeight}
onToggleLiked={onToggleLiked}
onScroll={onScroll}
scrollElRef={
scrollElRef as React.MutableRefObject<ScrollView | null>
}
/>
)}
</PagerWithHeader>
@ -387,14 +399,14 @@ interface FeedSectionProps {
onScroll: OnScrollHandler
headerHeight: number
isScrolledDown: boolean
scrollElRef: React.MutableRefObject<FlatList<any> | null>
}
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
function FeedSectionImpl(
{feed, onScroll, headerHeight, isScrolledDown},
{feed, onScroll, headerHeight, isScrolledDown, scrollElRef},
ref,
) {
const hasNew = feed.hasNewLatest && !feed.isRefreshing
const scrollElRef = React.useRef<FlatList>(null)
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({offset: -headerHeight})
@ -438,6 +450,7 @@ const AboutSection = observer(function AboutPageImpl({
headerHeight,
onToggleLiked,
onScroll,
scrollElRef,
}: {
feedOwnerDid: string
feedRkey: string
@ -445,6 +458,7 @@ const AboutSection = observer(function AboutPageImpl({
headerHeight: number
onToggleLiked: () => void
onScroll: OnScrollHandler
scrollElRef: React.MutableRefObject<ScrollView | null>
}) {
const pal = usePalette('default')
const {_} = useLingui()
@ -456,8 +470,12 @@ const AboutSection = observer(function AboutPageImpl({
return (
<ScrollView
ref={scrollElRef}
scrollEventThrottle={1}
contentContainerStyle={{paddingTop: headerHeight}}
contentContainerStyle={{
paddingTop: headerHeight,
paddingBottom: Dimensions.get('window').height - headerHeight,
}}
onScroll={scrollHandler}>
<View
style={[

View file

@ -175,18 +175,24 @@ export const ProfileListScreenInner = observer(
isHeaderReady={list.hasLoaded}
renderHeader={renderHeader}
onCurrentPageSelected={onCurrentPageSelected}>
{({onScroll, headerHeight, isScrolledDown}) => (
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
<FeedSection
ref={feedSectionRef}
scrollElRef={
scrollElRef as React.MutableRefObject<FlatList<any> | null>
}
feed={feed}
onScroll={onScroll}
headerHeight={headerHeight}
isScrolledDown={isScrolledDown}
/>
)}
{({onScroll, headerHeight, isScrolledDown}) => (
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
<AboutSection
ref={aboutSectionRef}
scrollElRef={
scrollElRef as React.MutableRefObject<FlatList<any> | null>
}
list={list}
descriptionRT={list.descriptionRT}
creator={list.data ? list.data.creator : undefined}
@ -223,9 +229,12 @@ export const ProfileListScreenInner = observer(
items={SECTION_TITLES_MOD}
isHeaderReady={list.hasLoaded}
renderHeader={renderHeader}>
{({onScroll, headerHeight, isScrolledDown}) => (
{({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
<AboutSection
list={list}
scrollElRef={
scrollElRef as React.MutableRefObject<FlatList<any> | null>
}
descriptionRT={list.descriptionRT}
creator={list.data ? list.data.creator : undefined}
isCurateList={list.isCuratelist}
@ -557,14 +566,14 @@ interface FeedSectionProps {
onScroll: OnScrollHandler
headerHeight: number
isScrolledDown: boolean
scrollElRef: React.MutableRefObject<FlatList<any> | null>
}
const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
function FeedSectionImpl(
{feed, onScroll, headerHeight, isScrolledDown},
{feed, scrollElRef, onScroll, headerHeight, isScrolledDown},
ref,
) {
const hasNew = feed.hasNewLatest && !feed.isRefreshing
const scrollElRef = React.useRef<FlatList>(null)
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({offset: -headerHeight})
@ -611,6 +620,7 @@ interface AboutSectionProps {
onScroll: OnScrollHandler
headerHeight: number
isScrolledDown: boolean
scrollElRef: React.MutableRefObject<FlatList<any> | null>
}
const AboutSection = React.forwardRef<SectionRef, AboutSectionProps>(
function AboutSectionImpl(
@ -624,13 +634,13 @@ const AboutSection = React.forwardRef<SectionRef, AboutSectionProps>(
onScroll,
headerHeight,
isScrolledDown,
scrollElRef,
},
ref,
) {
const pal = usePalette('default')
const {_} = useLingui()
const {isMobile} = useWebMediaQueries()
const scrollElRef = React.useRef<FlatList>(null)
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({offset: -headerHeight})