diff --git a/src/components/middle/MiddleHeader.tsx b/src/components/middle/MiddleHeader.tsx index 5dd5196b0..56e4a2bea 100644 --- a/src/components/middle/MiddleHeader.tsx +++ b/src/components/middle/MiddleHeader.tsx @@ -10,7 +10,7 @@ import { } from '../../api/types'; import { - EDITABLE_INPUT_ID, + EDITABLE_INPUT_CSS_SELECTOR, MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN, MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN, MOBILE_SCREEN_MAX_WIDTH, @@ -190,10 +190,8 @@ const MiddleHeader: FC = ({ // Workaround for missing UI when quickly clicking the Back button isBackButtonActive.current = false; if (IS_SINGLE_COLUMN_LAYOUT) { - const messageInput = document.getElementById(EDITABLE_INPUT_ID); - if (messageInput) { - messageInput.blur(); - } + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); + messageInput?.blur(); } if (isSelectModeActive) { diff --git a/src/components/middle/composer/Composer.tsx b/src/components/middle/composer/Composer.tsx index bb5c9ca6a..8250aeb45 100644 --- a/src/components/middle/composer/Composer.tsx +++ b/src/components/middle/composer/Composer.tsx @@ -23,6 +23,7 @@ import { InlineBotSettings } from '../../../types'; import { BASE_EMOJI_KEYWORD_LANG, EDITABLE_INPUT_ID, REPLIES_USER_ID, SEND_MESSAGE_ACTION_INTERVAL, + EDITABLE_INPUT_CSS_SELECTOR, } from '../../../config'; import { IS_VOICE_RECORDING_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT, IS_IOS } from '../../../util/environment'; import { MEMO_EMPTY_ARRAY } from '../../../util/memo'; @@ -398,7 +399,12 @@ const Composer: FC = ({ const insertTextAndUpdateCursor = useCallback((text: string, inputId: string = EDITABLE_INPUT_ID) => { const selection = window.getSelection()!; - const messageInput = document.getElementById(inputId)!; + let messageInput: HTMLDivElement; + if (inputId === EDITABLE_INPUT_ID) { + messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR)!; + } else { + messageInput = document.getElementById(inputId) as HTMLDivElement; + } const newHtml = renderText(text, ['escape_html', 'emoji_html', 'br_html']) .join('') .replace(/\u200b+/g, '\u200b'); @@ -543,7 +549,7 @@ const Composer: FC = ({ return; } - const messageInput = document.getElementById(EDITABLE_INPUT_ID)!; + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); if (currentAttachments.length || text) { if (slowMode && !isAdmin) { @@ -567,7 +573,7 @@ const Composer: FC = ({ }, }); - messageInput.blur(); + messageInput?.blur(); return; } @@ -593,7 +599,7 @@ const Composer: FC = ({ clearDraft({ chatId, localOnly: true }); - if (IS_IOS && messageInput === document.activeElement) { + if (IS_IOS && messageInput && messageInput === document.activeElement) { applyIosAutoCapitalizationFix(messageInput); } @@ -723,8 +729,8 @@ const Composer: FC = ({ }); } - const messageInput = document.getElementById(EDITABLE_INPUT_ID)!; - if (IS_IOS && messageInput === document.activeElement) { + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); + if (IS_IOS && messageInput && messageInput === document.activeElement) { applyIosAutoCapitalizationFix(messageInput); } @@ -777,14 +783,14 @@ const Composer: FC = ({ }, [setStickerSearchQuery, setGifSearchQuery]); const handleSymbolMenuOpen = useCallback(() => { - const messageInput = document.getElementById(EDITABLE_INPUT_ID)!; + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); if (!IS_SINGLE_COLUMN_LAYOUT || messageInput !== document.activeElement) { openSymbolMenu(); return; } - messageInput.blur(); + messageInput?.blur(); setTimeout(() => { closeBotCommandMenu(); openSymbolMenu(); @@ -792,7 +798,7 @@ const Composer: FC = ({ }, [openSymbolMenu, closeBotCommandMenu]); const handleSendAsMenuOpen = useCallback(() => { - const messageInput = document.getElementById(EDITABLE_INPUT_ID)!; + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); if (!IS_SINGLE_COLUMN_LAYOUT || messageInput !== document.activeElement) { closeBotCommandMenu(); @@ -801,7 +807,7 @@ const Composer: FC = ({ return; } - messageInput.blur(); + messageInput?.blur(); setTimeout(() => { closeBotCommandMenu(); closeSymbolMenu(); diff --git a/src/components/middle/composer/hooks/useDraft.ts b/src/components/middle/composer/hooks/useDraft.ts index 00400c4be..9d0615bbc 100644 --- a/src/components/middle/composer/hooks/useDraft.ts +++ b/src/components/middle/composer/hooks/useDraft.ts @@ -3,7 +3,7 @@ import { getActions } from '../../../../global'; import { ApiFormattedText, ApiMessage } from '../../../../api/types'; -import { DRAFT_DEBOUNCE, EDITABLE_INPUT_ID } from '../../../../config'; +import { DRAFT_DEBOUNCE, EDITABLE_INPUT_CSS_SELECTOR } from '../../../../config'; import usePrevious from '../../../../hooks/usePrevious'; import { debounce } from '../../../../util/schedulers'; import focusEditableElement from '../../../../util/focusEditableElement'; @@ -70,8 +70,10 @@ const useDraft = ( if (!IS_TOUCH_ENV) { requestAnimationFrame(() => { - const messageInput = document.getElementById(EDITABLE_INPUT_ID)!; - focusEditableElement(messageInput, true); + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); + if (messageInput) { + focusEditableElement(messageInput, true); + } }); } }, [chatId, threadId, draft, setHtml, updateDraft, prevChatId, prevThreadId, editedMessage]); diff --git a/src/components/middle/composer/hooks/useEditing.ts b/src/components/middle/composer/hooks/useEditing.ts index bc1421086..dc38f0bd8 100644 --- a/src/components/middle/composer/hooks/useEditing.ts +++ b/src/components/middle/composer/hooks/useEditing.ts @@ -5,7 +5,7 @@ import { ApiFormattedText, ApiMessage } from '../../../../api/types'; import { MessageListType } from '../../../../global/types'; import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps'; -import { EDITABLE_INPUT_ID } from '../../../../config'; +import { EDITABLE_INPUT_CSS_SELECTOR } from '../../../../config'; import parseMessageInput from '../../../../util/parseMessageInput'; import focusEditableElement from '../../../../util/focusEditableElement'; import { hasMessageMedia } from '../../../../global/helpers'; @@ -40,8 +40,10 @@ const useEditing = ( setHtml(html); // `fastRaf` would execute syncronously in this case requestAnimationFrame(() => { - const messageInput = document.getElementById(EDITABLE_INPUT_ID)!; - focusEditableElement(messageInput, true); + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); + if (messageInput) { + focusEditableElement(messageInput, true); + } }); }, [editedMessage, setHtml] as const); @@ -62,10 +64,12 @@ const useEditing = ( // Run 1 frame after editing draft reset fastRaf(() => { setHtml(getTextWithEntitiesAsHtml(draft)); - const messageInput = document.getElementById(EDITABLE_INPUT_ID)!; - requestAnimationFrame(() => { - focusEditableElement(messageInput, true); - }); + const messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR); + if (messageInput) { + requestAnimationFrame(() => { + focusEditableElement(messageInput, true); + }); + } }); }, [draft, setHtml]); diff --git a/src/components/middle/composer/hooks/useEmojiTooltip.ts b/src/components/middle/composer/hooks/useEmojiTooltip.ts index 37b286dc5..990b3d4f8 100644 --- a/src/components/middle/composer/hooks/useEmojiTooltip.ts +++ b/src/components/middle/composer/hooks/useEmojiTooltip.ts @@ -2,7 +2,7 @@ import { useCallback, useEffect, useState, } from '../../../../lib/teact/teact'; -import { EDITABLE_INPUT_ID } from '../../../../config'; +import { EDITABLE_INPUT_CSS_SELECTOR, EDITABLE_INPUT_ID } from '../../../../config'; import { MEMO_EMPTY_ARRAY } from '../../../../util/memo'; import { prepareForRegExp } from '../helpers/prepareForRegExp'; import { @@ -117,7 +117,12 @@ export default function useEmojiTooltip( const atIndex = currentHtml.lastIndexOf(':', isForce ? currentHtml.lastIndexOf(':') - 1 : undefined); if (atIndex !== -1) { onUpdateHtml(`${currentHtml.substr(0, atIndex)}${renderText(textEmoji, ['emoji_html'])}`); - const messageInput = document.getElementById(inputId)!; + let messageInput: HTMLDivElement; + if (inputId === EDITABLE_INPUT_ID) { + messageInput = document.querySelector(EDITABLE_INPUT_CSS_SELECTOR)!; + } else { + messageInput = document.getElementById(inputId) as HTMLDivElement; + } requestAnimationFrame(() => { focusEditableElement(messageInput, true, true); }); diff --git a/src/config.ts b/src/config.ts index 573d733ec..6e2e2bf0f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -84,6 +84,8 @@ export const SEND_MESSAGE_ACTION_INTERVAL = 3000; // 3s export const EDITABLE_INPUT_ID = 'editable-message-text'; export const EDITABLE_INPUT_MODAL_ID = 'editable-message-text-modal'; +// eslint-disable-next-line max-len +export const EDITABLE_INPUT_CSS_SELECTOR = `.Transition__slide--active #${EDITABLE_INPUT_ID}, .Transition > .to #${EDITABLE_INPUT_ID}`; export const CUSTOM_APPENDIX_ATTRIBUTE = 'data-has-custom-appendix';