This commit is contained in:
Dan Abramov
2024-01-19 05:00:45 +00:00
parent 296ab76535
commit 34d38573b1
3 changed files with 310 additions and 245 deletions
+18 -1
View File
@@ -126,6 +126,23 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
[scrollRefs],
)
const pagerRef = React.useRef(null)
React.useImperativeHandle(ref, () => ({
setPage: (index: number) => pagerRef.current?.setPage(index),
scrollTo: dy => {
'worklet'
const forcedScrollY = scrollY.value + dy
scrollY.value = forcedScrollY
lastForcedScrollY.value = forcedScrollY
const refs = scrollRefs.value
for (let i = 0; i < refs.length; i++) {
if (refs[i] != null) {
scrollTo(refs[i], 0, forcedScrollY, false)
}
}
},
}))
const lastForcedScrollY = useSharedValue(0)
const adjustScrollForOtherPages = () => {
'worklet'
@@ -178,7 +195,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
return (
<Pager
ref={ref}
ref={pagerRef}
testID={testID}
initialPage={initialPage}
onPageSelected={onPageSelectedInner}
+30 -3
View File
@@ -5,6 +5,7 @@ import {
TouchableWithoutFeedback,
View,
} from 'react-native'
import {GestureDetector, Gesture} from 'react-native-gesture-handler'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
@@ -68,6 +69,7 @@ export function ProfileHeader({
moderation,
hideBackButton = false,
isProfilePreview,
onPan,
}: Props) {
const pal = usePalette('default')
@@ -98,6 +100,7 @@ export function ProfileHeader({
moderation={moderation}
hideBackButton={hideBackButton}
isProfilePreview={isProfilePreview}
onPan={onPan}
/>
)
}
@@ -114,6 +117,7 @@ let ProfileHeaderLoaded = ({
moderation,
hideBackButton = false,
isProfilePreview,
onPan,
}: LoadedProps): React.ReactNode => {
const pal = usePalette('default')
const palInverted = usePalette('inverted')
@@ -441,7 +445,19 @@ let ProfileHeaderLoaded = ({
const followers = formatCount(profile.followersCount || 0)
const pluralizedFollowers = pluralize(profile.followersCount || 0, 'follower')
const pan = Gesture.Pan()
.activeOffsetY([-10, 10])
.failOffsetX([-10, 10])
.maxPointers(1)
.onUpdate(e => {
onPan(e)
})
.onEnd(e => {
onPan(null)
})
return (
<GestureDetector gesture={pan}>
<View style={pal.view}>
<UserBanner banner={profile.banner} moderation={moderation.avatar} />
<View style={styles.content}>
@@ -479,7 +495,9 @@ let ProfileHeaderLoaded = ({
{!isProfilePreview && hasSession && (
<TouchableOpacity
testID="suggestedFollowsBtn"
onPress={() => setShowSuggestedFollows(!showSuggestedFollows)}
onPress={() =>
setShowSuggestedFollows(!showSuggestedFollows)
}
style={[
styles.btn,
styles.mainBtn,
@@ -560,7 +578,11 @@ let ProfileHeaderLoaded = ({
accessibilityLabel={_(msg`More options`)}
accessibilityHint="">
<View style={[styles.btn, styles.secondaryBtn, pal.btn]}>
<FontAwesomeIcon icon="ellipsis" size={20} style={[pal.text]} />
<FontAwesomeIcon
icon="ellipsis"
size={20}
style={[pal.text]}
/>
</View>
</NativeDropdown>
) : undefined}
@@ -699,7 +721,11 @@ let ProfileHeaderLoaded = ({
accessibilityLabel={_(msg`View ${profile.handle}'s avatar`)}
accessibilityHint="">
<View
style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}>
style={[
pal.view,
{borderColor: pal.colors.background},
styles.avi,
]}>
<UserAvatar
size={80}
avatar={profile.avatar}
@@ -708,6 +734,7 @@ let ProfileHeaderLoaded = ({
</View>
</TouchableWithoutFeedback>
</View>
</GestureDetector>
)
}
ProfileHeaderLoaded = memo(ProfileHeaderLoaded)
+21
View File
@@ -40,6 +40,7 @@ import {Text} from '#/view/com/util/text/Text'
import {usePalette} from 'lib/hooks/usePalette'
import {isNative} from '#/platform/detection'
import {isInvalidHandle} from '#/lib/strings/handles'
import {useSharedValue} from 'react-native-reanimated'
interface SectionRef {
scrollToTop: () => void
@@ -254,17 +255,36 @@ function ProfileScreenLoaded({
// rendering
// =
let scrollHeader = () => {
'worklet'
}
React.useEffect(() => {
scrollHeader = pageRef.current.scrollTo
})
const lastTranslationY = useSharedValue(0)
const renderHeader = React.useCallback(() => {
return (
<ProfileHeader
profile={profile}
moderation={moderation}
hideBackButton={hideBackButton}
onPan={e => {
'worklet'
// console.log()
if (e) {
scrollHeader(lastTranslationY.value - e.translationY)
lastTranslationY.value = e.translationY
} else {
lastTranslationY.value = 0
}
}}
/>
)
}, [profile, moderation, hideBackButton])
const pageRef = React.useRef(null)
return (
<ScreenHider
testID="profileView"
@@ -272,6 +292,7 @@ function ProfileScreenLoaded({
screenDescription="profile"
moderation={moderation.account}>
<PagerWithHeader
ref={pageRef}
testID="profilePager"
isHeaderReady={true}
items={sectionTitles}