mirror of
https://github.com/danog/telegram-tt.git
synced 2024-11-30 04:39:00 +01:00
Support redirects from t.me (websync) (#1383)
This commit is contained in:
parent
6fa2fae909
commit
ae0ad36478
@ -73,6 +73,7 @@ export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet {
|
||||
thumbs,
|
||||
count,
|
||||
hash,
|
||||
shortName,
|
||||
} = set;
|
||||
|
||||
return {
|
||||
@ -85,6 +86,7 @@ export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet {
|
||||
hasThumbnail: Boolean(thumbs && thumbs.length),
|
||||
count,
|
||||
hash,
|
||||
shortName,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,12 @@ export function buildInputStickerSet(id: string, accessHash: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export function buildInputStickerSetShortName(shortName: string) {
|
||||
return new GramJs.InputStickerSetShortName({
|
||||
shortName,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildInputDocument(media: ApiSticker | ApiVideo) {
|
||||
const document = localDb.documents[media.id];
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { ApiSticker, ApiVideo, OnApiUpdate } from '../../types';
|
||||
|
||||
import { invokeRequest } from './client';
|
||||
import { buildStickerFromDocument, buildStickerSet, buildStickerSetCovered } from '../apiBuilders/symbols';
|
||||
import { buildInputStickerSet, buildInputDocument } from '../gramjsBuilders';
|
||||
import { buildInputStickerSet, buildInputDocument, buildInputStickerSetShortName } from '../gramjsBuilders';
|
||||
import { buildVideoFromDocument } from '../apiBuilders/messages';
|
||||
import { RECENT_STICKERS_LIMIT } from '../../../config';
|
||||
|
||||
@ -93,9 +93,12 @@ export async function faveSticker({
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchStickers({ stickerSetId, accessHash }: { stickerSetId: string; accessHash: string }) {
|
||||
export async function fetchStickers({ stickerSetShortName, stickerSetId, accessHash }:
|
||||
{ stickerSetShortName?: string; stickerSetId?: string; accessHash: string }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetStickerSet({
|
||||
stickerset: buildInputStickerSet(stickerSetId, accessHash),
|
||||
stickerset: stickerSetId
|
||||
? buildInputStickerSet(stickerSetId, accessHash)
|
||||
: buildInputStickerSetShortName(stickerSetShortName!),
|
||||
}));
|
||||
|
||||
if (!result) {
|
||||
|
@ -43,6 +43,7 @@ export interface ApiStickerSet {
|
||||
stickers?: ApiSticker[];
|
||||
packs?: Record<string, ApiSticker[]>;
|
||||
covers?: ApiSticker[];
|
||||
shortName: string;
|
||||
}
|
||||
|
||||
export interface ApiVideo {
|
||||
|
@ -8,7 +8,7 @@ import { GlobalActions } from '../../global/types';
|
||||
|
||||
import { STICKER_SIZE_MODAL } from '../../config';
|
||||
import { pick } from '../../util/iteratees';
|
||||
import { selectStickerSet } from '../../modules/selectors';
|
||||
import { selectStickerSet, selectStickerSetByShortName } from '../../modules/selectors';
|
||||
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import renderText from './helpers/renderText';
|
||||
@ -22,7 +22,8 @@ import './StickerSetModal.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
isOpen: boolean;
|
||||
fromSticker: ApiSticker;
|
||||
fromSticker?: ApiSticker;
|
||||
stickerSetShortName?: string;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
@ -37,6 +38,7 @@ const INTERSECTION_THROTTLE = 200;
|
||||
const StickerSetModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
isOpen,
|
||||
fromSticker,
|
||||
stickerSetShortName,
|
||||
stickerSet,
|
||||
onClose,
|
||||
loadStickers,
|
||||
@ -53,10 +55,19 @@ const StickerSetModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
const { stickerSetId, stickerSetAccessHash } = fromSticker;
|
||||
loadStickers({ stickerSetId, stickerSetAccessHash });
|
||||
if (fromSticker) {
|
||||
const { stickerSetId, stickerSetAccessHash } = fromSticker;
|
||||
loadStickers({
|
||||
stickerSetId,
|
||||
stickerSetAccessHash,
|
||||
});
|
||||
} else {
|
||||
loadStickers({
|
||||
stickerSetShortName,
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [isOpen, fromSticker, loadStickers]);
|
||||
}, [isOpen, fromSticker, loadStickers, stickerSetShortName]);
|
||||
|
||||
const handleSelect = useCallback((sticker: ApiSticker) => {
|
||||
sticker = {
|
||||
@ -69,9 +80,11 @@ const StickerSetModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}, [onClose, sendMessage]);
|
||||
|
||||
const handleButtonClick = useCallback(() => {
|
||||
toggleStickerSet({ stickerSetId: fromSticker.stickerSetId });
|
||||
onClose();
|
||||
}, [fromSticker.stickerSetId, onClose, toggleStickerSet]);
|
||||
if (stickerSet) {
|
||||
toggleStickerSet({ stickerSetId: stickerSet.id });
|
||||
onClose();
|
||||
}
|
||||
}, [onClose, stickerSet, toggleStickerSet]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@ -117,8 +130,12 @@ const StickerSetModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
};
|
||||
|
||||
export default memo(withGlobal(
|
||||
(global, { fromSticker }: OwnProps) => {
|
||||
return { stickerSet: selectStickerSet(global, fromSticker.stickerSetId) };
|
||||
(global, { fromSticker, stickerSetShortName }: OwnProps) => {
|
||||
return {
|
||||
stickerSet: fromSticker
|
||||
? selectStickerSet(global, fromSticker.stickerSetId)
|
||||
: selectStickerSetByShortName(global, stickerSetShortName!),
|
||||
};
|
||||
},
|
||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||
'loadStickers',
|
||||
|
@ -27,6 +27,8 @@ import useShowTransition from '../../hooks/useShowTransition';
|
||||
import useBackgroundMode from '../../hooks/useBackgroundMode';
|
||||
import useBeforeUnload from '../../hooks/useBeforeUnload';
|
||||
import useOnChange from '../../hooks/useOnChange';
|
||||
import { processDeepLink } from '../../util/deeplink';
|
||||
import { LOCATION_HASH } from '../../hooks/useHistoryBack';
|
||||
|
||||
import LeftColumn from '../left/LeftColumn';
|
||||
import MiddleColumn from '../middle/MiddleColumn';
|
||||
@ -38,6 +40,7 @@ import Dialogs from './Dialogs.async';
|
||||
import ForwardPicker from './ForwardPicker.async';
|
||||
import SafeLinkModal from './SafeLinkModal.async';
|
||||
import HistoryCalendar from './HistoryCalendar.async';
|
||||
import StickerSetModal from '../common/StickerSetModal.async';
|
||||
|
||||
import './Main.scss';
|
||||
|
||||
@ -55,11 +58,12 @@ type StateProps = {
|
||||
isHistoryCalendarOpen: boolean;
|
||||
shouldSkipHistoryAnimations?: boolean;
|
||||
language?: LangCode;
|
||||
openedStickerSetShortName?: string;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, (
|
||||
'loadAnimatedEmojis' | 'loadNotificationSettings' | 'loadNotificationExceptions' | 'updateIsOnline' |
|
||||
'loadTopInlineBots' | 'loadEmojiKeywords'
|
||||
'loadTopInlineBots' | 'loadEmojiKeywords' | 'openStickerSetShortName'
|
||||
)>;
|
||||
|
||||
const NOTIFICATION_INTERVAL = 1000;
|
||||
@ -82,12 +86,14 @@ const Main: FC<StateProps & DispatchProps> = ({
|
||||
isHistoryCalendarOpen,
|
||||
shouldSkipHistoryAnimations,
|
||||
language,
|
||||
openedStickerSetShortName,
|
||||
loadAnimatedEmojis,
|
||||
loadNotificationSettings,
|
||||
loadNotificationExceptions,
|
||||
updateIsOnline,
|
||||
loadTopInlineBots,
|
||||
loadEmojiKeywords,
|
||||
openStickerSetShortName,
|
||||
}) => {
|
||||
if (DEBUG && !DEBUG_isLogged) {
|
||||
DEBUG_isLogged = true;
|
||||
@ -114,6 +120,12 @@ const Main: FC<StateProps & DispatchProps> = ({
|
||||
loadTopInlineBots, loadEmojiKeywords, language,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (lastSyncTime && LOCATION_HASH.startsWith('#?tgaddr=')) {
|
||||
processDeepLink(decodeURIComponent(LOCATION_HASH.substr('#?tgaddr='.length)));
|
||||
}
|
||||
}, [lastSyncTime]);
|
||||
|
||||
const {
|
||||
transitionClassNames: middleColumnTransitionClassNames,
|
||||
} = useShowTransition(!isLeftColumnShown, undefined, true, undefined, shouldSkipHistoryAnimations);
|
||||
@ -223,6 +235,11 @@ const Main: FC<StateProps & DispatchProps> = ({
|
||||
{audioMessage && <AudioPlayer key={audioMessage.id} message={audioMessage} noUi />}
|
||||
<SafeLinkModal url={safeLinkModalUrl} />
|
||||
<HistoryCalendar isOpen={isHistoryCalendarOpen} />
|
||||
<StickerSetModal
|
||||
isOpen={!!openedStickerSetShortName}
|
||||
onClose={() => openStickerSetShortName({ stickerSetShortName: undefined })}
|
||||
stickerSetShortName={openedStickerSetShortName}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -269,10 +286,11 @@ export default memo(withGlobal(
|
||||
isHistoryCalendarOpen: Boolean(global.historyCalendarSelectedAt),
|
||||
shouldSkipHistoryAnimations: global.shouldSkipHistoryAnimations,
|
||||
language: global.settings.byKey.language,
|
||||
openedStickerSetShortName: global.openedStickerSetShortName,
|
||||
};
|
||||
},
|
||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||
'loadAnimatedEmojis', 'loadNotificationSettings', 'loadNotificationExceptions', 'updateIsOnline',
|
||||
'loadTopInlineBots', 'loadEmojiKeywords',
|
||||
'loadTopInlineBots', 'loadEmojiKeywords', 'openStickerSetShortName',
|
||||
]),
|
||||
)(Main));
|
||||
|
@ -421,6 +421,7 @@ export type GlobalState = {
|
||||
|
||||
safeLinkModalUrl?: string;
|
||||
historyCalendarSelectedAt?: number;
|
||||
openedStickerSetShortName?: string;
|
||||
|
||||
// TODO To be removed in August 2021
|
||||
shouldShowContextMenuHint?: boolean;
|
||||
@ -491,6 +492,7 @@ export type ActionTypes = (
|
||||
'loadStickers' | 'setStickerSearchQuery' | 'loadSavedGifs' | 'setGifSearchQuery' | 'searchMoreGifs' |
|
||||
'faveSticker' | 'unfaveSticker' | 'toggleStickerSet' | 'loadAnimatedEmojis' |
|
||||
'loadStickersForEmoji' | 'clearStickersForEmoji' | 'loadEmojiKeywords' | 'loadGreetingStickers' |
|
||||
'openStickerSetShortName' |
|
||||
// bots
|
||||
'clickInlineButton' | 'sendBotCommand' | 'loadTopInlineBots' | 'queryInlineBot' | 'sendInlineBotResult' |
|
||||
'resetInlineBot' | 'restartBot' |
|
||||
|
@ -9,6 +9,7 @@ import { areSortedArraysEqual } from '../util/iteratees';
|
||||
// TODO: may be different on other devices such as iPad, maybe take dpi into account?
|
||||
const SAFARI_EDGE_BACK_GESTURE_LIMIT = 300;
|
||||
const SAFARI_EDGE_BACK_GESTURE_DURATION = 350;
|
||||
export const LOCATION_HASH = window.location.hash;
|
||||
|
||||
type HistoryState = {
|
||||
currentIndex: number;
|
||||
@ -54,7 +55,7 @@ if (IS_IOS) {
|
||||
window.addEventListener('popstate', handleTouchEnd);
|
||||
}
|
||||
|
||||
window.history.replaceState({ index: historyState.currentIndex }, '');
|
||||
window.history.replaceState({ index: historyState.currentIndex }, '', window.location.pathname);
|
||||
|
||||
export default function useHistoryBack(
|
||||
isActive: boolean | undefined,
|
||||
|
@ -24,6 +24,7 @@ import {
|
||||
importLegacySession,
|
||||
clearLegacySessions,
|
||||
} from '../../../util/sessions';
|
||||
import { forceWebsync } from '../../../util/websync';
|
||||
|
||||
addReducer('initApi', (global: GlobalState, actions) => {
|
||||
(async () => {
|
||||
@ -128,6 +129,7 @@ addReducer('signOut', () => {
|
||||
try {
|
||||
await unsubscribe();
|
||||
await callApi('destroy');
|
||||
await forceWebsync(false);
|
||||
} catch (err) {
|
||||
// Do nothing
|
||||
}
|
||||
|
@ -83,10 +83,10 @@ addReducer('loadFeaturedStickers', (global) => {
|
||||
});
|
||||
|
||||
addReducer('loadStickers', (global, actions, payload) => {
|
||||
const { stickerSetId } = payload!;
|
||||
const { stickerSetId, stickerSetShortName } = payload!;
|
||||
let { stickerSetAccessHash } = payload!;
|
||||
|
||||
if (!stickerSetAccessHash) {
|
||||
if (!stickerSetAccessHash && !stickerSetShortName) {
|
||||
const stickerSet = selectStickerSet(global, stickerSetId);
|
||||
if (!stickerSet) {
|
||||
return;
|
||||
@ -95,7 +95,7 @@ addReducer('loadStickers', (global, actions, payload) => {
|
||||
stickerSetAccessHash = stickerSet.accessHash;
|
||||
}
|
||||
|
||||
void loadStickers(stickerSetId, stickerSetAccessHash);
|
||||
void loadStickers(stickerSetId, stickerSetAccessHash, stickerSetShortName);
|
||||
});
|
||||
|
||||
addReducer('loadAnimatedEmojis', () => {
|
||||
@ -257,8 +257,9 @@ async function loadFeaturedStickers(hash = 0) {
|
||||
));
|
||||
}
|
||||
|
||||
async function loadStickers(stickerSetId: string, accessHash: string) {
|
||||
const stickerSet = await callApi('fetchStickers', { stickerSetId, accessHash });
|
||||
async function loadStickers(stickerSetId: string, accessHash: string, stickerSetShortName?: string) {
|
||||
const stickerSet = await callApi('fetchStickers',
|
||||
{ stickerSetShortName, stickerSetId, accessHash });
|
||||
if (!stickerSet) {
|
||||
return;
|
||||
}
|
||||
@ -356,6 +357,14 @@ addReducer('clearStickersForEmoji', (global) => {
|
||||
};
|
||||
});
|
||||
|
||||
addReducer('openStickerSetShortName', (global, actions, payload) => {
|
||||
const { stickerSetShortName } = payload!;
|
||||
return {
|
||||
...global,
|
||||
openedStickerSetShortName: stickerSetShortName,
|
||||
};
|
||||
});
|
||||
|
||||
async function searchStickers(query: string, hash = 0) {
|
||||
const result = await callApi('searchStickers', { query, hash });
|
||||
|
||||
|
@ -17,6 +17,7 @@ import { subscribe } from '../../../util/notifications';
|
||||
import { updateUser } from '../../reducers';
|
||||
import { setLanguage } from '../../../util/langProvider';
|
||||
import { selectNotifySettings } from '../../selectors';
|
||||
import { forceWebsync } from '../../../util/websync';
|
||||
|
||||
addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
||||
if (DEBUG) {
|
||||
@ -90,6 +91,8 @@ function onUpdateAuthorizationState(update: ApiUpdateAuthorizationState) {
|
||||
|
||||
switch (authState) {
|
||||
case 'authorizationStateLoggingOut':
|
||||
void forceWebsync(false);
|
||||
|
||||
setGlobal({
|
||||
...global,
|
||||
isLoggingOut: true,
|
||||
@ -119,6 +122,8 @@ function onUpdateAuthorizationState(update: ApiUpdateAuthorizationState) {
|
||||
break;
|
||||
}
|
||||
|
||||
void forceWebsync(true);
|
||||
|
||||
setGlobal({
|
||||
...global,
|
||||
isLoggingOut: false,
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
import { setLanguage } from '../../../util/langProvider';
|
||||
import switchTheme from '../../../util/switchTheme';
|
||||
import { selectTheme } from '../../selectors';
|
||||
import { startWebsync } from '../../../util/websync';
|
||||
|
||||
const HISTORY_ANIMATION_DURATION = 450;
|
||||
|
||||
@ -28,6 +29,7 @@ addReducer('init', (global) => {
|
||||
document.body.classList.add(`animation-level-${animationLevel}`);
|
||||
document.body.classList.add(IS_TOUCH_ENV ? 'is-touch-env' : 'is-pointer-env');
|
||||
switchTheme(theme, animationLevel === ANIMATION_LEVEL_MAX);
|
||||
startWebsync();
|
||||
|
||||
if (IS_SAFARI) {
|
||||
document.body.classList.add('is-safari');
|
||||
|
@ -18,6 +18,10 @@ export function selectStickerSet(global: GlobalState, id: string) {
|
||||
return global.stickers.setsById[id];
|
||||
}
|
||||
|
||||
export function selectStickerSetByShortName(global: GlobalState, shortName: string) {
|
||||
return Object.values(global.stickers.setsById).find((l) => l.shortName.toLowerCase() === shortName.toLowerCase());
|
||||
}
|
||||
|
||||
export function selectStickersForEmoji(global: GlobalState, emoji: string) {
|
||||
const stickerSets = Object.values(global.stickers.setsById);
|
||||
let stickersForEmoji: ApiSticker[] = [];
|
||||
|
@ -30,9 +30,13 @@ self.addEventListener('activate', (e) => {
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
self.addEventListener('fetch', (e: FetchEvent) => {
|
||||
e.respondWith((() => {
|
||||
const { url } = e.request;
|
||||
const { url } = e.request;
|
||||
|
||||
if (url.includes('_websync_')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
e.respondWith((() => {
|
||||
if (url.includes('/progressive/')) {
|
||||
return respondForProgressive(e);
|
||||
}
|
||||
@ -43,6 +47,8 @@ self.addEventListener('fetch', (e: FetchEvent) => {
|
||||
|
||||
return fetch(e.request);
|
||||
})());
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
self.addEventListener('push', handlePush);
|
||||
|
54
src/util/deeplink.ts
Normal file
54
src/util/deeplink.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { getDispatch } from '../lib/teact/teactn';
|
||||
|
||||
export const processDeepLink = (url: string) => {
|
||||
const { protocol, searchParams, pathname } = new URL(url);
|
||||
|
||||
if (protocol !== 'tg:') return;
|
||||
|
||||
const { openChatByUsername, openStickerSetShortName } = getDispatch();
|
||||
|
||||
const method = pathname.replace(/^\/\//, '');
|
||||
const params: Record<string, string> = {};
|
||||
searchParams.forEach((value, key) => {
|
||||
params[key] = value;
|
||||
});
|
||||
|
||||
switch (method) {
|
||||
case 'resolve': {
|
||||
const {
|
||||
domain,
|
||||
} = params;
|
||||
|
||||
if (domain !== 'telegrampassport') {
|
||||
openChatByUsername({
|
||||
username: domain,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'privatepost':
|
||||
|
||||
break;
|
||||
case 'bg':
|
||||
|
||||
break;
|
||||
case 'join':
|
||||
|
||||
break;
|
||||
case 'addstickers': {
|
||||
const { set } = params;
|
||||
|
||||
openStickerSetShortName({
|
||||
stickerSetShortName: set,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'msg':
|
||||
|
||||
break;
|
||||
default:
|
||||
// Unsupported deeplink
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
82
src/util/websync.ts
Normal file
82
src/util/websync.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import { APP_VERSION } from '../config';
|
||||
import { getGlobal } from '../lib/teact/teactn';
|
||||
import { hasStoredSession } from './sessions';
|
||||
|
||||
const WEBSYNC_URLS = [
|
||||
't.me',
|
||||
'telegram.me',
|
||||
].map((domain) => `//${domain}/_websync_?`);
|
||||
const WEBSYNC_VERSION = `${APP_VERSION} Z`;
|
||||
const WEBSYNC_KEY = 'tgme_sync';
|
||||
const WEBSYNC_TIMEOUT = 86400;
|
||||
|
||||
const getTs = () => {
|
||||
return Math.floor(Number(new Date()) / 1000);
|
||||
};
|
||||
|
||||
const saveSync = (authed: boolean) => {
|
||||
const ts = getTs();
|
||||
localStorage.setItem(WEBSYNC_KEY, JSON.stringify({
|
||||
canRedirect: authed,
|
||||
ts,
|
||||
}));
|
||||
};
|
||||
|
||||
let lastTimeout: NodeJS.Timeout | undefined;
|
||||
|
||||
export const forceWebsync = (authed: boolean) => {
|
||||
const currentTs = getTs();
|
||||
|
||||
const { canRedirect, ts } = JSON.parse(localStorage.getItem(WEBSYNC_KEY) || '{}');
|
||||
|
||||
if (canRedirect !== authed || ts + WEBSYNC_TIMEOUT <= currentTs) {
|
||||
return Promise.all(WEBSYNC_URLS.map((url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
|
||||
const removeElement = () => !!document.body.removeChild(script);
|
||||
|
||||
script.src = url + new URLSearchParams({
|
||||
authed: Number(authed).toString(),
|
||||
version: WEBSYNC_VERSION,
|
||||
});
|
||||
|
||||
document.body.appendChild(script);
|
||||
|
||||
script.onload = () => {
|
||||
saveSync(authed);
|
||||
removeElement();
|
||||
if (lastTimeout) {
|
||||
clearTimeout(lastTimeout);
|
||||
lastTimeout = undefined;
|
||||
}
|
||||
startWebsync();
|
||||
resolve();
|
||||
};
|
||||
|
||||
script.onerror = () => {
|
||||
removeElement();
|
||||
reject();
|
||||
};
|
||||
});
|
||||
}));
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
export function startWebsync() {
|
||||
if (lastTimeout !== undefined) return;
|
||||
const currentTs = getTs();
|
||||
|
||||
const { ts } = JSON.parse(localStorage.getItem(WEBSYNC_KEY) || '{}');
|
||||
|
||||
const timeout = WEBSYNC_TIMEOUT - (currentTs - ts);
|
||||
|
||||
lastTimeout = setTimeout(() => {
|
||||
const { authState } = getGlobal();
|
||||
|
||||
const authed = authState === 'authorizationStateReady' || hasStoredSession(true);
|
||||
forceWebsync(authed);
|
||||
}, Math.max(0, timeout * 1000));
|
||||
}
|
Loading…
Reference in New Issue
Block a user