import type { FC } from '../../lib/teact/teact'; import React, { memo, useCallback, useEffect, useMemo, useRef, } from '../../lib/teact/teact'; import { getActions, withGlobal } from '../../global'; import type { ApiSticker, ApiStickerSet } from '../../api/types'; import type { MessageList } from '../../types'; import { EMOJI_SIZE_MODAL, STICKER_SIZE_MODAL, TME_LINK_PREFIX } from '../../config'; import { getAllowedAttachmentOptions, getCanPostInChat } from '../../global/helpers'; import { selectCanScheduleUntilOnline, selectChat, selectChatFullInfo, selectCurrentMessageList, selectIsChatWithSelf, selectIsCurrentUserPremium, selectPeerPaidMessagesStars, selectShouldSchedule, selectStickerSet, selectThreadInfo, selectTopic, } from '../../global/selectors'; import buildClassName from '../../util/buildClassName'; import { copyTextToClipboard } from '../../util/clipboard'; import renderText from './helpers/renderText'; import useAppLayout from '../../hooks/useAppLayout'; import { useIntersectionObserver } from '../../hooks/useIntersectionObserver'; import useOldLang from '../../hooks/useOldLang'; import usePreviousDeprecated from '../../hooks/usePreviousDeprecated'; import useSchedule from '../../hooks/useSchedule'; import useScrolledState from '../../hooks/useScrolledState'; import Button from '../ui/Button'; import DropdownMenu from '../ui/DropdownMenu'; import Loading from '../ui/Loading'; import MenuItem from '../ui/MenuItem'; import Modal from '../ui/Modal'; import Icon from './icons/Icon'; import StickerButton from './StickerButton'; import './StickerSetModal.scss'; export type OwnProps = { isOpen: boolean; fromSticker?: ApiSticker; stickerSetShortName?: string; onClose: () => void; }; type StateProps = { currentMessageList?: MessageList; canSendStickers?: boolean; stickerSet?: ApiStickerSet; canScheduleUntilOnline?: boolean; shouldSchedule?: boolean; isSavedMessages?: boolean; isCurrentUserPremium?: boolean; shouldUpdateStickerSetOrder?: boolean; }; const INTERSECTION_THROTTLE = 200; const StickerSetModal: FC = ({ isOpen, fromSticker, stickerSetShortName, stickerSet, canSendStickers, canScheduleUntilOnline, shouldSchedule, isSavedMessages, isCurrentUserPremium, shouldUpdateStickerSetOrder, currentMessageList, onClose, }) => { const { loadStickers, toggleStickerSet, sendMessage, showNotification, } = getActions(); // eslint-disable-next-line no-null/no-null const containerRef = useRef(null); // eslint-disable-next-line no-null/no-null const sharedCanvasRef = useRef(null); const lang = useOldLang(); const { isMobile } = useAppLayout(); const prevStickerSet = usePreviousDeprecated(stickerSet); const renderingStickerSet = stickerSet || prevStickerSet; const isAdded = Boolean(!renderingStickerSet?.isArchived && renderingStickerSet?.installedDate); const isEmoji = renderingStickerSet?.isEmoji; const [requestCalendar, calendar] = useSchedule(canScheduleUntilOnline); const { handleScroll: handleContentScroll, isAtBeginning: shouldHideTopBorder, } = useScrolledState(); const { observe: observeIntersection, } = useIntersectionObserver({ rootRef: containerRef, throttleMs: INTERSECTION_THROTTLE, isDisabled: !isOpen }); useEffect(() => { if (isOpen && !renderingStickerSet?.stickers) { loadStickers({ stickerSetInfo: fromSticker ? fromSticker.stickerSetInfo : { shortName: stickerSetShortName! }, }); } }, [isOpen, fromSticker, loadStickers, stickerSetShortName, renderingStickerSet]); const handleSelect = useCallback((sticker: ApiSticker, isSilent?: boolean, isScheduleRequested?: boolean) => { if (!currentMessageList) { return; } sticker = { ...sticker, isPreloadedGlobally: true, }; if (shouldSchedule || isScheduleRequested) { requestCalendar((scheduledAt) => { sendMessage({ messageList: currentMessageList, sticker, isSilent, scheduledAt, }); onClose(); }); } else { sendMessage({ messageList: currentMessageList, sticker, isSilent, shouldUpdateStickerSetOrder: shouldUpdateStickerSetOrder && isAdded, }); onClose(); } }, [currentMessageList, shouldSchedule, requestCalendar, onClose, shouldUpdateStickerSetOrder, isAdded]); const handleButtonClick = useCallback(() => { if (renderingStickerSet) { toggleStickerSet({ stickerSetId: renderingStickerSet.id }); onClose(); } }, [onClose, renderingStickerSet, toggleStickerSet]); const handleCopyLink = useCallback(() => { if (!renderingStickerSet) return; const { shortName } = renderingStickerSet; const suffix = isEmoji ? 'addemoji' : 'addstickers'; const url = `${TME_LINK_PREFIX}${suffix}/${shortName}`; copyTextToClipboard(url); showNotification({ message: lang('LinkCopied'), }); }, [isEmoji, lang, renderingStickerSet, showNotification]); const renderButtonText = () => { if (!renderingStickerSet) return lang('Loading'); const suffix = isEmoji ? 'Emoji' : 'Sticker'; return lang( isAdded ? `StickerPack.Remove${suffix}Count` : `StickerPack.Add${suffix}Count`, renderingStickerSet.count, 'i', ); }; const MoreMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => { return ({ onTrigger, isOpen: isMenuOpen }) => ( ); }, [isMobile]); function renderHeader() { const fullClassName = buildClassName('modal-header', !shouldHideTopBorder && 'with-top-border'); return (
{renderingStickerSet ? renderText(renderingStickerSet.title, ['emoji', 'links']) : lang('AccDescrStickerSet')}
{lang('StickersCopy')}
); } return ( {renderingStickerSet?.stickers ? ( <>
{renderingStickerSet.stickers.map((sticker) => ( ))}
) : ( )} {calendar}
); }; export default memo(withGlobal( (global, { fromSticker, stickerSetShortName }): StateProps => { const currentMessageList = selectCurrentMessageList(global); const { chatId, threadId } = currentMessageList || {}; const chat = chatId && selectChat(global, chatId); const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined; const sendOptions = chat ? getAllowedAttachmentOptions(chat, chatFullInfo) : undefined; const threadInfo = chatId && threadId ? selectThreadInfo(global, chatId, threadId) : undefined; const isMessageThread = Boolean(!threadInfo?.isCommentsInfo && threadInfo?.fromChannelId); const topic = chatId && threadId ? selectTopic(global, chatId, threadId) : undefined; const canSendStickers = Boolean( chat && threadId && getCanPostInChat(chat, topic, isMessageThread, chatFullInfo) && sendOptions?.canSendStickers, ); const isSavedMessages = Boolean(chatId) && selectIsChatWithSelf(global, chatId); const stickerSetInfo = fromSticker ? fromSticker.stickerSetInfo : stickerSetShortName ? { shortName: stickerSetShortName } : undefined; const stickerSet = stickerSetInfo ? selectStickerSet(global, stickerSetInfo) : undefined; const paidMessagesStars = chatId ? selectPeerPaidMessagesStars(global, chatId) : undefined; return { canScheduleUntilOnline: Boolean(chatId) && selectCanScheduleUntilOnline(global, chatId), canSendStickers, isSavedMessages, shouldSchedule: !paidMessagesStars && selectShouldSchedule(global), stickerSet, isCurrentUserPremium: selectIsCurrentUserPremium(global), shouldUpdateStickerSetOrder: global.settings.byKey.shouldUpdateStickerSetOrder, currentMessageList, }; }, )(StickerSetModal));