import React from 'react' import {View} from 'react-native' import {useReducedMotion} from 'react-native-reanimated' import {decideShouldRoll} from '#/lib/custom-animations/util' import {s} from '#/lib/styles' import {Text} from '#/view/com/util/text/Text' import {atoms as a, useTheme} from '#/alf' import {useFormatPostStatCount} from '#/components/PostControls/util' const animationConfig = { duration: 400, easing: 'cubic-bezier(0.4, 0, 0.2, 1)', fill: 'forwards' as FillMode, } const enteringUpKeyframe = [ {opacity: 0, transform: 'translateY(18px)'}, {opacity: 1, transform: 'translateY(0)'}, ] const enteringDownKeyframe = [ {opacity: 0, transform: 'translateY(-18px)'}, {opacity: 1, transform: 'translateY(0)'}, ] const exitingUpKeyframe = [ {opacity: 1, transform: 'translateY(0)'}, {opacity: 0, transform: 'translateY(-18px)'}, ] const exitingDownKeyframe = [ {opacity: 1, transform: 'translateY(0)'}, {opacity: 0, transform: 'translateY(18px)'}, ] export function CountWheel({ likeCount, big, isLiked, hasBeenToggled, }: { likeCount: number big?: boolean isLiked: boolean hasBeenToggled: boolean }) { const t = useTheme() const shouldAnimate = !useReducedMotion() && hasBeenToggled const shouldRoll = decideShouldRoll(isLiked, likeCount) const countView = React.useRef(null) const prevCountView = React.useRef(null) const [prevCount, setPrevCount] = React.useState(likeCount) const prevIsLiked = React.useRef(isLiked) const formatPostStatCount = useFormatPostStatCount() const formattedCount = formatPostStatCount(likeCount) const formattedPrevCount = formatPostStatCount(prevCount) React.useEffect(() => { if (isLiked === prevIsLiked.current) { return } const newPrevCount = isLiked ? likeCount - 1 : likeCount + 1 if (shouldAnimate && shouldRoll) { countView.current?.animate?.( isLiked ? enteringUpKeyframe : enteringDownKeyframe, animationConfig, ) prevCountView.current?.animate?.( isLiked ? exitingUpKeyframe : exitingDownKeyframe, animationConfig, ) setPrevCount(newPrevCount) } prevIsLiked.current = isLiked }, [isLiked, likeCount, shouldAnimate, shouldRoll]) if (likeCount < 1) { return null } return ( {formattedCount} {shouldAnimate && (likeCount > 1 || !isLiked) ? ( {formattedPrevCount} ) : null} ) }