diff --git a/src/screens/Profile/Header/GrowableBanner.tsx b/src/screens/Profile/Header/GrowableBanner.tsx index 3d2830439a..16eb27bd8b 100644 --- a/src/screens/Profile/Header/GrowableBanner.tsx +++ b/src/screens/Profile/Header/GrowableBanner.tsx @@ -2,6 +2,7 @@ import React, {useEffect, useState} from 'react' import {View} from 'react-native' import {ActivityIndicator} from 'react-native' import Animated, { + clamp, Extrapolation, interpolate, runOnJS, @@ -14,7 +15,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context' import {BlurView} from 'expo-blur' import {useIsFetching} from '@tanstack/react-query' -import {isIOS} from '#/platform/detection' +import {isIOS, isWeb} from '#/platform/detection' import {RQKEY_ROOT as STARTERPACK_RQKEY_ROOT} from '#/state/queries/actor-starter-packs' import {RQKEY_ROOT as FEED_RQKEY_ROOT} from '#/state/queries/post-feed' import {RQKEY_ROOT as FEEDGEN_RQKEY_ROOT} from '#/state/queries/profile-feedgens' @@ -33,8 +34,8 @@ export function GrowableBanner({ }) { const pagerContext = usePagerHeaderContext() - // plain non-growable mode for Android/Web - if (!pagerContext || !isIOS) { + // plain non-growable mode for Web + if (!pagerContext || isWeb) { return ( {children} @@ -43,20 +44,28 @@ export function GrowableBanner({ ) } - const {scrollY} = pagerContext + const {scrollY, headerHeight, minimumHeaderHeight} = pagerContext return ( - + {children} ) } function GrowableBannerInner({ + headerHeight, + minimumHeaderHeight, scrollY, backButton, children, }: { + headerHeight: number + minimumHeaderHeight: number scrollY: SharedValue backButton?: React.ReactNode children: React.ReactNode @@ -68,20 +77,33 @@ function GrowableBannerInner({ const animatedStyle = useAnimatedStyle(() => ({ transform: [ { - scale: interpolate(scrollY.get(), [-150, 0], [2, 1], { - extrapolateRight: Extrapolation.CLAMP, - }), + scale: interpolate( + scrollY.get(), + [-150, 0], + [2, 1], + Extrapolation.CLAMP, + ), + }, + { + translateY: clamp(scrollY.get() - minimumHeaderHeight, 0, headerHeight), }, ], })) const animatedBlurViewProps = useAnimatedProps(() => { + console.log( + 'scrollY', + scrollY.get(), + 'headerHeight', + headerHeight, + topInset, + ) return { intensity: interpolate( scrollY.get(), - [-300, -65, -15], - [50, 40, 0], - Extrapolation.CLAMP, + [-300, -65, -15, minimumHeaderHeight - 10, minimumHeaderHeight], + [50, 40, 0, 0, 50], + {extrapolateLeft: Extrapolation.CLAMP}, ), } }) diff --git a/src/screens/Profile/Header/index.tsx b/src/screens/Profile/Header/index.tsx index 69510c6c7d..8c225491f2 100644 --- a/src/screens/Profile/Header/index.tsx +++ b/src/screens/Profile/Header/index.tsx @@ -97,7 +97,6 @@ const MinimalHeader = React.memo(function MinimalHeader({ profile: AppBskyActorDefs.ProfileViewDetailed hideBackButton?: boolean }) { - const t = useTheme() const insets = useSafeAreaInsets() const ctx = usePagerHeaderContext() const [visible, setVisible] = useState(false) @@ -153,7 +152,6 @@ const MinimalHeader = React.memo(function MinimalHeader({ style={[ a.absolute, a.z_50, - t.atoms.bg, { top: 0, left: 0, diff --git a/src/view/com/pager/PagerHeaderContext.tsx b/src/view/com/pager/PagerHeaderContext.tsx index c979f7a6dd..283ac6ef5a 100644 --- a/src/view/com/pager/PagerHeaderContext.tsx +++ b/src/view/com/pager/PagerHeaderContext.tsx @@ -6,6 +6,7 @@ import {isNative} from '#/platform/detection' export const PagerHeaderContext = React.createContext<{ scrollY: SharedValue headerHeight: number + minimumHeaderHeight: number } | null>(null) /** @@ -17,15 +18,17 @@ export const PagerHeaderContext = React.createContext<{ export function PagerHeaderProvider({ scrollY, headerHeight, + minimumHeaderHeight, children, }: { scrollY: SharedValue headerHeight: number + minimumHeaderHeight: number children: React.ReactNode }) { const value = React.useMemo( - () => ({scrollY, headerHeight}), - [scrollY, headerHeight], + () => ({scrollY, headerHeight, minimumHeaderHeight}), + [scrollY, headerHeight, minimumHeaderHeight], ) return ( diff --git a/src/view/com/pager/PagerWithHeader.tsx b/src/view/com/pager/PagerWithHeader.tsx index dcf141f84d..49d7da60e0 100644 --- a/src/view/com/pager/PagerWithHeader.tsx +++ b/src/view/com/pager/PagerWithHeader.tsx @@ -66,6 +66,7 @@ export const PagerWithHeader = React.forwardRef( const [currentPage, setCurrentPage] = React.useState(0) const [tabBarHeight, setTabBarHeight] = React.useState(0) const [headerOnlyHeight, setHeaderOnlyHeight] = React.useState(0) + const [minimumHeaderHeight, setMinimumHeaderHeight] = React.useState(0) const scrollY = useSharedValue(0) const headerHeight = headerOnlyHeight + tabBarHeight @@ -89,7 +90,8 @@ export const PagerWithHeader = React.forwardRef( return ( + headerHeight={headerOnlyHeight} + minimumHeaderHeight={minimumHeaderHeight}> ( allowHeaderOverScroll={allowHeaderOverScroll} dragProgress={props.dragProgress} dragState={props.dragState} + minimumHeaderHeight={minimumHeaderHeight} + setMinimumHeaderHeight={setMinimumHeaderHeight} /> ) @@ -121,6 +125,8 @@ export const PagerWithHeader = React.forwardRef( scrollY, testID, allowHeaderOverScroll, + minimumHeaderHeight, + setMinimumHeaderHeight, ], ) @@ -236,6 +242,8 @@ let PagerTabBar = ({ allowHeaderOverScroll, dragProgress, dragState, + minimumHeaderHeight, + setMinimumHeaderHeight, }: { currentPage: number headerOnlyHeight: number @@ -255,8 +263,9 @@ let PagerTabBar = ({ allowHeaderOverScroll?: boolean dragProgress: SharedValue dragState: SharedValue<'idle' | 'dragging' | 'settling'> + minimumHeaderHeight: number + setMinimumHeaderHeight: (height: number) => void }): React.ReactNode => { - const [minimumHeaderHeight, setMinimumHeaderHeight] = React.useState(0) const headerTransform = useAnimatedStyle(() => { const translateY = Math.min(