import React, { FC, memo, useLayoutEffect, useRef, } from '../../../lib/teact/teact'; import { ApiAvailableReaction, ApiMediaFormat } from '../../../api/types'; import useMedia from '../../../hooks/useMedia'; import useHorizontalScroll from '../../../hooks/useHorizontalScroll'; import useFlag from '../../../hooks/useFlag'; import useShowTransition from '../../../hooks/useShowTransition'; import { getTouchY } from '../../../util/scrollLock'; import ReactionStaticEmoji from '../../common/ReactionStaticEmoji'; import AnimatedSticker from '../../common/AnimatedSticker'; import './ReactionSelector.scss'; const REACTION_SIZE = 32; type OwnProps = { enabledReactions?: string[]; onSendReaction: (reaction: string, x: number, y: number) => void; isPrivate?: boolean; availableReactions?: ApiAvailableReaction[]; isReady?: boolean; }; const AvailableReaction: FC<{ reaction: ApiAvailableReaction; isReady?: boolean; onSendReaction: (reaction: string, x: number, y: number) => void; }> = ({ reaction, onSendReaction, isReady }) => { // eslint-disable-next-line no-null/no-null const containerRef = useRef(null); const mediaData = useMedia(`document${reaction.selectAnimation?.id}`, !isReady, ApiMediaFormat.Lottie); const [isActivated, activate, deactivate] = useFlag(); const [isAnimationLoaded, markAnimationLoaded] = useFlag(); const shouldRenderAnimated = Boolean(isReady && mediaData); const { transitionClassNames: animatedClassNames } = useShowTransition(shouldRenderAnimated); const { shouldRender: shouldRenderStatic, transitionClassNames: staticClassNames } = useShowTransition( !isReady || !isAnimationLoaded, undefined, true, ); function handleClick() { if (!containerRef.current) return; const { x, y } = containerRef.current.getBoundingClientRect(); onSendReaction(reaction.reaction, x, y); } return (
{shouldRenderStatic && ( )} {shouldRenderAnimated && ( )}
); }; const ReactionSelector: FC = ({ availableReactions, enabledReactions, onSendReaction, isPrivate, isReady, }) => { // eslint-disable-next-line no-null/no-null const itemsScrollRef = useRef(null); const [isHorizontalScrollEnabled, enableHorizontalScroll] = useFlag(false); useHorizontalScroll(itemsScrollRef.current, !isHorizontalScrollEnabled); useLayoutEffect(() => { enableHorizontalScroll(); }, [enableHorizontalScroll]); const handleWheel = (e: React.WheelEvent | React.TouchEvent) => { if (!itemsScrollRef) return; const deltaY = 'deltaY' in e ? e.deltaY : getTouchY(e); if (deltaY) { e.preventDefault(); } }; if ((!isPrivate && !enabledReactions?.length) || !availableReactions) return undefined; return (
{availableReactions?.map((reaction) => { if (reaction.isInactive || (!isPrivate && (!enabledReactions || !enabledReactions.includes(reaction.reaction)))) return undefined; return ( ); })}
); }; export default memo(ReactionSelector);