import type { FC } from '../../../lib/teact/teact'; import React, { memo, useMemo, useRef } from '../../../lib/teact/teact'; import { withGlobal } from '../../../global'; import type { ApiAvailableReaction, ApiChatReactions, ApiReaction } from '../../../api/types'; import { getReactionUniqueKey, sortReactions } from '../../../global/helpers'; import { selectChatFullInfo } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { REM } from '../../common/helpers/mediaDimensions'; import useAppLayout from '../../../hooks/useAppLayout'; import useWindowSize from '../../../hooks/useWindowSize'; import ReactionEmoji from '../../common/ReactionEmoji'; import styles from './ReactionPickerLimited.module.scss'; type OwnProps = { chatId: string; loadAndPlay: boolean; onReactionSelect?: (reaction: ApiReaction) => void; selectedReactionIds?: string[]; }; type StateProps = { enabledReactions?: ApiChatReactions; availableReactions?: ApiAvailableReaction[]; topReactions: ApiReaction[]; canAnimate?: boolean; isSavedMessages?: boolean; isCurrentUserPremium?: boolean; }; const REACTION_SIZE = 36; const GRID_GAP_THRESHOLD = 600; const MODAL_PADDING_SIZE_REM = 0.5; const MODAL_MAX_HEIGHT_REM = 18; const MODAL_MAX_WIDTH_REM = 26.25; const GRID_GAP_DESKTOP_REM = 0.625; const GRID_GAP_MOBILE_REM = 0.5; const ReactionPickerLimited: FC = ({ loadAndPlay, enabledReactions, availableReactions, topReactions, selectedReactionIds, onReactionSelect, }) => { // eslint-disable-next-line no-null/no-null const sharedCanvasRef = useRef(null); // eslint-disable-next-line no-null/no-null const sharedCanvasHqRef = useRef(null); const { width: windowWidth } = useWindowSize(); const { isTouchScreen } = useAppLayout(); const allAvailableReactions = useMemo(() => { if (!enabledReactions) { return []; } if (enabledReactions.type === 'all') { return sortReactions((availableReactions || []).map(({ reaction }) => reaction), topReactions); } return sortReactions(enabledReactions.allowed, topReactions); }, [availableReactions, enabledReactions, topReactions]); const pickerHeight = useMemo(() => { const pickerWidth = Math.min(MODAL_MAX_WIDTH_REM * REM, windowWidth); const gapWidth = (windowWidth > GRID_GAP_THRESHOLD ? GRID_GAP_DESKTOP_REM : GRID_GAP_MOBILE_REM) * REM; const availableWidth = pickerWidth - MODAL_PADDING_SIZE_REM * REM; const itemsInRow = Math.floor((availableWidth + gapWidth) / (REACTION_SIZE + gapWidth)); const rowsCount = Math.ceil(allAvailableReactions.length / itemsInRow); const pickerMaxHeight = rowsCount * REACTION_SIZE + (rowsCount - 1) * gapWidth + MODAL_PADDING_SIZE_REM * REM * 2; return Math.min(MODAL_MAX_HEIGHT_REM * REM, pickerMaxHeight); }, [allAvailableReactions.length, windowWidth]); return (
{allAvailableReactions.map((reaction) => { const reactionId = getReactionUniqueKey(reaction); const isSelected = reactionId ? selectedReactionIds?.includes(reactionId) : undefined; return ( ); })}
); }; export default memo(withGlobal( (global, { chatId }): StateProps => { const { availableReactions, topReactions } = global; const { enabledReactions } = selectChatFullInfo(global, chatId) || {}; return { enabledReactions, availableReactions, topReactions, }; }, )(ReactionPickerLimited));