From ff5c480ef8627974e878499181361c181abea7f5 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Wed, 14 Sep 2022 00:30:11 +0200 Subject: [PATCH] Composer: Fix error when opening chat with read-only restriction (#2025) --- src/api/gramjs/methods/messages.ts | 2 +- src/components/main/GameModal.tsx | 31 +++++++++++++++---- src/components/middle/composer/Composer.tsx | 5 +++ .../middle/composer/MessageInput.tsx | 5 --- .../middle/composer/StickerPicker.tsx | 17 +++++----- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/api/gramjs/methods/messages.ts b/src/api/gramjs/methods/messages.ts index 4ba7759d..4f8be32d 100644 --- a/src/api/gramjs/methods/messages.ts +++ b/src/api/gramjs/methods/messages.ts @@ -1058,7 +1058,7 @@ export async function sendPollVote({ export async function closePoll({ chat, messageId, poll, -} : { +}: { chat: ApiChat; messageId: number; poll: ApiPoll; diff --git a/src/components/main/GameModal.tsx b/src/components/main/GameModal.tsx index 4d1995d5..bb45ebe5 100644 --- a/src/components/main/GameModal.tsx +++ b/src/components/main/GameModal.tsx @@ -1,8 +1,13 @@ -import type { FC } from '../../lib/teact/teact'; import React, { memo, useCallback, useEffect } from '../../lib/teact/teact'; import { getActions } from '../../lib/teact/teactn'; -import type { GlobalState } from '../../global/types'; +import type { FC } from '../../lib/teact/teact'; +import type { GlobalState } from '../../global/types'; +import { MAIN_THREAD_ID } from '../../api/types'; + +import { withGlobal } from '../../global'; +import { selectChat } from '../../global/selectors'; +import { getCanPostInChat } from '../../global/helpers'; import windowSize from '../../util/windowSize'; import useLang from '../../hooks/useLang'; @@ -22,7 +27,11 @@ type OwnProps = { gameTitle?: string; }; -const GameModal: FC = ({ openedGame, gameTitle }) => { +type StateProps = { + canPost?: boolean; +}; + +const GameModal: FC = ({ openedGame, gameTitle, canPost }) => { const { closeGame, showNotification, openForwardMenu } = getActions(); const lang = useLang(); const { url, chatId, messageId } = openedGame || {}; @@ -31,7 +40,7 @@ const GameModal: FC = ({ openedGame, gameTitle }) => { const sendMessageAction = useSendMessageAction(chatId); useInterval(() => { sendMessageAction({ type: 'playingGame' }); - }, isOpen ? PLAY_GAME_ACTION_INTERVAL : undefined); + }, isOpen && canPost ? PLAY_GAME_ACTION_INTERVAL : undefined); const handleMessage = useCallback((event: MessageEvent) => { try { @@ -45,7 +54,7 @@ const GameModal: FC = ({ openedGame, gameTitle }) => { showNotification({ message: 'Unsupported game action' }); } } catch (e) { - // Ignore messages from other origins + // Ignore other messages } }, [chatId, closeGame, messageId, openForwardMenu, showNotification]); @@ -91,4 +100,14 @@ const GameModal: FC = ({ openedGame, gameTitle }) => { ); }; -export default memo(GameModal); +export default memo(withGlobal( + (global, { openedGame }): StateProps => { + const { chatId } = openedGame || {}; + const chat = chatId && selectChat(global, chatId); + const canPost = Boolean(chat) && getCanPostInChat(chat, MAIN_THREAD_ID); + + return { + canPost, + }; + }, +)(GameModal)); diff --git a/src/components/middle/composer/Composer.tsx b/src/components/middle/composer/Composer.tsx index 6933f483..4753c096 100644 --- a/src/components/middle/composer/Composer.tsx +++ b/src/components/middle/composer/Composer.tsx @@ -370,6 +370,11 @@ const Composer: FC = ({ } }, [activeVoiceRecording, sendMessageAction]); + useEffect(() => { + if (!html || editingMessage) return; + sendMessageAction({ type: 'typing' }); + }, [editingMessage, html, sendMessageAction]); + const mainButtonState = editingMessage ? MainButtonState.Edit : (!IS_VOICE_RECORDING_SUPPORTED || activeVoiceRecording || (html && !attachments.length) || isForwarding) ? (shouldSchedule ? MainButtonState.Schedule : MainButtonState.Send) diff --git a/src/components/middle/composer/MessageInput.tsx b/src/components/middle/composer/MessageInput.tsx index 1c391c86..8e62022b 100644 --- a/src/components/middle/composer/MessageInput.tsx +++ b/src/components/middle/composer/MessageInput.tsx @@ -19,7 +19,6 @@ import captureKeyboardListeners from '../../../util/captureKeyboardListeners'; import useLayoutEffectWithPrevDeps from '../../../hooks/useLayoutEffectWithPrevDeps'; import useFlag from '../../../hooks/useFlag'; import { isHeavyAnimating } from '../../../hooks/useHeavyAnimationCheck'; -import useSendMessageAction from '../../../hooks/useSendMessageAction'; import useLang from '../../../hooks/useLang'; import parseEmojiOnlyString from '../../common/helpers/parseEmojiOnlyString'; import { isSelectionInsideInput } from './helpers/selection'; @@ -80,7 +79,6 @@ function clearSelection() { const MessageInput: FC = ({ id, chatId, - threadId, captionLimit, isAttachmentModalInput, editableInputId, @@ -115,8 +113,6 @@ const MessageInput: FC = ({ const [textFormatterAnchorPosition, setTextFormatterAnchorPosition] = useState(); const [selectedRange, setSelectedRange] = useState(); - const sendMessageAction = useSendMessageAction(chatId, threadId); - useEffect(() => { if (!isAttachmentModalInput) return; updateInputHeight(false); @@ -286,7 +282,6 @@ const MessageInput: FC = ({ const { innerHTML, textContent } = e.currentTarget; onUpdate(innerHTML === SAFARI_BR ? '' : innerHTML); - sendMessageAction({ type: 'typing' }); // Reset focus on the input to remove any active styling when input is cleared if ( diff --git a/src/components/middle/composer/StickerPicker.tsx b/src/components/middle/composer/StickerPicker.tsx index 5486e0ba..44c01b6e 100644 --- a/src/components/middle/composer/StickerPicker.tsx +++ b/src/components/middle/composer/StickerPicker.tsx @@ -1,4 +1,3 @@ -import type { FC } from '../../../lib/teact/teact'; import React, { useState, useEffect, memo, useRef, useMemo, useCallback, } from '../../../lib/teact/teact'; @@ -6,6 +5,7 @@ import { getActions, withGlobal } from '../../../global'; import type { ApiStickerSet, ApiSticker, ApiChat } from '../../../api/types'; import type { StickerSetOrRecent } from '../../../types'; +import type { FC } from '../../../lib/teact/teact'; import { CHAT_STICKER_SET_ID, @@ -80,8 +80,8 @@ const StickerPicker: FC = ({ stickerSetsById, shouldPlay, isSavedMessages, - onStickerSelect, isCurrentUserPremium, + onStickerSelect, }) => { const { loadRecentStickers, @@ -200,11 +200,11 @@ const StickerPicker: FC = ({ ), [allSets, areAddedLoaded]); useEffect(() => { - if (loadAndPlay) { - loadRecentStickers(); - sendMessageAction({ type: 'chooseSticker' }); - } - }, [loadAndPlay, loadRecentStickers, sendMessageAction]); + if (!loadAndPlay) return; + loadRecentStickers(); + if (!canSendStickers) return; + sendMessageAction({ type: 'chooseSticker' }); + }, [canSendStickers, loadAndPlay, loadRecentStickers, sendMessageAction]); useHorizontalScroll(headerRef.current); @@ -244,8 +244,9 @@ const StickerPicker: FC = ({ }, [faveSticker]); const handleMouseMove = useCallback(() => { + if (!canSendStickers) return; sendMessageAction({ type: 'chooseSticker' }); - }, [sendMessageAction]); + }, [canSendStickers, sendMessageAction]); const handleRemoveRecentSticker = useCallback((sticker: ApiSticker) => { removeRecentSticker({ sticker });