1 line
127 KiB
Plaintext
1 line
127 KiB
Plaintext
{"version":3,"sources":["webpack:///./src/components/languageChangeButton.ts","webpack:///./src/helpers/fixBase64String.ts","webpack:///./src/components/telInputField.ts","webpack:///./src/components/ripple.ts","webpack:///./src/pages/pageSignIn.ts","webpack:///./src/pages/pageSignQR.ts","webpack:///./src/helpers/dom/clickEvent.ts","webpack:///./src/components/button.ts","webpack:///./src/components/misc.ts","webpack:///./src/components/scrollable.ts","webpack:///./src/components/appNavigationController.ts","webpack:///./src/components/checkboxField.ts","webpack:///./src/helpers/dom/toggleDisability.ts","webpack:///./src/helpers/bytes.ts","webpack:///./src/helpers/dom/dispatchEvent.ts","webpack:///./src/helpers/dom/findUpTag.ts","webpack:///./src/helpers/sequentialDom.ts","webpack:///./src/lib/mtproto/serverTimeManager.ts","webpack:///./src/helpers/dom/placeCaretAtEnd.ts","webpack:///./src/helpers/dom/isSwipingBackSafari.ts","webpack:///./src/helpers/formatPhoneNumber.ts"],"names":["cachedPromise","set","getLanguageChangeButton","appendTo","getConfig","then","config","suggested_lang_code","lastRequestedLangCode","Promise","all","getStrings","getCacheLangPack","strings","backup","forEach","string","backupString","get","key","push","btnChangeLanguage","text","lastElementChild","classList","remove","window","requestAnimationFrame","append","addEventListener","once","e","disabled","getLangPack","fixBase64String","str","toUrl","replace","TelInputField","options","super","label","name","pasted","lastValue","this","container","add","telEl","input","HTMLInputElement","type","autocomplete","inputMode","pixelRatio","devicePixelRatio","letterSpacing","style","setProperty","originalFunc","setValueSilently","bind","value","formattedPhoneNumber","Math","abs","length","setLabel","formatted","country","countryCode","leftPattern","code","dataset","onInput","test","metaKey","ctrlKey","shiftKey","preventDefault","rippleClickId","ripple","elem","callback","resolve","onEnd","prepend","attachListenerTo","querySelector","r","document","createElement","handler","contains","drawRipple","clientX","clientY","startTime","Date","now","clickId","duration","getComputedStyle","getPropertyValue","elapsedTime","cb","mutate","delay","max","setTimeout","removeEventListener","touchStartFired","rect","getBoundingClientRect","clickX","left","clickY","top","size","sqrt","height","width","x","y","isRippleUnneeded","target","includes","tagName","touchEnd","settings","animationsEnabled","touches","cancelBubble","stopPropagation","passive","button","btnQr","btnNext","page","setCountries","countries","countriesList","filter","pFlags","hidden","sort","a","b","default_name","localeCompare","liMap","Map","lastCountrySelected","lastCountryCodeSelected","inputWrapper","countryInputField","countryInput","selectWrapper","arrowDown","selectList","appendChild","initSelect","c","emoji","iso2","liArr","country_codes","li","wrapped","wrapEmojiText","spanEmoji","innerHTML","el","defaultName","span","innerText","country_code","selectCountryByTarget","childNodes","phoneCode","find","_countryCode","telInputField","hidePicker","focus","hideTimeout","display","clearTimeout","undefined","offsetWidth","select","pageEl","parentElement","element","position","margin","mouseDownHandlerAttached","onMouseDown","capture","_value","toLowerCase","matches","good","Boolean","indexOf","blur","loadLottieWorkers","countryName","visibility","onSubmit","signedCheckboxField","withRipple","checked","keepSigned","pushToState","toggleStorage","getState","state","storage","isAvailable","toggle","phone_number","invokeApi","api_id","id","api_hash","hash","_","m","default","mount","Object","assign","catch","err","setError","console","error","h4","subtitle","nearestDcResult","langPack","getFromCache","lang_code","dcs","Set","done","this_dc","promise","nearest_dc","getNetworker","dcId","delete","_dcs","g","shift","dbKey","finally","removeAttribute","imageDiv","preloader","btnBack","helpList","stop","QRCodeStyling","prevToken","ignoreErrors","iterate","isLoop","loginToken","except_ids","dc_id","setBaseDcId","token","authorization","setUser","user","encoded","url","documentElement","surfaceColor","trim","textColor","primaryColor","logoUrl","fetch","res","blob","Blob","reader","FileReader","onload","result","readAsDataURL","qrCode","data","image","dotsOptions","color","cornersSquareOptions","imageOptions","imageSize","backgroundOptions","qrOptions","errorCorrectionLevel","lastChild","_drawingPromise","race","_canvas","_image","animation","children","Array","from","slice","timestamp","diff","expires","serverTimeOffset","warn","handled","func","CLICK_EVENT_NAME","attachClickEvent","listenerSetter","touchMouseDown","detachClickEvent","simulateClickEvent","className","asDiv","icon","noRipple","rippleSquare","onlyMobile","setAttribute","putPreloader","returnDiv","html","div","insertAdjacentHTML","setButtonLoader","onMouseMove","openedMenu","diffX","right","diffY","bottom","closeBtnMenu","onClick","menuOverlay","dispatchEvent","openedMenuOnClose","removeByType","openBtnMenu","menuElement","onClose","pushItem","onPop","canAnimate","insertBefore","positionMenu","pageX","pageY","side","scrollWidth","menuWidth","scrollHeight","menuHeight","body","windowWidth","windowHeight","isMobile","verticalSide","sides","intermediateX","intermediateY","possibleSides","_cancelContextMenuOpening","_cancelContextMenuOpeningTimeout","cancelContextMenuOpening","attachContextMenuListener","removeManual","timeout","onCancel","ScrollableBase","logPrefix","onScrollMeasure","isHeavyAnimationInProgress","needCheckAfterAnimation","log","Error","onScroll","cancelAnimationFrame","Scrollable","onScrollOffset","withPaddingContainer","lastScrollTop","lastScrollDirection","loadedAll","onScrolledTop","onScrolledBottom","splitUp","onAdditionalScroll","scrollTop","checkForTriggers","maxScrollTop","clientHeight","setListeners","elements","padding","round","offsetHeight","getDistanceToEnd","ScrollableX","splitCount","scrollHorizontally","deltaX","clientWidth","scrollLeft","deltaY","appNavigationController","navigations","manual","debug","currentHash","location","isPossibleSwipe","onHashChange","replaceState","pushState","item","pop","handleItem","onEscape","back","history","scrollRestoration","noBlurOnPop","i","index","ret","findItemByType","backByItem","splice","noHistory","origin","pathname","single","CheckboxField","restriction","toggleDisability","stateKey","stateValue","stateValues","setByKey","textArgs","box","checkSvg","createElementNS","setAttributeNS","use","bg","border","withHover","event","Event","bubbles","cancelable","disable","bytesToHex","bytes","arr","toString","join","bytesFromHex","hexString","len","Uint8Array","ceil","start","parseInt","charAt","substr","bytesToBase64","mod3","nLen","nUint24","nIdx","String","fromCharCode","uint6ToBase64","nUint6","bytesCmp","bytes1","bytes2","bytesXor","convertToUint8Array","TextEncoder","encode","bufferConcats","args","reduce","acc","v","byteLength","tmp","lastLength","ArrayBuffer","bytesFromWordss","o","bytesToWordss","words","Uint32Array","simulateEvent","findUpTag","tag","closest","sequentialDom","promises","raf","scheduled","kind","scheduleFlush","do","read","write","serverTimeManager","to","addTaskListener","task","payload","placeCaretAtEnd","ignoreTouchCheck","activeElement","getSelection","createRange","range","selectNodeContents","collapse","sel","removeAllRanges","addRange","createTextRange","textRange","moveToElementText","isSwipingBackSafari","TouchEvent","prefixes","maxPrefixLength","setPrefix","prefix","formatPhoneNumber","originalStr","prefixCountry","patterns","searchForPattern","pattern","mostMatchedPatternMatches","mostMatchedPattern","_pattern","patternMatches","k","min","split","symbol","idx"],"mappings":"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","file":"15.b14001265d6da1e62429.chunk.js","sourcesContent":["/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\nimport loadFonts from \"../helpers/dom/loadFonts\";\nimport { Config, LangPackDifference, LangPackString } from \"../layer\";\nimport I18n, { LangPackKey } from \"../lib/langPack\";\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\nimport rootScope from \"../lib/rootScope\";\nimport Button from \"./button\";\nimport { putPreloader } from \"./misc\";\n\nlet set = false;\n\nfunction getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {\n if(cachedPromise) return cachedPromise;\n return cachedPromise = apiManager.getConfig().then(config => {\n if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {\n //I18n.loadLangPack(config.suggested_lang_code);\n\n return Promise.all([\n config,\n I18n.getStrings(config.suggested_lang_code, ['Login.ContinueOnLanguage']),\n I18n.getCacheLangPack()\n ]);\n } else {\n return [] as any;\n }\n });\n}\n\nlet cachedPromise: ReturnType<typeof getLang>;\n\nexport default function getLanguageChangeButton(appendTo: HTMLElement) {\n if(set) return;\n getLang().then(([config, strings]) => {\n if(!config) {\n return;\n }\n\n const backup: LangPackString[] = [];\n strings.forEach(string => {\n const backupString = I18n.strings.get(string.key as LangPackKey);\n if(!backupString) {\n return;\n }\n \n backup.push(backupString);\n I18n.strings.set(string.key as LangPackKey, string);\n });\n\n const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});\n btnChangeLanguage.lastElementChild.classList.remove('i18n'); // prevent changing language\n loadFonts().then(() => {\n window.requestAnimationFrame(() => {\n appendTo.append(btnChangeLanguage);\n });\n });\n\n rootScope.addEventListener('language_change', () => {\n btnChangeLanguage.remove();\n }, {once: true});\n\n backup.forEach(string => {\n I18n.strings.set(string.key as LangPackKey, string);\n });\n \n attachClickEvent(btnChangeLanguage, (e) => {\n cancelEvent(e);\n\n set = true;\n\n btnChangeLanguage.disabled = true;\n putPreloader(btnChangeLanguage);\n\n I18n.getLangPack(config.suggested_lang_code);\n });\n });\n}\n","export default function fixBase64String(str: string, toUrl: boolean) {\n if(toUrl) {\n return str.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/\\=+$/, '');\n } else {\n return str.replace(/-/g, '+').replace(/_/g, '/');\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport placeCaretAtEnd from \"../helpers/dom/placeCaretAtEnd\";\nimport { formatPhoneNumber } from \"../helpers/formatPhoneNumber\";\nimport { IS_APPLE, IS_ANDROID, IS_APPLE_MOBILE } from \"../environment/userAgent\";\nimport { HelpCountry, HelpCountryCode } from \"../layer\";\nimport InputField, { InputFieldOptions } from \"./inputField\";\n\nexport default class TelInputField extends InputField {\n private pasted = false;\n public lastValue = '';\n \n constructor(options: InputFieldOptions & {\n onInput?: (formatted: ReturnType<typeof formatPhoneNumber>) => void\n } = {}) {\n super({\n label: 'Contacts.PhoneNumber.Placeholder',\n //plainText: true,\n name: 'phone',\n ...options\n });\n\n this.container.classList.add('input-field-phone');\n\n let telEl = this.input;\n if(telEl instanceof HTMLInputElement) {\n telEl.type = 'tel';\n telEl.autocomplete = 'rr55RandomRR55';\n } else {\n telEl.inputMode = 'decimal';\n\n const pixelRatio = window.devicePixelRatio;\n if(pixelRatio > 1) {\n let letterSpacing: number;\n if(IS_APPLE) {\n letterSpacing = pixelRatio * -.16;\n } else if(IS_ANDROID) {\n letterSpacing = 0;\n }\n\n telEl.style.setProperty('--letter-spacing', letterSpacing + 'px');\n }\n\n const originalFunc = this.setValueSilently.bind(this);\n this.setValueSilently = (value) => {\n originalFunc(value);\n placeCaretAtEnd(this.input, true);\n };\n }\n\n telEl.addEventListener('input', () => {\n //console.log('input', this.value);\n telEl.classList.remove('error');\n \n const value = this.value;\n const diff = Math.abs(value.length - this.lastValue.length);\n if(diff > 1 && !this.pasted && IS_APPLE_MOBILE) {\n this.setValueSilently(this.lastValue + value);\n }\n \n this.pasted = false;\n \n this.setLabel();\n \n let formattedPhoneNumber: ReturnType<typeof formatPhoneNumber>;\n let formatted: string, country: HelpCountry, countryCode: HelpCountryCode, leftPattern = '';\n if(this.value.replace(/\\++/, '+') === '+') {\n this.setValueSilently('+');\n } else {\n formattedPhoneNumber = formatPhoneNumber(this.value);\n formatted = formattedPhoneNumber.formatted;\n country = formattedPhoneNumber.country;\n leftPattern = formattedPhoneNumber.leftPattern;\n countryCode = formattedPhoneNumber.code;\n this.setValueSilently(this.lastValue = formatted ? '+' + formatted : '');\n }\n \n telEl.dataset.leftPattern = leftPattern/* .replace(/X/g, '0') */;\n \n //console.log(formatted, country);\n\n options.onInput && options.onInput(formattedPhoneNumber);\n });\n \n telEl.addEventListener('paste', () => {\n this.pasted = true;\n //console.log('paste', telEl.value);\n });\n \n /* telEl.addEventListener('change', (e) => {\n console.log('change', telEl.value);\n }); */\n \n telEl.addEventListener('keypress', (e) => {\n //console.log('keypress', this.value);\n const key = e.key;\n if(/\\D/.test(key) && !(e.metaKey || e.ctrlKey) && key !== 'Backspace' && !(key === '+' && e.shiftKey/* && !this.value */)) {\n e.preventDefault();\n return false;\n }\n });\n \n /* telEl.addEventListener('focus', function(this: typeof telEl, e) {\n this.removeAttribute('readonly'); // fix autocomplete\n });*/\n }\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport sequentialDom from \"../helpers/sequentialDom\";\r\nimport {IS_TOUCH_SUPPORTED} from \"../environment/touchSupport\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport findUpAsChild from \"../helpers/dom/findUpAsChild\";\r\n\r\nlet rippleClickId = 0;\r\nexport function ripple(\r\n elem: HTMLElement, \r\n callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(), \r\n onEnd: (id: number) => void = null, \r\n prepend = false,\r\n attachListenerTo = elem\r\n) {\r\n //return;\r\n if(elem.querySelector('.c-ripple')) return;\r\n elem.classList.add('rp');\r\n \r\n let r = document.createElement('div');\r\n r.classList.add('c-ripple');\r\n\r\n const isSquare = elem.classList.contains('rp-square');\r\n if(isSquare) {\r\n r.classList.add('is-square');\r\n }\r\n\r\n elem[prepend ? 'prepend' : 'append'](r);\r\n\r\n let handler: () => void;\r\n //let animationEndPromise: Promise<number>;\r\n const drawRipple = (clientX: number, clientY: number) => {\r\n const startTime = Date.now();\r\n const elem = document.createElement('div');\r\n\r\n const clickId = rippleClickId++;\r\n \r\n //console.log('ripple drawRipple');\r\n \r\n const duration = +window.getComputedStyle(r).getPropertyValue('--ripple-duration').replace('s', '') * 1000;\r\n //console.log('ripple duration', duration);\r\n\r\n handler = () => {\r\n //handler = () => animationEndPromise.then((duration) => {\r\n //console.log('ripple animation was:', duration);\r\n\r\n //const duration = isSquare || mediaSizes.isMobile ? 200 : 700;\r\n //return;\r\n let elapsedTime = Date.now() - startTime;\r\n const cb = () => {\r\n //console.log('ripple elapsedTime total pre-remove:', Date.now() - startTime);\r\n sequentialDom.mutate(() => {\r\n elem.remove();\r\n });\r\n \r\n if(onEnd) onEnd(clickId);\r\n };\r\n if(elapsedTime < duration) {\r\n let delay = Math.max(duration - elapsedTime, duration / 2);\r\n setTimeout(() => elem.classList.add('hiding'), Math.max(delay - duration / 2, 0));\r\n\r\n setTimeout(cb, delay);\r\n } else {\r\n elem.classList.add('hiding');\r\n setTimeout(cb, duration / 2);\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('contextmenu', handler);\r\n }\r\n\r\n handler = null;\r\n touchStartFired = false;\r\n };\r\n //});\r\n\r\n callback && callback(clickId);\r\n\r\n /* callback().then((bad) => {\r\n if(bad) {\r\n span.remove();\r\n return;\r\n } */\r\n \r\n //console.log('ripple after promise', Date.now() - startTime);\r\n //console.log('ripple tooSlow:', tooSlow);\r\n /* if(tooSlow) {\r\n span.remove();\r\n return;\r\n } */\r\n\r\n window.requestAnimationFrame(() => {\r\n const rect = r.getBoundingClientRect();\r\n elem.classList.add('c-ripple__circle');\r\n\r\n const clickX = clientX - rect.left;\r\n const clickY = clientY - rect.top;\r\n\r\n const radius = Math.sqrt((Math.abs(clickY - rect.height / 2) + rect.height / 2) ** 2 + (Math.abs(clickX - rect.width / 2) + rect.width / 2) ** 2);\r\n const size = radius;\r\n\r\n // center of circle\r\n const x = clickX - size / 2;\r\n const y = clickY - size / 2;\r\n\r\n //console.log('ripple click', offsetFromCenter, size, clickX, clickY);\r\n\r\n elem.style.width = elem.style.height = size + 'px';\r\n elem.style.left = x + 'px';\r\n elem.style.top = y + 'px';\r\n\r\n // нижний код выполняется с задержкой\r\n /* animationEndPromise = new Promise((resolve) => {\r\n span.addEventListener('animationend', () => {\r\n // 713 -> 700\r\n resolve(((Date.now() - startTime) / 100 | 0) * 100);\r\n }, {once: true});\r\n }); */\r\n \r\n // нижний код не всегда включает анимацию ПРИ КЛИКЕ НА ТАЧПАД БЕЗ ТАПТИК ЭНЖИНА\r\n /* span.style.display = 'none';\r\n r.append(span);\r\n duration = +window.getComputedStyle(span).getPropertyValue('animation-duration').replace('s', '') * 1000;\r\n span.style.display = ''; */\r\n\r\n r.append(elem);\r\n\r\n //r.classList.add('active');\r\n //handler();\r\n });\r\n //});\r\n };\r\n\r\n const isRippleUnneeded = (e: Event) => e.target !== elem && (\r\n ['BUTTON', 'A'].includes((e.target as HTMLElement).tagName) \r\n || findUpClassName(e.target as HTMLElement, 'c-ripple') !== r\r\n ) && (\r\n attachListenerTo === elem \r\n || !findUpAsChild(e.target, attachListenerTo)\r\n );\r\n\r\n // TODO: rename this variable\r\n let touchStartFired = false;\r\n if(IS_TOUCH_SUPPORTED) {\r\n let touchEnd = () => {\r\n handler && handler();\r\n };\r\n \r\n attachListenerTo.addEventListener('touchstart', (e) => {\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n\r\n //console.log('ripple touchstart', e);\r\n if(e.touches.length > 1 || touchStartFired || isRippleUnneeded(e)) {\r\n return;\r\n }\r\n \r\n //console.log('touchstart', e);\r\n touchStartFired = true;\r\n \r\n let {clientX, clientY} = e.touches[0];\r\n drawRipple(clientX, clientY);\r\n attachListenerTo.addEventListener('touchend', touchEnd, {once: true});\r\n \r\n window.addEventListener('touchmove', (e) => {\r\n e.cancelBubble = true;\r\n e.stopPropagation();\r\n touchEnd();\r\n attachListenerTo.removeEventListener('touchend', touchEnd);\r\n }, {once: true});\r\n }, {passive: true});\r\n } else {\r\n attachListenerTo.addEventListener('mousedown', (e) => {\r\n if(![0, 2].includes(e.button)) { // only left and right buttons\r\n return;\r\n }\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n //console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') === r);\r\n\r\n if(attachListenerTo.dataset.ripple === '0' || isRippleUnneeded(e)) {\r\n return;\r\n } else if(touchStartFired) {\r\n touchStartFired = false;\r\n return;\r\n }\r\n \r\n let {clientX, clientY} = e;\r\n drawRipple(clientX, clientY);\r\n window.addEventListener('mouseup', handler, {once: true, passive: true});\r\n window.addEventListener('contextmenu', handler, {once: true, passive: true});\r\n }, {passive: true});\r\n }\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { putPreloader } from \"../components/misc\";\r\nimport Scrollable from '../components/scrollable';\r\nimport appStateManager from \"../lib/appManagers/appStateManager\";\r\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\r\nimport { RichTextProcessor } from '../lib/richtextprocessor';\r\nimport Page from \"./page\";\r\nimport InputField from \"../components/inputField\";\r\nimport CheckboxField from \"../components/checkboxField\";\r\nimport Button from \"../components/button\";\r\nimport fastSmoothScroll from \"../helpers/fastSmoothScroll\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport App from \"../config/app\";\r\nimport I18n, { _i18n, i18n } from \"../lib/langPack\";\r\nimport lottieLoader from \"../lib/rlottie/lottieLoader\";\r\nimport { ripple } from \"../components/ripple\";\r\nimport findUpTag from \"../helpers/dom/findUpTag\";\r\nimport findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport { randomLong } from \"../helpers/random\";\r\nimport AppStorage from \"../lib/storage\";\r\nimport CacheStorageController from \"../lib/cacheStorage\";\r\nimport pageSignQR from \"./pageSignQR\";\r\nimport getLanguageChangeButton from \"../components/languageChangeButton\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\r\nimport replaceContent from \"../helpers/dom/replaceContent\";\r\nimport toggleDisability from \"../helpers/dom/toggleDisability\";\r\nimport sessionStorage from \"../lib/sessionStorage\";\r\nimport { DcAuthKey } from \"../types\";\r\nimport placeCaretAtEnd from \"../helpers/dom/placeCaretAtEnd\";\r\nimport { HelpCountry, HelpCountryCode } from \"../layer\";\r\nimport { getCountryEmoji } from \"../vendor/emoji\";\r\nimport simulateEvent from \"../helpers/dom/dispatchEvent\";\r\nimport stateStorage from \"../lib/stateStorage\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport TelInputField from \"../components/telInputField\";\r\nimport IS_EMOJI_SUPPORTED from \"../environment/emojiSupport\";\r\n\r\n//import _countries from '../countries_pretty.json';\r\nlet btnNext: HTMLButtonElement = null, btnQr: HTMLButtonElement;\r\n\r\nlet onFirstMount = () => {\r\n /* if(Modes.test) {\r\n Countries.push({\r\n _: 'help.country',\r\n default_name: 'Test Country',\r\n country_codes: [{\r\n _: 'help.countryCode',\r\n country_code: '999 66',\r\n patterns: ['999 66 XXX XX']\r\n }],\r\n iso2: 'KK'\r\n });\r\n \r\n console.log('Added test country to list!');\r\n } */\r\n\r\n //const countries: Country[] = _countries.default.filter(c => c.emoji);\r\n // const countries: Country[] = Countries.filter(c => c.emoji).sort((a, b) => a.name.localeCompare(b.name));\r\n // const countries = I18n.countriesList.filter(country => !country.pFlags?.hidden);\r\n const setCountries = () => {\r\n countries = I18n.countriesList\r\n .filter(country => !country.pFlags?.hidden)\r\n .sort((a, b) => (a.name || a.default_name).localeCompare(b.name || b.default_name));\r\n };\r\n let countries: HelpCountry.helpCountry[]; \r\n\r\n setCountries();\r\n\r\n rootScope.addEventListener('language_change', () => {\r\n setCountries();\r\n });\r\n\r\n const liMap: Map<string, HTMLLIElement[]> = new Map();\r\n\r\n let lastCountrySelected: HelpCountry, lastCountryCodeSelected: HelpCountryCode;\r\n\r\n const inputWrapper = document.createElement('div');\r\n inputWrapper.classList.add('input-wrapper');\r\n\r\n const countryInputField = new InputField({\r\n label: 'Login.CountrySelectorLabel',\r\n name: randomLong()\r\n });\r\n\r\n countryInputField.container.classList.add('input-select');\r\n\r\n const countryInput = countryInputField.input;\r\n // countryInput.autocomplete = randomLong();\r\n\r\n const selectWrapper = document.createElement('div');\r\n selectWrapper.classList.add('select-wrapper', 'z-depth-3', 'hide');\r\n\r\n const arrowDown = document.createElement('span');\r\n arrowDown.classList.add('arrow', 'arrow-down');\r\n countryInputField.container.append(arrowDown);\r\n\r\n const selectList = document.createElement('ul');\r\n selectWrapper.appendChild(selectList);\r\n\r\n const scroll = new Scrollable(selectWrapper);\r\n\r\n let initSelect = () => {\r\n initSelect = null;\r\n\r\n countries.forEach((c) => {\r\n const emoji = getCountryEmoji(c.iso2);\r\n\r\n const liArr: Array<HTMLLIElement> = [];\r\n c.country_codes.forEach((countryCode) => {\r\n const li = document.createElement('li');\r\n\r\n let wrapped = RichTextProcessor.wrapEmojiText(emoji);\r\n if(IS_EMOJI_SUPPORTED) {\r\n const spanEmoji = document.createElement('span');\r\n spanEmoji.innerHTML = wrapped;\r\n li.append(spanEmoji);\r\n } else {\r\n li.innerHTML = wrapped;\r\n }\r\n \r\n const el = i18n(c.default_name as any);\r\n el.dataset.defaultName = c.default_name;\r\n li.append(el);\r\n\r\n const span = document.createElement('span');\r\n span.classList.add('phone-code');\r\n span.innerText = '+' + countryCode.country_code;\r\n li.appendChild(span);\r\n\r\n liArr.push(li);\r\n selectList.append(li);\r\n });\r\n\r\n liMap.set(c.iso2, liArr);\r\n });\r\n \r\n selectList.addEventListener('mousedown', (e) => {\r\n if(e.button !== 0) { // other buttons but left shall not pass\r\n return;\r\n }\r\n \r\n const target = findUpTag(e.target, 'LI')\r\n selectCountryByTarget(target);\r\n //console.log('clicked', e, countryName, phoneCode);\r\n });\r\n\r\n countryInputField.container.appendChild(selectWrapper);\r\n };\r\n\r\n const selectCountryByTarget = (target: HTMLElement) => {\r\n const defaultName = (target.childNodes[1] as HTMLElement).dataset.defaultName;\r\n const phoneCode = target.querySelector<HTMLElement>('.phone-code').innerText;\r\n const countryCode = phoneCode.replace(/\\D/g, '');\r\n\r\n replaceContent(countryInput, i18n(defaultName as any));\r\n simulateEvent(countryInput, 'input');\r\n lastCountrySelected = countries.find(c => c.default_name === defaultName);\r\n lastCountryCodeSelected = lastCountrySelected.country_codes.find(_countryCode => _countryCode.country_code === countryCode);\r\n \r\n telInputField.value = telInputField.lastValue = phoneCode;\r\n hidePicker();\r\n setTimeout(() => {\r\n telEl.focus();\r\n placeCaretAtEnd(telEl, true);\r\n }, 0);\r\n };\r\n \r\n initSelect();\r\n\r\n let hideTimeout: number;\r\n\r\n countryInput.addEventListener('focus', function(this: typeof countryInput, e) {\r\n if(initSelect) {\r\n initSelect();\r\n } else {\r\n countries.forEach((c) => {\r\n liMap.get(c.iso2).forEach(li => li.style.display = '');\r\n });\r\n }\r\n\r\n clearTimeout(hideTimeout);\r\n hideTimeout = undefined;\r\n\r\n selectWrapper.classList.remove('hide');\r\n void selectWrapper.offsetWidth; // reflow\r\n selectWrapper.classList.add('active');\r\n\r\n countryInputField.select();\r\n\r\n fastSmoothScroll({\r\n container: page.pageEl.parentElement.parentElement, \r\n element: countryInput, \r\n position: 'start', \r\n margin: 4\r\n });\r\n\r\n setTimeout(() => {\r\n if(!mouseDownHandlerAttached) {\r\n document.addEventListener('mousedown', onMouseDown, {capture: true});\r\n mouseDownHandlerAttached = true;\r\n }\r\n }, 0);\r\n });\r\n\r\n let mouseDownHandlerAttached = false;\r\n const onMouseDown = (e: MouseEvent) => {\r\n if(findUpClassName(e.target, 'input-select')) {\r\n return;\r\n }\r\n if(e.target === countryInput) {\r\n return;\r\n }\r\n\r\n hidePicker();\r\n document.removeEventListener('mousedown', onMouseDown, {capture: true});\r\n mouseDownHandlerAttached = false;\r\n };\r\n\r\n const hidePicker = () => {\r\n if(hideTimeout !== undefined) return;\r\n selectWrapper.classList.remove('active');\r\n hideTimeout = window.setTimeout(() => {\r\n selectWrapper.classList.add('hide');\r\n hideTimeout = undefined;\r\n }, 200);\r\n };\r\n /* false && countryInput.addEventListener('blur', function(this: typeof countryInput, e) {\r\n hidePicker();\r\n \r\n e.cancelBubble = true;\r\n }, {capture: true}); */\r\n\r\n countryInput.addEventListener('keyup', (e) => {\r\n const key = e.key;\r\n if(e.ctrlKey || key === 'Control') return false;\r\n\r\n //let i = new RegExp('^' + this.value, 'i');\r\n let _value = countryInputField.value.toLowerCase();\r\n let matches: HelpCountry[] = [];\r\n countries.forEach((c) => {\r\n let good = !![c.name, c.default_name].filter(Boolean).find(str => str.toLowerCase().indexOf(_value) !== -1)/* === 0 */;//i.test(c.name);\r\n\r\n liMap.get(c.iso2).forEach(li => li.style.display = good ? '' : 'none');\r\n if(good) matches.push(c);\r\n });\r\n\r\n // Код ниже автоматически выберет страну если она осталась одна при поиске\r\n /* if(matches.length === 1 && matches[0].li.length === 1) {\r\n if(matches[0].name === lastCountrySelected) return false;\r\n //console.log('clicking', matches[0]);\r\n\r\n var clickEvent = document.createEvent('MouseEvents');\r\n clickEvent.initEvent('mousedown', true, true);\r\n matches[0].li[0].dispatchEvent(clickEvent);\r\n return false;\r\n } else */if(matches.length === 0) {\r\n countries.forEach((c) => {\r\n liMap.get(c.iso2).forEach(li => li.style.display = '');\r\n });\r\n } else if(matches.length === 1 && key === 'Enter') {\r\n selectCountryByTarget(liMap.get(matches[0].iso2)[0]);\r\n }\r\n });\r\n\r\n arrowDown.addEventListener('mousedown', function(this: typeof arrowDown, e) {\r\n e.cancelBubble = true;\r\n e.preventDefault();\r\n if(countryInput.matches(':focus')) countryInput.blur();\r\n else countryInput.focus();\r\n });\r\n\r\n const telInputField = new TelInputField({\r\n onInput: (formatted) => {\r\n lottieLoader.loadLottieWorkers();\r\n\r\n const {country, code} = formatted || {};\r\n let countryName = country ? country.name || country.default_name : ''/* 'Unknown' */;\r\n if(countryName !== countryInputField.value && (\r\n !lastCountrySelected || \r\n !country ||\r\n !code || (\r\n lastCountrySelected !== country && \r\n lastCountryCodeSelected.country_code !== code.country_code\r\n )\r\n )\r\n ) {\r\n replaceContent(countryInput, country ? i18n(country.default_name as any) : countryName);\r\n lastCountrySelected = country;\r\n lastCountryCodeSelected = code;\r\n }\r\n \r\n //if(country && (telInputField.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {\r\n if(country || (telInputField.value.length - 1) > 1) {\r\n btnNext.style.visibility = '';\r\n } else {\r\n btnNext.style.visibility = 'hidden';\r\n }\r\n }\r\n });\r\n\r\n const telEl = telInputField.input;\r\n\r\n telEl.addEventListener('keypress', (e) => {\r\n //console.log('keypress', this.value);\r\n if(!btnNext.style.visibility &&/* this.value.length >= 9 && */ e.key === 'Enter') {\r\n return onSubmit();\r\n }\r\n });\r\n\r\n /* telEl.addEventListener('focus', function(this: typeof telEl, e) {\r\n this.removeAttribute('readonly'); // fix autocomplete\r\n });*/\r\n\r\n const signedCheckboxField = new CheckboxField({\r\n text: 'Login.KeepSigned', \r\n name: 'keepSession',\r\n withRipple: true,\r\n checked: true\r\n });\r\n\r\n signedCheckboxField.input.addEventListener('change', () => {\r\n const keepSigned = signedCheckboxField.checked;\r\n appStateManager.pushToState('keepSigned', keepSigned);\r\n \r\n AppStorage.toggleStorage(keepSigned);\r\n CacheStorageController.toggleStorage(keepSigned);\r\n apiManager.toggleStorage(keepSigned);\r\n sessionStorage.toggleStorage(keepSigned);\r\n });\r\n\r\n appStateManager.getState().then(state => {\r\n if(!appStateManager.storage.isAvailable()) {\r\n signedCheckboxField.checked = false;\r\n signedCheckboxField.label.classList.add('checkbox-disabled');\r\n } else {\r\n signedCheckboxField.checked = state.keepSigned;\r\n }\r\n });\r\n\r\n btnNext = Button('btn-primary btn-color-primary', {text: 'Login.Next'});\r\n btnNext.style.visibility = 'hidden';\r\n\r\n const onSubmit = (e?: Event) => {\r\n if(e) {\r\n cancelEvent(e);\r\n }\r\n\r\n const toggle = toggleDisability([/* telEl, countryInput, */btnNext, btnQr], true);\r\n\r\n replaceContent(btnNext, i18n('PleaseWait'));\r\n putPreloader(btnNext);\r\n\r\n //return;\r\n\r\n let phone_number = telInputField.value;\r\n apiManager.invokeApi('auth.sendCode', {\r\n phone_number: phone_number,\r\n api_id: App.id,\r\n api_hash: App.hash,\r\n settings: {\r\n _: 'codeSettings' // that's how we sending Type\r\n }\r\n //lang_code: navigator.language || 'en'\r\n }).then((code) => {\r\n //console.log('got code', code);\r\n\r\n import('./pageAuthCode').then(m => m.default.mount(Object.assign(code, {phone_number: phone_number})));\r\n }).catch(err => {\r\n toggle();\r\n\r\n switch(err.type) {\r\n case 'PHONE_NUMBER_INVALID':\r\n telInputField.setError();\r\n replaceContent(telInputField.label, i18n('Login.PhoneLabelInvalid'));\r\n telEl.classList.add('error');\r\n replaceContent(btnNext, i18n('Login.Next'));\r\n break;\r\n default:\r\n console.error('auth.sendCode error:', err);\r\n btnNext.innerText = err.type;\r\n break;\r\n }\r\n });\r\n };\r\n\r\n attachClickEvent(btnNext, onSubmit);\r\n\r\n btnQr = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Login'});\r\n\r\n let qrMounted = false;\r\n btnQr.addEventListener('click', () => {\r\n pageSignQR.mount();\r\n /* const promise = import('./pageSignQR');\r\n btnQr.disabled = true;\r\n\r\n let preloaderDiv: HTMLElement;\r\n if(!qrMounted) {\r\n preloaderDiv = putPreloader(btnQr);\r\n qrMounted = true;\r\n }\r\n\r\n promise.then(module => {\r\n module.default.mount();\r\n\r\n setTimeout(() => {\r\n btnQr.removeAttribute('disabled');\r\n if(preloaderDiv) {\r\n preloaderDiv.remove();\r\n }\r\n }, 200);\r\n }); */\r\n });\r\n\r\n inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr);\r\n\r\n const h4 = document.createElement('h4');\r\n h4.classList.add('text-center');\r\n _i18n(h4, 'Login.Title');\r\n\r\n const subtitle = document.createElement('div');\r\n subtitle.classList.add('subtitle', 'text-center');\r\n _i18n(subtitle, 'Login.StartText');\r\n\r\n page.pageEl.querySelector('.container').append(h4, subtitle, inputWrapper);\r\n\r\n let tryAgain = () => {\r\n apiManager.invokeApi('help.getNearestDc').then((nearestDcResult) => {\r\n const langPack = stateStorage.getFromCache('langPack');\r\n if(langPack && !langPack.countries?.hash) {\r\n I18n.getLangPack(langPack.lang_code).then(() => {\r\n simulateEvent(telEl, 'input');\r\n });\r\n }\r\n\r\n const dcs = new Set([1, 2, 3, 4, 5]);\r\n const done: number[] = [nearestDcResult.this_dc];\r\n\r\n let promise: Promise<any>;\r\n if(nearestDcResult.nearest_dc !== nearestDcResult.this_dc) {\r\n promise = apiManager.getNetworker(nearestDcResult.nearest_dc).then(() => {\r\n done.push(nearestDcResult.nearest_dc);\r\n });\r\n }\r\n\r\n (promise || Promise.resolve()).then(() => {\r\n done.forEach(dcId => {\r\n dcs.delete(dcId);\r\n });\r\n\r\n const _dcs = [...dcs];\r\n const g = async(): Promise<void> => {\r\n const dcId = _dcs.shift();\r\n if(!dcId) return;\r\n\r\n const dbKey: DcAuthKey = `dc${dcId}_auth_key` as any;\r\n const key = await sessionStorage.get(dbKey);\r\n if(key) {\r\n return g();\r\n }\r\n\r\n setTimeout(() => { // * если одновременно запросить все нетворкеры, не будет проходить запрос на код\r\n apiManager.getNetworker(dcId/* , {fileDownload: true} */).finally(g);\r\n }, /* done.includes(dcId) ? 0 : */3000);\r\n };\r\n \r\n g();\r\n });\r\n \r\n return nearestDcResult;\r\n }).then((nearestDcResult) => {\r\n if(!countryInputField.value.length && !telInputField.value.length) {\r\n selectCountryByTarget(liMap.get(nearestDcResult.country)[0]);\r\n }\r\n \r\n //console.log('woohoo', nearestDcResult, country);\r\n })//.catch(tryAgain);\r\n };\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n setTimeout(() => {\r\n telEl.focus();\r\n }, 0);\r\n }\r\n\r\n getLanguageChangeButton(inputWrapper);\r\n\r\n tryAgain();\r\n};\r\n\r\nconst page = new Page('page-sign', true, onFirstMount, () => {\r\n if(btnNext) {\r\n replaceContent(btnNext, i18n('Login.Next'));\r\n ripple(btnNext, undefined, undefined, true);\r\n btnNext.removeAttribute('disabled');\r\n }\r\n\r\n if(btnQr) {\r\n btnQr.removeAttribute('disabled');\r\n }\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignIn'});\r\n});\r\n\r\nexport default page;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport type { DcId } from '../types';\r\nimport type { ApiError } from '../lib/mtproto/apiManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport Page from './page';\r\nimport serverTimeManager from '../lib/mtproto/serverTimeManager';\r\nimport { AuthAuthorization, AuthLoginToken } from '../layer';\r\nimport { bytesCmp, bytesToBase64 } from '../helpers/bytes';\r\nimport App from '../config/app';\r\nimport Button from '../components/button';\r\nimport { _i18n, i18n, LangPackKey } from '../lib/langPack';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport rootScope from '../lib/rootScope';\r\nimport { putPreloader } from '../components/misc';\r\nimport getLanguageChangeButton from '../components/languageChangeButton';\r\nimport { pause } from '../helpers/schedulers/pause';\r\nimport fixBase64String from '../helpers/fixBase64String';\r\n\r\nconst FETCH_INTERVAL = 3;\r\n\r\nlet onFirstMount = async() => {\r\n const pageElement = page.pageEl;\r\n const imageDiv = pageElement.querySelector('.auth-image') as HTMLDivElement;\r\n\r\n let preloader = putPreloader(imageDiv, true);\r\n\r\n const inputWrapper = document.createElement('div');\r\n inputWrapper.classList.add('input-wrapper');\r\n\r\n const btnBack = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Cancel'});\r\n inputWrapper.append(btnBack);\r\n\r\n getLanguageChangeButton(inputWrapper);\r\n\r\n const container = imageDiv.parentElement;\r\n\r\n const h4 = document.createElement('h4');\r\n _i18n(h4, 'Login.QR.Title');\r\n\r\n const helpList = document.createElement('ol');\r\n helpList.classList.add('qr-description');\r\n (['Login.QR.Help1', 'Login.QR.Help2', 'Login.QR.Help3'] as LangPackKey[]).forEach((key) => {\r\n const li = document.createElement('li');\r\n li.append(i18n(key));\r\n helpList.append(li);\r\n });\r\n\r\n container.append(h4, helpList, inputWrapper);\r\n\r\n btnBack.addEventListener('click', () => {\r\n import('./pageSignIn').then(m => m.default.mount());\r\n stop = true;\r\n });\r\n \r\n const results = await Promise.all([\r\n import('qr-code-styling' as any)\r\n ]);\r\n const QRCodeStyling = results[0].default;\r\n\r\n let stop = false;\r\n rootScope.addEventListener('user_auth', () => {\r\n stop = true;\r\n cachedPromise = null;\r\n }, {once: true});\r\n \r\n let options: {dcId?: DcId, ignoreErrors: true} = {ignoreErrors: true};\r\n let prevToken: Uint8Array | number[];\r\n\r\n const iterate = async(isLoop: boolean) => {\r\n try {\r\n let loginToken = await apiManager.invokeApi('auth.exportLoginToken', {\r\n api_id: App.id,\r\n api_hash: App.hash,\r\n except_ids: []\r\n }, {ignoreErrors: true});\r\n \r\n if(loginToken._ === 'auth.loginTokenMigrateTo') {\r\n if(!options.dcId) {\r\n options.dcId = loginToken.dc_id as DcId;\r\n apiManager.setBaseDcId(loginToken.dc_id);\r\n //continue;\r\n }\r\n \r\n loginToken = await apiManager.invokeApi('auth.importLoginToken', {\r\n token: loginToken.token\r\n }, options) as AuthLoginToken.authLoginToken;\r\n }\r\n\r\n if(loginToken._ === 'auth.loginTokenSuccess') {\r\n const authorization = loginToken.authorization as any as AuthAuthorization.authAuthorization;\r\n apiManager.setUser(authorization.user);\r\n import('./pageIm').then(m => m.default.mount());\r\n return true;\r\n }\r\n\r\n /* // to base64\r\n var decoder = new TextDecoder('utf8');\r\n var b64encoded = btoa(String.fromCharCode.apply(null, [...loginToken.token])); */\r\n\r\n if(!prevToken || !bytesCmp(prevToken, loginToken.token)) {\r\n prevToken = loginToken.token;\r\n\r\n let encoded = bytesToBase64(loginToken.token);\r\n let url = \"tg://login?token=\" + fixBase64String(encoded, true);\r\n\r\n const style = window.getComputedStyle(document.documentElement);\r\n const surfaceColor = style.getPropertyValue('--surface-color').trim();\r\n const textColor = style.getPropertyValue('--primary-text-color').trim();\r\n const primaryColor = style.getPropertyValue('--primary-color').trim();\r\n\r\n const logoUrl = await fetch('assets/img/logo_padded.svg')\r\n .then(res => res.text())\r\n .then(text => {\r\n text = text.replace(/(fill:).+?(;)/, `$1${primaryColor}$2`);\r\n const blob = new Blob([text], {type: 'image/svg+xml;charset=utf-8'});\r\n\r\n // * because iOS Safari doesn't want to eat objectURL\r\n return new Promise<string>((resolve) => {\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n resolve(e.target.result as string);\r\n };\r\n reader.readAsDataURL(blob);\r\n });\r\n //return URL.createObjectURL(blob);\r\n });\r\n\r\n const qrCode = new QRCodeStyling({\r\n width: 240 * window.devicePixelRatio,\r\n height: 240 * window.devicePixelRatio,\r\n data: url,\r\n image: logoUrl,\r\n dotsOptions: {\r\n color: textColor,\r\n type: 'rounded'\r\n },\r\n cornersSquareOptions: {\r\n type: 'extra-rounded'\r\n },\r\n imageOptions: {\r\n imageSize: 1,\r\n margin: 0\r\n },\r\n backgroundOptions: {\r\n color: surfaceColor\r\n },\r\n qrOptions: {\r\n errorCorrectionLevel: \"L\"\r\n }\r\n });\r\n\r\n qrCode.append(imageDiv);\r\n (imageDiv.lastChild as HTMLCanvasElement).classList.add('qr-canvas');\r\n\r\n let promise: Promise<void>;\r\n if(qrCode._drawingPromise) {\r\n promise = qrCode._drawingPromise;\r\n } else {\r\n promise = Promise.race([\r\n pause(1000),\r\n new Promise<void>((resolve) => {\r\n qrCode._canvas._image.addEventListener('load', () => {\r\n window.requestAnimationFrame(() => resolve());\r\n }, {once: true});\r\n })\r\n ]);\r\n }\r\n\r\n // * это костыль, но библиотека не предоставляет никаких событий\r\n await promise.then(() => {\r\n if(preloader) {\r\n preloader.style.animation = 'hide-icon .4s forwards';\r\n\r\n const c = imageDiv.children[1] as HTMLElement;\r\n c.style.display = 'none';\r\n c.style.animation = 'grow-icon .4s forwards';\r\n setTimeout(() => {\r\n c.style.display = '';\r\n }, 150);\r\n\r\n setTimeout(() => {\r\n c.style.animation = '';\r\n }, 500);\r\n preloader = undefined;\r\n } else {\r\n Array.from(imageDiv.children).slice(0, -1).forEach(el => {\r\n el.remove();\r\n });\r\n }\r\n });\r\n }\r\n\r\n if(isLoop) {\r\n let timestamp = Date.now() / 1000;\r\n let diff = loginToken.expires - timestamp - serverTimeManager.serverTimeOffset;\r\n \r\n await pause(diff > FETCH_INTERVAL ? 1e3 * FETCH_INTERVAL : 1e3 * diff | 0);\r\n }\r\n } catch(err) {\r\n switch((err as ApiError).type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n console.warn('pageSignQR: SESSION_PASSWORD_NEEDED');\r\n (err as ApiError).handled = true;\r\n import('./pagePassword').then(m => m.default.mount());\r\n stop = true;\r\n cachedPromise = null;\r\n break;\r\n default:\r\n console.error('pageSignQR: default error:', err);\r\n stop = true;\r\n break;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n //await iterate(false);\r\n\r\n return async() => {\r\n stop = false;\r\n\r\n do {\r\n if(stop) {\r\n break;\r\n }\r\n \r\n const needBreak = await iterate(true);\r\n if(needBreak) {\r\n break;\r\n }\r\n } while(true);\r\n };\r\n};\r\n\r\nlet cachedPromise: Promise<() => Promise<void>>;\r\nconst page = new Page('page-signQR', true, () => {\r\n return cachedPromise;\r\n}, () => {\r\n //console.log('onMount');\r\n if(!cachedPromise) cachedPromise = onFirstMount();\r\n cachedPromise.then(func => {\r\n func();\r\n });\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignQr'});\r\n});\r\n\r\nexport default page;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport type ListenerSetter from \"../listenerSetter\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../../environment/touchSupport\";\r\nimport simulateEvent from \"./dispatchEvent\";\r\n\r\nexport const CLICK_EVENT_NAME: 'mousedown' /* | 'touchend' */ | 'click' = (IS_TOUCH_SUPPORTED ? 'mousedown' : 'click') as any;\r\nexport type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;\r\nexport function attachClickEvent(elem: HTMLElement | Window, callback: (e: /* TouchEvent | */MouseEvent) => void, options: AttachClickOptions = {}) {\r\n const add = options.listenerSetter ? options.listenerSetter.add(elem) : elem.addEventListener.bind(elem);\r\n // const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);\r\n\r\n options.touchMouseDown = true;\r\n /* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {\r\n add('mousedown', callback, options);\r\n } else if(CLICK_EVENT_NAME === 'touchend') {\r\n const o = {...options, once: true};\r\n\r\n const onTouchStart = (e: TouchEvent) => {\r\n const onTouchMove = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n remove('touchend', onTouchEnd, o);\r\n };\r\n \r\n const onTouchEnd = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n callback(e);\r\n if(options.once) {\r\n remove('touchstart', onTouchStart);\r\n }\r\n };\r\n \r\n add('touchend', onTouchEnd, o);\r\n add('touchmove', onTouchMove, o);\r\n };\r\n\r\n add('touchstart', onTouchStart);\r\n } else {\r\n add(CLICK_EVENT_NAME, callback, options);\r\n } */\r\n add(CLICK_EVENT_NAME, callback, options);\r\n}\r\n\r\nexport function detachClickEvent(elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options?: AddEventListenerOptions) {\r\n // if(CLICK_EVENT_NAME === 'touchend') {\r\n // elem.removeEventListener('touchstart', callback, options);\r\n // } else {\r\n elem.removeEventListener(CLICK_EVENT_NAME, callback, options);\r\n // }\r\n}\r\n\r\nexport function simulateClickEvent(elem: HTMLElement) {\r\n simulateEvent(elem, CLICK_EVENT_NAME);\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { i18n, LangPackKey } from \"../lib/langPack\";\r\nimport { ripple } from \"./ripple\";\r\n\r\nexport type ButtonOptions = Partial<{\r\n noRipple: true, \r\n onlyMobile: true, \r\n icon: string, \r\n rippleSquare: true, \r\n text: LangPackKey, \r\n disabled: boolean,\r\n asDiv: boolean\r\n}>;\r\n\r\nconst Button = (className: string, options: ButtonOptions = {}) => {\r\n const button: HTMLButtonElement = document.createElement(options.asDiv ? 'div' : 'button') as any;\r\n button.className = className + (options.icon ? ' tgico-' + options.icon : '');\r\n\r\n if(!options.noRipple) {\r\n if(options.rippleSquare) {\r\n button.classList.add('rp-square');\r\n }\r\n\r\n ripple(button);\r\n }\r\n\r\n if(options.onlyMobile) {\r\n button.classList.add('only-handhelds');\r\n }\r\n\r\n if(options.disabled) {\r\n button.setAttribute('disabled', 'true');\r\n }\r\n\r\n if(options.text) {\r\n button.append(i18n(options.text));\r\n }\r\n\r\n return button;\r\n};\r\n\r\nexport default Button;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { CLICK_EVENT_NAME } from \"../helpers/dom/clickEvent\";\r\nimport ListenerSetter from \"../helpers/listenerSetter\";\r\nimport mediaSizes from \"../helpers/mediaSizes\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport { IS_APPLE, IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport appNavigationController from \"./appNavigationController\";\r\n\r\nexport function putPreloader(elem: Element, returnDiv = false): HTMLElement {\r\n const html = `\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"preloader-circular\" viewBox=\"25 25 50 50\">\r\n <circle class=\"preloader-path\" cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-miterlimit=\"10\"/>\r\n </svg>`;\r\n\r\n if(returnDiv) {\r\n const div = document.createElement('div');\r\n div.classList.add('preloader');\r\n div.innerHTML = html;\r\n\r\n if(elem) {\r\n elem.appendChild(div);\r\n }\r\n\r\n return div;\r\n }\r\n \r\n elem.insertAdjacentHTML('beforeend', html);\r\n return elem.lastElementChild as HTMLElement;\r\n}\r\n\r\nMOUNT_CLASS_TO.putPreloader = putPreloader;\r\n\r\nexport function setButtonLoader(elem: HTMLButtonElement, icon = 'check') {\r\n elem.classList.remove('tgico-' + icon);\r\n elem.disabled = true;\r\n putPreloader(elem);\r\n\r\n return () => {\r\n elem.innerHTML = '';\r\n elem.classList.add('tgico-' + icon);\r\n elem.removeAttribute('disabled');\r\n };\r\n}\r\n\r\n/* export function parseMenuButtonsTo(to: {[name: string]: HTMLElement}, elements: HTMLCollection | NodeListOf<HTMLElement>) {\r\n Array.from(elements).forEach(el => {\r\n const match = el.className.match(/(?:^|\\s)menu-(.+?)(?:$|\\s)/);\r\n if(!match) return;\r\n to[match[1]] = el as HTMLElement;\r\n });\r\n} */\r\n\r\nlet onMouseMove = (e: MouseEvent) => {\r\n let rect = openedMenu.getBoundingClientRect();\r\n let {clientX, clientY} = e;\r\n \r\n let diffX = clientX >= rect.right ? clientX - rect.right : rect.left - clientX;\r\n let diffY = clientY >= rect.bottom ? clientY - rect.bottom : rect.top - clientY;\r\n \r\n if(diffX >= 100 || diffY >= 100) {\r\n closeBtnMenu();\r\n //openedMenu.parentElement.click();\r\n }\r\n //console.log('mousemove', diffX, diffY);\r\n};\r\n\r\nconst onClick = (e: MouseEvent | TouchEvent) => {\r\n //cancelEvent(e);\r\n closeBtnMenu();\r\n};\r\n\r\n// ! no need in this due to the same handler in appNavigationController\r\n/* const onKeyDown = (e: KeyboardEvent) => {\r\n if(e.key === 'Escape') {\r\n closeBtnMenu();\r\n cancelEvent(e);\r\n }\r\n}; */\r\n\r\nexport const closeBtnMenu = () => {\r\n if(openedMenu) {\r\n openedMenu.classList.remove('active');\r\n openedMenu.parentElement.classList.remove('menu-open');\r\n //openedMenu.previousElementSibling.remove(); // remove overlay\r\n if(menuOverlay) menuOverlay.remove();\r\n openedMenu = null;\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', false);\r\n }\r\n \r\n if(openedMenuOnClose) {\r\n openedMenuOnClose();\r\n openedMenuOnClose = null;\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('mousemove', onMouseMove);\r\n //window.removeEventListener('keydown', onKeyDown, {capture: true});\r\n window.removeEventListener('contextmenu', onClick);\r\n }\r\n\r\n document.removeEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.removeByType('menu');\r\n }\r\n};\r\n\r\nwindow.addEventListener('resize', () => {\r\n if(openedMenu) {\r\n closeBtnMenu();\r\n }\r\n \r\n /* if(openedMenu && (openedMenu.style.top || openedMenu.style.left)) {\r\n const rect = openedMenu.getBoundingClientRect();\r\n const {innerWidth, innerHeight} = window;\r\n\r\n console.log(innerWidth, innerHeight, rect);\r\n } */\r\n});\r\n\r\nlet openedMenu: HTMLElement = null, openedMenuOnClose: () => void = null, menuOverlay: HTMLElement = null;\r\nexport function openBtnMenu(menuElement: HTMLElement, onClose?: () => void) {\r\n closeBtnMenu();\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.pushItem({\r\n type: 'menu',\r\n onPop: (canAnimate) => {\r\n closeBtnMenu();\r\n }\r\n });\r\n }\r\n \r\n openedMenu = menuElement;\r\n openedMenu.classList.add('active');\r\n openedMenu.parentElement.classList.add('menu-open');\r\n\r\n if(!menuOverlay) {\r\n menuOverlay = document.createElement('div');\r\n menuOverlay.classList.add('btn-menu-overlay');\r\n\r\n // ! because this event must be canceled, and can't cancel on menu click (below)\r\n menuOverlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n });\r\n }\r\n\r\n openedMenu.parentElement.insertBefore(menuOverlay, openedMenu);\r\n\r\n //document.body.classList.add('disable-hover');\r\n \r\n openedMenuOnClose = onClose;\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.addEventListener('mousemove', onMouseMove);\r\n //window.addEventListener('keydown', onKeyDown, {capture: true});\r\n window.addEventListener('contextmenu', onClick, {once: true});\r\n }\r\n\r\n /* // ! because this event must be canceled, and can't cancel on menu click (below)\r\n overlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n }); */\r\n \r\n // ! safari iOS doesn't handle window click event on overlay, idk why\r\n document.addEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', true);\r\n}\r\n\r\nconst PADDING_TOP = 8;\r\nconst PADDING_LEFT = 8;\r\nexport function positionMenu({pageX, pageY}: MouseEvent | Touch, elem: HTMLElement, side?: 'left' | 'right' | 'center') {\r\n //let {clientX, clientY} = e;\r\n\r\n // * side mean the OPEN side\r\n\r\n let {scrollWidth: menuWidth, scrollHeight: menuHeight} = elem;\r\n //let {innerWidth: windowWidth, innerHeight: windowHeight} = window;\r\n const rect = document.body.getBoundingClientRect();\r\n const windowWidth = rect.width;\r\n const windowHeight = rect.height;\r\n\r\n side = mediaSizes.isMobile ? 'right' : 'left';\r\n let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top';\r\n\r\n const getSides = () => {\r\n return {\r\n x: {\r\n left: pageX,\r\n right: pageX - menuWidth\r\n },\r\n intermediateX: side === 'right' ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,\r\n //intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,\r\n y: {\r\n top: pageY,\r\n bottom: pageY - menuHeight\r\n },\r\n //intermediateY: verticalSide === 'top' ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,\r\n intermediateY: pageY < windowHeight / 2 ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,\r\n };\r\n };\r\n\r\n const sides = getSides();\r\n\r\n const possibleSides = {\r\n x: {\r\n left: sides.x.left + menuWidth + PADDING_LEFT <= windowWidth,\r\n right: sides.x.right >= PADDING_LEFT\r\n },\r\n y: {\r\n top: sides.y.top + menuHeight + PADDING_TOP <= windowHeight,\r\n bottom: sides.y.bottom - PADDING_TOP >= PADDING_TOP\r\n }\r\n };\r\n\r\n /* if(side === undefined) {\r\n if((clientX + menuWidth + PADDING_LEFT) > windowWidth) {\r\n side = 'right';\r\n }\r\n } */\r\n\r\n {\r\n /* const x = sides.x;\r\n\r\n const s = Object.keys(x) as (keyof typeof possibleSides.x)[];\r\n if(side) {\r\n s.findAndSplice(s => s === side);\r\n s.unshift(side);\r\n }\r\n\r\n const possibleSide = s.find(s => possibleSides.x[s]); */\r\n let left: number;\r\n /* if(possibleSide) {\r\n left = x[possibleSide];\r\n side = possibleSide;\r\n } else {\r\n left = sides.intermediateX;\r\n side = undefined;\r\n } */\r\n left = possibleSides.x[side] ? sides.x[side] : (side = 'center', sides.intermediateX);\r\n \r\n elem.style.left = left + 'px';\r\n }\r\n\r\n /* if((clientY + menuHeight + PADDING_TOP) > windowHeight) {\r\n elem.style.top = clamp(clientY - menuHeight, PADDING_TOP, windowHeight - menuHeight - PADDING_TOP) + 'px';\r\n // elem.style.top = (innerHeight - scrollHeight - PADDING_TOP) + 'px';\r\n verticalSide = 'bottom';\r\n } else {\r\n elem.style.top = Math.max(PADDING_TOP, clientY) + 'px';\r\n verticalSide = 'top';\r\n } */\r\n\r\n {\r\n let top: number;\r\n\r\n top = possibleSides.y[verticalSide] ? sides.y[verticalSide] : (verticalSide = 'center', sides.intermediateY);\r\n \r\n elem.style.top = top + 'px';\r\n }\r\n \r\n elem.className = elem.className.replace(/(top|center|bottom)-(left|center|right)/g, '');\r\n elem.classList.add(\r\n //(verticalSide === 'center' ? verticalSide : (verticalSide === 'bottom' ? 'top' : 'bottom')) +\r\n (verticalSide === 'center' ? verticalSide : 'bottom') +\r\n '-' +\r\n (side === 'center' ? side : (side === 'left' ? 'right' : 'left')));\r\n}\r\n\r\nlet _cancelContextMenuOpening = false, _cancelContextMenuOpeningTimeout = 0;\r\nexport function cancelContextMenuOpening() {\r\n if(_cancelContextMenuOpeningTimeout) {\r\n clearTimeout(_cancelContextMenuOpeningTimeout);\r\n }\r\n \r\n _cancelContextMenuOpeningTimeout = window.setTimeout(() => {\r\n _cancelContextMenuOpeningTimeout = 0;\r\n _cancelContextMenuOpening = false;\r\n }, .4e3);\r\n\r\n _cancelContextMenuOpening = true;\r\n}\r\n\r\nexport function attachContextMenuListener(element: HTMLElement, callback: (e: Touch | MouseEvent) => void, listenerSetter?: ListenerSetter) {\r\n const add = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\r\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, element) : element.removeEventListener.bind(element);\r\n\r\n if(IS_APPLE && IS_TOUCH_SUPPORTED) {\r\n let timeout: number;\r\n\r\n const options: EventListenerOptions = {capture: true};\r\n\r\n const onCancel = () => {\r\n clearTimeout(timeout);\r\n // @ts-ignore\r\n remove('touchmove', onCancel, options);\r\n // @ts-ignore\r\n remove('touchend', onCancel, options);\r\n // @ts-ignore\r\n remove('touchcancel', onCancel, options);\r\n };\r\n\r\n add('touchstart', (e: TouchEvent) => {\r\n if(e.touches.length > 1) {\r\n onCancel();\r\n return;\r\n }\r\n \r\n add('touchmove', onCancel, options);\r\n add('touchend', onCancel, options);\r\n add('touchcancel', onCancel, options);\r\n\r\n timeout = window.setTimeout(() => {\r\n if(_cancelContextMenuOpening) {\r\n onCancel();\r\n return;\r\n }\r\n\r\n callback(e.touches[0]);\r\n onCancel();\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n }, .4e3);\r\n });\r\n\r\n /* if(!isSafari) {\r\n add('contextmenu', (e: any) => {\r\n cancelEvent(e);\r\n }, {passive: false, capture: true});\r\n } */\r\n } else {\r\n add('contextmenu', IS_TOUCH_SUPPORTED ? (e: any) => {\r\n callback(e);\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n } : callback);\r\n }\r\n};\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport { logger, LogTypes } from \"../lib/logger\";\r\nimport fastSmoothScroll, { ScrollOptions } from \"../helpers/fastSmoothScroll\";\r\nimport useHeavyAnimationCheck from \"../hooks/useHeavyAnimationCheck\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\n/*\r\nvar el = $0;\r\nvar height = 0;\r\nvar checkUp = false;\r\n\r\ndo {\r\n height += el.scrollHeight;\r\n} while(el = (checkUp ? el.previousElementSibling : el.nextElementSibling));\r\nconsole.log(height);\r\n*/\r\n\r\n/*\r\nArray.from($0.querySelectorAll('.bubble-content')).forEach(_el => {\r\n\t//_el.style.display = '';\t\r\n\t//return;\r\n\r\n\tlet el = _el.parentElement;\r\n\tlet height = el.scrollHeight;\r\n\tlet width = el.scrollWidth;\r\n\tel.style.width = width + 'px';\r\n\tel.style.height = height + 'px';\r\n\t_el.style.display = 'none';\r\n});\r\n*/\r\n\r\n/* const scrollables: Map<HTMLElement, Scrollable> = new Map();\r\nconst scrollsIntersector = new IntersectionObserver(entries => {\r\n for(let entry of entries) {\r\n const scrollable = scrollables.get(entry.target as HTMLElement);\r\n\r\n if(entry.isIntersecting) {\r\n scrollable.isVisible = true;\r\n } else {\r\n scrollable.isVisible = false;\r\n\r\n if(!isInDOM(entry.target)) {\r\n scrollsIntersector.unobserve(scrollable.container);\r\n scrollables.delete(scrollable.container);\r\n }\r\n }\r\n }\r\n}); */\r\n\r\nexport class ScrollableBase {\r\n protected log: ReturnType<typeof logger>;\r\n\r\n public onScrollMeasure: number = 0;\r\n protected onScroll: () => void;\r\n\r\n public isHeavyAnimationInProgress = false;\r\n protected needCheckAfterAnimation = false;\r\n\r\n constructor(public el: HTMLElement, logPrefix = '', public container: HTMLElement = document.createElement('div')) {\r\n this.container.classList.add('scrollable');\r\n\r\n this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : ''), LogTypes.Error);\r\n\r\n if(el) {\r\n Array.from(el.children).forEach(c => this.container.append(c));\r\n\r\n el.append(this.container);\r\n }\r\n //this.onScroll();\r\n }\r\n\r\n protected setListeners() {\r\n window.addEventListener('resize', this.onScroll, {passive: true});\r\n this.container.addEventListener('scroll', this.onScroll, {passive: true, capture: true});\r\n\r\n useHeavyAnimationCheck(() => {\r\n this.isHeavyAnimationInProgress = true;\r\n\r\n if(this.onScrollMeasure) {\r\n this.needCheckAfterAnimation = true;\r\n window.cancelAnimationFrame(this.onScrollMeasure);\r\n }\r\n }, () => {\r\n this.isHeavyAnimationInProgress = false;\r\n\r\n if(this.needCheckAfterAnimation) {\r\n this.onScroll();\r\n this.needCheckAfterAnimation = false;\r\n }\r\n });\r\n }\r\n\r\n public append(element: HTMLElement) {\r\n this.container.append(element);\r\n }\r\n\r\n public scrollIntoViewNew(options: Omit<ScrollOptions, 'container'>) {\r\n //return Promise.resolve();\r\n return fastSmoothScroll({\r\n ...options,\r\n container: this.container\r\n });\r\n }\r\n}\r\n\r\nexport type SliceSides = 'top' | 'bottom';\r\nexport type SliceSidesContainer = {[k in SliceSides]: boolean};\r\n\r\nexport default class Scrollable extends ScrollableBase {\r\n public splitUp: HTMLElement;\r\n public padding: HTMLElement;\r\n \r\n public onAdditionalScroll: () => void;\r\n public onScrolledTop: () => void;\r\n public onScrolledBottom: () => void;\r\n \r\n public lastScrollTop: number = 0;\r\n public lastScrollDirection: number = 0;\r\n\r\n public loadedAll: SliceSidesContainer = {top: true, bottom: false};\r\n\r\n constructor(el: HTMLElement, logPrefix = '', public onScrollOffset = 300, withPaddingContainer?: boolean) {\r\n super(el, logPrefix);\r\n\r\n /* if(withPaddingContainer) {\r\n this.padding = document.createElement('div');\r\n this.padding.classList.add('scrollable-padding');\r\n Array.from(this.container.children).forEach(c => this.padding.append(c));\r\n this.container.append(this.padding);\r\n } */\r\n\r\n this.container.classList.add('scrollable-y');\r\n this.setListeners();\r\n }\r\n\r\n public setVirtualContainer(el?: HTMLElement) {\r\n this.splitUp = el;\r\n this.log('setVirtualContainer:', el, this);\r\n }\r\n\r\n public onScroll = () => {\r\n //if(this.debug) {\r\n //this.log('onScroll call', this.onScrollMeasure);\r\n //}\r\n\r\n //return;\r\n\r\n if(this.isHeavyAnimationInProgress) {\r\n if(this.onScrollMeasure) {\r\n window.cancelAnimationFrame(this.onScrollMeasure);\r\n }\r\n\r\n this.needCheckAfterAnimation = true;\r\n return;\r\n }\r\n\r\n //if(this.onScrollMeasure || ((this.scrollLocked || (!this.onScrolledTop && !this.onScrolledBottom)) && !this.splitUp && !this.onAdditionalScroll)) return;\r\n if((!this.onScrolledTop && !this.onScrolledBottom) && !this.splitUp && !this.onAdditionalScroll) return;\r\n if(this.onScrollMeasure) window.cancelAnimationFrame(this.onScrollMeasure);\r\n this.onScrollMeasure = window.requestAnimationFrame(() => {\r\n this.onScrollMeasure = 0;\r\n\r\n const scrollTop = this.container.scrollTop;\r\n this.lastScrollDirection = this.lastScrollTop === scrollTop ? 0 : (this.lastScrollTop < scrollTop ? 1 : -1); // * 1 - bottom, -1 - top\r\n this.lastScrollTop = scrollTop;\r\n\r\n if(this.onAdditionalScroll && this.lastScrollDirection !== 0) {\r\n this.onAdditionalScroll();\r\n }\r\n \r\n if(this.checkForTriggers) {\r\n this.checkForTriggers();\r\n }\r\n });\r\n };\r\n\r\n public checkForTriggers = () => {\r\n if((!this.onScrolledTop && !this.onScrolledBottom)) return;\r\n\r\n if(this.isHeavyAnimationInProgress) {\r\n this.onScroll();\r\n return;\r\n }\r\n\r\n const scrollHeight = this.container.scrollHeight;\r\n if(!scrollHeight) { // незачем вызывать триггеры если блок пустой или не виден\r\n return;\r\n }\r\n\r\n const clientHeight = this.container.clientHeight;\r\n const maxScrollTop = scrollHeight - clientHeight;\r\n const scrollTop = this.lastScrollTop;\r\n\r\n //this.log('checkForTriggers:', scrollTop, maxScrollTop);\r\n\r\n if(this.onScrolledTop && scrollTop <= this.onScrollOffset && this.lastScrollDirection <= 0/* && direction === -1 */) {\r\n this.onScrolledTop();\r\n }\r\n\r\n if(this.onScrolledBottom && (maxScrollTop - scrollTop) <= this.onScrollOffset && this.lastScrollDirection >= 0/* && direction === 1 */) {\r\n this.onScrolledBottom();\r\n }\r\n };\r\n\r\n public prepend(...elements: (HTMLElement | DocumentFragment)[]) {\r\n (this.splitUp || this.padding || this.container).prepend(...elements);\r\n }\r\n\r\n public append(...elements: (HTMLElement | DocumentFragment)[]) {\r\n (this.splitUp || this.padding || this.container).append(...elements);\r\n }\r\n\r\n public getDistanceToEnd() {\r\n return this.scrollHeight - Math.round(this.scrollTop + this.container.offsetHeight);\r\n }\r\n\r\n get isScrolledDown() {\r\n return this.getDistanceToEnd() <= 1;\r\n }\r\n\r\n set scrollTop(y: number) {\r\n this.container.scrollTop = y;\r\n }\r\n \r\n get scrollTop() {\r\n //this.log.trace('get scrollTop');\r\n return this.container.scrollTop;\r\n }\r\n \r\n get scrollHeight() {\r\n return this.container.scrollHeight;\r\n }\r\n}\r\n\r\nexport class ScrollableX extends ScrollableBase {\r\n constructor(el: HTMLElement, logPrefix = '', public onScrollOffset = 300, public splitCount = 15, public container: HTMLElement = document.createElement('div')) {\r\n super(el, logPrefix, container);\r\n\r\n this.container.classList.add('scrollable-x');\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n const scrollHorizontally = (e: any) => {\r\n if(!e.deltaX && this.container.scrollWidth > this.container.clientWidth) {\r\n this.container.scrollLeft += e.deltaY / 4;\r\n cancelEvent(e);\r\n }\r\n };\r\n \r\n this.container.addEventListener('wheel', scrollHorizontally, {passive: false});\r\n }\r\n }\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport { IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport { logger } from \"../lib/logger\";\r\nimport { doubleRaf } from \"../helpers/schedulers\";\r\nimport blurActiveElement from \"../helpers/dom/blurActiveElement\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { indexOfAndSplice } from \"../helpers/array\";\r\nimport isSwipingBackSafari from \"../helpers/dom/isSwipingBackSafari\";\r\n\r\nexport type NavigationItem = {\r\n type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' | \r\n 'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' | \r\n 'global-search' | 'voice' | 'mobile-search',\r\n onPop: (canAnimate: boolean) => boolean | void,\r\n onEscape?: () => boolean,\r\n noHistory?: boolean,\r\n noBlurOnPop?: boolean,\r\n};\r\n\r\nexport class AppNavigationController {\r\n private navigations: Array<NavigationItem> = [];\r\n private id = Date.now();\r\n private manual = false;\r\n private log = logger('NC');\r\n private debug = true;\r\n private currentHash = window.location.hash;\r\n public onHashChange: () => void;\r\n\r\n constructor() {\r\n let isPossibleSwipe = false;\r\n window.addEventListener('popstate', (e) => {\r\n this.debug && this.log('popstate', e, isPossibleSwipe);\r\n\r\n if(window.location.hash !== this.currentHash) {\r\n this.onHashChange && this.onHashChange();\r\n this.replaceState();\r\n return;\r\n }\r\n this.currentHash = window.location.hash;\r\n\r\n const id: number = e.state;\r\n if(id !== this.id/* && !this.navigations.length */) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n const item = this.navigations.pop();\r\n if(!item) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n this.manual = !isPossibleSwipe;\r\n this.handleItem(item);\r\n //this.pushState(); // * prevent adding forward arrow\r\n });\r\n\r\n window.addEventListener('keydown', (e) => {\r\n const item = this.navigations[this.navigations.length - 1];\r\n if(!item) return;\r\n if(e.key === 'Escape' && (item.onEscape ? item.onEscape() : true)) {\r\n cancelEvent(e);\r\n this.back(item.type);\r\n }\r\n }, {capture: true, passive: false});\r\n\r\n if(IS_MOBILE_SAFARI) {\r\n const options = {passive: true};\r\n window.addEventListener('touchstart', (e) => {\r\n if(e.touches.length > 1) return;\r\n this.debug && this.log('touchstart');\r\n\r\n if(isSwipingBackSafari(e)) {\r\n isPossibleSwipe = true;\r\n\r\n window.addEventListener('touchend', () => {\r\n setTimeout(() => {\r\n isPossibleSwipe = false;\r\n }, 100);\r\n }, {passive: true, once: true});\r\n }\r\n\r\n /* const detach = () => {\r\n window.removeEventListener('touchend', onTouchEnd);\r\n window.removeEventListener('touchmove', onTouchMove);\r\n };\r\n\r\n let moved = false;\r\n const onTouchMove = (e: TouchEvent) => {\r\n this.debug && this.log('touchmove');\r\n if(e.touches.length > 1) {\r\n detach();\r\n return;\r\n }\r\n\r\n moved = true;\r\n };\r\n\r\n const onTouchEnd = (e: TouchEvent) => {\r\n this.debug && this.log('touchend');\r\n if(e.touches.length > 1 || !moved) {\r\n detach();\r\n return;\r\n }\r\n\r\n isPossibleSwipe = true;\r\n doubleRaf().then(() => {\r\n isPossibleSwipe = false;\r\n });\r\n\r\n detach();\r\n };\r\n\r\n window.addEventListener('touchend', onTouchEnd, options);\r\n window.addEventListener('touchmove', onTouchMove, options); */\r\n }, options);\r\n }\r\n\r\n history.scrollRestoration = 'manual';\r\n\r\n this.pushState(); // * push init state\r\n }\r\n\r\n private handleItem(item: NavigationItem) {\r\n const good = item.onPop(!this.manual ? false : undefined);\r\n this.debug && this.log('popstate, navigation:', item, this.navigations);\r\n if(good === false) {\r\n this.pushItem(item);\r\n } else if(!item.noBlurOnPop) {\r\n blurActiveElement(); // no better place for it\r\n }\r\n\r\n this.manual = false;\r\n }\r\n\r\n public findItemByType(type: NavigationItem['type']) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n return {item, index: i};\r\n }\r\n }\r\n }\r\n\r\n public back(type?: NavigationItem['type']) {\r\n if(type) {\r\n const ret = this.findItemByType(type);\r\n if(ret) {\r\n this.backByItem(ret.item, ret.index);\r\n return;\r\n }\r\n }\r\n\r\n history.back();\r\n }\r\n\r\n public backByItem(item: NavigationItem, index = this.navigations.indexOf(item)) {\r\n this.manual = true;\r\n // ! commented because 'popstate' event will be fired with delay\r\n //if(index !== (this.navigations.length - 1)) {\r\n this.navigations.splice(index, 1);\r\n this.handleItem(item);\r\n //}\r\n }\r\n\r\n public pushItem(item: NavigationItem) {\r\n this.navigations.push(item);\r\n this.debug && this.log('pushstate', item, this.navigations);\r\n\r\n if(!item.noHistory) {\r\n this.pushState();\r\n }\r\n }\r\n\r\n private pushState() {\r\n this.manual = false;\r\n history.pushState(this.id, '');\r\n }\r\n\r\n public replaceState() {\r\n history.replaceState(this.id, '', location.origin + location.pathname);\r\n }\r\n\r\n public removeItem(item: NavigationItem) {\r\n if(!item) {\r\n return;\r\n }\r\n \r\n indexOfAndSplice(this.navigations, item);\r\n }\r\n\r\n public removeByType(type: NavigationItem['type'], single = false) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n this.navigations.splice(i, 1);\r\n\r\n if(single) {\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst appNavigationController = new AppNavigationController();\r\nMOUNT_CLASS_TO.appNavigationController = appNavigationController;\r\nexport default appNavigationController;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport appStateManager from \"../lib/appManagers/appStateManager\";\r\nimport { getDeepProperty } from \"../helpers/object\";\r\nimport { ripple } from \"./ripple\";\r\nimport { LangPackKey, _i18n } from \"../lib/langPack\";\r\n\r\nexport type CheckboxFieldOptions = {\r\n text?: LangPackKey,\r\n textArgs?: any[],\r\n name?: string, \r\n round?: boolean, \r\n toggle?: boolean,\r\n stateKey?: string,\r\n stateValues?: any[],\r\n disabled?: boolean,\r\n checked?: boolean,\r\n restriction?: boolean,\r\n withRipple?: boolean,\r\n withHover?: boolean,\r\n};\r\nexport default class CheckboxField {\r\n public input: HTMLInputElement;\r\n public label: HTMLLabelElement;\r\n public span: HTMLSpanElement;\r\n\r\n constructor(options: CheckboxFieldOptions = {}) {\r\n const label = this.label = document.createElement('label');\r\n label.classList.add('checkbox-field');\r\n\r\n if(options.restriction) {\r\n label.classList.add('checkbox-field-restriction');\r\n }\r\n\r\n if(options.round) {\r\n label.classList.add('checkbox-field-round');\r\n }\r\n\r\n if(options.disabled) {\r\n this.toggleDisability(true);\r\n }\r\n\r\n const input = this.input = document.createElement('input');\r\n input.classList.add('checkbox-field-input');\r\n input.type = 'checkbox';\r\n if(options.name) {\r\n input.id = 'input-' + options.name;\r\n }\r\n\r\n if(options.checked) {\r\n input.checked = true;\r\n }\r\n\r\n if(options.stateKey) {\r\n appStateManager.getState().then(state => {\r\n const stateValue = getDeepProperty(state, options.stateKey);\r\n let checked: boolean;\r\n if(options.stateValues) {\r\n checked = options.stateValues.indexOf(stateValue) === 1;\r\n } else {\r\n checked = stateValue;\r\n }\r\n\r\n this.setValueSilently(checked);\r\n\r\n input.addEventListener('change', () => {\r\n let value: any;\r\n if(options.stateValues) {\r\n value = options.stateValues[input.checked ? 1 : 0];\r\n } else {\r\n value = input.checked;\r\n }\r\n\r\n appStateManager.setByKey(options.stateKey, value);\r\n });\r\n });\r\n }\r\n\r\n let span: HTMLSpanElement;\r\n if(options.text) {\r\n span = this.span = document.createElement('span');\r\n span.classList.add('checkbox-caption');\r\n _i18n(span, options.text, options.textArgs);\r\n } else {\r\n label.classList.add('checkbox-without-caption');\r\n }\r\n\r\n label.append(input);\r\n\r\n if(options.toggle) {\r\n label.classList.add('checkbox-field-toggle');\r\n\r\n const toggle = document.createElement('div');\r\n toggle.classList.add('checkbox-toggle');\r\n label.append(toggle);\r\n } else {\r\n const box = document.createElement('div');\r\n box.classList.add('checkbox-box');\r\n \r\n const checkSvg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n checkSvg.classList.add('checkbox-box-check');\r\n checkSvg.setAttributeNS(null, 'viewBox', '0 0 24 24');\r\n const use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(null, 'href', '#check');\r\n use.setAttributeNS(null, 'x', '-1');\r\n checkSvg.append(use);\r\n \r\n const bg = document.createElement('div');\r\n bg.classList.add('checkbox-box-background');\r\n \r\n const border = document.createElement('div');\r\n border.classList.add('checkbox-box-border');\r\n \r\n box.append(border, bg, checkSvg);\r\n \r\n label.append(box);\r\n }\r\n\r\n if(span) {\r\n label.append(span);\r\n }\r\n\r\n if(options.withRipple) {\r\n label.classList.add('checkbox-ripple', 'hover-effect');\r\n ripple(label, undefined, undefined, true);\r\n //label.prepend(input);\r\n } else if(options.withHover) {\r\n label.classList.add('hover-effect');\r\n }\r\n }\r\n\r\n get checked() {\r\n return this.input.checked;\r\n }\r\n\r\n set checked(checked: boolean) {\r\n /* if(this.checked === checked) {\r\n return;\r\n } */\r\n \r\n this.setValueSilently(checked);\r\n\r\n const event = new Event('change', {bubbles: true, cancelable: true});\r\n this.input.dispatchEvent(event);\r\n }\r\n\r\n public setValueSilently(checked: boolean) {\r\n this.input.checked = checked;\r\n }\r\n\r\n public toggleDisability(disable: boolean) {\r\n this.label.classList.toggle('checkbox-disabled', disable);\r\n return () => this.toggleDisability(!disable);\r\n }\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nexport default function toggleDisability(elements: HTMLElement[], disable: boolean): () => void {\r\n if(disable) {\r\n elements.forEach(el => el.setAttribute('disabled', 'true'));\r\n } else {\r\n elements.forEach(el => el.removeAttribute('disabled'));\r\n }\r\n\r\n return () => toggleDisability(elements, !disable);\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n * \r\n * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nexport function bytesToHex(bytes: ArrayLike<number>) {\r\n const length = bytes.length;\r\n const arr: string[] = new Array(length);\r\n for(let i = 0; i < length; ++i) {\r\n arr[i] = (bytes[i] < 16 ? '0' : '') + (bytes[i] || 0).toString(16);\r\n }\r\n return arr.join('');\r\n}\r\n\r\nexport function bytesFromHex(hexString: string) {\r\n const len = hexString.length;\r\n const bytes = new Uint8Array(Math.ceil(len / 2));\r\n let start = 0;\r\n\r\n if(len % 2) { // read 0x581 as 0x0581\r\n bytes[start++] = parseInt(hexString.charAt(0), 16);\r\n }\r\n\r\n for(let i = start; i < len; i += 2) {\r\n bytes[start++] = parseInt(hexString.substr(i, 2), 16);\r\n }\r\n\r\n return bytes;\r\n}\r\n\r\nexport function bytesToBase64(bytes: number[] | Uint8Array) {\r\n let mod3: number;\r\n let result = '';\r\n\r\n for(let nLen = bytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; ++nIdx) {\r\n mod3 = nIdx % 3;\r\n nUint24 |= bytes[nIdx] << (16 >>> mod3 & 24);\r\n if(mod3 === 2 || nLen - nIdx === 1) {\r\n result += String.fromCharCode(\r\n uint6ToBase64(nUint24 >>> 18 & 63),\r\n uint6ToBase64(nUint24 >>> 12 & 63),\r\n uint6ToBase64(nUint24 >>> 6 & 63),\r\n uint6ToBase64(nUint24 & 63)\r\n );\r\n nUint24 = 0;\r\n }\r\n }\r\n\r\n return result.replace(/A(?=A$|$)/g, '=');\r\n}\r\n\r\nexport function uint6ToBase64(nUint6: number) {\r\n return nUint6 < 26\r\n ? nUint6 + 65\r\n : nUint6 < 52\r\n ? nUint6 + 71\r\n : nUint6 < 62\r\n ? nUint6 - 4\r\n : nUint6 === 62\r\n ? 43\r\n : nUint6 === 63\r\n ? 47\r\n : 65;\r\n}\r\n\r\nexport function bytesCmp(bytes1: number[] | Uint8Array, bytes2: number[] | Uint8Array) {\r\n const len = bytes1.length;\r\n if(len !== bytes2.length) {\r\n return false;\r\n }\r\n\r\n for(let i = 0; i < len; ++i) {\r\n if(bytes1[i] !== bytes2[i]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function bytesXor(bytes1: Uint8Array, bytes2: Uint8Array) {\r\n const len = bytes1.length;\r\n const bytes = new Uint8Array(len);\r\n\r\n for(let i = 0; i < len; ++i) {\r\n bytes[i] = bytes1[i] ^ bytes2[i];\r\n }\r\n\r\n return bytes;\r\n}\r\n\r\n/* export function bytesToArrayBuffer(b: number[]) {\r\n return (new Uint8Array(b)).buffer;\r\n}\r\n\r\nexport function convertToArrayBuffer(bytes: any | ArrayBuffer | Uint8Array) {\r\n // Be careful with converting subarrays!!\r\n if(bytes instanceof ArrayBuffer) {\r\n return bytes;\r\n }\r\n if(bytes.buffer !== undefined &&\r\n bytes.buffer.byteLength === bytes.length * bytes.BYTES_PER_ELEMENT) {\r\n return bytes.buffer;\r\n }\r\n return bytesToArrayBuffer(bytes);\r\n} */\r\n\r\nexport function convertToUint8Array(bytes: Uint8Array | ArrayBuffer | number[] | string): Uint8Array {\r\n if(bytes instanceof Uint8Array) {\r\n return bytes;\r\n } else if(typeof(bytes) === 'string') {\r\n return new TextEncoder().encode(bytes);\r\n }\r\n\r\n return new Uint8Array(bytes);\r\n}\r\n\r\n/* export function bytesFromArrayBuffer(buffer: ArrayBuffer) {\r\n const len = buffer.byteLength;\r\n const byteView = new Uint8Array(buffer);\r\n const bytes: number[] = [];\r\n\r\n for(let i = 0; i < len; ++i) {\r\n bytes[i] = byteView[i];\r\n }\r\n\r\n return bytes;\r\n}\r\n\r\nexport function bufferConcat(buffer1: any, buffer2: any) {\r\n const l1 = buffer1.byteLength || buffer1.length;\r\n const l2 = buffer2.byteLength || buffer2.length;\r\n const tmp = new Uint8Array(l1 + l2);\r\n tmp.set(buffer1 instanceof ArrayBuffer ? new Uint8Array(buffer1) : buffer1, 0);\r\n tmp.set(buffer2 instanceof ArrayBuffer ? new Uint8Array(buffer2) : buffer2, l1);\r\n\r\n return tmp.buffer;\r\n} */\r\n\r\nexport function bufferConcats(...args: (ArrayBuffer | Uint8Array | number[])[]) {\r\n const length = args.reduce((acc, v) => acc + ((v as ArrayBuffer).byteLength || (v as Uint8Array).length), 0);\r\n\r\n const tmp = new Uint8Array(length);\r\n \r\n let lastLength = 0;\r\n args.forEach(b => {\r\n tmp.set(b instanceof ArrayBuffer ? new Uint8Array(b) : b, lastLength);\r\n lastLength += (b as ArrayBuffer).byteLength || (b as Uint8Array).length;\r\n });\r\n\r\n return tmp/* .buffer */;\r\n}\r\n\r\nexport function bytesFromWordss(input: Uint32Array) {\r\n const o = new Uint8Array(input.byteLength);\r\n for(let i = 0, length = input.length * 4; i < length; ++i) {\r\n o[i] = ((input[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);\r\n }\r\n\r\n return o;\r\n}\r\n\r\nexport function bytesToWordss(input: Parameters<typeof convertToUint8Array>[0]) {\r\n const bytes = convertToUint8Array(input);\r\n\r\n const words: number[] = [];\r\n for(let i = 0, len = bytes.length; i < len; ++i) {\r\n words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8);\r\n }\r\n\r\n return new Uint32Array(words);\r\n}\r\n\r\n// * https://stackoverflow.com/a/52827031\r\n/* export const isBigEndian = (() => {\r\n const array = new Uint8Array(4);\r\n const view = new Uint32Array(array.buffer);\r\n return !((view[0] = 1) & array[0]);\r\n})(); */\r\n","export default function simulateEvent(elem: EventTarget, name: string) {\n const event = new Event(name, {bubbles: true, cancelable: true});\n elem.dispatchEvent(event);\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nexport default function findUpTag(el: any, tag: string): HTMLElement {\r\n return el.closest(tag);\r\n /* if(el.tagName === tag) return el; // 03.02.2020\r\n\r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.tagName === tag) \r\n return el;\r\n }\r\n return null; */\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { fastRaf } from \"./schedulers\";\r\nimport { CancellablePromise, deferredPromise } from \"./cancellablePromise\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport isInDOM from \"./dom/isInDOM\";\r\n\r\nclass SequentialDom {\r\n private promises: Partial<{\r\n read: CancellablePromise<void>,\r\n write: CancellablePromise<void>\r\n }> = {};\r\n private raf = fastRaf.bind(null);\r\n private scheduled = false;\r\n\r\n private do(kind: keyof SequentialDom['promises'], callback?: VoidFunction) {\r\n let promise = this.promises[kind];\r\n if(!promise) {\r\n this.scheduleFlush();\r\n promise = this.promises[kind] = deferredPromise<void>();\r\n }\r\n\r\n if(callback !== undefined) {\r\n promise.then(() => callback());\r\n }\r\n \r\n return promise;\r\n }\r\n\r\n public measure(callback?: VoidFunction) {\r\n return this.do('read', callback);\r\n }\r\n\r\n public mutate(callback?: VoidFunction) {\r\n return this.do('write', callback);\r\n }\r\n\r\n /**\r\n * Will fire instantly if element is not connected\r\n * @param element \r\n * @param callback \r\n */\r\n public mutateElement(element: HTMLElement, callback?: VoidFunction) {\r\n const promise = isInDOM(element) ? this.mutate() : Promise.resolve();\r\n\r\n if(callback !== undefined) {\r\n promise.then(() => callback());\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n private scheduleFlush() {\r\n if(!this.scheduled) {\r\n this.scheduled = true;\r\n\r\n this.raf(() => {\r\n this.promises.read && this.promises.read.resolve();\r\n this.promises.write && this.promises.write.resolve();\r\n\r\n this.scheduled = false;\r\n this.promises = {};\r\n });\r\n }\r\n }\r\n}\r\n\r\nconst sequentialDom = new SequentialDom();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.sequentialDom = sequentialDom);\r\nexport default sequentialDom;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n * \r\n * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nimport type { ApplyServerTimeOffsetTask } from './timeManager';\r\nimport { MOUNT_CLASS_TO } from '../../config/debug';\r\n// import { tsNow } from '../../helpers/date';\r\nimport sessionStorage from '../sessionStorage';\r\nimport apiManager from './mtprotoworker';\r\n\r\nexport class ServerTimeManager {\r\n /* private midnightNoOffset: number;\r\n private midnightOffseted: Date;\r\n\r\n private midnightOffset: number; */\r\n\r\n public serverTimeOffset: number; // in seconds\r\n /* private timeParams: {\r\n midnightOffset: number,\r\n serverTimeOffset: number\r\n }; */\r\n\r\n constructor() {\r\n /* const timestampNow = tsNow(true);\r\n this.midnightNoOffset = timestampNow - (timestampNow % 86400);\r\n this.midnightOffseted = new Date();\r\n this.midnightOffseted.setHours(0, 0, 0, 0);\r\n \r\n this.midnightOffset = this.midnightNoOffset - (Math.floor(+this.midnightOffseted / 1000)); */\r\n\r\n this.serverTimeOffset = 0;\r\n /* this.timeParams = {\r\n midnightOffset: this.midnightOffset,\r\n serverTimeOffset: this.serverTimeOffset\r\n }; */\r\n\r\n sessionStorage.get('server_time_offset').then((to) => {\r\n if(to) {\r\n this.serverTimeOffset = to;\r\n // this.timeParams.serverTimeOffset = to;\r\n }\r\n });\r\n\r\n apiManager.addTaskListener('applyServerTimeOffset', (task: ApplyServerTimeOffsetTask) => {\r\n this.serverTimeOffset = task.payload;\r\n });\r\n }\r\n}\r\n\r\nconst serverTimeManager = new ServerTimeManager();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.serverTimeManager = serverTimeManager);\r\nexport default serverTimeManager;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n * \r\n * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nimport { IS_TOUCH_SUPPORTED } from \"../../environment/touchSupport\";\r\n\r\nexport default function placeCaretAtEnd(el: HTMLElement, ignoreTouchCheck = false) {\r\n if(IS_TOUCH_SUPPORTED && (!ignoreTouchCheck || document.activeElement !== el)) {\r\n return;\r\n }\r\n \r\n el.focus();\r\n if(typeof window.getSelection !== \"undefined\" && typeof document.createRange !== \"undefined\") {\r\n var range = document.createRange();\r\n range.selectNodeContents(el);\r\n range.collapse(false);\r\n var sel = window.getSelection();\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n // @ts-ignore\r\n } else if(typeof document.body.createTextRange !== \"undefined\") {\r\n // @ts-ignore\r\n var textRange = document.body.createTextRange();\r\n textRange.moveToElementText(el);\r\n textRange.collapse(false);\r\n textRange.select();\r\n }\r\n}\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport { IS_MOBILE_SAFARI } from \"../../environment/userAgent\";\n\nexport default function isSwipingBackSafari(e: TouchEvent | MouseEvent) {\n return IS_MOBILE_SAFARI && e instanceof TouchEvent && e.touches[0].clientX < 30;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport { HelpCountry, HelpCountryCode } from \"../layer\";\nimport I18n from \"../lib/langPack\";\n\nlet sortedCountries: HelpCountry[];\ntype PrefixCountry = {country: HelpCountry, code: HelpCountryCode};\nconst prefixes: Map<string, PrefixCountry> = new Map();\nlet maxPrefixLength = 0;\nconst setPrefix = (country: HelpCountry, code: HelpCountryCode, prefix: string = '') => {\n prefix = code.country_code + prefix;\n /* if(prefixes.has(prefix)) {\n console.error('asdasdasd', prefixes.get(prefix), country, code);\n } */\n maxPrefixLength = Math.max(maxPrefixLength, prefix.length);\n prefixes.set(prefix, {country, code});\n};\n\nexport function formatPhoneNumber(originalStr: string): {\n formatted: string,\n country: HelpCountry,\n code: HelpCountryCode,\n leftPattern: string\n} {\n originalStr = originalStr || '';\n \n if(!prefixes.size) {\n I18n.countriesList.forEach(country => {\n country.country_codes.forEach(code => {\n const s = {country, code};\n\n if(code.prefixes) {\n code.prefixes.forEach(prefix => {\n setPrefix(country, code, prefix);\n });\n } else {\n setPrefix(country, code);\n }\n });\n });\n }\n\n // return {formatted: originalStr, country: undefined as any, leftPattern: ''};\n let str = originalStr.replace(/\\D/g, '');\n let phoneCode = str.slice(0, maxPrefixLength);\n \n ////console.log('str', str, phoneCode);\n // if(!sortedCountries) {\n // sortedCountries = I18n.countriesList.slice().sort((a, b) => b.country_codes[0].country_code.length - a.country_codes[0].country_code.length);\n // }\n \n // let country = sortedCountries.find((c) => {\n // return c.country_codes.find((c) => phoneCode.indexOf(c.replace(/\\D/g, '')) === 0);\n // });\n\n let prefixCountry: PrefixCountry;\n for(let i = phoneCode.length - 1; i >= 0; --i) { // lookup for country by prefix\n prefixCountry = prefixes.get(phoneCode.slice(0, i + 1));\n if(prefixCountry) {\n break;\n }\n }\n\n if(!prefixCountry) {\n return {\n formatted: str, \n country: undefined, \n code: undefined, \n leftPattern: ''\n };\n }\n\n // country = /* PhoneCodesMain[country.phoneCode] || */country;\n const country = prefixCountry.country;\n \n const patterns = prefixCountry.code.patterns || [];\n const searchForPattern = str.slice(prefixCountry.code.country_code.length); // splice country code\n let pattern = '', mostMatchedPatternMatches = 0, mostMatchedPattern = '';\n for(let i = patterns.length - 1; i >= 0; --i) {\n pattern = patterns[i];\n\n const _pattern = pattern.replace(/ /g, '');\n let patternMatches = 0;\n for(let k = 0, length = Math.min(searchForPattern.length, _pattern.length); k < length; ++k) {\n if(searchForPattern[k] === _pattern[k] || _pattern[k] === 'X') {\n ++patternMatches;\n } else {\n patternMatches = 0;\n break;\n }\n }\n\n if(patternMatches > mostMatchedPatternMatches) {\n mostMatchedPatternMatches = patternMatches;\n mostMatchedPattern = pattern;\n }\n }\n\n pattern = mostMatchedPattern || pattern;\n pattern = pattern.replace(/\\d/g, 'X');\n\n pattern = prefixCountry.code.country_code + ' ' + pattern;\n // let pattern = country.pattern || country.phoneCode;\n pattern.split('').forEach((symbol, idx) => {\n if(symbol === ' ' && str[idx] !== ' ' && str.length > idx) {\n str = str.slice(0, idx) + ' ' + str.slice(idx);\n }\n });\n \n /* if(country.pattern) {\n str = str.slice(0, country.pattern.length);\n } */\n\n let leftPattern = pattern && pattern.length > str.length ? pattern.slice(str.length) : '';\n if(leftPattern) {\n /* const length = str.length;\n leftPattern = leftPattern.split('').map((_, idx) => (length + idx).toString().slice(-1)).join(''); */\n leftPattern = leftPattern.replace(/X/g, '‒');\n // leftPattern = leftPattern.replace(/X/g, '0');\n }\n \n return {formatted: str, country, code: prefixCountry.code, leftPattern};\n}\n"],"sourceRoot":""} |