Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

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

at main 131 lines 2.8 kB view raw
1import {View} from 'react-native' 2import Animated, { 3 Keyframe, 4 LayoutAnimationConfig, 5 useReducedMotion, 6} from 'react-native-reanimated' 7 8import {useTheme} from '#/alf' 9import { 10 Heart2_Filled_Stroke2_Corner0_Rounded as HeartIconFilled, 11 Heart2_Stroke2_Corner0_Rounded as HeartIconOutline, 12} from '#/components/icons/Heart2' 13 14const keyframe = new Keyframe({ 15 0: { 16 transform: [{scale: 1}], 17 }, 18 10: { 19 transform: [{scale: 0.7}], 20 }, 21 40: { 22 transform: [{scale: 1.2}], 23 }, 24 100: { 25 transform: [{scale: 1}], 26 }, 27}) 28 29const circle1Keyframe = new Keyframe({ 30 0: { 31 opacity: 0, 32 transform: [{scale: 0}], 33 }, 34 10: { 35 opacity: 0.4, 36 }, 37 40: { 38 transform: [{scale: 1.5}], 39 }, 40 95: { 41 opacity: 0.4, 42 }, 43 100: { 44 opacity: 0, 45 transform: [{scale: 1.5}], 46 }, 47}) 48 49const circle2Keyframe = new Keyframe({ 50 0: { 51 opacity: 0, 52 transform: [{scale: 0}], 53 }, 54 10: { 55 opacity: 1, 56 }, 57 40: { 58 transform: [{scale: 0}], 59 }, 60 95: { 61 opacity: 1, 62 }, 63 100: { 64 opacity: 0, 65 transform: [{scale: 1.5}], 66 }, 67}) 68 69export function AnimatedLikeIcon({ 70 isLiked, 71 big, 72 hasBeenToggled, 73}: { 74 isLiked: boolean 75 big?: boolean 76 hasBeenToggled: boolean 77}) { 78 const t = useTheme() 79 const size = big ? 22 : 18 80 const shouldAnimate = !useReducedMotion() && hasBeenToggled 81 82 return ( 83 <View> 84 <LayoutAnimationConfig skipEntering> 85 {isLiked ? ( 86 <Animated.View 87 entering={shouldAnimate ? keyframe.duration(300) : undefined}> 88 <HeartIconFilled style={{color: t.palette.pink}} width={size} /> 89 </Animated.View> 90 ) : ( 91 <HeartIconOutline 92 style={[{color: t.palette.contrast_500}, {pointerEvents: 'none'}]} 93 width={size} 94 /> 95 )} 96 {isLiked && shouldAnimate ? ( 97 <> 98 <Animated.View 99 entering={circle1Keyframe.duration(300)} 100 style={{ 101 position: 'absolute', 102 backgroundColor: t.palette.pink, 103 top: 0, 104 left: 0, 105 width: size, 106 height: size, 107 zIndex: -1, 108 pointerEvents: 'none', 109 borderRadius: size / 2, 110 }} 111 /> 112 <Animated.View 113 entering={circle2Keyframe.duration(300)} 114 style={{ 115 position: 'absolute', 116 backgroundColor: t.atoms.bg.backgroundColor, 117 top: 0, 118 left: 0, 119 width: size, 120 height: size, 121 zIndex: -1, 122 pointerEvents: 'none', 123 borderRadius: size / 2, 124 }} 125 /> 126 </> 127 ) : null} 128 </LayoutAnimationConfig> 129 </View> 130 ) 131}