wip fancy banner

This commit is contained in:
Samuel Newman
2024-12-11 23:56:58 +00:00
parent 3e384f6314
commit 83233c2225
4 changed files with 49 additions and 17 deletions
+33 -11
View File
@@ -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 (
<View style={[a.w_full, a.h_full]}>
{children}
@@ -43,20 +44,28 @@ export function GrowableBanner({
)
}
const {scrollY} = pagerContext
const {scrollY, headerHeight, minimumHeaderHeight} = pagerContext
return (
<GrowableBannerInner scrollY={scrollY} backButton={backButton}>
<GrowableBannerInner
scrollY={scrollY}
backButton={backButton}
headerHeight={headerHeight}
minimumHeaderHeight={minimumHeaderHeight}>
{children}
</GrowableBannerInner>
)
}
function GrowableBannerInner({
headerHeight,
minimumHeaderHeight,
scrollY,
backButton,
children,
}: {
headerHeight: number
minimumHeaderHeight: number
scrollY: SharedValue<number>
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},
),
}
})
-2
View File
@@ -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,
+5 -2
View File
@@ -6,6 +6,7 @@ import {isNative} from '#/platform/detection'
export const PagerHeaderContext = React.createContext<{
scrollY: SharedValue<number>
headerHeight: number
minimumHeaderHeight: number
} | null>(null)
/**
@@ -17,15 +18,17 @@ export const PagerHeaderContext = React.createContext<{
export function PagerHeaderProvider({
scrollY,
headerHeight,
minimumHeaderHeight,
children,
}: {
scrollY: SharedValue<number>
headerHeight: number
minimumHeaderHeight: number
children: React.ReactNode
}) {
const value = React.useMemo(
() => ({scrollY, headerHeight}),
[scrollY, headerHeight],
() => ({scrollY, headerHeight, minimumHeaderHeight}),
[scrollY, headerHeight, minimumHeaderHeight],
)
return (
<PagerHeaderContext.Provider value={value}>
+11 -2
View File
@@ -66,6 +66,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
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<PagerRef, PagerWithHeaderProps>(
return (
<PagerHeaderProvider
scrollY={scrollY}
headerHeight={headerOnlyHeight}>
headerHeight={headerOnlyHeight}
minimumHeaderHeight={minimumHeaderHeight}>
<PagerTabBar
headerOnlyHeight={headerOnlyHeight}
items={items}
@@ -105,6 +107,8 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
allowHeaderOverScroll={allowHeaderOverScroll}
dragProgress={props.dragProgress}
dragState={props.dragState}
minimumHeaderHeight={minimumHeaderHeight}
setMinimumHeaderHeight={setMinimumHeaderHeight}
/>
</PagerHeaderProvider>
)
@@ -121,6 +125,8 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
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<number>
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(