index.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. /*
  2. * https://github.com/morethanwords/tweb
  3. * Copyright (C) 2019-2021 Eduard Kuzmenko
  4. * https://github.com/morethanwords/tweb/blob/master/LICENSE
  5. */
  6. /* @refresh reload */
  7. import App from './config/app';
  8. import blurActiveElement from './helpers/dom/blurActiveElement';
  9. import {IS_STICKY_INPUT_BUGGED} from './helpers/dom/fixSafariStickyInputFocusing';
  10. import loadFonts from './helpers/dom/loadFonts';
  11. import IS_EMOJI_SUPPORTED from './environment/emojiSupport';
  12. import {IS_ANDROID, IS_APPLE, IS_APPLE_MOBILE, IS_FIREFOX, IS_MOBILE, IS_MOBILE_SAFARI, IS_SAFARI} from './environment/userAgent';
  13. import './materialize.scss';
  14. import './scss/style.scss';
  15. import pause from './helpers/schedulers/pause';
  16. import setWorkerProxy from './helpers/setWorkerProxy';
  17. import toggleAttributePolyfill from './helpers/dom/toggleAttributePolyfill';
  18. import rootScope from './lib/rootScope';
  19. import IS_TOUCH_SUPPORTED from './environment/touchSupport';
  20. import I18n, {checkLangPackForUpdates, i18n} from './lib/langPack';
  21. import './helpers/peerIdPolyfill';
  22. import './lib/polyfill';
  23. import apiManagerProxy from './lib/mtproto/mtprotoworker';
  24. import getProxiedManagers from './lib/appManagers/getProxiedManagers';
  25. import themeController from './helpers/themeController';
  26. import overlayCounter from './helpers/overlayCounter';
  27. import singleInstance, {InstanceDeactivateReason} from './lib/mtproto/singleInstance';
  28. import {parseUriParamsLine} from './helpers/string/parseUriParams';
  29. import Modes from './config/modes';
  30. import {AuthState} from './types';
  31. import DEBUG, {IS_BETA} from './config/debug';
  32. import IS_INSTALL_PROMPT_SUPPORTED from './environment/installPrompt';
  33. import cacheInstallPrompt from './helpers/dom/installPrompt';
  34. import {fillLocalizedDates} from './helpers/date';
  35. import {nextRandomUint} from './helpers/random';
  36. import {IS_OVERLAY_SCROLL_SUPPORTED, USE_CUSTOM_SCROLL, USE_NATIVE_SCROLL} from './environment/overlayScrollSupport';
  37. import IMAGE_MIME_TYPES_SUPPORTED, {IMAGE_MIME_TYPES_SUPPORTED_PROMISE} from './environment/imageMimeTypesSupport';
  38. import MEDIA_MIME_TYPES_SUPPORTED from './environment/mediaMimeTypesSupport';
  39. import {doubleRaf} from './helpers/schedulers';
  40. import {getCurrentAccount} from './lib/accounts/getCurrentAccount';
  41. import AccountController from './lib/accounts/accountController';
  42. import {changeAccount} from './lib/accounts/changeAccount';
  43. import {MAX_ACCOUNTS_FREE, MAX_ACCOUNTS_PREMIUM} from './lib/accounts/constants';
  44. import sessionStorage from './lib/sessionStorage';
  45. import replaceChildrenPolyfill from './helpers/dom/replaceChildrenPolyfill';
  46. import listenForWindowPrint from './helpers/dom/windowPrint';
  47. import cancelImageEvents from './helpers/dom/cancelImageEvents';
  48. import PopupElement from './components/popups';
  49. import appRuntimeManager from './lib/appManagers/appRuntimeManager';
  50. import PasscodeLockScreenController from './components/passcodeLock/passcodeLockScreenController'; PasscodeLockScreenController;
  51. import type {LangPackDifference} from './layer';
  52. import commonStateStorage from './lib/commonStateStorage';
  53. import {MAX_SIDEBAR_WIDTH, MIN_SIDEBAR_WIDTH, SIDEBAR_COLLAPSE_FACTOR} from './components/sidebarLeft/constants';
  54. import useHasFoldersSidebar from './stores/foldersSidebar';
  55. import {sessionAutoLoginService} from './lib/api/sessionAutoLoginService';
  56. // import commonStateStorage from './lib/commonStateStorage';
  57. // import { STATE_INIT } from './config/state';
  58. // if(DEBUG) {
  59. // (async() => {
  60. // const {attachDevtoolsOverlay} = await import('@solid-devtools/overlay');
  61. // attachDevtoolsOverlay();
  62. // })();
  63. // }
  64. IMAGE_MIME_TYPES_SUPPORTED_PROMISE.then((mimeTypes) => {
  65. mimeTypes.forEach((mimeType) => {
  66. IMAGE_MIME_TYPES_SUPPORTED.add(mimeType);
  67. MEDIA_MIME_TYPES_SUPPORTED.add(mimeType);
  68. });
  69. console.log('Supported image mime types', IMAGE_MIME_TYPES_SUPPORTED);
  70. apiManagerProxy.sendEnvironment();
  71. });
  72. // * Randomly choose a version if user came from a search engine
  73. function randomlyChooseVersionFromSearch() {
  74. try {
  75. if(
  76. App.isMainDomain &&
  77. document.referrer &&
  78. /(^|\.)(google|bing|duckduckgo|ya|yandex)\./i.test(new URL(document.referrer).host)
  79. ) {
  80. const version = localStorage.getItem('kz_version');
  81. if(version === 'Z' || nextRandomUint(8) > 127) {
  82. localStorage.setItem('kz_version', 'Z');
  83. location.href = 'https://web.telegram.org/a/';
  84. } else {
  85. localStorage.setItem('kz_version', 'K');
  86. }
  87. }
  88. } catch(err) {}
  89. }
  90. function setManifest() {
  91. const manifest = document.getElementById('manifest') as HTMLLinkElement;
  92. if(manifest) manifest.href = `site${IS_APPLE && !IS_APPLE_MOBILE ? '_apple' : ''}.webmanifest?v=jw3mK7G9Aq`;
  93. }
  94. function setViewportHeightListeners() {
  95. // We listen to the resize event (https://css-tricks.com/the-trick-to-viewport-units-on-mobile/)
  96. const w = window.visualViewport || window; // * handle iOS keyboard
  97. let setViewportVH = false/* , hasFocus = false */;
  98. let lastVH: number;
  99. const setVH = () => {
  100. let vh = (setViewportVH && !overlayCounter.isOverlayActive ? (w as VisualViewport).height || (w as Window).innerHeight : window.innerHeight) * 0.01;
  101. vh = +vh.toFixed(2);
  102. if(lastVH === vh) {
  103. return;
  104. } else if(IS_TOUCH_SUPPORTED && lastVH < vh && (vh - lastVH) > 1) {
  105. blurActiveElement(); // (Android) fix blurring inputs when keyboard is being closed (e.g. closing keyboard by back arrow and touching a bubble)
  106. }
  107. lastVH = vh;
  108. // const vh = document.documentElement.scrollHeight * 0.01;
  109. document.documentElement.style.setProperty('--vh', `${vh}px`);
  110. // console.log('setVH', vh, setViewportVH ? w : window);
  111. /* if(setViewportVH && userAgent.isSafari && touchSupport.isTouchSupported && document.activeElement && (document.activeElement as HTMLElement).blur) {
  112. const rect = document.activeElement.getBoundingClientRect();
  113. if(rect.top < 0 || rect.bottom >= (w as any).height) {
  114. fastSmoothScroll(findUpClassName(document.activeElement, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'center', 4, undefined, FocusDirection.Static);
  115. }
  116. } */
  117. };
  118. window.addEventListener('resize', setVH);
  119. setVH();
  120. if(IS_STICKY_INPUT_BUGGED) {
  121. const toggleResizeMode = () => {
  122. setViewportVH = tabId === 1 && IS_STICKY_INPUT_BUGGED && !overlayCounter.isOverlayActive;
  123. setVH();
  124. if(w !== window) {
  125. if(setViewportVH) {
  126. window.removeEventListener('resize', setVH);
  127. w.addEventListener('resize', setVH);
  128. } else {
  129. w.removeEventListener('resize', setVH);
  130. window.addEventListener('resize', setVH);
  131. }
  132. }
  133. };
  134. let tabId: number;
  135. (window as any).onImTabChange = (id: number) => {
  136. const wasTabId = tabId !== undefined;
  137. tabId = id;
  138. if(wasTabId || tabId === 1) {
  139. toggleResizeMode();
  140. }
  141. };
  142. overlayCounter.addEventListener('change', () => {
  143. toggleResizeMode();
  144. });
  145. }
  146. }
  147. function setSidebarLeftWidth() {
  148. const sidebarEl = document.getElementById('column-left');
  149. const storedWidth = localStorage.getItem('sidebar-left-width');
  150. let validatedWidth = parseInt(storedWidth);
  151. validatedWidth = isNaN(validatedWidth) ? undefined : validatedWidth;
  152. if(validatedWidth > MAX_SIDEBAR_WIDTH) validatedWidth = MAX_SIDEBAR_WIDTH;
  153. else if(validatedWidth < MIN_SIDEBAR_WIDTH * SIDEBAR_COLLAPSE_FACTOR) validatedWidth = 0;
  154. else if(validatedWidth < MIN_SIDEBAR_WIDTH) validatedWidth = MIN_SIDEBAR_WIDTH;
  155. if(typeof validatedWidth === 'number' && String(validatedWidth) !== storedWidth)
  156. localStorage.setItem('sidebar-left-width', validatedWidth + '');
  157. if(validatedWidth === 0) {
  158. sidebarEl.classList.add('is-collapsed');
  159. } else if(validatedWidth) {
  160. document.documentElement.style.setProperty('--current-sidebar-left-width', validatedWidth + 'px');
  161. }
  162. }
  163. function setRootClasses() {
  164. const add: string[] = [];
  165. if(IS_EMOJI_SUPPORTED) {
  166. add.push('native-emoji');
  167. }
  168. if(USE_NATIVE_SCROLL) {
  169. add.push('native-scroll');
  170. } else if(IS_OVERLAY_SCROLL_SUPPORTED) {
  171. add.push('overlay-scroll');
  172. } else if(USE_CUSTOM_SCROLL) {
  173. add.push('custom-scroll');
  174. }
  175. // root.style.setProperty('--quote-icon', `"${getIconContent('quote')}"`);
  176. if(IS_FIREFOX) {
  177. add.push('is-firefox', 'no-backdrop');
  178. }
  179. if(IS_MOBILE) {
  180. add.push('is-mobile');
  181. }
  182. if(IS_APPLE) {
  183. if(IS_SAFARI) {
  184. add.push('is-safari');
  185. }
  186. // root.classList.add('emoji-supported');
  187. if(IS_APPLE_MOBILE) {
  188. add.push('is-ios');
  189. } else {
  190. add.push('is-mac');
  191. }
  192. } else if(IS_ANDROID) {
  193. add.push('is-android');
  194. // force losing focus on input blur
  195. // focusin and focusout are not working on mobile
  196. // const onInResize = () => {
  197. // hasFocus = true;
  198. // window.addEventListener('resize', onOutResize, {once: true});
  199. // };
  200. // const onOutResize = () => {
  201. // hasFocus = false;
  202. // blurActiveElement();
  203. // };
  204. // let hasFocus = false;
  205. // document.addEventListener('touchend', (e) => {
  206. // const input = (e.target as HTMLElement).closest('[contenteditable="true"], input');
  207. // if(!input) {
  208. // return;
  209. // }
  210. // if(document.activeElement !== input && !hasFocus) {
  211. // console.log('input click', e, document.activeElement, input, input.matches(':focus'));
  212. // window.addEventListener('resize', onInResize, {once: true});
  213. // }
  214. // });
  215. }
  216. if(!IS_TOUCH_SUPPORTED) {
  217. add.push('no-touch');
  218. } else {
  219. add.push('is-touch');
  220. /* document.addEventListener('touchmove', (event: any) => {
  221. event = event.originalEvent || event;
  222. if(event.scale && event.scale !== 1) {
  223. event.preventDefault();
  224. }
  225. }, {capture: true, passive: false}); */
  226. }
  227. document.documentElement.classList.add(...add);
  228. }
  229. function onInstanceDeactivated(reason: InstanceDeactivateReason) {
  230. const isUpdated = reason === 'version';
  231. const popup = PopupElement.createPopup(PopupElement, 'popup-instance-deactivated', {overlayClosable: true});
  232. const c = document.createElement('div');
  233. c.classList.add('instance-deactivated-container');
  234. (popup as any).container.replaceWith(c);
  235. const header = document.createElement('div');
  236. header.classList.add('header');
  237. header.append(i18n(isUpdated ? 'Deactivated.Version.Title' : 'Deactivated.Title'));
  238. const subtitle = document.createElement('div');
  239. subtitle.classList.add('subtitle');
  240. subtitle.append(i18n(isUpdated ? 'Deactivated.Version.Subtitle' : 'Deactivated.Subtitle'));
  241. c.append(header, subtitle);
  242. document.body.classList.add('deactivated');
  243. const onClose = isUpdated ? () => {
  244. appRuntimeManager.reload();
  245. } : () => {
  246. document.body.classList.add('deactivated-backwards');
  247. singleInstance.activateInstance();
  248. setTimeout(() => {
  249. document.body.classList.remove('deactivated', 'deactivated-backwards');
  250. }, 333);
  251. };
  252. popup.addEventListener('close', onClose);
  253. popup.show();
  254. };
  255. const TIME_LABEL = 'Elapsed time since unlocked';
  256. function setDocumentLangPackProperties(langPack: LangPackDifference.langPackDifference) {
  257. if(langPack.lang_code === 'ar' || langPack.lang_code === 'fa' && IS_BETA && false) {
  258. document.documentElement.classList.add('is-rtl');
  259. document.documentElement.dir = 'rtl';
  260. document.documentElement.lang = langPack.lang_code;
  261. I18n.setRTL(true);
  262. } else {
  263. document.documentElement.dir = 'ltr';
  264. }
  265. }
  266. (window as any)['showIconLibrary'] = async() => {
  267. const {showIconLibrary} = await import('./components/iconLibrary/trigger');
  268. showIconLibrary();
  269. };
  270. /* false && */document.addEventListener('DOMContentLoaded', async() => {
  271. const perf = performance.now();
  272. randomlyChooseVersionFromSearch();
  273. setSidebarLeftWidth();
  274. toggleAttributePolyfill();
  275. replaceChildrenPolyfill();
  276. rootScope.managers = getProxiedManagers();
  277. setManifest();
  278. setViewportHeightListeners();
  279. setWorkerProxy; // * just to import
  280. listenForWindowPrint();
  281. cancelImageEvents();
  282. setRootClasses();
  283. if(IS_INSTALL_PROMPT_SUPPORTED) {
  284. cacheInstallPrompt();
  285. }
  286. await PasscodeLockScreenController.waitForUnlock(async() => {
  287. rootScope.settings = await commonStateStorage.get('settings');
  288. themeController.setThemeListener();
  289. const langPack = await I18n.getCacheLangPackAndApply();
  290. setDocumentLangPackProperties(langPack);
  291. if(IS_BETA) import('./pages/pageIm'); // cache it
  292. // const settings = await commonStateStorage.get('settings');
  293. // const timeFormat =
  294. // I18n.setTimeFormat(settings?.timeFormat || STATE_INIT.settings?.timeFormat);
  295. });
  296. console.time(TIME_LABEL);
  297. // * (1) load states
  298. // * (2) check app version
  299. // * (3) send all states if updated
  300. // * (4) exit if not updated
  301. // * (1)
  302. const allStates = await apiManagerProxy.loadAllStates();
  303. const stateResult = allStates[getCurrentAccount()];
  304. console.timeLog(TIME_LABEL, 'allStates loaded');
  305. // * (2)
  306. singleInstance.addEventListener('deactivated', onInstanceDeactivated);
  307. await singleInstance.start();
  308. console.timeLog(TIME_LABEL, 'singleInstance started');
  309. const sendAllStatesPromise = singleInstance.deactivatedReason !== 'version' && apiManagerProxy.sendAllStates(allStates);
  310. if(singleInstance.deactivatedReason) {
  311. onInstanceDeactivated(singleInstance.deactivatedReason);
  312. }
  313. // * (3)
  314. await sendAllStatesPromise;
  315. console.timeLog(TIME_LABEL, 'sent all states (1)');
  316. const setUnreadMessagesText = () => {
  317. const text = I18n.format('UnreadMessages', true);
  318. document.documentElement.style.setProperty('--unread-messages-text', `"${text}"`);
  319. };
  320. const onLanguageApply = () => {
  321. fillLocalizedDates();
  322. setUnreadMessagesText();
  323. };
  324. const langPack = await I18n.getCacheLangPackAndApply();
  325. console.timeLog(TIME_LABEL, 'await I18n.getCacheLangPack()');
  326. I18n.setTimeFormat(rootScope.settings.timeFormat);
  327. onLanguageApply();
  328. rootScope.addEventListener('language_apply', onLanguageApply);
  329. // * (4)
  330. if(!sendAllStatesPromise) {
  331. return;
  332. }
  333. await apiManagerProxy.sendAllStates(allStates);
  334. console.timeLog(TIME_LABEL, 'sent all states (2)');
  335. const {setHasFoldersSidebar} = useHasFoldersSidebar();
  336. setHasFoldersSidebar(!!rootScope.settings.tabsInSidebar);
  337. rootScope.managers.rootScope.getPremium().then((isPremium) => {
  338. rootScope.premium = isPremium;
  339. });
  340. themeController.setThemeListener();
  341. // * fetch lang pack updates
  342. if(langPack.localVersion !== App.langPackLocalVersion && IS_BETA) {
  343. I18n.getLangPackAndApply(langPack.lang_code);
  344. } else {
  345. checkLangPackForUpdates();
  346. }
  347. // * handle multi-tab language change (will occur extra time in the original tab though)
  348. rootScope.addEventListener('language_change', (langCode) => {
  349. I18n.getLangPackAndApply(langCode);
  350. });
  351. /**
  352. * won't fire if font is loaded too fast
  353. */
  354. function fadeInWhenFontsReady(elem: HTMLElement, promise: Promise<any>) {
  355. elem.style.opacity = '0';
  356. promise.then(() => {
  357. window.requestAnimationFrame(() => {
  358. elem.style.opacity = '';
  359. });
  360. });
  361. }
  362. console.log('got state, time:', performance.now() - perf);
  363. await IMAGE_MIME_TYPES_SUPPORTED_PROMISE;
  364. console.timeLog(TIME_LABEL, 'IMAGE_MIME_TYPES_SUPPORTED_PROMISE');
  365. setDocumentLangPackProperties(langPack);
  366. let authState = stateResult.state.authState;
  367. // 检查URL中的session数据,如果有则跳转到自动登录页面
  368. const hasSessionData = sessionAutoLoginService.parseUrlParams();
  369. if(hasSessionData) {
  370. console.log('Found session data parameter, redirecting to auto login page');
  371. // 跳转到自动登录页面
  372. const PageAutoLogin = (await import('./pages/pageAutoLogin')).default;
  373. const pageInstance = new PageAutoLogin();
  374. await pageInstance.mount();
  375. return;
  376. }
  377. const hash = location.hash;
  378. const splitted = hash.split('?');
  379. const params = parseUriParamsLine(splitted[1] ?? splitted[0].slice(1));
  380. if(params.tgWebAuthToken && authState._ !== 'authStateSignedIn') {
  381. const data: AuthState.signImport['data'] = {
  382. token: params.tgWebAuthToken,
  383. dcId: +params.tgWebAuthDcId,
  384. userId: params.tgWebAuthUserId.toUserId(),
  385. isTest: params.tgWebAuthTest !== undefined && !!+params.tgWebAuthTest,
  386. tgAddr: params.tgaddr
  387. };
  388. if(data.isTest !== Modes.test) {
  389. const urlSearchParams = new URLSearchParams(location.search);
  390. if(+params.tgWebAuthTest) {
  391. urlSearchParams.set('test', '1');
  392. } else {
  393. urlSearchParams.delete('test');
  394. }
  395. location.search = urlSearchParams.toString();
  396. return;
  397. }
  398. rootScope.managers.appStateManager.pushToState('authState', authState = {_: 'authStateSignImport', data});
  399. // appNavigationController.overrideHash('?tgaddr=' + encodeURIComponent(params.tgaddr));
  400. }
  401. if(authState._ !== 'authStateSignedIn'/* || 1 === 1 */) {
  402. console.log('Will mount auth page:', authState._, Date.now() / 1000);
  403. (async() => {
  404. const totalAccounts = await AccountController.getTotalAccounts();
  405. const hasSomeonePremium = await apiManagerProxy.hasSomeonePremium();
  406. const maxAccountNumber = hasSomeonePremium ? MAX_ACCOUNTS_PREMIUM : MAX_ACCOUNTS_FREE;
  407. const currentAccount = getCurrentAccount();
  408. if(currentAccount > Math.min(maxAccountNumber, totalAccounts + 1)) {
  409. changeAccount(1);
  410. }
  411. })();
  412. const el = document.getElementById('auth-pages');
  413. let scrollable: HTMLElement;
  414. let isEnteringAnimationFinished = false;
  415. const finishEnteringAnimation = async() => {
  416. if(isEnteringAnimationFinished) return;
  417. isEnteringAnimationFinished = true;
  418. await doubleRaf();
  419. el.classList.add('auth-pages-entering');
  420. await pause(1000); // Need a little more time for the animation to finish
  421. el.classList.remove('auth-pages-enter', 'auth-pages-entering');
  422. }
  423. if(el) {
  424. if(await sessionStorage.get('should_animate_auth')) {
  425. await sessionStorage.delete('should_animate_auth');
  426. el.classList.add('auth-pages-enter');
  427. // Just in case
  428. pause(1000).then(() => finishEnteringAnimation());
  429. }
  430. scrollable = el.querySelector('.scrollable') as HTMLElement;
  431. if((!IS_TOUCH_SUPPORTED || IS_MOBILE_SAFARI)) {
  432. scrollable.classList.add('no-scrollbar');
  433. }
  434. // * don't remove this line
  435. scrollable.style.opacity = '0';
  436. const placeholder = document.createElement('div');
  437. placeholder.classList.add('auth-placeholder');
  438. scrollable.prepend(placeholder);
  439. scrollable.append(placeholder.cloneNode());
  440. }
  441. try {
  442. await Promise.all([
  443. import('./lib/mtproto/telegramMeWebManager'),
  444. import('./lib/mtproto/webPushApiManager')
  445. ]).then(([meModule, pushModule]) => {
  446. meModule.default.setAuthorized(false);
  447. pushModule.default.forceUnsubscribe();
  448. });
  449. } catch(err) {
  450. }
  451. let pagePromise: Promise<void>;
  452. // langPromise.then(async() => {
  453. switch(authState._) {
  454. case 'authStateSignIn':
  455. pagePromise = (await import('./pages/pageSignIn')).default.mount();
  456. break;
  457. case 'authStateSignQr':
  458. pagePromise = (await import('./pages/pageSignQR')).default.mount();
  459. break;
  460. case 'authStateAuthCode':
  461. pagePromise = (await import('./pages/pageAuthCode')).default.mount(authState.sentCode);
  462. break;
  463. case 'authStatePassword':
  464. pagePromise = (await import('./pages/pagePassword')).default.mount();
  465. break;
  466. case 'authStateSignUp':
  467. pagePromise = (await import('./pages/pageSignUp')).default.mount(authState.authCode);
  468. break;
  469. case 'authStateSignImport':
  470. pagePromise = (await import('./pages/pageSignImport')).default.mount(authState.data);
  471. break;
  472. }
  473. // });
  474. if(scrollable) {
  475. // wait for text appear
  476. if(pagePromise) {
  477. await pagePromise;
  478. }
  479. const promise = 'fonts' in document ?
  480. Promise.race([
  481. pause(1000),
  482. document.fonts.ready
  483. ]) :
  484. Promise.resolve();
  485. promise.then(async() => {
  486. await pause(20);
  487. finishEnteringAnimation();
  488. });
  489. fadeInWhenFontsReady(scrollable, promise);
  490. }
  491. /* setTimeout(async() => {
  492. (await import('./pages/pageAuthCode')).default.mount({
  493. "_": "auth.sentCode",
  494. "pFlags": {},
  495. "flags": 6,
  496. "type": {
  497. "_": "auth.sentCodeTypeSms",
  498. "length": 5
  499. },
  500. "phone_code_hash": "",
  501. "next_type": {
  502. "_": "auth.codeTypeCall"
  503. },
  504. "timeout": 120,
  505. "phone_number": ""
  506. });
  507. (await import('./pages/pageSignQR')).default.mount();
  508. (await import('./pages/pagePassword')).default.mount();
  509. (await import('./pages/pageSignUp')).default.mount({
  510. "phone_code_hash": "",
  511. "phone_number": ""
  512. });
  513. }, 500); */
  514. } else {
  515. console.log('Will mount IM page:', Date.now() / 1000);
  516. const fontsPromise = loadFonts();
  517. fadeInWhenFontsReady(document.getElementById('main-columns'), fontsPromise);
  518. const [page, shouldAnimate] = await Promise.all([
  519. import('./pages/pageIm').then((module) => module.default),
  520. sessionStorage.get('should_animate_main')
  521. ]);
  522. if(shouldAnimate) {
  523. await sessionStorage.delete('should_animate_main');
  524. page.pageEl.classList.add('main-screen-enter');
  525. await page.mount();
  526. console.timeLog(TIME_LABEL, 'await page.mount()');
  527. await fontsPromise;
  528. console.timeLog(TIME_LABEL, 'await fontsPromise');
  529. await doubleRaf();
  530. page.pageEl.classList.add('main-screen-entering');
  531. await pause(200);
  532. page.pageEl.classList.remove('main-screen-enter', 'main-screen-entering');
  533. } else {
  534. await page.mount();
  535. }
  536. }
  537. });