import React, { FC, memo, useRef, useCallback, useState, } from '../../lib/teact/teact'; import { withGlobal } from '../../lib/teact/teactn'; import { GlobalActions, MessageListType } from '../../global/types'; import { MAIN_THREAD_ID } from '../../api/types'; import { IAnchorPosition } from '../../types'; import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment'; import { pick } from '../../util/iteratees'; import { isChatChannel, isChatSuperGroup } from '../../modules/helpers'; import { selectChat, selectIsChatBotNotStarted, selectIsChatWithSelf, selectIsInSelectMode, selectIsRightColumnShown, } from '../../modules/selectors'; import useLang from '../../hooks/useLang'; import Button from '../ui/Button'; import HeaderMenuContainer from './HeaderMenuContainer.async'; interface OwnProps { chatId: number; threadId: number; messageListType: MessageListType; } interface StateProps { noMenu?: boolean; isChannel?: boolean; isRightColumnShown?: boolean; canStartBot?: boolean; canSubscribe?: boolean; canSearch?: boolean; canMute?: boolean; canSelect?: boolean; canLeave?: boolean; } type DispatchProps = Pick; // Chrome breaks layout when focusing input during transition const SEARCH_FOCUS_DELAY_MS = 400; const HeaderActions: FC = ({ chatId, threadId, noMenu, isChannel, canStartBot, canSubscribe, canSearch, canMute, canSelect, canLeave, isRightColumnShown, joinChannel, sendBotCommand, openLocalTextSearch, }) => { // eslint-disable-next-line no-null/no-null const menuButtonRef = useRef(null); const [isMenuOpen, setIsMenuOpen] = useState(false); const [menuPosition, setMenuPosition] = useState(undefined); const handleHeaderMenuOpen = useCallback(() => { setIsMenuOpen(true); const rect = menuButtonRef.current!.getBoundingClientRect(); setMenuPosition({ x: rect.right, y: rect.bottom }); }, []); const handleHeaderMenuClose = useCallback(() => { setIsMenuOpen(false); }, []); const handleHeaderMenuHide = useCallback(() => { setMenuPosition(undefined); }, []); const handleSubscribeClick = useCallback(() => { joinChannel({ chatId }); }, [joinChannel, chatId]); const handleStartBot = useCallback(() => { sendBotCommand({ command: '/start' }); }, [sendBotCommand]); const handleSearchClick = useCallback(() => { openLocalTextSearch(); if (IS_SINGLE_COLUMN_LAYOUT) { // iOS requires synchronous focus on user event. const searchInput = document.querySelector('#MobileSearch input')!; searchInput.focus(); } else { setTimeout(() => { const searchInput = document.querySelector('.RightHeader .SearchInput input'); if (searchInput) { searchInput.focus(); } }, SEARCH_FOCUS_DELAY_MS); } }, [openLocalTextSearch]); const lang = useLang(); return (
{!IS_SINGLE_COLUMN_LAYOUT && canSubscribe && ( )} {!IS_SINGLE_COLUMN_LAYOUT && canStartBot && ( )} {!IS_SINGLE_COLUMN_LAYOUT && canSearch && ( )} {(IS_SINGLE_COLUMN_LAYOUT || !canSubscribe) && ( )} {menuPosition && ( )}
); }; export default memo(withGlobal( (global, { chatId, threadId, messageListType }): StateProps => { const chat = selectChat(global, chatId); const isChannel = Boolean(chat && isChatChannel(chat)); if (chat && chat.isRestricted) { return { noMenu: true, }; } const isChatWithSelf = selectIsChatWithSelf(global, chatId); const isMainThread = messageListType === 'thread' && threadId === MAIN_THREAD_ID; const isDiscussionThread = messageListType === 'thread' && threadId !== MAIN_THREAD_ID; const isRightColumnShown = selectIsRightColumnShown(global); const canStartBot = Boolean(selectIsChatBotNotStarted(global, chatId)); const canSubscribe = Boolean( isMainThread && chat && (isChannel || isChatSuperGroup(chat)) && chat.isNotJoined, ); const canSearch = isMainThread || isDiscussionThread; const canMute = isMainThread && !isChatWithSelf && !canSubscribe; const canSelect = !selectIsInSelectMode(global); const canLeave = isMainThread && !canSubscribe; const noMenu = !( (IS_SINGLE_COLUMN_LAYOUT && canSubscribe) || (IS_SINGLE_COLUMN_LAYOUT && canSearch) || canMute || canSelect || canLeave ); return { noMenu, isChannel, isRightColumnShown, canStartBot, canSubscribe, canSearch, canMute, canSelect, canLeave, }; }, (setGlobal, actions): DispatchProps => pick(actions, [ 'joinChannel', 'sendBotCommand', 'openLocalTextSearch', ]), )(HeaderActions));