Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
119
fork

Configure Feed

Select the types of activity you want to include in your feed.

at a876aae44ea07494ebea9727350aa060b81f317b 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}