From c1eafdd9d5dbf19f0ad1b78ae3338e76799cb95a Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 10 Mar 2023 02:34:05 +0100 Subject: [PATCH] Group Management: Flood api error handling (#2769) --- src/api/gramjs/methods/chats.ts | 2 +- .../right/management/ManageGroup.tsx | 33 ++++++++++++++----- src/global/actions/api/chats.ts | 11 ++++++- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/api/gramjs/methods/chats.ts b/src/api/gramjs/methods/chats.ts index 77ec379b9..e47fe75e3 100644 --- a/src/api/gramjs/methods/chats.ts +++ b/src/api/gramjs/methods/chats.ts @@ -1373,7 +1373,7 @@ export function toggleForum({ return invokeRequest(new GramJs.channels.ToggleForum({ channel: buildInputPeer(id, accessHash), enabled: isEnabled, - }), true); + }), true, true); } export async function createTopic({ diff --git a/src/components/right/management/ManageGroup.tsx b/src/components/right/management/ManageGroup.tsx index aee72c86f..bb26ffcea 100644 --- a/src/components/right/management/ManageGroup.tsx +++ b/src/components/right/management/ManageGroup.tsx @@ -17,12 +17,13 @@ import { isChatBasicGroup, isChatPublic, } from '../../../global/helpers'; -import useMedia from '../../../hooks/useMedia'; -import useLang from '../../../hooks/useLang'; -import useFlag from '../../../hooks/useFlag'; +import { debounce } from '../../../util/schedulers'; import { selectChat, selectTabState } from '../../../global/selectors'; import { formatInteger } from '../../../util/textFormat'; import renderText from '../../common/helpers/renderText'; +import useMedia from '../../../hooks/useMedia'; +import useLang from '../../../hooks/useLang'; +import useFlag from '../../../hooks/useFlag'; import useHistoryBack from '../../../hooks/useHistoryBack'; import AvatarEditable from '../../ui/AvatarEditable'; @@ -81,6 +82,8 @@ const ALL_PERMISSIONS: Array = [ // so we need to define the amount manually const TOTAL_PERMISSIONS_COUNT = ALL_PERMISSIONS.length + 1; +const runDebounced = debounce((cb) => cb(), 500, false); + const ManageGroup: FC = ({ chatId, chat, @@ -121,6 +124,7 @@ const ManageGroup: FC = ({ const [about, setAbout] = useState(currentAbout); const [photo, setPhoto] = useState(); const [error, setError] = useState(); + const [isForumEnabled, setIsForumEnabled] = useState(chat.isForum); const imageHash = getChatAvatarHash(chat); const currentAvatarBlobUrl = useMedia(imageHash, false, ApiMediaFormat.BlobUrl); const isPublicGroup = useMemo(() => hasLinkedChannel || isChatPublic(chat), [chat, hasLinkedChannel]); @@ -141,6 +145,11 @@ const ManageGroup: FC = ({ } }, [chatId, loadExportedChatInvites, lastSyncTime, canInvite, loadChatJoinRequests]); + // Resetting `isForum` switch on flood wait error + useEffect(() => { + setIsForumEnabled(Boolean(chat.isForum)); + }, [chat.isForum]); + useEffect(() => { if (progress === ManagementProgress.Complete) { setIsProfileFieldsTouched(false); @@ -223,8 +232,16 @@ const ManageGroup: FC = ({ }, [chat, togglePreHistoryHidden]); const handleForumToggle = useCallback(() => { - toggleForum({ chatId, isEnabled: !chat.isForum }); - }, [chat.isForum, chatId, toggleForum]); + setIsForumEnabled((current) => { + const newIsForumEnabled = !current; + + runDebounced(() => { + toggleForum({ chatId, isEnabled: newIsForumEnabled }); + }); + + return newIsForumEnabled; + }); + }, [chatId, toggleForum]); useEffect(() => { if (!isChannelsPremiumLimitReached) { @@ -304,7 +321,7 @@ const ManageGroup: FC = ({
= ({ > {lang('ChannelPermissions')} - {enabledPermissionsCount}/{TOTAL_PERMISSIONS_COUNT - (chat.isForum ? 0 : 1)} + {enabledPermissionsCount}/{TOTAL_PERMISSIONS_COUNT - (isForumEnabled ? 0 : 1)} = ({ diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index e6fc7b930..0e3798cff 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -1676,7 +1676,16 @@ addActionHandler('toggleForum', async (global, actions, payload): Promise global = updateChat(global, chatId, { isForum: isEnabled }); setGlobal(global); - const result = await callApi('toggleForum', { chat, isEnabled }); + let result: true | undefined; + try { + result = await callApi('toggleForum', { chat, isEnabled }); + } catch (error) { + if ((error as ApiError).message.startsWith('A wait of')) { + actions.showNotification({ message: langProvider.translate('FloodWait'), tabId }); + } else { + actions.showDialog({ data: { ...(error as ApiError), hasErrorKey: true }, tabId }); + } + } if (!result) { global = getGlobal();