Update Manager: Various fixes
This commit is contained in:
parent
5c52c1ea5c
commit
38b0336bdb
@ -30,7 +30,12 @@ import {
|
||||
} from '../helpers';
|
||||
import { ChatAbortController } from '../ChatAbortController';
|
||||
import {
|
||||
updateChannelState, getDifference, init as initUpdatesManager, processUpdate, reset as resetUpdatesManager,
|
||||
updateChannelState,
|
||||
getDifference,
|
||||
init as initUpdatesManager,
|
||||
processUpdate,
|
||||
reset as resetUpdatesManager,
|
||||
scheduleGetChannelDifference,
|
||||
} from '../updateManager';
|
||||
|
||||
const DEFAULT_USER_AGENT = 'Unknown UserAgent';
|
||||
@ -482,3 +487,7 @@ export function setAllowHttpTransport(allowHttpTransport: boolean) {
|
||||
export function setShouldDebugExportedSenders(value: boolean) {
|
||||
client.setShouldDebugExportedSenders(value);
|
||||
}
|
||||
|
||||
export function requestChannelDifference(channelId: string) {
|
||||
scheduleGetChannelDifference(channelId);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
export {
|
||||
destroy, disconnect, downloadMedia, fetchCurrentUser, repairFileReference, abortChatRequests, abortRequestGroup,
|
||||
setForceHttpTransport, setShouldDebugExportedSenders, setAllowHttpTransport,
|
||||
setForceHttpTransport, setShouldDebugExportedSenders, setAllowHttpTransport, requestChannelDifference,
|
||||
} from './client';
|
||||
|
||||
export {
|
||||
|
||||
@ -6,7 +6,7 @@ import { UpdateConnectionState, UpdateServerTimeOffset } from '../../lib/gramjs/
|
||||
import { DEBUG } from '../../config';
|
||||
import localDb from './localDb';
|
||||
import SortedQueue from '../../util/SortedQueue';
|
||||
import { dispatchUserAndChatUpdates, requestSync, updater } from './updater';
|
||||
import { dispatchUserAndChatUpdates, sendUpdate, updater } from './updater';
|
||||
import { addEntitiesToLocalDb } from './helpers';
|
||||
import { buildInputEntity } from './gramjsBuilders';
|
||||
import { buildApiPeerId } from './apiBuilders/peers';
|
||||
@ -17,8 +17,8 @@ export type State = {
|
||||
pts: number;
|
||||
qts: number;
|
||||
};
|
||||
type SeqUpdate = GramJs.Updates | GramJs.UpdatesCombined;
|
||||
type PtsUpdate = GramJs.TypeUpdate & { pts: number };
|
||||
type SeqUpdate = (GramJs.Updates | GramJs.UpdatesCombined) & { _isFromDifference?: true };
|
||||
type PtsUpdate = GramJs.TypeUpdate & { pts: number } & { _isFromDifference?: true };
|
||||
|
||||
const COMMON_BOX_QUEUE_ID = '0';
|
||||
const CHANNEL_DIFFERENCE_LIMIT = 1000;
|
||||
@ -49,7 +49,7 @@ export function applyState(state: State) {
|
||||
localDb.commonBoxState.qts = state.qts;
|
||||
}
|
||||
|
||||
export function processUpdate(update: Update) {
|
||||
export function processUpdate(update: Update, isFromDifference?: boolean) {
|
||||
if (update instanceof UpdateConnectionState) {
|
||||
if (update.state === UpdateConnectionState.connected && isInited) {
|
||||
scheduleGetDifference();
|
||||
@ -70,6 +70,11 @@ export function processUpdate(update: Update) {
|
||||
}
|
||||
|
||||
if (update instanceof GramJs.Updates || update instanceof GramJs.UpdatesCombined) {
|
||||
if (isFromDifference) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
(update as SeqUpdate)._isFromDifference = true;
|
||||
}
|
||||
|
||||
saveSeqUpdate(update);
|
||||
return;
|
||||
}
|
||||
@ -79,6 +84,10 @@ export function processUpdate(update: Update) {
|
||||
getChannelDifference(getUpdateChannelId(update));
|
||||
return;
|
||||
}
|
||||
if (isFromDifference) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
(update as PtsUpdate)._isFromDifference = true;
|
||||
}
|
||||
savePtsUpdate(update);
|
||||
return;
|
||||
}
|
||||
@ -165,7 +174,8 @@ function popSeqQueue() {
|
||||
const localSeq = localDb.commonBoxState.seq;
|
||||
const seqStart = 'seqStart' in update ? update.seqStart : update.seq;
|
||||
|
||||
if (seqStart === 0) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
if (seqStart === 0 || (update._isFromDifference && seqStart >= localSeq + 1)) {
|
||||
applyUpdate(update);
|
||||
} else if (seqStart === localSeq + 1) {
|
||||
clearTimeout(seqTimeout);
|
||||
@ -198,7 +208,10 @@ function popPtsQueue(channelId: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pts === localPts + ptsCount) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
if (update._isFromDifference && pts >= localPts + ptsCount) {
|
||||
applyUpdate(update);
|
||||
} else if (pts === localPts + ptsCount) {
|
||||
clearTimeout(PTS_TIMEOUTS.get(channelId));
|
||||
PTS_TIMEOUTS.delete(channelId);
|
||||
|
||||
@ -216,7 +229,7 @@ function popPtsQueue(channelId: string) {
|
||||
popPtsQueue(channelId);
|
||||
}
|
||||
|
||||
function scheduleGetChannelDifference(channelId: string) {
|
||||
export function scheduleGetChannelDifference(channelId: string) {
|
||||
if (PTS_TIMEOUTS.has(channelId)) return;
|
||||
|
||||
const timeout = setTimeout(async () => {
|
||||
@ -258,6 +271,11 @@ export async function getDifference() {
|
||||
return;
|
||||
}
|
||||
|
||||
sendUpdate({
|
||||
'@type': 'updateFetchingDifference',
|
||||
isFetching: true,
|
||||
});
|
||||
|
||||
const response = await invoke(new GramJs.updates.GetDifference({
|
||||
pts: localDb.commonBoxState.pts,
|
||||
date: localDb.commonBoxState.date,
|
||||
@ -275,6 +293,10 @@ export async function getDifference() {
|
||||
if (response instanceof GramJs.updates.DifferenceEmpty) {
|
||||
localDb.commonBoxState.seq = response.seq;
|
||||
localDb.commonBoxState.date = response.date;
|
||||
sendUpdate({
|
||||
'@type': 'updateFetchingDifference',
|
||||
isFetching: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -285,7 +307,13 @@ export async function getDifference() {
|
||||
|
||||
if (response instanceof GramJs.updates.DifferenceSlice) {
|
||||
getDifference();
|
||||
return;
|
||||
}
|
||||
|
||||
sendUpdate({
|
||||
'@type': 'updateFetchingDifference',
|
||||
isFetching: false,
|
||||
});
|
||||
}
|
||||
|
||||
async function getChannelDifference(channelId: string) {
|
||||
@ -336,7 +364,9 @@ async function getChannelDifference(channelId: string) {
|
||||
function forceSync() {
|
||||
reset();
|
||||
|
||||
requestSync();
|
||||
sendUpdate({
|
||||
'@type': 'requestSync',
|
||||
});
|
||||
|
||||
loadRemoteState();
|
||||
}
|
||||
@ -389,7 +419,7 @@ function processDifference(
|
||||
dispatchUserAndChatUpdates(difference.chats);
|
||||
|
||||
difference.otherUpdates.forEach((update) => {
|
||||
processUpdate(update);
|
||||
processUpdate(update, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { GroupCallConnectionData } from '../../lib/secret-sauce';
|
||||
import { Api as GramJs, connection } from '../../lib/gramjs';
|
||||
import type {
|
||||
ApiMessage, ApiMessageExtendedMediaPreview, ApiUpdateConnectionStateType, OnApiUpdate,
|
||||
ApiMessage, ApiMessageExtendedMediaPreview, ApiUpdate, ApiUpdateConnectionStateType, OnApiUpdate,
|
||||
} from '../types';
|
||||
|
||||
import { DEBUG, GENERAL_TOPIC_ID } from '../../config';
|
||||
@ -117,10 +117,8 @@ export function dispatchUserAndChatUpdates(entities: (GramJs.TypeUser | GramJs.T
|
||||
});
|
||||
}
|
||||
|
||||
export function requestSync() {
|
||||
onUpdate({
|
||||
'@type': 'requestSync',
|
||||
});
|
||||
export function sendUpdate(update: ApiUpdate) {
|
||||
onUpdate(update);
|
||||
}
|
||||
|
||||
export function updater(update: Update) {
|
||||
|
||||
@ -615,6 +615,11 @@ export type ApiUpdateMessageTranslations = {
|
||||
toLanguageCode: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateFetchingDifference = {
|
||||
'@type': 'updateFetchingDifference';
|
||||
isFetching: boolean;
|
||||
};
|
||||
|
||||
export type ApiRequestReconnectApi = {
|
||||
'@type': 'requestReconnectApi';
|
||||
};
|
||||
@ -649,7 +654,7 @@ export type ApiUpdate = (
|
||||
ApiUpdatePhoneCallConnectionState | ApiUpdateBotMenuButton | ApiUpdateTranscribedAudio | ApiUpdateUserEmojiStatus |
|
||||
ApiUpdateMessageExtendedMedia | ApiUpdateConfig | ApiUpdateTopicNotifyExceptions | ApiUpdatePinnedTopic |
|
||||
ApiUpdatePinnedTopicsOrder | ApiUpdateTopic | ApiUpdateTopics | ApiUpdateRecentEmojiStatuses |
|
||||
ApiUpdateRecentReactions | ApiRequestReconnectApi | ApiRequestSync
|
||||
ApiUpdateRecentReactions | ApiRequestReconnectApi | ApiRequestSync | ApiUpdateFetchingDifference
|
||||
);
|
||||
|
||||
export type OnApiUpdate = (update: ApiUpdate) => void;
|
||||
|
||||
@ -93,7 +93,7 @@ type StateProps =
|
||||
hasPasscode?: boolean;
|
||||
canSetPasscode?: boolean;
|
||||
}
|
||||
& Pick<GlobalState, 'connectionState' | 'isSyncing' | 'archiveSettings'>
|
||||
& Pick<GlobalState, 'connectionState' | 'isSyncing' | 'isFetchingDifference' | 'archiveSettings'>
|
||||
& Pick<TabState, 'canInstall'>;
|
||||
|
||||
const CLEAR_DATE_SEARCH_PARAM = { date: undefined };
|
||||
@ -121,6 +121,7 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
||||
animationLevel,
|
||||
connectionState,
|
||||
isSyncing,
|
||||
isFetchingDifference,
|
||||
isMessageListOpen,
|
||||
isConnectionStatusMinimized,
|
||||
areChatsLoaded,
|
||||
@ -154,7 +155,12 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
||||
const archivedUnreadChatsCount = useFolderManagerForUnreadCounters()[ARCHIVED_FOLDER_ID]?.chatsCount || 0;
|
||||
|
||||
const { connectionStatus, connectionStatusText, connectionStatusPosition } = useConnectionStatus(
|
||||
lang, connectionState, isSyncing, isMessageListOpen, isConnectionStatusMinimized, !areChatsLoaded,
|
||||
lang,
|
||||
connectionState,
|
||||
isSyncing || isFetchingDifference,
|
||||
isMessageListOpen,
|
||||
isConnectionStatusMinimized,
|
||||
!areChatsLoaded,
|
||||
);
|
||||
|
||||
const handleLockScreenHotkey = useLastCallback((e: KeyboardEvent) => {
|
||||
@ -485,7 +491,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
query: searchQuery, fetchingStatus, chatId, date,
|
||||
} = tabState.globalSearch;
|
||||
const {
|
||||
currentUserId, connectionState, isSyncing, archiveSettings,
|
||||
currentUserId, connectionState, isSyncing, archiveSettings, isFetchingDifference,
|
||||
} = global;
|
||||
const { isConnectionStatusMinimized, animationLevel } = global.settings.byKey;
|
||||
|
||||
@ -499,6 +505,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
animationLevel,
|
||||
connectionState,
|
||||
isSyncing,
|
||||
isFetchingDifference,
|
||||
isMessageListOpen: Boolean(selectCurrentMessageList(global)),
|
||||
isConnectionStatusMinimized,
|
||||
isCurrentUserPremium: selectIsCurrentUserPremium(global),
|
||||
|
||||
@ -105,7 +105,8 @@ type StateProps = {
|
||||
shouldSkipHistoryAnimations?: boolean;
|
||||
currentTransitionKey: number;
|
||||
connectionState?: GlobalState['connectionState'];
|
||||
isSyncing?: GlobalState['isSyncing'];
|
||||
isSyncing?: boolean;
|
||||
isFetchingDifference?: boolean;
|
||||
};
|
||||
|
||||
const MiddleHeader: FC<OwnProps & StateProps> = ({
|
||||
@ -132,6 +133,7 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
||||
currentTransitionKey,
|
||||
connectionState,
|
||||
isSyncing,
|
||||
isFetchingDifference,
|
||||
getCurrentPinnedIndexes,
|
||||
getLoadingPinnedId,
|
||||
onFocusPinnedMessage,
|
||||
@ -319,7 +321,7 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
}, [shouldUseStackedToolsClass, canRevealTools, canToolsCollideWithChatInfo, isRightColumnShown]);
|
||||
|
||||
const { connectionStatusText } = useConnectionStatus(lang, connectionState, isSyncing, true);
|
||||
const { connectionStatusText } = useConnectionStatus(lang, connectionState, isSyncing || isFetchingDifference, true);
|
||||
|
||||
function renderInfo() {
|
||||
if (messageListType === 'thread') {
|
||||
@ -524,6 +526,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
currentTransitionKey: Math.max(0, messageLists.length - 1),
|
||||
connectionState: global.connectionState,
|
||||
isSyncing: global.isSyncing,
|
||||
isFetchingDifference: global.isFetchingDifference,
|
||||
hasButtonInHeader: canStartBot || canRestartBot || canSubscribe || shouldSendJoinRequest,
|
||||
};
|
||||
|
||||
|
||||
@ -179,6 +179,12 @@ addActionHandler('signOut', async (global, actions, payload): Promise<void> => {
|
||||
}
|
||||
});
|
||||
|
||||
addActionHandler('requestChannelDifference', (global, actions, payload): ActionReturnType => {
|
||||
const { chatId } = payload;
|
||||
|
||||
void callApi('requestChannelDifference', chatId);
|
||||
});
|
||||
|
||||
addActionHandler('reset', (global, actions): ActionReturnType => {
|
||||
clearStoredSession();
|
||||
clearEncryptedSession();
|
||||
|
||||
@ -23,6 +23,8 @@ import { clearWebTokenAuth } from '../../../util/routing';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import { setServerTimeOffset } from '../../../util/serverTime';
|
||||
import { isChatChannel, isChatSuperGroup } from '../../helpers';
|
||||
import { unique } from '../../../util/iteratees';
|
||||
|
||||
addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
switch (update['@type']) {
|
||||
@ -59,7 +61,6 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
break;
|
||||
|
||||
case 'requestReconnectApi':
|
||||
global = getGlobal();
|
||||
global = { ...global, isSynced: false };
|
||||
setGlobal(global);
|
||||
|
||||
@ -74,6 +75,11 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
actions.sync();
|
||||
break;
|
||||
|
||||
case 'updateFetchingDifference':
|
||||
global = { ...global, isFetchingDifference: update.isFetching };
|
||||
setGlobal(global);
|
||||
break;
|
||||
|
||||
case 'error': {
|
||||
Object.values(global.byTabId).forEach(({ id: tabId }) => {
|
||||
const paymentShippingError = getShippingError(update.error);
|
||||
@ -216,6 +222,19 @@ function onUpdateConnectionState<T extends GlobalState>(
|
||||
};
|
||||
setGlobal(global);
|
||||
|
||||
const channelStackIds = Object.values(global.byTabId)
|
||||
.flatMap((tab) => tab.messageLists)
|
||||
.map((messageList) => messageList.chatId)
|
||||
.filter((chatId) => {
|
||||
const chat = global.chats.byId[chatId];
|
||||
return isChatChannel(chat) || isChatSuperGroup(chat);
|
||||
});
|
||||
if (connectionState === 'connectionStateReady' && channelStackIds.length) {
|
||||
unique(channelStackIds).forEach((chatId) => {
|
||||
actions.requestChannelDifference({ chatId });
|
||||
});
|
||||
}
|
||||
|
||||
if (connectionState === 'connectionStateBroken') {
|
||||
actions.signOut({ forceInitApi: true });
|
||||
}
|
||||
|
||||
@ -590,6 +590,7 @@ export type GlobalState = {
|
||||
isSyncing?: boolean;
|
||||
isUpdateAvailable?: boolean;
|
||||
isSynced?: boolean;
|
||||
isFetchingDifference?: boolean;
|
||||
leftColumnWidth?: number;
|
||||
lastIsChatInfoShown?: boolean;
|
||||
initialUnreadNotifications?: number;
|
||||
@ -1592,6 +1593,9 @@ export interface ActionPayloads {
|
||||
|
||||
// Initial
|
||||
signOut: { forceInitApi?: boolean } | undefined;
|
||||
requestChannelDifference: {
|
||||
chatId: string;
|
||||
};
|
||||
|
||||
// Misc
|
||||
setInstallPrompt: { canInstall: boolean } & WithTabId;
|
||||
|
||||
@ -18,7 +18,7 @@ type ConnectionStatusPosition =
|
||||
export default function useConnectionStatus(
|
||||
lang: LangFn,
|
||||
connectionState: GlobalState['connectionState'],
|
||||
isSyncing: GlobalState['isSyncing'],
|
||||
isSyncing: boolean | undefined,
|
||||
hasMiddleHeader: boolean,
|
||||
isMinimized?: boolean,
|
||||
isDisabled?: boolean,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user