import { AnimatePresence, motion } from 'framer-motion'; import { Fragment, useEffect, useMemo, useRef, useState } from 'react'; import Confetti from 'react-confetti'; import PropTypes from 'prop-types'; import resolveConfig from 'tailwindcss/resolveConfig'; import { defaultViewerStreamActionAnimationProps, reversedViewerStreamActionVariants } from './viewerStreamActionsTheme.js'; import { clsm, range } from '../../../utils'; import { ConfettiClosed, ConfettiOpen } from '../../../assets/icons'; import { PROFILE_COLORS } from '../../../constants'; import tailwindConfig from '../../../tailwind.config'; const resolvedTailwindConfig = resolveConfig(tailwindConfig); const style = getComputedStyle(document.documentElement); const creatorGradientTransition = { duration: 2, ease: 'linear', repeat: Infinity, type: 'tween' }; const Celebration = ({ chatContainerDimensions, color, shouldRun }) => { const [isIconOpen, setIsIconOpen] = useState(false); const [hasBannerEntered, setHasBannerEntered] = useState(false); const animationIntervalIdRef = useRef(); const profileColors = useMemo( () => Object.entries(resolvedTailwindConfig.theme.colors.profile).reduce( (acc, [key, value]) => { if (key !== 'default') { const cssVarValue = style.getPropertyValue( `--base-profile-color-${key}` ); return { ...acc, [key]: value.DEFAULT.replace(/var\(--[a-z-]+\)/, cssVarValue) }; } return acc; }, {} ), [] ); const creatorGradientSteps = useMemo( () => `${profileColors.salmon} 0deg, ${profileColors.yellow} 54.38deg, ${profileColors.green} 110.62deg, ${profileColors.turquoise} 166.87deg, ${profileColors.blue} 223.13deg, ${profileColors.purple} 277.5deg, ${profileColors.lavender} 331.88deg, ${profileColors.salmon} 360deg`, [profileColors] ); useEffect(() => { const clearAnimationIntervalId = () => { clearInterval(animationIntervalIdRef.current); animationIntervalIdRef.current = null; }; if (shouldRun) { animationIntervalIdRef.current = setInterval(() => { setIsIconOpen((prev) => !prev); setHasBannerEntered(true); }, 500); } else { setIsIconOpen(false); setHasBannerEntered(false); clearAnimationIntervalId(); } return clearAnimationIntervalId; }, [shouldRun]); return ( <> {chatContainerDimensions ? ( ) : null} {shouldRun && (
{range(5).map((index) => ( {isIconOpen ? : } ))}
)}
); }; Celebration.propTypes = { chatContainerDimensions: PropTypes.shape({ width: PropTypes.number, height: PropTypes.number }), color: PropTypes.oneOf([...PROFILE_COLORS, 'default']), shouldRun: PropTypes.bool }; Celebration.defaultProps = { chatContainerDimensions: null, color: 'default', shouldRun: false }; export default Celebration;