import type { FC } from '../../../lib/teact/teact'; import { memo, useRef, useState } from '../../../lib/teact/teact'; import { getActions } from '../../../global'; import type { ApiSticker, ApiVideo } from '../../../api/types'; import type { IAnchorPosition, ThreadId } from '../../../types'; import { EDITABLE_INPUT_CSS_SELECTOR, EDITABLE_INPUT_MODAL_CSS_SELECTOR } from '../../../config'; import buildClassName from '../../../util/buildClassName'; import useFlag from '../../../hooks/useFlag'; import useLastCallback from '../../../hooks/useLastCallback'; import Icon from '../../common/icons/Icon'; import Button from '../../ui/Button'; import ResponsiveHoverButton from '../../ui/ResponsiveHoverButton'; import Spinner from '../../ui/Spinner'; import SymbolMenu from './SymbolMenu.async'; const MOBILE_KEYBOARD_HIDE_DELAY_MS = 100; type OwnProps = { chatId: string; threadId?: ThreadId; isMobile?: boolean; isReady?: boolean; isSymbolMenuOpen?: boolean; canSendGifs?: boolean; canSendStickers?: boolean; isMessageComposer?: boolean; idPrefix: string; forceDarkTheme?: boolean; openSymbolMenu: VoidFunction; closeSymbolMenu: VoidFunction; onCustomEmojiSelect: (emoji: ApiSticker) => void; onStickerSelect?: ( sticker: ApiSticker, isSilent?: boolean, shouldSchedule?: boolean, shouldPreserveInput?: boolean, canUpdateStickerSetsOrder?: boolean, ) => void; onGifSelect?: (gif: ApiVideo, isSilent?: boolean, shouldSchedule?: boolean) => void; onRemoveSymbol: VoidFunction; onEmojiSelect: (emoji: string) => void; closeBotCommandMenu?: VoidFunction; closeSendAsMenu?: VoidFunction; isSymbolMenuForced?: boolean; isAttachmentModal?: boolean; canSendPlainText?: boolean; className?: string; inputCssSelector?: string; }; const SymbolMenuButton: FC = ({ chatId, threadId, isMobile, canSendGifs, canSendStickers, isMessageComposer, isReady, isSymbolMenuOpen, idPrefix, isAttachmentModal, canSendPlainText, isSymbolMenuForced, className, forceDarkTheme, inputCssSelector = EDITABLE_INPUT_CSS_SELECTOR, openSymbolMenu, closeSymbolMenu, onCustomEmojiSelect, onStickerSelect, onGifSelect, onRemoveSymbol, onEmojiSelect, closeBotCommandMenu, closeSendAsMenu, }) => { const { setStickerSearchQuery, setGifSearchQuery, addRecentEmoji, addRecentCustomEmoji, } = getActions(); const triggerRef = useRef(); const [isSymbolMenuLoaded, onSymbolMenuLoadingComplete] = useFlag(); const [contextMenuAnchor, setContextMenuAnchor] = useState(undefined); const symbolMenuButtonClassName = buildClassName( 'composer-action-button mobile-symbol-menu-button', !isReady && 'not-ready', isSymbolMenuLoaded ? (isSymbolMenuOpen && 'menu-opened') : (isSymbolMenuOpen && 'is-loading'), ); const handleActivateSymbolMenu = useLastCallback(() => { closeBotCommandMenu?.(); closeSendAsMenu?.(); openSymbolMenu(); const triggerEl = triggerRef.current; if (!triggerEl) return; const { x, y } = triggerEl.getBoundingClientRect(); setContextMenuAnchor({ x, y }); }); const handleSearchOpen = useLastCallback((type: 'stickers' | 'gifs') => { if (type === 'stickers') { setStickerSearchQuery({ query: '' }); setGifSearchQuery({ query: undefined }); } else { setGifSearchQuery({ query: '' }); setStickerSearchQuery({ query: undefined }); } }); const handleSymbolMenuOpen = useLastCallback(() => { const messageInput = document.querySelector( isAttachmentModal ? EDITABLE_INPUT_MODAL_CSS_SELECTOR : inputCssSelector, ); if (!isMobile || messageInput !== document.activeElement) { openSymbolMenu(); return; } messageInput?.blur(); setTimeout(() => { closeBotCommandMenu?.(); openSymbolMenu(); }, MOBILE_KEYBOARD_HIDE_DELAY_MS); }); const getTriggerElement = useLastCallback(() => triggerRef.current); const getRootElement = useLastCallback(() => triggerRef.current?.closest('.custom-scroll, .no-scrollbar')); const getMenuElement = useLastCallback(() => document.querySelector('#portals .SymbolMenu .bubble')); const getLayout = useLastCallback(() => ({ withPortal: true })); return ( <> {isMobile ? ( ) : (
)} ); }; export default memo(SymbolMenuButton);