From b421ac25d235069cfeab1fa683e04c885f0a93a2 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 8 Sep 2023 18:39:09 +0200 Subject: [PATCH] Chat: Fix unread counter after sleep (#3799) --- src/api/gramjs/updateManager.ts | 43 ++++++++++++++++++++++----------- src/global/actions/api/sync.ts | 1 + 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/api/gramjs/updateManager.ts b/src/api/gramjs/updateManager.ts index 8dcc598ad..608836560 100644 --- a/src/api/gramjs/updateManager.ts +++ b/src/api/gramjs/updateManager.ts @@ -49,7 +49,7 @@ export function applyState(state: State) { localDb.commonBoxState.qts = state.qts; } -export function processUpdate(update: Update, isFromDifference?: boolean) { +export function processUpdate(update: Update, isFromDifference?: boolean, shouldOnlySave?: boolean) { if (update instanceof UpdateConnectionState) { if (update.state === UpdateConnectionState.connected && isInited) { scheduleGetDifference(); @@ -75,7 +75,7 @@ export function processUpdate(update: Update, isFromDifference?: boolean) { (update as SeqUpdate)._isFromDifference = true; } - saveSeqUpdate(update); + saveSeqUpdate(update, shouldOnlySave); return; } @@ -88,7 +88,7 @@ export function processUpdate(update: Update, isFromDifference?: boolean) { // eslint-disable-next-line no-underscore-dangle (update as PtsUpdate)._isFromDifference = true; } - savePtsUpdate(update); + savePtsUpdate(update, shouldOnlySave); return; } @@ -150,13 +150,13 @@ function applyUpdate(updateObject: SeqUpdate | PtsUpdate) { } } -function saveSeqUpdate(update: GramJs.Updates | GramJs.UpdatesCombined) { +function saveSeqUpdate(update: GramJs.Updates | GramJs.UpdatesCombined, shouldOnlySave?: boolean) { SEQ_QUEUE.add(update); - popSeqQueue(); + if (!shouldOnlySave) popSeqQueue(); } -function savePtsUpdate(update: PtsUpdate) { +function savePtsUpdate(update: PtsUpdate, shouldOnlySave?: boolean) { const channelId = getUpdateChannelId(update); const ptsQueue = PTS_QUEUE.get(channelId) || new SortedQueue(ptsComparator); @@ -164,7 +164,7 @@ function savePtsUpdate(update: PtsUpdate) { PTS_QUEUE.set(channelId, ptsQueue); - popPtsQueue(channelId); + if (!shouldOnlySave) popPtsQueue(channelId); } function popSeqQueue() { @@ -282,9 +282,6 @@ export async function getDifference() { qts: localDb.commonBoxState.qts, })); - SEQ_QUEUE.clear(); - PTS_QUEUE.get(COMMON_BOX_QUEUE_ID)?.clear(); - if (!response || response instanceof GramJs.updates.DifferenceTooLong) { forceSync(); return; @@ -333,8 +330,6 @@ async function getChannelDifference(channelId: string) { limit: CHANNEL_DIFFERENCE_LIMIT, })); - PTS_QUEUE.delete(channelId); - if (!response) { if (DEBUG) { // eslint-disable-next-line no-console @@ -351,10 +346,11 @@ async function getChannelDifference(channelId: string) { localDb.channelPtsById[channelId] = response.pts; if (response instanceof GramJs.updates.ChannelDifferenceEmpty) { + popPtsQueue(channelId); // Continue processing updates in queue return; } - processDifference(response); + processDifference(response, channelId); if (!response.final) { getChannelDifference(channelId); @@ -403,6 +399,7 @@ async function loadRemoteState() { function processDifference( difference: GramJs.updates.Difference | GramJs.updates.DifferenceSlice | GramJs.updates.ChannelDifference, + channelId?: string, ) { difference.newMessages.forEach((message) => { updater(new GramJs.UpdateNewMessage({ @@ -418,9 +415,27 @@ function processDifference( dispatchUserAndChatUpdates(difference.users); dispatchUserAndChatUpdates(difference.chats); + // Ignore `pts`/`seq` holes when applying updates from difference + // BUT, if we got an `UpdateChannelTooLong`, make sure to process other updates after receiving `ChannelDifference` + const channelTooLongIds = new Set(); + difference.otherUpdates.forEach((update) => { - processUpdate(update, true); + const updateChannelId = getUpdateChannelId(update); + + if (update instanceof GramJs.UpdateChannelTooLong) { + channelTooLongIds.add(getUpdateChannelId(update)); + } + + const shouldApplyImmediately = !channelTooLongIds.has(updateChannelId); + processUpdate(update, shouldApplyImmediately, !shouldApplyImmediately); }); + + // Continue processing updates in queues + if (channelId) { + popPtsQueue(channelId); + } else { + popSeqQueue(); + } } function getPtsCount(update: PtsUpdate) { diff --git a/src/global/actions/api/sync.ts b/src/global/actions/api/sync.ts index 8ebf078a4..43da30f20 100644 --- a/src/global/actions/api/sync.ts +++ b/src/global/actions/api/sync.ts @@ -74,6 +74,7 @@ addActionHandler('sync', (global, actions): ActionReturnType => { ...global, isSyncing: false, isSynced: true, + isFetchingDifference: false, }; setGlobal(global);