TeactN: Fixes for sync global sets and gets

This commit is contained in:
Alexander Zinchuk 2022-04-19 15:11:41 +02:00
parent 747974b24a
commit 986d4d867d
6 changed files with 56 additions and 45 deletions

View File

@ -1,9 +1,7 @@
export const APP_NAME = process.env.APP_NAME || 'Telegram WebZ'; export const APP_NAME = process.env.APP_NAME || 'Telegram WebZ';
export const APP_VERSION = process.env.APP_VERSION!; export const APP_VERSION = process.env.APP_VERSION!;
export const DEBUG = ( export const DEBUG = process.env.APP_ENV !== 'production';
process.env.APP_ENV !== 'production' && process.env.APP_ENV !== 'perf' && process.env.APP_ENV !== 'test'
);
export const DEBUG_MORE = false; export const DEBUG_MORE = false;
export const IS_TEST = process.env.APP_ENV === 'test'; export const IS_TEST = process.env.APP_ENV === 'test';

View File

@ -81,7 +81,7 @@ addActionHandler('openChat', (global, actions, payload) => {
} }
// Please telegram send us some updates about linked chat 🙏 // Please telegram send us some updates about linked chat 🙏
if (chat && chat.lastMessage && chat.lastMessage.threadInfo) { if (chat?.lastMessage?.threadInfo) {
actions.requestThreadInfoUpdate({ actions.requestThreadInfoUpdate({
chatId: chat.lastMessage.threadInfo.chatId, chatId: chat.lastMessage.threadInfo.chatId,
threadId: chat.lastMessage.threadInfo.threadId, threadId: chat.lastMessage.threadInfo.threadId,

View File

@ -28,13 +28,13 @@ const CURRENT_CHAT_UNREAD_DELAY = 1500;
addActionHandler('apiUpdate', (global, actions, update) => { addActionHandler('apiUpdate', (global, actions, update) => {
switch (update['@type']) { switch (update['@type']) {
case 'updateChat': { case 'updateChat': {
setGlobal(updateChat(global, update.id, update.chat, update.newProfilePhoto));
if (!update.noTopChatsRequest && !selectIsChatListed(global, update.id)) { if (!update.noTopChatsRequest && !selectIsChatListed(global, update.id)) {
// Chat can appear in dialogs list. // Chat can appear in dialogs list.
actions.loadTopChats(); actions.loadTopChats();
} }
setGlobal(updateChat(global, update.id, update.chat, update.newProfilePhoto));
if (update.chat.id) { if (update.chat.id) {
closeMessageNotifications({ closeMessageNotifications({
chatId: update.chat.id, chatId: update.chat.id,

View File

@ -47,7 +47,6 @@ import {
import { import {
getMessageContent, isUserId, isMessageLocal, getMessageText, checkIfReactionAdded, getMessageContent, isUserId, isMessageLocal, getMessageText, checkIfReactionAdded,
} from '../../helpers'; } from '../../helpers';
import { onTickEnd } from '../../../util/schedulers';
const ANIMATION_DELAY = 350; const ANIMATION_DELAY = 350;
@ -69,8 +68,6 @@ addActionHandler('apiUpdate', (global, actions, update) => {
); );
} }
setGlobal(global);
const newMessage = selectChatMessage(global, chatId, id)!; const newMessage = selectChatMessage(global, chatId, id)!;
if (selectIsMessageInCurrentMessageList(global, chatId, message as ApiMessage)) { if (selectIsMessageInCurrentMessageList(global, chatId, message as ApiMessage)) {
@ -104,9 +101,11 @@ addActionHandler('apiUpdate', (global, actions, update) => {
}, ANIMATION_DELAY); }, ANIMATION_DELAY);
} }
} else { } else {
setGlobal(updateChatLastMessage(getGlobal(), chatId, newMessage)); global = updateChatLastMessage(global, chatId, newMessage);
} }
setGlobal(global);
// Edge case: New message in an old (not loaded) chat. // Edge case: New message in an old (not loaded) chat.
if (!selectIsChatListed(global, chatId)) { if (!selectIsChatListed(global, chatId)) {
actions.loadTopChats(); actions.loadTopChats();
@ -495,19 +494,19 @@ addActionHandler('apiUpdate', (global, actions, update) => {
global = updateChatMessage(global, chatId, id, { reactions: update.reactions }); global = updateChatMessage(global, chatId, id, { reactions: update.reactions });
setGlobal(global);
if (shouldNotify) { if (shouldNotify) {
const newMessage = selectChatMessage(global, chatId, id); const newMessage = selectChatMessage(global, chatId, id);
if (!chat || !newMessage) return; if (!chat || !newMessage) return;
onTickEnd(() => {
notifyAboutMessage({ void notifyAboutMessage({
chat, chat,
message: newMessage, message: newMessage,
isReaction: true, isReaction: true,
});
}); });
} }
setGlobal(global);
break; break;
} }
} }
@ -551,15 +550,13 @@ function updateThreadUnread(global: GlobalState, actions: GlobalActions, message
if (originMessage) { if (originMessage) {
global = updateThreadUnreadFromForwardedMessage(global, originMessage, chatId, message.id, isDeleting); global = updateThreadUnreadFromForwardedMessage(global, originMessage, chatId, message.id, isDeleting);
} else { } else {
onTickEnd(() => { actions.loadMessage({
actions.loadMessage({ chatId,
chatId, messageId: message.replyToMessageId,
messageId: message.replyToMessageId, threadUpdate: {
threadUpdate: { isDeleting,
isDeleting, lastMessageId: message.id,
lastMessageId: message.id, },
},
});
}); });
} }
} }
@ -673,8 +670,6 @@ function deleteMessages(chatId: string | undefined, ids: number[], actions: Glob
} }
}); });
setGlobal(global);
actions.requestChatUpdate({ chatId }); actions.requestChatUpdate({ chatId });
const threadIdsToUpdate: number[] = []; const threadIdsToUpdate: number[] = [];

View File

@ -42,8 +42,6 @@ addActionHandler('openChat', (global, actions, payload) => {
forwardMessages: {}, forwardMessages: {},
}), }),
}; };
setGlobal(global);
} }
return updateCurrentMessageList(global, id, threadId, type, shouldReplaceHistory); return updateCurrentMessageList(global, id, threadId, type, shouldReplaceHistory);

View File

@ -15,7 +15,7 @@ export default React;
type GlobalState = type GlobalState =
AnyLiteral AnyLiteral
& { DEBUG_id: number }; & { DEBUG_capturedId?: number };
type ActionNames = string; type ActionNames = string;
type ActionPayload = any; type ActionPayload = any;
@ -38,10 +38,10 @@ type MapStateToProps<OwnProps = undefined> = ((global: GlobalState, ownProps: Ow
let currentGlobal = {} as GlobalState; let currentGlobal = {} as GlobalState;
// eslint-disable-next-line @typescript-eslint/naming-convention // 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 // eslint-disable-next-line @typescript-eslint/naming-convention
const DEBUG_resetIdThrottled = throttleWithTickEnd(() => { const DEBUG_releaseCapturedIdThrottled = throttleWithTickEnd(() => {
DEBUG_currentGlobalId = Math.random(); DEBUG_currentCapturedId = undefined;
}); });
const actionHandlers: Record<string, ActionHandler[]> = {}; const actionHandlers: Record<string, ActionHandler[]> = {};
@ -71,9 +71,11 @@ function runCallbacks(forceOnHeavyAnimation = false) {
export function setGlobal(newGlobal?: GlobalState, options?: ActionOptions) { export function setGlobal(newGlobal?: GlobalState, options?: ActionOptions) {
if (typeof newGlobal === 'object' && newGlobal !== currentGlobal) { if (typeof newGlobal === 'object' && newGlobal !== currentGlobal) {
if (DEBUG) { 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'); throw new Error('[TeactN.setGlobal] Attempt to set an outdated global');
} }
DEBUG_currentCapturedId = undefined;
} }
currentGlobal = newGlobal; currentGlobal = newGlobal;
@ -87,9 +89,12 @@ export function setGlobal(newGlobal?: GlobalState, options?: ActionOptions) {
export function getGlobal() { export function getGlobal() {
if (DEBUG) { if (DEBUG) {
DEBUG_currentGlobalId = Math.random(); DEBUG_currentCapturedId = Math.random();
currentGlobal.DEBUG_id = DEBUG_currentGlobalId; currentGlobal = {
DEBUG_resetIdThrottled(); ...currentGlobal,
DEBUG_capturedId: DEBUG_currentCapturedId,
};
DEBUG_releaseCapturedIdThrottled();
} }
return currentGlobal; return currentGlobal;
@ -99,15 +104,30 @@ export function getActions() {
return actions; return actions;
} }
function handleAction(name: string, payload?: ActionPayload, options?: ActionOptions) { let actionQueue: NoneToVoidFunction[] = [];
actionHandlers[name]?.forEach((handler) => {
const response = handler(DEBUG ? getGlobal() : currentGlobal, actions, payload);
if (!response || typeof response.then === 'function') {
return;
}
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() { function updateContainers() {