Bluesky app fork with some witchin' additions 馃挮
at main 97 lines 2.9 kB view raw
1import {interpolate, useAnimatedStyle} from 'react-native-reanimated' 2import {useSafeAreaInsets} from 'react-native-safe-area-context' 3 4import {useMinimalShellMode} from '#/state/shell/minimal-mode' 5import {useShellLayout} from '#/state/shell/shell-layout' 6import {IS_LIQUID_GLASS} from '#/env' 7 8// Keep these separated so that we only pay for useAnimatedStyle that gets used. 9 10export function useMinimalShellHeaderTransform() { 11 const {headerMode} = useMinimalShellMode() 12 const {headerHeight} = useShellLayout() 13 const {top: topInset} = useSafeAreaInsets() 14 15 const headerPinnedHeight = IS_LIQUID_GLASS ? topInset : 0 16 17 const headerTransform = useAnimatedStyle(() => { 18 const headerModeValue = headerMode.get() 19 const hHeight = headerHeight.get() 20 21 if (IS_LIQUID_GLASS) { 22 // bit of a hackfix, but: the header can get affected by scrollEdgeEffects 23 // when animating from closed to open. workaround is to trigger a relayout 24 // by offsetting the top position. the actual value doesn't matter, and we 25 // simultaneously offset it using the translate transform. 26 // I think a cleaner way to do it would be to use UIScrollEdgeElementContainerInteraction 27 // manually or something like that, because this kinda sucks -sfn 28 const relayoutingOffset = headerModeValue === 0 ? 1 : 0 29 return { 30 top: relayoutingOffset, 31 pointerEvents: headerModeValue === 0 ? 'auto' : 'none', 32 opacity: Math.pow(1 - headerModeValue, 2), 33 transform: [ 34 { 35 translateY: 36 interpolate( 37 headerModeValue, 38 [0, 1], 39 [0, headerPinnedHeight - hHeight], 40 ) - relayoutingOffset, 41 }, 42 ], 43 } 44 } 45 46 return { 47 pointerEvents: headerModeValue === 0 ? 'auto' : 'none', 48 opacity: Math.pow(1 - headerModeValue, 2), 49 transform: [ 50 { 51 translateY: interpolate(headerModeValue, [0, 1], [0, -hHeight]), 52 }, 53 ], 54 } 55 }) 56 57 return headerTransform 58} 59 60export function useMinimalShellFooterTransform() { 61 const {footerMode} = useMinimalShellMode() 62 const {footerHeight} = useShellLayout() 63 64 const footerTransform = useAnimatedStyle(() => { 65 const footerModeValue = footerMode.get() 66 return { 67 pointerEvents: footerModeValue === 0 ? 'auto' : 'none', 68 opacity: Math.pow(1 - footerModeValue, 2), 69 transform: [ 70 { 71 translateY: interpolate( 72 footerModeValue, 73 [0, 1], 74 [0, footerHeight.get()], 75 ), 76 }, 77 ], 78 } 79 }) 80 81 return footerTransform 82} 83 84export function useMinimalShellFabTransform() { 85 const {footerMode} = useMinimalShellMode() 86 87 const fabTransform = useAnimatedStyle(() => { 88 return { 89 transform: [ 90 { 91 translateY: interpolate(footerMode.get(), [0, 1], [-44, 0]), 92 }, 93 ], 94 } 95 }) 96 return fabTransform 97}