import React, { useEffect, useState } from 'react'; import { FormattedNumber } from 'react-intl'; import { TransitionMotion, spring } from 'react-motion'; import { useSettings } from 'soapbox/hooks'; const obfuscatedCount = (count: number) => { if (count < 0) { return 0; } else if (count <= 1) { return count; } else { return '1+'; } }; interface IAnimatedNumber { value: number obfuscate?: boolean } const AnimatedNumber: React.FC = ({ value, obfuscate }) => { const reduceMotion = useSettings().get('reduceMotion'); const [direction, setDirection] = useState(1); const [displayedValue, setDisplayedValue] = useState(value); useEffect(() => { if (displayedValue !== undefined) { if (value > displayedValue) setDirection(1); else if (value < displayedValue) setDirection(-1); } setDisplayedValue(value); }, [value]); const willEnter = () => ({ y: -1 * direction }); const willLeave = () => ({ y: spring(1 * direction, { damping: 35, stiffness: 400 }) }); if (reduceMotion) { return obfuscate ? <>{obfuscatedCount(displayedValue)} : ; } const styles = [{ key: `${displayedValue}`, data: displayedValue, style: { y: spring(0, { damping: 35, stiffness: 400 }) }, }]; return ( {items => ( {items.map(({ key, data, style }) => ( 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : } ))} )} ); }; export default AnimatedNumber;