diff --git a/src/components/middle/HeaderActions.tsx b/src/components/middle/HeaderActions.tsx index 37037312a..1ec70a77e 100644 --- a/src/components/middle/HeaderActions.tsx +++ b/src/components/middle/HeaderActions.tsx @@ -12,6 +12,7 @@ import { MAIN_THREAD_ID } from '../../api/types'; import type { IAnchorPosition } from '../../types'; import { ManagementScreens } from '../../types'; +import { ANIMATION_LEVEL_MIN } from '../../config'; import { ARE_CALLS_SUPPORTED, IS_PWA, IS_SINGLE_COLUMN_LAYOUT, } from '../../util/environment'; @@ -57,10 +58,11 @@ interface StateProps { pendingJoinRequests?: number; shouldJoinToSend?: boolean; shouldSendJoinRequest?: boolean; + noAnimation?: boolean; } // Chrome breaks layout when focusing input during transition -const SEARCH_FOCUS_DELAY_MS = 400; +const SEARCH_FOCUS_DELAY_MS = 320; const HeaderActions: FC = ({ chatId, @@ -82,6 +84,7 @@ const HeaderActions: FC = ({ canExpandActions, shouldJoinToSend, shouldSendJoinRequest, + noAnimation, }) => { const { joinChannel, @@ -140,15 +143,15 @@ const HeaderActions: FC = ({ // iOS requires synchronous focus on user event. const searchInput = document.querySelector('#MobileSearch input')!; searchInput.focus(); + } else if (noAnimation) { + // The second RAF is necessary because teact must update the state and render the async component + requestAnimationFrame(() => { + requestAnimationFrame(setFocusInSearchInput); + }); } else { - setTimeout(() => { - const searchInput = document.querySelector('.RightHeader .SearchInput input'); - if (searchInput) { - searchInput.focus(); - } - }, SEARCH_FOCUS_DELAY_MS); + setTimeout(setFocusInSearchInput, SEARCH_FOCUS_DELAY_MS); } - }, [openLocalTextSearch]); + }, [noAnimation, openLocalTextSearch]); function handleRequestCall() { requestCall({ userId: chatId }); @@ -325,6 +328,7 @@ export default memo(withGlobal( const pendingJoinRequests = chat.fullInfo?.requestsPending; const shouldJoinToSend = Boolean(chat?.isNotJoined && chat.isJoinToSend); const shouldSendJoinRequest = Boolean(chat?.isNotJoined && chat.isJoinRequest); + const noAnimation = global.settings.byKey.animationLevel === ANIMATION_LEVEL_MIN; return { noMenu: false, @@ -343,6 +347,12 @@ export default memo(withGlobal( pendingJoinRequests, shouldJoinToSend, shouldSendJoinRequest, + noAnimation, }; }, )(HeaderActions)); + +function setFocusInSearchInput() { + const searchInput = document.querySelector('.RightHeader .SearchInput input'); + searchInput?.focus(); +} diff --git a/src/components/right/RightSearch.tsx b/src/components/right/RightSearch.tsx index 4668d1bf0..b4ed7056e 100644 --- a/src/components/right/RightSearch.tsx +++ b/src/components/right/RightSearch.tsx @@ -1,4 +1,6 @@ -import React, { useMemo, memo, useRef } from '../../lib/teact/teact'; +import React, { + useMemo, memo, useRef, useEffect, +} from '../../lib/teact/teact'; import { getActions, getGlobal, withGlobal } from '../../global'; import type { FC } from '../../lib/teact/teact'; @@ -15,11 +17,12 @@ import { import { isChatChannel, } from '../../global/helpers'; +import { disableDirectTextInput, enableDirectTextInput } from '../../util/directInputManager'; +import { renderMessageSummary } from '../common/helpers/renderMessageText'; import useLang from '../../hooks/useLang'; import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation'; import useHistoryBack from '../../hooks/useHistoryBack'; import useInfiniteScroll from '../../hooks/useInfiniteScroll'; -import { renderMessageSummary } from '../common/helpers/renderMessageText'; import InfiniteScroll from '../ui/InfiniteScroll'; import ListItem from '../ui/ListItem'; @@ -71,6 +74,16 @@ const RightSearch: FC = ({ onBack: onClose, }); + useEffect(() => { + if (!isActive) { + return undefined; + } + + disableDirectTextInput(); + + return enableDirectTextInput; + }, [isActive]); + const [viewportIds, getMore] = useInfiniteScroll(searchTextMessagesLocal, foundIds); const viewportResults = useMemo(() => {