diff --git a/src/screens/Profile/Header/GrowableAvatar.tsx b/src/screens/Profile/Header/GrowableAvatar.tsx new file mode 100644 index 0000000000..20ac14892d --- /dev/null +++ b/src/screens/Profile/Header/GrowableAvatar.tsx @@ -0,0 +1,61 @@ +import React from 'react' +import {StyleProp, View, ViewStyle} from 'react-native' +import Animated, { + Extrapolation, + interpolate, + SharedValue, + useAnimatedStyle, +} from 'react-native-reanimated' + +import {isIOS} from '#/platform/detection' +import {usePagerHeaderContext} from '#/view/com/pager/PagerHeaderContext' + +export function GrowableAvatar({ + children, + style, +}: { + children: React.ReactNode + style?: StyleProp +}) { + const pagerContext = usePagerHeaderContext() + + // pagerContext should only be present on iOS, but better safe than sorry + if (!pagerContext || !isIOS) { + return {children} + } + + const {scrollY} = pagerContext + + return ( + + {children} + + ) +} + +function GrowableAvatarInner({ + scrollY, + children, + style, +}: { + scrollY: SharedValue + children: React.ReactNode + style?: StyleProp +}) { + const animatedStyle = useAnimatedStyle(() => ({ + transform: [ + { + scale: interpolate(scrollY.value, [-150, 0], [1.2, 1], { + extrapolateRight: Extrapolation.CLAMP, + }), + }, + ], + })) + + return ( + + {children} + + ) +} diff --git a/src/screens/Profile/Header/Shell.tsx b/src/screens/Profile/Header/Shell.tsx index d31912ddad..f7011fd359 100644 --- a/src/screens/Profile/Header/Shell.tsx +++ b/src/screens/Profile/Header/Shell.tsx @@ -19,6 +19,7 @@ import {UserBanner} from '#/view/com/util/UserBanner' import {atoms as a, useTheme} from '#/alf' import {LabelsOnMe} from '#/components/moderation/LabelsOnMe' import {ProfileHeaderAlerts} from '#/components/moderation/ProfileHeaderAlerts' +import {GrowableAvatar} from './GrowableAvatar' import {GrowableBanner} from './GrowableBanner' interface Props { @@ -119,27 +120,29 @@ let ProfileHeaderShell = ({ )} - - - - - + + + + + + + ) } @@ -168,10 +171,12 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - avi: { + aviPosition: { position: 'absolute', top: 110, left: 10, + }, + avi: { width: 94, height: 94, borderRadius: 47,