From 986d4d867d3e4338d3be1c7360ef4a12f37de11e Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 19 Apr 2022 15:11:41 +0200 Subject: [PATCH] TeactN: Fixes for sync global sets and gets --- src/config.ts | 4 +- src/global/actions/api/chats.ts | 2 +- src/global/actions/apiUpdaters/chats.ts | 4 +- src/global/actions/apiUpdaters/messages.ts | 39 ++++++++--------- src/global/actions/ui/chats.ts | 2 - src/lib/teact/teactn.tsx | 50 +++++++++++++++------- 6 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/config.ts b/src/config.ts index 6e2e2bf0f..74c0f0bb9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,9 +1,7 @@ export const APP_NAME = process.env.APP_NAME || 'Telegram WebZ'; export const APP_VERSION = process.env.APP_VERSION!; -export const DEBUG = ( - process.env.APP_ENV !== 'production' && process.env.APP_ENV !== 'perf' && process.env.APP_ENV !== 'test' -); +export const DEBUG = process.env.APP_ENV !== 'production'; export const DEBUG_MORE = false; export const IS_TEST = process.env.APP_ENV === 'test'; diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index 563cde64e..dc1361d88 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -81,7 +81,7 @@ addActionHandler('openChat', (global, actions, payload) => { } // Please telegram send us some updates about linked chat 🙏 - if (chat && chat.lastMessage && chat.lastMessage.threadInfo) { + if (chat?.lastMessage?.threadInfo) { actions.requestThreadInfoUpdate({ chatId: chat.lastMessage.threadInfo.chatId, threadId: chat.lastMessage.threadInfo.threadId, diff --git a/src/global/actions/apiUpdaters/chats.ts b/src/global/actions/apiUpdaters/chats.ts index 634d9fe15..1c8e924c6 100644 --- a/src/global/actions/apiUpdaters/chats.ts +++ b/src/global/actions/apiUpdaters/chats.ts @@ -28,13 +28,13 @@ const CURRENT_CHAT_UNREAD_DELAY = 1500; addActionHandler('apiUpdate', (global, actions, update) => { switch (update['@type']) { case 'updateChat': { + setGlobal(updateChat(global, update.id, update.chat, update.newProfilePhoto)); + if (!update.noTopChatsRequest && !selectIsChatListed(global, update.id)) { // Chat can appear in dialogs list. actions.loadTopChats(); } - setGlobal(updateChat(global, update.id, update.chat, update.newProfilePhoto)); - if (update.chat.id) { closeMessageNotifications({ chatId: update.chat.id, diff --git a/src/global/actions/apiUpdaters/messages.ts b/src/global/actions/apiUpdaters/messages.ts index f8820407c..83ea8c0b9 100644 --- a/src/global/actions/apiUpdaters/messages.ts +++ b/src/global/actions/apiUpdaters/messages.ts @@ -47,7 +47,6 @@ import { import { getMessageContent, isUserId, isMessageLocal, getMessageText, checkIfReactionAdded, } from '../../helpers'; -import { onTickEnd } from '../../../util/schedulers'; const ANIMATION_DELAY = 350; @@ -69,8 +68,6 @@ addActionHandler('apiUpdate', (global, actions, update) => { ); } - setGlobal(global); - const newMessage = selectChatMessage(global, chatId, id)!; if (selectIsMessageInCurrentMessageList(global, chatId, message as ApiMessage)) { @@ -104,9 +101,11 @@ addActionHandler('apiUpdate', (global, actions, update) => { }, ANIMATION_DELAY); } } else { - setGlobal(updateChatLastMessage(getGlobal(), chatId, newMessage)); + global = updateChatLastMessage(global, chatId, newMessage); } + setGlobal(global); + // Edge case: New message in an old (not loaded) chat. if (!selectIsChatListed(global, chatId)) { actions.loadTopChats(); @@ -495,19 +494,19 @@ addActionHandler('apiUpdate', (global, actions, update) => { global = updateChatMessage(global, chatId, id, { reactions: update.reactions }); + setGlobal(global); + if (shouldNotify) { const newMessage = selectChatMessage(global, chatId, id); if (!chat || !newMessage) return; - onTickEnd(() => { - notifyAboutMessage({ - chat, - message: newMessage, - isReaction: true, - }); + + void notifyAboutMessage({ + chat, + message: newMessage, + isReaction: true, }); } - setGlobal(global); break; } } @@ -551,15 +550,13 @@ function updateThreadUnread(global: GlobalState, actions: GlobalActions, message if (originMessage) { global = updateThreadUnreadFromForwardedMessage(global, originMessage, chatId, message.id, isDeleting); } else { - onTickEnd(() => { - actions.loadMessage({ - chatId, - messageId: message.replyToMessageId, - threadUpdate: { - isDeleting, - lastMessageId: message.id, - }, - }); + actions.loadMessage({ + chatId, + messageId: message.replyToMessageId, + threadUpdate: { + isDeleting, + lastMessageId: message.id, + }, }); } } @@ -673,8 +670,6 @@ function deleteMessages(chatId: string | undefined, ids: number[], actions: Glob } }); - setGlobal(global); - actions.requestChatUpdate({ chatId }); const threadIdsToUpdate: number[] = []; diff --git a/src/global/actions/ui/chats.ts b/src/global/actions/ui/chats.ts index 4372cf01b..5d6191194 100644 --- a/src/global/actions/ui/chats.ts +++ b/src/global/actions/ui/chats.ts @@ -42,8 +42,6 @@ addActionHandler('openChat', (global, actions, payload) => { forwardMessages: {}, }), }; - - setGlobal(global); } return updateCurrentMessageList(global, id, threadId, type, shouldReplaceHistory); diff --git a/src/lib/teact/teactn.tsx b/src/lib/teact/teactn.tsx index 5fbd6202f..5c31d70b1 100644 --- a/src/lib/teact/teactn.tsx +++ b/src/lib/teact/teactn.tsx @@ -15,7 +15,7 @@ export default React; type GlobalState = AnyLiteral - & { DEBUG_id: number }; + & { DEBUG_capturedId?: number }; type ActionNames = string; type ActionPayload = any; @@ -38,10 +38,10 @@ type MapStateToProps = ((global: GlobalState, ownProps: Ow let currentGlobal = {} as GlobalState; // eslint-disable-next-line @typescript-eslint/naming-convention -let DEBUG_currentGlobalId: number | undefined; +let DEBUG_currentCapturedId: number | undefined; // eslint-disable-next-line @typescript-eslint/naming-convention -const DEBUG_resetIdThrottled = throttleWithTickEnd(() => { - DEBUG_currentGlobalId = Math.random(); +const DEBUG_releaseCapturedIdThrottled = throttleWithTickEnd(() => { + DEBUG_currentCapturedId = undefined; }); const actionHandlers: Record = {}; @@ -71,9 +71,11 @@ function runCallbacks(forceOnHeavyAnimation = false) { export function setGlobal(newGlobal?: GlobalState, options?: ActionOptions) { if (typeof newGlobal === 'object' && newGlobal !== currentGlobal) { if (DEBUG) { - if (newGlobal.DEBUG_id && newGlobal.DEBUG_id !== DEBUG_currentGlobalId) { + if (newGlobal.DEBUG_capturedId && newGlobal.DEBUG_capturedId !== DEBUG_currentCapturedId) { throw new Error('[TeactN.setGlobal] Attempt to set an outdated global'); } + + DEBUG_currentCapturedId = undefined; } currentGlobal = newGlobal; @@ -87,9 +89,12 @@ export function setGlobal(newGlobal?: GlobalState, options?: ActionOptions) { export function getGlobal() { if (DEBUG) { - DEBUG_currentGlobalId = Math.random(); - currentGlobal.DEBUG_id = DEBUG_currentGlobalId; - DEBUG_resetIdThrottled(); + DEBUG_currentCapturedId = Math.random(); + currentGlobal = { + ...currentGlobal, + DEBUG_capturedId: DEBUG_currentCapturedId, + }; + DEBUG_releaseCapturedIdThrottled(); } return currentGlobal; @@ -99,15 +104,30 @@ export function getActions() { return actions; } -function handleAction(name: string, payload?: ActionPayload, options?: ActionOptions) { - actionHandlers[name]?.forEach((handler) => { - const response = handler(DEBUG ? getGlobal() : currentGlobal, actions, payload); - if (!response || typeof response.then === 'function') { - return; - } +let actionQueue: NoneToVoidFunction[] = []; - setGlobal(response as GlobalState, options); +function handleAction(name: string, payload?: ActionPayload, options?: ActionOptions) { + actionQueue.push(() => { + actionHandlers[name]?.forEach((handler) => { + const response = handler(DEBUG ? getGlobal() : currentGlobal, actions, payload); + if (!response || typeof response.then === 'function') { + return; + } + + setGlobal(response as GlobalState, options); + }); }); + + if (actionQueue.length === 1) { + try { + while (actionQueue.length) { + actionQueue[0](); + actionQueue.shift(); + } + } finally { + actionQueue = []; + } + } } function updateContainers() {