[Perf] Simplify usage of serverTimeOffset

This commit is contained in:
Alexander Zinchuk 2023-01-22 18:12:27 +01:00
parent 2d23ec775e
commit 9080082823
39 changed files with 115 additions and 218 deletions

View File

@ -20,7 +20,7 @@ import {
buildApiPeerId, getApiChatIdFromMtpPeer, isPeerChat, isPeerUser,
} from './peers';
import { omitVirtualClassFields } from './helpers';
import { getServerTime } from '../../../util/serverTime';
import { getServerTime, getServerTimeOffset } from '../../../util/serverTime';
import { buildApiReaction } from './messages';
import { buildApiUsernames } from './common';
@ -79,14 +79,13 @@ function buildApiChatFieldsFromPeerEntity(
export function buildApiChatFromDialog(
dialog: GramJs.Dialog,
peerEntity: GramJs.TypeUser | GramJs.TypeChat,
serverTimeOffset: number,
): ApiChat {
const {
peer, folderId, unreadMark, unreadCount, unreadMentionsCount, unreadReactionsCount,
notifySettings: { silent, muteUntil },
readOutboxMaxId, readInboxMaxId, draft,
} = dialog;
const isMuted = silent || (typeof muteUntil === 'number' && getServerTime(serverTimeOffset) < muteUntil);
const isMuted = silent || (typeof muteUntil === 'number' && getServerTime() < muteUntil);
return {
id: getApiChatIdFromMtpPeer(peer),
@ -316,7 +315,6 @@ export function buildChatMembers(
export function buildChatTypingStatus(
update: GramJs.UpdateUserTyping | GramJs.UpdateChatUserTyping | GramJs.UpdateChannelUserTyping,
serverTimeOffset: number,
) {
let action: string = '';
let emoticon: string | undefined;
@ -361,7 +359,7 @@ export function buildChatTypingStatus(
action,
...(emoticon && { emoji: emoticon }),
...(!(update instanceof GramJs.UpdateUserTyping) && { userId: getApiChatIdFromMtpPeer(update.fromId) }),
timestamp: Date.now() + serverTimeOffset * 1000,
timestamp: Date.now() + getServerTimeOffset() * 1000,
};
}

View File

@ -60,6 +60,7 @@ import { addPhotoToLocalDb, resolveMessageApiChatId, serializeBytes } from '../h
import { buildApiPeerId, getApiChatIdFromMtpPeer, isPeerUser } from './peers';
import { buildApiCallDiscardReason } from './calls';
import { getEmojiOnlyCountForMessage } from '../../../global/helpers/getEmojiOnlyCountForMessage';
import { getServerTimeOffset } from '../../../util/serverTime';
const LOCAL_MEDIA_UPLOADING_TEMP_ID = 'temp';
const INPUT_WAVEFORM_LENGTH = 63;
@ -1263,7 +1264,6 @@ export function buildLocalMessage(
groupedId?: string,
scheduledAt?: number,
sendAs?: ApiChat | ApiUser,
serverTimeOffset = 0,
): ApiMessage {
const localId = getNextLocalMessageId();
const media = attachment && buildUploadingMedia(attachment);
@ -1286,7 +1286,7 @@ export function buildLocalMessage(
...(poll && buildNewPoll(poll, localId)),
...(contact && { contact }),
},
date: scheduledAt || Math.round(Date.now() / 1000) + serverTimeOffset,
date: scheduledAt || Math.round(Date.now() / 1000) + getServerTimeOffset(),
isOutgoing: !isChannel,
senderId: sendAs?.id || currentUserId,
...(replyingTo && { replyToMessageId: replyingTo }),
@ -1312,7 +1312,6 @@ export function buildLocalForwardedMessage({
toChat,
toThreadId,
message,
serverTimeOffset,
scheduledAt,
noAuthors,
noCaptions,
@ -1321,7 +1320,6 @@ export function buildLocalForwardedMessage({
toChat: ApiChat;
toThreadId?: number;
message: ApiMessage;
serverTimeOffset: number;
scheduledAt?: number;
noAuthors?: boolean;
noCaptions?: boolean;
@ -1358,7 +1356,7 @@ export function buildLocalForwardedMessage({
id: localId,
chatId: toChat.id,
content: updatedContent,
date: scheduledAt || Math.round(Date.now() / 1000) + serverTimeOffset,
date: scheduledAt || Math.round(Date.now() / 1000) + getServerTimeOffset(),
isOutgoing: !asIncomingInChatWithSelf && toChat.type !== 'chatTypeChannel',
senderId: currentUserId,
sendingState: 'messageSendingStatePending',

View File

@ -123,7 +123,7 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
}
export function buildApiNotifyException(
notifySettings: GramJs.TypePeerNotifySettings, peer: GramJs.TypePeer, serverTimeOffset: number,
notifySettings: GramJs.TypePeerNotifySettings, peer: GramJs.TypePeer,
) {
const {
silent, muteUntil, showPreviews, otherSound,
@ -133,14 +133,14 @@ export function buildApiNotifyException(
return {
chatId: getApiChatIdFromMtpPeer(peer),
isMuted: silent || (typeof muteUntil === 'number' && getServerTime(serverTimeOffset) < muteUntil),
isMuted: silent || (typeof muteUntil === 'number' && getServerTime() < muteUntil),
...(!hasSound && { isSilent: true }),
...(showPreviews !== undefined && { shouldShowPreviews: Boolean(showPreviews) }),
};
}
export function buildApiNotifyExceptionTopic(
notifySettings: GramJs.TypePeerNotifySettings, peer: GramJs.TypePeer, topicId: number, serverTimeOffset: number,
notifySettings: GramJs.TypePeerNotifySettings, peer: GramJs.TypePeer, topicId: number,
) {
const {
silent, muteUntil, showPreviews, otherSound,
@ -151,7 +151,7 @@ export function buildApiNotifyExceptionTopic(
return {
chatId: getApiChatIdFromMtpPeer(peer),
topicId,
isMuted: silent || (typeof muteUntil === 'number' && getServerTime(serverTimeOffset) < muteUntil),
isMuted: silent || (typeof muteUntil === 'number' && getServerTime() < muteUntil),
...(!hasSound && { isSilent: true }),
...(showPreviews !== undefined && { shouldShowPreviews: Boolean(showPreviews) }),
};

View File

@ -81,14 +81,12 @@ export async function fetchChats({
offsetDate,
archived,
withPinned,
serverTimeOffset,
lastLocalServiceMessage,
}: {
limit: number;
offsetDate?: number;
archived?: boolean;
withPinned?: boolean;
serverTimeOffset: number;
lastLocalServiceMessage?: ApiMessage;
}) {
const result = await invokeRequest(new GramJs.messages.GetDialogs({
@ -144,7 +142,7 @@ export async function fetchChats({
}
const peerEntity = peersByKey[getPeerKey(dialog.peer)];
const chat = buildApiChatFromDialog(dialog, peerEntity, serverTimeOffset);
const chat = buildApiChatFromDialog(dialog, peerEntity);
if (
chat.id === SERVICE_NOTIFICATIONS_USER_ID
@ -294,11 +292,10 @@ export async function fetchChat({
export async function requestChatUpdate({
chat,
serverTimeOffset,
lastLocalMessage,
noLastMessage,
}: {
chat: ApiChat; serverTimeOffset: number; lastLocalMessage?: ApiMessage; noLastMessage?: boolean;
chat: ApiChat; lastLocalMessage?: ApiMessage; noLastMessage?: boolean;
}) {
const { id, accessHash } = chat;
@ -334,7 +331,7 @@ export async function requestChatUpdate({
'@type': 'updateChat',
id,
chat: {
...buildApiChatFromDialog(dialog, peerEntity, serverTimeOffset),
...buildApiChatFromDialog(dialog, peerEntity),
...(!noLastMessage && { lastMessage }),
},
});
@ -558,9 +555,9 @@ async function getFullChannelInfo(
}
export async function updateChatMutedState({
chat, isMuted, serverTimeOffset,
chat, isMuted,
}: {
chat: ApiChat; isMuted: boolean; serverTimeOffset: number;
chat: ApiChat; isMuted: boolean;
}) {
await invokeRequest(new GramJs.account.UpdateNotifySettings({
peer: new GramJs.InputNotifyPeer({
@ -577,7 +574,6 @@ export async function updateChatMutedState({
void requestChatUpdate({
chat,
serverTimeOffset,
noLastMessage: true,
});
}
@ -585,8 +581,7 @@ export async function updateChatMutedState({
export async function updateTopicMutedState({
chat, topicId, isMuted,
}: {
chat: ApiChat; topicId: number; isMuted: boolean; serverTimeOffset: number;
chat: ApiChat; topicId: number; isMuted: boolean;
}) {
await invokeRequest(new GramJs.account.UpdateNotifySettings({
peer: new GramJs.InputNotifyForumTopic({

View File

@ -175,11 +175,6 @@ function handleGramJsUpdate(update: any) {
isConnected = update.state === connection.UpdateConnectionState.connected;
} else if (update instanceof GramJs.UpdatesTooLong) {
void handleTerminatedSession();
} else if (update instanceof connection.UpdateServerTimeOffset) {
onUpdate({
'@type': 'updateServerTimeOffset',
serverTimeOffset: update.timeOffset,
});
} else if (update instanceof GramJs.UpdateConfig) {
// eslint-disable-next-line no-underscore-dangle
const currentUser = (update as GramJs.UpdateConfig & { _entities?: (GramJs.TypeUser | GramJs.TypeChat)[] })

View File

@ -64,6 +64,7 @@ import {
import { interpolateArray } from '../../../util/waveform';
import { requestChatUpdate } from './chats';
import { getEmojiOnlyCountForMessage } from '../../../global/helpers/getEmojiOnlyCountForMessage';
import { getServerTimeOffset } from '../../../util/serverTime';
const FAST_SEND_TIMEOUT = 1000;
const INPUT_WAVEFORM_LENGTH = 63;
@ -216,7 +217,6 @@ export function sendMessage(
groupedId,
noWebPage,
sendAs,
serverTimeOffset,
shouldUpdateStickerSetsOrder,
}: {
chat: ApiChat;
@ -234,7 +234,6 @@ export function sendMessage(
groupedId?: string;
noWebPage?: boolean;
sendAs?: ApiUser | ApiChat;
serverTimeOffset?: number;
shouldUpdateStickerSetsOrder?: boolean;
},
onProgress?: ApiOnProgress,
@ -253,7 +252,6 @@ export function sendMessage(
groupedId,
scheduledAt,
sendAs,
serverTimeOffset,
);
onUpdate({
@ -498,16 +496,14 @@ export async function editMessage({
text,
entities,
noWebPage,
serverTimeOffset,
}: {
chat: ApiChat;
message: ApiMessage;
text: string;
entities?: ApiMessageEntity[];
noWebPage?: boolean;
serverTimeOffset: number;
}) {
const isScheduled = message.date * 1000 > Date.now() + serverTimeOffset * 1000;
const isScheduled = message.date * 1000 > Date.now() + getServerTimeOffset() * 1000;
let messageUpdate: Partial<ApiMessage> = {
content: {
...message.content,
@ -780,9 +776,9 @@ export async function sendMessageAction({
}
export async function markMessageListRead({
chat, threadId, maxId = -1, serverTimeOffset,
chat, threadId, maxId = -1,
}: {
chat: ApiChat; threadId: number; maxId?: number; serverTimeOffset: number;
chat: ApiChat; threadId: number; maxId?: number;
}) {
const isChannel = getEntityTypeById(chat.id) === 'channel';
@ -807,7 +803,7 @@ export async function markMessageListRead({
}
if (threadId === MAIN_THREAD_ID) {
void requestChatUpdate({ chat, serverTimeOffset, noLastMessage: true });
void requestChatUpdate({ chat, noLastMessage: true });
} else {
void requestThreadInfoUpdate({ chat, threadId });
}
@ -1191,7 +1187,6 @@ export async function forwardMessages({
toChat,
toThreadId,
messages,
serverTimeOffset,
isSilent,
scheduledAt,
sendAs,
@ -1204,7 +1199,6 @@ export async function forwardMessages({
toChat: ApiChat;
toThreadId?: number;
messages: ApiMessage[];
serverTimeOffset: number;
isSilent?: boolean;
scheduledAt?: number;
sendAs?: ApiUser | ApiChat;
@ -1221,7 +1215,6 @@ export async function forwardMessages({
toChat,
toThreadId,
message,
serverTimeOffset,
scheduledAt,
noAuthors,
noCaptions,

View File

@ -251,9 +251,7 @@ export function terminateAllWebAuthorizations() {
return invokeRequest(new GramJs.account.ResetWebAuthorizations());
}
export async function fetchNotificationExceptions({
serverTimeOffset,
}: { serverTimeOffset: number }) {
export async function fetchNotificationExceptions() {
const result = await invokeRequest(new GramJs.account.GetNotifyExceptions({
compareSound: true,
}), undefined, undefined, true);
@ -269,15 +267,13 @@ export async function fetchNotificationExceptions({
return acc;
}
acc.push(buildApiNotifyException(update.notifySettings, update.peer.peer, serverTimeOffset));
acc.push(buildApiNotifyException(update.notifySettings, update.peer.peer));
return acc;
}, [] as ApiNotifyException[]);
}
export async function fetchNotificationSettings({
serverTimeOffset,
}: { serverTimeOffset: number }) {
export async function fetchNotificationSettings() {
const [
isMutedContactSignUpNotification,
privateContactNotificationsSettings,
@ -314,17 +310,17 @@ export async function fetchNotificationSettings({
hasContactJoinedNotifications: !isMutedContactSignUpNotification,
hasPrivateChatsNotifications: !(
privateSilent
|| (typeof privateMuteUntil === 'number' && getServerTime(serverTimeOffset) < privateMuteUntil)
|| (typeof privateMuteUntil === 'number' && getServerTime() < privateMuteUntil)
),
hasPrivateChatsMessagePreview: privateShowPreviews,
hasGroupNotifications: !(
groupSilent || (typeof groupMuteUntil === 'number'
&& getServerTime(serverTimeOffset) < groupMuteUntil)
&& getServerTime() < groupMuteUntil)
),
hasGroupMessagePreview: groupShowPreviews,
hasBroadcastNotifications: !(
broadcastSilent || (typeof broadcastMuteUntil === 'number'
&& getServerTime(serverTimeOffset) < broadcastMuteUntil)
&& getServerTime() < broadcastMuteUntil)
),
hasBroadcastMessagePreview: broadcastShowPreviews,
};

View File

@ -4,7 +4,9 @@ import type {
ApiMessage, ApiMessageExtendedMediaPreview, ApiUpdateConnectionStateType, OnApiUpdate,
} from '../types';
import { DEBUG, GENERAL_TOPIC_ID } from '../../config';
import { omit, pick } from '../../util/iteratees';
import { getServerTimeOffset, setServerTimeOffset } from '../../util/serverTime';
import {
buildApiMessage,
buildApiMessageFromShort,
@ -39,7 +41,6 @@ import {
} from './gramjsBuilders';
import localDb from './localDb';
import { omitVirtualClassFields } from './apiBuilders/helpers';
import { DEBUG, GENERAL_TOPIC_ID } from '../../config';
import {
addMessageToLocalDb,
addEntitiesWithPhotosToLocalDb,
@ -79,7 +80,6 @@ export function init(_onUpdate: OnApiUpdate) {
}
const sentMessageIds = new Set();
let serverTimeOffset = 0;
// Workaround for a situation when an incorrect update comes with an undefined property `adminRights`
let shouldIgnoreNextChannelUpdate = false;
const IGNORE_NEXT_CHANNEL_UPDATE_TIMEOUT = 2000;
@ -121,7 +121,12 @@ function dispatchUserAndChatUpdates(entities: (GramJs.TypeUser | GramJs.TypeChat
export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
if (update instanceof connection.UpdateServerTimeOffset) {
serverTimeOffset = update.timeOffset;
setServerTimeOffset(update.timeOffset);
onUpdate({
'@type': 'updateServerTimeOffset',
serverTimeOffset: update.timeOffset,
});
} else if (update instanceof connection.UpdateConnectionState) {
let connectionState: ApiUpdateConnectionStateType;
@ -423,7 +428,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
},
});
} else {
const currentDate = Date.now() / 1000 + serverTimeOffset;
const currentDate = Date.now() / 1000 + getServerTimeOffset();
const message = buildApiMessageFromNotification(update, currentDate);
if (isMessageWithMedia(update)) {
@ -478,7 +483,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
sentMessageIds.add(update.id);
// Edge case for "Send When Online"
const isAlreadySent = 'date' in update && update.date * 1000 < Date.now() + serverTimeOffset * 1000;
const isAlreadySent = 'date' in update && update.date * 1000 < Date.now() + getServerTimeOffset() * 1000;
onUpdate({
'@type': localMessage.isScheduled && !isAlreadySent
@ -675,7 +680,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
) {
onUpdate({
'@type': 'updateNotifyExceptions',
...buildApiNotifyException(update.notifySettings, update.peer.peer, serverTimeOffset),
...buildApiNotifyException(update.notifySettings, update.peer.peer),
});
} else if (
update instanceof GramJs.UpdateNotifySettings
@ -684,7 +689,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
onUpdate({
'@type': 'updateTopicNotifyExceptions',
...buildApiNotifyExceptionTopic(
update.notifySettings, update.peer.peer, update.peer.topMsgId, serverTimeOffset,
update.notifySettings, update.peer.peer, update.peer.topMsgId,
),
});
} else if (
@ -707,7 +712,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
onUpdate({
'@type': 'updateChatTypingStatus',
id,
typingStatus: buildChatTypingStatus(update, serverTimeOffset),
typingStatus: buildChatTypingStatus(update),
});
}
} else if (update instanceof GramJs.UpdateChannelUserTyping) {
@ -717,7 +722,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
'@type': 'updateChatTypingStatus',
id,
threadId: update.topMsgId,
typingStatus: buildChatTypingStatus(update, serverTimeOffset),
typingStatus: buildChatTypingStatus(update),
});
} else if (update instanceof GramJs.UpdateChannel) {
// eslint-disable-next-line @typescript-eslint/naming-convention
@ -907,7 +912,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
'@type': 'updateNotifySettings',
peerType,
isSilent: Boolean(silent
|| (typeof muteUntil === 'number' && Date.now() + serverTimeOffset * 1000 < muteUntil * 1000)),
|| (typeof muteUntil === 'number' && Date.now() + getServerTimeOffset() * 1000 < muteUntil * 1000)),
shouldShowPreviews: Boolean(showPreviews),
});
} else if (update instanceof GramJs.UpdatePeerBlocked) {

View File

@ -48,7 +48,6 @@ type StateProps =
isSavedMessages?: boolean;
animationLevel: AnimationLevel;
areMessagesLoaded: boolean;
serverTimeOffset: number;
}
& Pick<GlobalState, 'lastSyncTime'>;
@ -71,7 +70,6 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
areMessagesLoaded,
animationLevel,
lastSyncTime,
serverTimeOffset,
adminMember,
}) => {
const {
@ -133,7 +131,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
return (
<span className={buildClassName('status', isUserOnline(user, userStatus) && 'online')}>
{mainUsername && <span className="handle">{mainUsername}</span>}
<span className="user-status" dir="auto">{getUserStatus(lang, user, userStatus, serverTimeOffset)}</span>
<span className="user-status" dir="auto">{getUserStatus(lang, user, userStatus)}</span>
</span>
);
}
@ -188,7 +186,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>(
(global, { userId, forceShowSelf }): StateProps => {
const { lastSyncTime, serverTimeOffset } = global;
const { lastSyncTime } = global;
const user = selectUser(global, userId);
const userStatus = selectUserStatus(global, userId);
const isSavedMessages = !forceShowSelf && user && user.isSelf;
@ -200,7 +198,6 @@ export default memo(withGlobal<OwnProps>(
userStatus,
isSavedMessages,
areMessagesLoaded,
serverTimeOffset,
animationLevel: global.settings.byKey.animationLevel,
};
},

View File

@ -46,7 +46,6 @@ type StateProps =
chat?: ApiChat;
isSavedMessages?: boolean;
animationLevel: AnimationLevel;
serverTimeOffset: number;
mediaId?: number;
avatarOwnerId?: string;
topic?: ApiTopic;
@ -66,7 +65,6 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
isSavedMessages,
connectionState,
animationLevel,
serverTimeOffset,
mediaId,
avatarOwnerId,
topic,
@ -227,7 +225,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
if (user) {
return (
<div className={buildClassName(styles.status, 'status', isUserOnline(user, userStatus) && 'online')}>
<span className="user-status" dir="auto">{getUserStatus(lang, user, userStatus, serverTimeOffset)}</span>
<span className="user-status" dir="auto">{getUserStatus(lang, user, userStatus)}</span>
</div>
);
}
@ -296,7 +294,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>(
(global, { userId, forceShowSelf }): StateProps => {
const { connectionState, serverTimeOffset } = global;
const { connectionState } = global;
const user = selectUser(global, userId);
const userStatus = selectUserStatus(global, userId);
const chat = selectChat(global, userId);
@ -314,7 +312,6 @@ export default memo(withGlobal<OwnProps>(
chat,
isSavedMessages,
animationLevel,
serverTimeOffset,
mediaId,
avatarOwnerId,
...(topic && {

View File

@ -26,7 +26,6 @@ type StateProps = {
usersById: Record<string, ApiUser>;
userStatusesById: Record<string, ApiUserStatus>;
contactIds?: string[];
serverTimeOffset: number;
};
const ContactList: FC<OwnProps & StateProps> = ({
@ -35,7 +34,6 @@ const ContactList: FC<OwnProps & StateProps> = ({
usersById,
userStatusesById,
contactIds,
serverTimeOffset,
onReset,
}) => {
const {
@ -61,8 +59,8 @@ const ContactList: FC<OwnProps & StateProps> = ({
const filteredIds = filterUsersByName(contactIds, usersById, filter);
return sortUserIds(filteredIds, usersById, userStatusesById, undefined, serverTimeOffset);
}, [contactIds, filter, usersById, userStatusesById, serverTimeOffset]);
return sortUserIds(filteredIds, usersById, userStatusesById);
}, [contactIds, filter, usersById, userStatusesById]);
const [viewportIds, getMore] = useInfiniteScroll(undefined, listIds, Boolean(filter));
@ -108,7 +106,6 @@ export default memo(withGlobal<OwnProps>(
usersById,
userStatusesById,
contactIds,
serverTimeOffset: global.serverTimeOffset,
};
},
)(ContactList));

View File

@ -35,7 +35,6 @@ type StateProps = {
user?: ApiUser;
userStatus?: ApiUserStatus;
phoneCodeList: ApiCountryCode[];
serverTimeOffset?: number;
};
const NewContactModal: FC<OwnProps & StateProps> = ({
@ -45,7 +44,6 @@ const NewContactModal: FC<OwnProps & StateProps> = ({
user,
userStatus,
phoneCodeList,
serverTimeOffset,
}) => {
const { updateContact, importContact, closeNewContactDialog } = getActions();
@ -130,7 +128,7 @@ const NewContactModal: FC<OwnProps & StateProps> = ({
: lang('MobileHidden')}
</p>
<span className="NewContactModal__user-status" dir="auto">
{getUserStatus(lang, renderingUser!, userStatus, serverTimeOffset!)}
{getUserStatus(lang, renderingUser!, userStatus)}
</span>
</div>
</div>
@ -232,7 +230,6 @@ export default memo(withGlobal<OwnProps>(
return {
user: userId ? selectUser(global, userId) : undefined,
userStatus: userId ? selectUserStatus(global, userId) : undefined,
serverTimeOffset: global.serverTimeOffset,
phoneCodeList: global.countryList.phoneCodes,
};
},

View File

@ -2,7 +2,7 @@ import type { FC } from '../../../lib/teact/teact';
import React, {
memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
} from '../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../global';
import { getActions, withGlobal } from '../../../global';
import type { GlobalState, MessageListType } from '../../../global/types';
import type {
@ -635,12 +635,9 @@ const Composer: FC<OwnProps & StateProps> = ({
const checkSlowMode = useCallback(() => {
if (slowMode && !isAdmin) {
// No need to subscribe on updates in `mapStateToProps`
const { serverTimeOffset } = getGlobal();
const messageInput = document.querySelector<HTMLDivElement>(EDITABLE_INPUT_CSS_SELECTOR);
const nowSeconds = getServerTime(serverTimeOffset);
const nowSeconds = getServerTime();
const secondsSinceLastMessage = lastMessageSendTimeSeconds.current
&& Math.floor(nowSeconds - lastMessageSendTimeSeconds.current);
const nextSendDateNotReached = slowMode.nextSendDate && slowMode.nextSendDate > nowSeconds;
@ -692,10 +689,7 @@ const Composer: FC<OwnProps & StateProps> = ({
shouldGroupMessages: sendGrouped,
});
// No need to subscribe on updates in `mapStateToProps`
const { serverTimeOffset } = getGlobal();
lastMessageSendTimeSeconds.current = getServerTime(serverTimeOffset);
lastMessageSendTimeSeconds.current = getServerTime();
clearDraft({ chatId, localOnly: true });
@ -738,9 +732,6 @@ const Composer: FC<OwnProps & StateProps> = ({
return;
}
// No need to subscribe on updates in `mapStateToProps`
const { serverTimeOffset } = getGlobal();
if (!validateTextLength(text)) return;
const messageInput = document.querySelector<HTMLDivElement>(EDITABLE_INPUT_CSS_SELECTOR);
@ -764,7 +755,7 @@ const Composer: FC<OwnProps & StateProps> = ({
});
}
lastMessageSendTimeSeconds.current = getServerTime(serverTimeOffset);
lastMessageSendTimeSeconds.current = getServerTime();
clearDraft({ chatId, localOnly: true });

View File

@ -55,7 +55,6 @@ type OwnProps = {
isInSelectMode?: boolean;
isSelected?: boolean;
theme: ISettings['theme'];
serverTimeOffset: number;
};
const Location: FC<OwnProps> = ({
@ -65,7 +64,6 @@ const Location: FC<OwnProps> = ({
isInSelectMode,
isSelected,
theme,
serverTimeOffset,
}) => {
const { openUrl } = getActions();
// eslint-disable-next-line no-null/no-null
@ -78,7 +76,7 @@ const Location: FC<OwnProps> = ({
const location = getMessageLocation(message)!;
const { type, geo } = location;
const serverTime = getServerTime(serverTimeOffset);
const serverTime = getServerTime();
const isExpired = isGeoLiveExpired(message, serverTime);
const secondsBeforeEnd = (type === 'geoLive' && !isExpired) ? message.date + location.period - serverTime
: undefined;
@ -122,7 +120,7 @@ const Location: FC<OwnProps> = ({
const svgEl = countdownEl.lastElementChild;
const timerEl = countdownEl.firstElementChild as SVGElement;
const timeLeft = message.date + location.period - getServerTime(serverTimeOffset);
const timeLeft = message.date + location.period - getServerTime();
const strokeDashOffset = (1 - timeLeft / location.period) * circumference;
const text = formatCountdownShort(lang, timeLeft * 1000);
@ -139,7 +137,7 @@ const Location: FC<OwnProps> = ({
timerEl.textContent = text;
svgEl.firstElementChild!.setAttribute('stroke-dashoffset', `-${strokeDashOffset}`);
}
}, [type, message.date, location, serverTimeOffset, lang]);
}, [type, message.date, location, lang]);
useLayoutEffect(() => {
if (countdownRef.current) {

View File

@ -201,7 +201,6 @@ type StateProps = {
isGroup?: boolean;
canReply?: boolean;
lastSyncTime?: number;
serverTimeOffset: number;
highlight?: string;
animatedEmoji?: string;
animatedCustomEmoji?: string;
@ -297,7 +296,6 @@ const Message: FC<OwnProps & StateProps> = ({
isGroup,
canReply,
lastSyncTime,
serverTimeOffset,
highlight,
animatedEmoji,
animatedCustomEmoji,
@ -546,7 +544,7 @@ const Message: FC<OwnProps & StateProps> = ({
hasComments: repliesThreadInfo && repliesThreadInfo.messagesCount > 0,
hasActionButton: canForward || canFocus,
hasReactions,
isGeoLiveActive: location?.type === 'geoLive' && !isGeoLiveExpired(message, getServerTime(serverTimeOffset)),
isGeoLiveActive: location?.type === 'geoLive' && !isGeoLiveExpired(message, getServerTime()),
withVoiceTranscription,
});
@ -959,7 +957,6 @@ const Message: FC<OwnProps & StateProps> = ({
isSelected={isSelected}
theme={theme}
peer={sender}
serverTimeOffset={serverTimeOffset}
/>
)}
</div>
@ -1174,7 +1171,7 @@ const Message: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>(
(global, ownProps): StateProps => {
const {
focusedMessage, forwardMessages, lastSyncTime, serverTimeOffset,
focusedMessage, forwardMessages, lastSyncTime,
} = global;
const {
message, album, withSenderName, withAvatar, threadId, messageListType, isLastInDocumentGroup, isFirstInGroup,
@ -1280,7 +1277,6 @@ export default memo(withGlobal<OwnProps>(
isGroup,
canReply,
lastSyncTime,
serverTimeOffset,
highlight,
animatedEmoji,
animatedCustomEmoji,

View File

@ -18,6 +18,7 @@ import { renderTextWithEntities } from '../../common/helpers/renderTextWithEntit
import { formatMediaDuration } from '../../../util/dateFormat';
import type { LangFn } from '../../../hooks/useLang';
import useLang from '../../../hooks/useLang';
import { getServerTimeOffset } from '../../../util/serverTime';
import CheckboxGroup from '../../ui/CheckboxGroup';
import RadioGroup from '../../ui/RadioGroup';
@ -37,7 +38,6 @@ type OwnProps = {
type StateProps = {
recentVoterIds?: number[];
usersById: Record<string, ApiUser>;
serverTimeOffset: number;
};
const SOLUTION_CONTAINER_ID = '#middle-column-portals';
@ -50,7 +50,6 @@ const Poll: FC<OwnProps & StateProps> = ({
recentVoterIds,
usersById,
onSendVote,
serverTimeOffset,
}) => {
const { loadMessage, openPollResults, requestConfetti } = getActions();
@ -62,7 +61,7 @@ const Poll: FC<OwnProps & StateProps> = ({
const [wasSubmitted, setWasSubmitted] = useState<boolean>(false);
const [closePeriod, setClosePeriod] = useState<number>(
!summary.closed && summary.closeDate && summary.closeDate > 0
? Math.min(summary.closeDate - Math.floor(Date.now() / 1000) + serverTimeOffset, summary.closePeriod!)
? Math.min(summary.closeDate - Math.floor(Date.now() / 1000) + getServerTimeOffset(), summary.closePeriod!)
: 0,
);
// eslint-disable-next-line no-null/no-null
@ -362,7 +361,7 @@ function stopPropagation(e: React.MouseEvent<HTMLDivElement>) {
export default memo(withGlobal<OwnProps>(
(global, { poll }) => {
const { recentVoterIds } = poll.results;
const { serverTimeOffset, users: { byId: usersById } } = global;
const { users: { byId: usersById } } = global;
if (!recentVoterIds || recentVoterIds.length === 0) {
return {};
}
@ -370,7 +369,6 @@ export default memo(withGlobal<OwnProps>(
return {
recentVoterIds,
usersById,
serverTimeOffset,
};
},
)(Poll));

View File

@ -98,7 +98,6 @@ type StateProps = {
isRightColumnShown: boolean;
isRestricted?: boolean;
lastSyncTime?: number;
serverTimeOffset: number;
activeDownloadIds: number[];
isChatProtected?: boolean;
};
@ -141,7 +140,6 @@ const Profile: FC<OwnProps & StateProps> = ({
isRestricted,
lastSyncTime,
activeDownloadIds,
serverTimeOffset,
isChatProtected,
}) => {
const {
@ -197,7 +195,6 @@ const Profile: FC<OwnProps & StateProps> = ({
chatMessages,
foundIds,
lastSyncTime,
serverTimeOffset,
topicId,
);
const isFirstTab = resultType === 'members' || (!hasMembersTab && resultType === 'media');
@ -583,7 +580,6 @@ export default memo(withGlobal<OwnProps>(
isRightColumnShown: selectIsRightColumnShown(global),
isRestricted: chat?.isRestricted,
lastSyncTime: global.lastSyncTime,
serverTimeOffset: global.serverTimeOffset,
activeDownloadIds,
usersById,
userStatusesById,

View File

@ -24,7 +24,6 @@ export default function useProfileViewportIds(
chatMessages?: Record<number, ApiMessage>,
foundIds?: number[],
lastSyncTime?: number,
serverTimeOffset = 0,
topicId?: number,
) {
const resultType = tabType === 'members' || !mediaSearchType ? tabType : mediaSearchType;
@ -38,10 +37,8 @@ export default function useProfileViewportIds(
groupChatMembers.map(({ userId }) => userId),
usersById,
userStatusesById,
undefined,
serverTimeOffset,
);
}, [groupChatMembers, serverTimeOffset, usersById, userStatusesById]);
}, [groupChatMembers, usersById, userStatusesById]);
const chatIds = useMemo(() => {
if (!commonChatIds || !chatsById) {

View File

@ -29,7 +29,6 @@ type StateProps = {
user?: ApiUser;
isSavedMessages?: boolean;
animationLevel: AnimationLevel;
serverTimeOffset: number;
};
const JoinRequest: FC<OwnProps & StateProps> = ({
@ -40,7 +39,6 @@ const JoinRequest: FC<OwnProps & StateProps> = ({
isChannel,
user,
animationLevel,
serverTimeOffset,
}) => {
const { openChat, hideChatJoinRequest } = getActions();
@ -48,7 +46,7 @@ const JoinRequest: FC<OwnProps & StateProps> = ({
const lang = useLang();
const fullName = getUserFullName(user);
const fixedDate = (date - getServerTime(serverTimeOffset)) * 1000 + Date.now();
const fixedDate = (date - getServerTime()) * 1000 + Date.now();
const dateString = isToday(new Date(fixedDate))
? formatTime(lang, fixedDate) : formatHumanDate(lang, fixedDate, true, false, true);
@ -102,7 +100,6 @@ export default memo(withGlobal<OwnProps>(
return {
user,
animationLevel: global.settings.byKey.animationLevel,
serverTimeOffset: global.serverTimeOffset,
};
},
)(JoinRequest));

View File

@ -45,7 +45,6 @@ type StateProps = {
isSearching?: boolean;
localUserIds?: string[];
globalUserIds?: string[];
serverTimeOffset: number;
currentUserId?: string;
canDeleteMembers?: boolean;
isBasicGroup?: boolean;
@ -65,7 +64,6 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
localUserIds,
isSearching,
searchQuery,
serverTimeOffset,
currentUserId,
canDeleteMembers,
isBasicGroup,
@ -100,12 +98,10 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
members.map(({ userId }) => userId),
usersById,
userStatusesById,
undefined,
serverTimeOffset,
);
return noAdmins ? userIds.filter((userId) => !adminIds.includes(userId)) : userIds;
}, [members, userStatusesById, serverTimeOffset, noAdmins, adminIds]);
}, [members, userStatusesById, noAdmins, adminIds]);
const displayedIds = useMemo(() => {
// No need for expensive global updates on users, so we avoid them
@ -282,7 +278,6 @@ export default memo(withGlobal<OwnProps>(
globalUserIds,
localUserIds,
canDeleteMembers,
serverTimeOffset: global.serverTimeOffset,
currentUserId: global.currentUserId,
};
},

View File

@ -26,7 +26,6 @@ type StateProps = {
userStatusesById: Record<string, ApiUserStatus>;
members?: ApiChatMember[];
isChannel?: boolean;
serverTimeOffset: number;
};
const ManageGroupUserPermissionsCreate: FC<OwnProps & StateProps> = ({
@ -38,7 +37,6 @@ const ManageGroupUserPermissionsCreate: FC<OwnProps & StateProps> = ({
onChatMemberSelect,
onClose,
isActive,
serverTimeOffset,
}) => {
useHistoryBack({
isActive,
@ -54,10 +52,8 @@ const ManageGroupUserPermissionsCreate: FC<OwnProps & StateProps> = ({
members.filter((member) => !member.isOwner).map(({ userId }) => userId),
usersById,
userStatusesById,
undefined,
serverTimeOffset,
);
}, [members, serverTimeOffset, usersById, userStatusesById]);
}, [members, usersById, userStatusesById]);
const handleExceptionMemberClick = useCallback((memberId: string) => {
onChatMemberSelect(memberId);
@ -105,7 +101,6 @@ export default memo(withGlobal<OwnProps>(
usersById,
userStatusesById,
isChannel,
serverTimeOffset: global.serverTimeOffset,
};
},
)(ManageGroupUserPermissionsCreate));

View File

@ -37,14 +37,12 @@ type OwnProps = {
type StateProps = {
editingInvite?: ApiExportedInvite;
serverTimeOffset: number;
};
const ManageInvite: FC<OwnProps & StateProps> = ({
chatId,
editingInvite,
isActive,
serverTimeOffset,
onClose,
onScreenSelect,
}) => {
@ -71,7 +69,7 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
setTitle('');
setSelectedExpireOption('unlimited');
setSelectedUsageOption('0');
setCustomExpireDate(getServerTime(serverTimeOffset) * 1000 + DEFAULT_CUSTOM_EXPIRE_DATE);
setCustomExpireDate(getServerTime() * 1000 + DEFAULT_CUSTOM_EXPIRE_DATE);
setCustomUsageLimit(10);
setIsRequestNeeded(false);
} else {
@ -84,7 +82,7 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
setCustomUsageLimit(usageLimit);
}
if (expireDate) {
const minSafeDate = getServerTime(serverTimeOffset) + DEFAULT_CUSTOM_EXPIRE_DATE;
const minSafeDate = getServerTime() + DEFAULT_CUSTOM_EXPIRE_DATE;
setSelectedExpireOption('custom');
setCustomExpireDate(Math.max(expireDate, minSafeDate) * 1000);
}
@ -92,7 +90,7 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
setIsRequestNeeded(true);
}
}
}, [editingInvite, serverTimeOffset]);
}, [editingInvite]);
const handleIsRequestChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setIsRequestNeeded(e.target.checked);
@ -117,12 +115,12 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
let expireDate;
switch (selectedExpireOption) {
case 'custom':
expireDate = getServerTime(serverTimeOffset) + (customExpireDate - Date.now()) / 1000;
expireDate = getServerTime() + (customExpireDate - Date.now()) / 1000;
break;
case 'hour':
case 'day':
case 'week':
expireDate = getServerTime(serverTimeOffset) + DEFAULT_EXPIRE_DATE[selectedExpireOption] / 1000;
expireDate = getServerTime() + DEFAULT_EXPIRE_DATE[selectedExpireOption] / 1000;
break;
case 'unlimited':
expireDate = 0;
@ -153,7 +151,6 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
}, [
chatId, customExpireDate, customUsageLimit, editExportedChatInvite, editingInvite,
exportChatInvite, isRequestNeeded, selectedExpireOption, selectedUsageOption, title, onScreenSelect,
serverTimeOffset,
]);
return (
@ -272,7 +269,6 @@ export default memo(withGlobal<OwnProps>(
return {
editingInvite,
serverTimeOffset: global.serverTimeOffset,
};
},
)(ManageInvite));

View File

@ -29,7 +29,6 @@ type StateProps = {
requesters?: ApiChatInviteImporter[];
admin?: ApiUser;
isChannel?: boolean;
serverTimeOffset: number;
};
const ManageInviteInfo: FC<OwnProps & StateProps> = ({
@ -39,7 +38,6 @@ const ManageInviteInfo: FC<OwnProps & StateProps> = ({
requesters,
isChannel,
isActive,
serverTimeOffset,
onClose,
}) => {
const {
@ -53,8 +51,8 @@ const ManageInviteInfo: FC<OwnProps & StateProps> = ({
const {
usage = 0, usageLimit, link, adminId,
} = invite || {};
const expireDate = invite?.expireDate && (invite.expireDate - getServerTime(serverTimeOffset)) * 1000 + Date.now();
const isExpired = ((invite?.expireDate || 0) - getServerTime(serverTimeOffset)) < 0;
const expireDate = invite?.expireDate && (invite.expireDate - getServerTime()) * 1000 + Date.now();
const isExpired = ((invite?.expireDate || 0) - getServerTime()) < 0;
useEffect(() => {
if (link) {
@ -191,7 +189,6 @@ export default memo(withGlobal<OwnProps>(
importers,
requesters,
isChannel,
serverTimeOffset: global.serverTimeOffset,
};
},
)(ManageInviteInfo));

View File

@ -41,7 +41,6 @@ type StateProps = {
isChannel?: boolean;
exportedInvites?: ApiExportedInvite[];
revokedExportedInvites?: ApiExportedInvite[];
serverTimeOffset: number;
};
const BULLET = '\u2022';
@ -61,7 +60,6 @@ const ManageInvites: FC<OwnProps & StateProps> = ({
revokedExportedInvites,
isActive,
isChannel,
serverTimeOffset,
onClose,
onScreenSelect,
}) => {
@ -91,9 +89,9 @@ const ManageInvites: FC<OwnProps & StateProps> = ({
if (!exportedInvites) return undefined;
return exportedInvites
.some(({ expireDate }) => (
expireDate && (expireDate - getServerTime(serverTimeOffset) < MILLISECONDS_IN_DAY / 1000)
expireDate && (expireDate - getServerTime() < MILLISECONDS_IN_DAY / 1000)
));
}, [exportedInvites, serverTimeOffset]);
}, [exportedInvites]);
const forceUpdate = useForceUpdate();
useInterval(() => {
forceUpdate();
@ -211,7 +209,7 @@ const ManageInvites: FC<OwnProps & StateProps> = ({
if (usageLimit !== undefined && usage === usageLimit) {
text += ` ${BULLET} ${lang('LinkLimitReached')}`;
} else if (expireDate) {
const diff = (expireDate - getServerTime(serverTimeOffset)) * 1000;
const diff = (expireDate - getServerTime()) * 1000;
text += ` ${BULLET} `;
if (diff > 0) {
text += lang('InviteLink.ExpiresIn', formatCountdown(lang, diff));
@ -236,7 +234,7 @@ const ManageInvites: FC<OwnProps & StateProps> = ({
return 'link-status-icon-green';
}
if (expireDate) {
const diff = (expireDate - getServerTime(serverTimeOffset)) * 1000;
const diff = (expireDate - getServerTime()) * 1000;
if (diff <= 0) {
return 'link-status-icon-red';
}
@ -425,7 +423,6 @@ export default memo(withGlobal<OwnProps>(
exportedInvites: invites,
revokedExportedInvites: revokedInvites,
chat,
serverTimeOffset: global.serverTimeOffset,
isChannel,
};
},

View File

@ -27,7 +27,6 @@ type OwnProps = {
type StateProps = {
chat?: ApiChat;
isChannel?: boolean;
serverTimeOffset: number;
};
const ManageJoinRequests: FC<OwnProps & StateProps> = ({
@ -129,7 +128,6 @@ export default memo(withGlobal<OwnProps>(
return {
chat,
serverTimeOffset: global.serverTimeOffset,
isChannel: chat && isChatChannel(chat),
};
},

View File

@ -200,7 +200,7 @@ addActionHandler('restartBot', async (global, actions, payload) => {
addActionHandler('loadTopInlineBots', async (global) => {
const { lastRequestedAt } = global.topInlineBots;
if (lastRequestedAt && getServerTime(global.serverTimeOffset) - lastRequestedAt < TOP_PEERS_REQUEST_COOLDOWN) {
if (lastRequestedAt && getServerTime() - lastRequestedAt < TOP_PEERS_REQUEST_COOLDOWN) {
return;
}
@ -218,7 +218,7 @@ addActionHandler('loadTopInlineBots', async (global) => {
topInlineBots: {
...global.topInlineBots,
userIds: ids,
lastRequestedAt: getServerTime(global.serverTimeOffset),
lastRequestedAt: getServerTime(),
},
};
setGlobal(global);

View File

@ -263,7 +263,6 @@ addActionHandler('loadTopChats', () => {
});
addActionHandler('requestChatUpdate', (global, actions, payload) => {
const { serverTimeOffset } = global;
const { chatId } = payload!;
const chat = selectChat(global, chatId);
if (!chat) {
@ -272,7 +271,6 @@ addActionHandler('requestChatUpdate', (global, actions, payload) => {
void callApi('requestChatUpdate', {
chat,
serverTimeOffset,
...(chatId === SERVICE_NOTIFICATIONS_USER_ID && {
lastLocalMessage: selectLastServiceNotification(global)?.message,
}),
@ -280,7 +278,6 @@ addActionHandler('requestChatUpdate', (global, actions, payload) => {
});
addActionHandler('updateChatMutedState', (global, actions, payload) => {
const { serverTimeOffset } = global;
const { chatId, isMuted } = payload!;
const chat = selectChat(global, chatId);
if (!chat) {
@ -288,11 +285,10 @@ addActionHandler('updateChatMutedState', (global, actions, payload) => {
}
setGlobal(updateChat(global, chatId, { isMuted }));
void callApi('updateChatMutedState', { chat, isMuted, serverTimeOffset });
void callApi('updateChatMutedState', { chat, isMuted });
});
addActionHandler('updateTopicMutedState', (global, actions, payload) => {
const { serverTimeOffset } = global;
const { chatId, isMuted, topicId } = payload;
const chat = selectChat(global, chatId);
if (!chat) {
@ -301,7 +297,7 @@ addActionHandler('updateTopicMutedState', (global, actions, payload) => {
setGlobal(updateTopic(global, chatId, topicId, { isMuted }));
void callApi('updateTopicMutedState', {
chat, topicId, isMuted, serverTimeOffset,
chat, topicId, isMuted,
});
});
@ -582,11 +578,10 @@ addActionHandler('deleteChatFolder', (global, actions, payload) => {
addActionHandler('toggleChatUnread', (global, actions, payload) => {
const { id } = payload!;
const { serverTimeOffset } = global;
const chat = selectChat(global, id);
if (chat) {
if (chat.unreadCount) {
void callApi('markMessageListRead', { serverTimeOffset, chat, threadId: MAIN_THREAD_ID });
void callApi('markMessageListRead', { chat, threadId: MAIN_THREAD_ID });
} else {
void callApi('toggleDialogUnread', {
chat,
@ -608,7 +603,6 @@ addActionHandler('markTopicRead', (global, actions, payload) => {
chat,
threadId: topicId,
maxId: lastTopicMessageId,
serverTimeOffset: global.serverTimeOffset,
});
global = getGlobal();
@ -1553,7 +1547,6 @@ async function loadChats(
offsetDate,
archived: listType === 'archived',
withPinned: shouldReplace,
serverTimeOffset: global.serverTimeOffset,
lastLocalServiceMessage,
});

View File

@ -303,7 +303,6 @@ addActionHandler('sendMessage', (global, actions, payload) => {
});
addActionHandler('editMessage', (global, actions, payload) => {
const { serverTimeOffset } = global;
const { text, entities } = payload!;
const currentMessageList = selectCurrentMessageList(global);
@ -319,7 +318,7 @@ addActionHandler('editMessage', (global, actions, payload) => {
}
void callApi('editMessage', {
chat, message, text, entities, noWebPage: selectNoWebPage(global, chatId, threadId), serverTimeOffset,
chat, message, text, entities, noWebPage: selectNoWebPage(global, chatId, threadId),
});
actions.setEditingId({ messageId: undefined });
@ -515,7 +514,6 @@ addActionHandler('sendMessageAction', async (global, actions, payload) => {
});
addActionHandler('markMessageListRead', (global, actions, payload) => {
const { serverTimeOffset } = global;
const currentMessageList = selectCurrentMessageList(global);
if (!currentMessageList) {
return undefined;
@ -531,7 +529,7 @@ addActionHandler('markMessageListRead', (global, actions, payload) => {
runDebouncedForMarkRead(() => {
void callApi('markMessageListRead', {
serverTimeOffset, chat, threadId, maxId,
chat, threadId, maxId,
});
});
@ -679,7 +677,6 @@ addActionHandler('forwardMessages', (global, action, payload) => {
toChat,
toThreadId,
messages: realMessages,
serverTimeOffset: getGlobal().serverTimeOffset,
isSilent,
scheduledAt,
sendAs,
@ -992,7 +989,6 @@ async function sendMessage(params: {
sticker?: ApiSticker;
gif?: ApiVideo;
poll?: ApiNewPoll;
serverTimeOffset?: number;
isSilent?: boolean;
scheduledAt?: number;
sendAs?: ApiChat | ApiUser;
@ -1024,7 +1020,6 @@ async function sendMessage(params: {
}
const global = getGlobal();
params.serverTimeOffset = global.serverTimeOffset;
const currentMessageList = selectCurrentMessageList(global);
if (!currentMessageList) {
return;

View File

@ -316,10 +316,8 @@ addActionHandler('unblockContact', async (global, actions, payload) => {
setGlobal(removeBlockedContact(getGlobal(), contactId));
});
addActionHandler('loadNotificationExceptions', async (global) => {
const { serverTimeOffset } = global;
const result = await callApi('fetchNotificationExceptions', { serverTimeOffset });
addActionHandler('loadNotificationExceptions', async () => {
const result = await callApi('fetchNotificationExceptions');
if (!result) {
return;
}
@ -327,11 +325,8 @@ addActionHandler('loadNotificationExceptions', async (global) => {
setGlobal(addNotifyExceptions(getGlobal(), result));
});
addActionHandler('loadNotificationSettings', async (global) => {
const { serverTimeOffset } = global;
const result = await callApi('fetchNotificationSettings', {
serverTimeOffset,
});
addActionHandler('loadNotificationSettings', async () => {
const result = await callApi('fetchNotificationSettings');
if (!result) {
return;
}
@ -637,11 +632,11 @@ addActionHandler('loadAppConfig', async () => {
});
});
addActionHandler('loadConfig', async (global) => {
addActionHandler('loadConfig', async () => {
const config = await callApi('fetchConfig');
if (!config) return;
const timeout = config.expiresAt - getServerTime(global.serverTimeOffset);
const timeout = config.expiresAt - getServerTime();
requestActionTimeout('loadConfig', timeout * 1000);
setGlobal({

View File

@ -66,7 +66,7 @@ addActionHandler('loadUser', async (global, actions, payload) => {
addActionHandler('loadTopUsers', (global) => {
const { topPeers: { lastRequestedAt } } = global;
if (!lastRequestedAt || getServerTime(global.serverTimeOffset) - lastRequestedAt > TOP_PEERS_REQUEST_COOLDOWN) {
if (!lastRequestedAt || getServerTime() - lastRequestedAt > TOP_PEERS_REQUEST_COOLDOWN) {
void loadTopUsers();
}
});
@ -138,7 +138,7 @@ async function loadTopUsers() {
topPeers: {
...global.topPeers,
userIds: ids,
lastRequestedAt: getServerTime(global.serverTimeOffset),
lastRequestedAt: getServerTime(),
},
};
setGlobal(global);

View File

@ -19,6 +19,7 @@ import { selectNotifySettings } from '../../selectors';
import { forceWebsync } from '../../../util/websync';
import { getShippingError, shouldClosePaymentModal } from '../../../util/getReadableErrorText';
import { clearWebTokenAuth } from '../../../util/routing';
import { setServerTimeOffset } from '../../../util/serverTime';
addActionHandler('apiUpdate', (global, actions, update) => {
switch (update['@type']) {
@ -205,16 +206,7 @@ function onUpdateSession(update: ApiUpdateSession) {
}
function onUpdateServerTimeOffset(update: ApiUpdateServerTimeOffset) {
const global = getGlobal();
if (global.serverTimeOffset === update.serverTimeOffset) {
return;
}
setGlobal({
...global,
serverTimeOffset: update.serverTimeOffset,
});
setServerTimeOffset(update.serverTimeOffset);
}
function onUpdateCurrentUser(update: ApiUpdateCurrentUser) {

View File

@ -645,7 +645,7 @@ addActionHandler('checkVersionNotification', (global, actions) => {
const message: Omit<ApiMessage, 'id'> = {
chatId: SERVICE_NOTIFICATIONS_USER_ID,
date: getServerTime(global.serverTimeOffset),
date: getServerTime(),
content: {
text: parseMessageInput(versionNotification, true),
},

View File

@ -4,7 +4,7 @@ import { SERVICE_NOTIFICATIONS_USER_ID } from '../../config';
import { formatFullDate, formatTime } from '../../util/dateFormat';
import { orderBy } from '../../util/iteratees';
import type { LangFn } from '../../hooks/useLang';
import { getServerTime } from '../../util/serverTime';
import { getServerTime, getServerTimeOffset } from '../../util/serverTime';
import { prepareSearchWordsForNeedle } from '../../util/searchWords';
import { formatPhoneNumber } from '../../util/phoneNumber';
@ -67,7 +67,7 @@ export function getUserFullName(user?: ApiUser) {
}
export function getUserStatus(
lang: LangFn, user: ApiUser, userStatus: ApiUserStatus | undefined, serverTimeOffset: number,
lang: LangFn, user: ApiUser, userStatus: ApiUserStatus | undefined,
) {
if (user.id === SERVICE_NOTIFICATIONS_USER_ID) {
return lang('ServiceNotifications').toLowerCase();
@ -99,6 +99,7 @@ export function getUserStatus(
if (!wasOnline) return lang('LastSeen.Offline');
const serverTimeOffset = getServerTimeOffset();
const now = new Date(new Date().getTime() + serverTimeOffset * 1000);
const wasOnlineDate = new Date(wasOnline * 1000);
@ -191,10 +192,9 @@ export function sortUserIds(
usersById: Record<string, ApiUser>,
userStatusesById: Record<string, ApiUserStatus>,
priorityIds?: string[],
serverTimeOffset = 0,
) {
return orderBy(userIds, (id) => {
const now = getServerTime(serverTimeOffset);
const now = getServerTime();
if (priorityIds && priorityIds.includes(id)) {
// Assuming that online status expiration date can't be as far as two days from now,

View File

@ -14,7 +14,6 @@ export const INITIAL_STATE: GlobalState = {
isChatInfoShown: false,
newChatMembersProgress: NewChatMembersProgress.Closed,
uiReadyState: 0,
serverTimeOffset: 0,
isUpdateAvailable: false,
authRememberMe: true,

View File

@ -464,7 +464,7 @@ export function selectAllowedMessageActions(global: GlobalState, message: ApiMes
const isMessageEditable = (
(
canEditMessagesIndefinitely
|| getServerTime(global.serverTimeOffset) - message.date < MESSAGE_EDIT_ALLOWED_TIME
|| getServerTime() - message.date < MESSAGE_EDIT_ALLOWED_TIME
) && !(
content.sticker || content.contact || content.poll || content.action || content.audio
|| (content.video?.isRound) || content.location || content.invoice

View File

@ -159,7 +159,6 @@ export type GlobalState = {
isSyncing?: boolean;
isUpdateAvailable?: boolean;
lastSyncTime?: number;
serverTimeOffset: number;
leftColumnWidth?: number;
// TODO Move to `auth`.

View File

@ -1,11 +1,11 @@
import React, { useCallback, useState } from '../lib/teact/teact';
import { getGlobal } from '../lib/teact/teactn';
import { SCHEDULED_WHEN_ONLINE } from '../config';
import { getDayStartAt } from '../util/dateFormat';
import useLang from './useLang';
import CalendarModal from '../components/common/CalendarModal.async';
import { getServerTimeOffset } from '../util/serverTime';
type OnScheduledCallback = (scheduledAt: number) => void;
@ -18,10 +18,9 @@ const useSchedule = (
const [onScheduled, setOnScheduled] = useState<OnScheduledCallback | undefined>();
const handleMessageSchedule = useCallback((date: Date, isWhenOnline = false) => {
const { serverTimeOffset } = getGlobal();
// Scheduled time can not be less than 10 seconds in future
const scheduledAt = Math.round(Math.max(date.getTime(), Date.now() + 60 * 1000) / 1000)
+ (isWhenOnline ? 0 : serverTimeOffset);
+ (isWhenOnline ? 0 : getServerTimeOffset());
onScheduled?.(scheduledAt);
setOnScheduled(undefined);
}, [onScheduled]);

View File

@ -179,12 +179,8 @@ let areSettingsLoaded = false;
async function loadNotificationSettings() {
if (areSettingsLoaded) return selectNotifySettings(getGlobal());
const [resultSettings, resultExceptions] = await Promise.all([
callApi('fetchNotificationSettings', {
serverTimeOffset: getGlobal().serverTimeOffset,
}),
callApi('fetchNotificationExceptions', {
serverTimeOffset: getGlobal().serverTimeOffset,
}),
callApi('fetchNotificationSettings'),
callApi('fetchNotificationExceptions'),
]);
if (!resultSettings) return selectNotifySettings(getGlobal());

View File

@ -1,3 +1,13 @@
export const getServerTime = (serverTimeOffset: number) => {
let serverTimeOffset = 0;
export function setServerTimeOffset(_serverTimeOffset: number) {
serverTimeOffset = _serverTimeOffset;
}
export function getServerTimeOffset() {
return serverTimeOffset;
}
export function getServerTime() {
return Math.floor(Date.now() / 1000) + serverTimeOffset;
};
}