import { forwardRef, memo, useEffect, useRef, useState, } from 'react' import { isMobileDevice } from 'config' import { defaultTheme } from 'features/Theme/config' import { Button, Svg, Path, } from './styled' const COLOR_PAIRS = [ ['#FF0000', '#FFDF00'], ['#70FF00', '#0001FF'], ['#CD00FF', defaultTheme.colors.white], [defaultTheme.colors.white, defaultTheme.colors.white], [defaultTheme.colors.white, defaultTheme.colors.white], [defaultTheme.colors.white, defaultTheme.colors.white], ['#FF0000', '#FFDF00'], ['#70FF00', '#0001FF'], ['#CD00FF', defaultTheme.colors.white], [], ] const OFFSET_CHANGE_SPEED = isMobileDevice ? 20 : 5 const ANIMATION_INTERVAL = 5000 const FREEZE_TIME = 6000 const PARTICLES_GENERATION_TIME = 1500 type Props = { onClick: () => void, setGenerateParticles: (state: boolean) => void, } const LikeButtonFC = forwardRef(( { onClick, setGenerateParticles, }, ref, ) => { const stop1Ref = useRef(null) const stop2Ref = useRef(null) const [canAnimate, setCanAnimate] = useState(false) const [isDisabled, setIsDisabled] = useState(false) const freezeTimeoutIdRef = useRef(null) const generateTimeoutIdRef = useRef(null) const startGenerateParticles = () => setGenerateParticles(true) const stopGenerateParticles = () => setGenerateParticles(false) const handleClick = () => { onClick() setIsDisabled(true) startGenerateParticles() freezeTimeoutIdRef.current = setTimeout(() => setIsDisabled(false), FREEZE_TIME) generateTimeoutIdRef.current = setTimeout(stopGenerateParticles, PARTICLES_GENERATION_TIME) } useEffect(() => { let requestAnimationId: number let timeoutId: NodeJS.Timeout let index = 0 let offset = 100 const animate = () => { if (!stop1Ref.current || !stop2Ref.current) return stop1Ref.current.setAttribute('offset', `${offset}%`) stop2Ref.current.setAttribute('offset', `${offset}%`) stop1Ref.current.setAttribute('stop-color', `${COLOR_PAIRS[index][0]}`) stop2Ref.current.setAttribute('stop-color', `${COLOR_PAIRS[index][1]}`) offset = Math.max(offset - OFFSET_CHANGE_SPEED, 0) if (offset === 0) { offset = 100 index = index + 1 <= COLOR_PAIRS.length - 1 ? index + 1 : 0 } if (index === COLOR_PAIRS.length - 1 && offset === 100) { requestAnimationId && cancelAnimationFrame(requestAnimationId) setCanAnimate(false) index = 0 timeoutId = setTimeout(() => { requestAnimationId = requestAnimationFrame(animate) }, ANIMATION_INTERVAL) } else { requestAnimationId = requestAnimationFrame(animate) setCanAnimate(true) } } timeoutId = setTimeout(animate, ANIMATION_INTERVAL) return () => { timeoutId && clearTimeout(timeoutId) requestAnimationId && cancelAnimationFrame(requestAnimationId) } }, []) useEffect(() => () => { freezeTimeoutIdRef.current && clearTimeout(freezeTimeoutIdRef.current) generateTimeoutIdRef.current && clearTimeout(generateTimeoutIdRef.current) }, []) return ( ) }) export const LikeButton = memo(LikeButtonFC)