wip
This commit is contained in:
@@ -126,6 +126,23 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
|
|||||||
[scrollRefs],
|
[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 lastForcedScrollY = useSharedValue(0)
|
||||||
const adjustScrollForOtherPages = () => {
|
const adjustScrollForOtherPages = () => {
|
||||||
'worklet'
|
'worklet'
|
||||||
@@ -178,7 +195,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Pager
|
<Pager
|
||||||
ref={ref}
|
ref={pagerRef}
|
||||||
testID={testID}
|
testID={testID}
|
||||||
initialPage={initialPage}
|
initialPage={initialPage}
|
||||||
onPageSelected={onPageSelectedInner}
|
onPageSelected={onPageSelectedInner}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
TouchableWithoutFeedback,
|
TouchableWithoutFeedback,
|
||||||
View,
|
View,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
import {GestureDetector, Gesture} from 'react-native-gesture-handler'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
@@ -68,6 +69,7 @@ export function ProfileHeader({
|
|||||||
moderation,
|
moderation,
|
||||||
hideBackButton = false,
|
hideBackButton = false,
|
||||||
isProfilePreview,
|
isProfilePreview,
|
||||||
|
onPan,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
||||||
@@ -98,6 +100,7 @@ export function ProfileHeader({
|
|||||||
moderation={moderation}
|
moderation={moderation}
|
||||||
hideBackButton={hideBackButton}
|
hideBackButton={hideBackButton}
|
||||||
isProfilePreview={isProfilePreview}
|
isProfilePreview={isProfilePreview}
|
||||||
|
onPan={onPan}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -114,6 +117,7 @@ let ProfileHeaderLoaded = ({
|
|||||||
moderation,
|
moderation,
|
||||||
hideBackButton = false,
|
hideBackButton = false,
|
||||||
isProfilePreview,
|
isProfilePreview,
|
||||||
|
onPan,
|
||||||
}: LoadedProps): React.ReactNode => {
|
}: LoadedProps): React.ReactNode => {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const palInverted = usePalette('inverted')
|
const palInverted = usePalette('inverted')
|
||||||
@@ -441,7 +445,19 @@ let ProfileHeaderLoaded = ({
|
|||||||
const followers = formatCount(profile.followersCount || 0)
|
const followers = formatCount(profile.followersCount || 0)
|
||||||
const pluralizedFollowers = pluralize(profile.followersCount || 0, 'follower')
|
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 (
|
return (
|
||||||
|
<GestureDetector gesture={pan}>
|
||||||
<View style={pal.view}>
|
<View style={pal.view}>
|
||||||
<UserBanner banner={profile.banner} moderation={moderation.avatar} />
|
<UserBanner banner={profile.banner} moderation={moderation.avatar} />
|
||||||
<View style={styles.content}>
|
<View style={styles.content}>
|
||||||
@@ -479,7 +495,9 @@ let ProfileHeaderLoaded = ({
|
|||||||
{!isProfilePreview && hasSession && (
|
{!isProfilePreview && hasSession && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
testID="suggestedFollowsBtn"
|
testID="suggestedFollowsBtn"
|
||||||
onPress={() => setShowSuggestedFollows(!showSuggestedFollows)}
|
onPress={() =>
|
||||||
|
setShowSuggestedFollows(!showSuggestedFollows)
|
||||||
|
}
|
||||||
style={[
|
style={[
|
||||||
styles.btn,
|
styles.btn,
|
||||||
styles.mainBtn,
|
styles.mainBtn,
|
||||||
@@ -560,7 +578,11 @@ let ProfileHeaderLoaded = ({
|
|||||||
accessibilityLabel={_(msg`More options`)}
|
accessibilityLabel={_(msg`More options`)}
|
||||||
accessibilityHint="">
|
accessibilityHint="">
|
||||||
<View style={[styles.btn, styles.secondaryBtn, pal.btn]}>
|
<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>
|
</View>
|
||||||
</NativeDropdown>
|
</NativeDropdown>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
@@ -699,7 +721,11 @@ let ProfileHeaderLoaded = ({
|
|||||||
accessibilityLabel={_(msg`View ${profile.handle}'s avatar`)}
|
accessibilityLabel={_(msg`View ${profile.handle}'s avatar`)}
|
||||||
accessibilityHint="">
|
accessibilityHint="">
|
||||||
<View
|
<View
|
||||||
style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}>
|
style={[
|
||||||
|
pal.view,
|
||||||
|
{borderColor: pal.colors.background},
|
||||||
|
styles.avi,
|
||||||
|
]}>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
size={80}
|
size={80}
|
||||||
avatar={profile.avatar}
|
avatar={profile.avatar}
|
||||||
@@ -708,6 +734,7 @@ let ProfileHeaderLoaded = ({
|
|||||||
</View>
|
</View>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
</View>
|
</View>
|
||||||
|
</GestureDetector>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ProfileHeaderLoaded = memo(ProfileHeaderLoaded)
|
ProfileHeaderLoaded = memo(ProfileHeaderLoaded)
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import {Text} from '#/view/com/util/text/Text'
|
|||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {isInvalidHandle} from '#/lib/strings/handles'
|
import {isInvalidHandle} from '#/lib/strings/handles'
|
||||||
|
import {useSharedValue} from 'react-native-reanimated'
|
||||||
|
|
||||||
interface SectionRef {
|
interface SectionRef {
|
||||||
scrollToTop: () => void
|
scrollToTop: () => void
|
||||||
@@ -254,17 +255,36 @@ function ProfileScreenLoaded({
|
|||||||
|
|
||||||
// rendering
|
// rendering
|
||||||
// =
|
// =
|
||||||
|
let scrollHeader = () => {
|
||||||
|
'worklet'
|
||||||
|
}
|
||||||
|
React.useEffect(() => {
|
||||||
|
scrollHeader = pageRef.current.scrollTo
|
||||||
|
})
|
||||||
|
|
||||||
|
const lastTranslationY = useSharedValue(0)
|
||||||
const renderHeader = React.useCallback(() => {
|
const renderHeader = React.useCallback(() => {
|
||||||
return (
|
return (
|
||||||
<ProfileHeader
|
<ProfileHeader
|
||||||
profile={profile}
|
profile={profile}
|
||||||
moderation={moderation}
|
moderation={moderation}
|
||||||
hideBackButton={hideBackButton}
|
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])
|
}, [profile, moderation, hideBackButton])
|
||||||
|
|
||||||
|
const pageRef = React.useRef(null)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScreenHider
|
<ScreenHider
|
||||||
testID="profileView"
|
testID="profileView"
|
||||||
@@ -272,6 +292,7 @@ function ProfileScreenLoaded({
|
|||||||
screenDescription="profile"
|
screenDescription="profile"
|
||||||
moderation={moderation.account}>
|
moderation={moderation.account}>
|
||||||
<PagerWithHeader
|
<PagerWithHeader
|
||||||
|
ref={pageRef}
|
||||||
testID="profilePager"
|
testID="profilePager"
|
||||||
isHeaderReady={true}
|
isHeaderReady={true}
|
||||||
items={sectionTitles}
|
items={sectionTitles}
|
||||||
|
|||||||
Reference in New Issue
Block a user