import type { MouseEventHandler, PropsWithChildren } from 'react'; import { createContext, useCallback, useContext, useMemo, useState, } from 'react'; import { cleanExtraEmojis } from '@/flavours/glitch/features/emoji/normalize'; import { autoPlayGif } from '@/flavours/glitch/initial_state'; import { polymorphicForwardRef } from '@/types/polymorphic'; import type { CustomEmojiMapArg, ExtraCustomEmojiMap, } from 'flavours/glitch/features/emoji/types'; // Animation context export const AnimateEmojiContext = createContext(null); // Polymorphic provider component type AnimateEmojiProviderProps = Required & { className?: string; }; export const AnimateEmojiProvider = polymorphicForwardRef< 'div', AnimateEmojiProviderProps >( ( { children, as: Wrapper = 'div', className, onMouseEnter, onMouseLeave, ...props }, ref, ) => { const [animate, setAnimate] = useState(autoPlayGif ?? false); const handleEnter: MouseEventHandler = useCallback( (event) => { onMouseEnter?.(event); if (!autoPlayGif) { setAnimate(true); } }, [onMouseEnter], ); const handleLeave: MouseEventHandler = useCallback( (event) => { onMouseLeave?.(event); if (!autoPlayGif) { setAnimate(false); } }, [onMouseLeave], ); // If there's a parent context or GIFs autoplay, we don't need handlers. const parentContext = useContext(AnimateEmojiContext); if (parentContext !== null) { return ( {children} ); } return ( {children} ); }, ); AnimateEmojiProvider.displayName = 'AnimateEmojiProvider'; // Handle custom emoji export const CustomEmojiContext = createContext({}); export const CustomEmojiProvider = ({ children, emojis: rawEmojis, }: PropsWithChildren<{ emojis?: CustomEmojiMapArg }>) => { const emojis = useMemo(() => cleanExtraEmojis(rawEmojis) ?? {}, [rawEmojis]); return ( {children} ); };