1 line
120 KiB
Plaintext
1 line
120 KiB
Plaintext
{"version":3,"sources":["webpack:///./src/pages/pageSignIn.ts","webpack:///./src/pages/pageSignQR.ts","webpack:///./src/pages/pageAuthCode.ts","webpack:///./src/helpers/dom/replaceContent.ts","webpack:///./src/components/inputField.ts","webpack:///./src/components/scrollable.ts","webpack:///./src/helpers/dom/getRichValue.ts","webpack:///./src/components/checkboxField.ts","webpack:///./src/helpers/dom/toggleDisability.ts","webpack:///./src/helpers/dom/findUpTag.ts","webpack:///./src/lib/mtproto/serverTimeManager.ts","webpack:///./src/helpers/dom/getRichElementValue.ts","webpack:///./src/helpers/dom/findUpAttribute.ts","webpack:///./src/helpers/dom/isInputEmpty.ts","webpack:///./src/helpers/bytes.ts","webpack:///./src/lib/filemanager.ts","webpack:///./src/lib/cacheStorage.ts","webpack:///./src/components/languageChangeButton.ts","webpack:///./src/components/monkeys/tracking.ts","webpack:///./src/components/codeInputField.ts"],"names":["btnQr","btnNext","page","test","push","name","phoneCode","code","emoji","pattern","console","log","countries","filter","c","sort","a","b","localeCompare","lastCountrySelected","inputWrapper","document","createElement","classList","add","countryInputField","label","plainText","container","countryInput","input","autocomplete","selectWrapper","arrowDown","append","selectList","appendChild","initSelect","forEach","liArr","split","li","wrapped","wrapEmojiText","emojiSupported","spanEmoji","innerHTML","span","innerText","addEventListener","e","button","target","tagName","selectCountryByTarget","countryName","childNodes","textContent","querySelector","value","find","telEl","lastValue","hidePicker","setTimeout","focus","hideTimeout","style","display","clearTimeout","undefined","remove","offsetWidth","select","pageEl","parentElement","mouseDownHandlerAttached","onMouseDown","capture","removeEventListener","window","ctrlKey","key","_value","this","toLowerCase","matches","good","indexOf","length","cancelBubble","preventDefault","blur","pasted","telInputField","type","loadLottieWorkers","formatted","country","Math","abs","setLabel","replace","o","visibility","metaKey","shiftKey","onSubmit","signedCheckboxField","text","withRipple","checked","keepSigned","pushToState","toggleStorage","getState","then","state","storage","isAvailable","toggle","phone_number","invokeApi","api_id","id","api_hash","hash","settings","_","m","default","mount","Object","assign","catch","err","setError","error","h4","subtitle","nearestDcResult","dcs","Set","done","this_dc","promise","nearest_dc","getNetworker","Promise","resolve","dcId","delete","_dcs","g","shift","dbKey","get","finally","removeAttribute","cachedPromise","imageDiv","preloader","btnBack","helpList","stop","QRCodeStyling","all","once","prevToken","options","ignoreErrors","iterate","isLoop","loginToken","except_ids","dc_id","setBaseDcId","token","authorization","setUserAuth","user","url","getComputedStyle","documentElement","surfaceColor","getPropertyValue","trim","textColor","primaryColor","logoUrl","fetch","res","blob","Blob","reader","FileReader","onload","result","readAsDataURL","qrCode","width","devicePixelRatio","height","data","image","dotsOptions","color","cornersSquareOptions","imageOptions","imageSize","margin","backgroundOptions","qrOptions","errorCorrectionLevel","lastChild","_drawingPromise","race","_canvas","_image","requestAnimationFrame","animation","children","Array","from","slice","el","timestamp","Date","now","diff","expires","serverTimeOffset","warn","handled","func","codeInput","authCode","headerElement","sentTypeElement","CODELENGTH","codeInputField","onFill","submitCode","cleanup","monkey","setAttribute","params","phone_code_hash","phone_code","response","size","isMobile","load","_authCode","evt","createEvent","initEvent","dispatchEvent","getElementsByClassName","args","sentCode","replaceContent","elem","node","firstChild","replaceWith","init","originalEvent","clipboardData","getData","entities","parseEntities","wrapRichText","noLinks","wrappingDraft","execCommand","InputState","maxLength","showLengthOn","round","placeholder","processInput","labelText","firstElementChild","observer","MutationObserver","inputFake","onFakeInput","observe","characterData","childList","subtree","animate","wasInputFakeClientHeight","showScrollDebounced","className","border","labelEl","lastElementChild","showingLength","wasError","contains","inputLength","isError","labelOptions","scrollHeight","clientHeight","setValueSilently","event","Event","bubbles","cancelable","fireFakeInput","originalValue","silent","wrapDraftText","Error","Valid","setState","ScrollableBase","logPrefix","onScrollMeasure","isHeavyAnimationInProgress","needCheckAfterAnimation","onScroll","passive","cancelAnimationFrame","element","position","maxDistance","forceDirection","forceDuration","axis","Scrollable","onScrollOffset","withPaddingContainer","super","onAdditionalScroll","onScrolledTop","onScrolledBottom","lastScrollTop","lastScrollDirection","loadedAll","top","bottom","splitUp","scrollTop","checkForTriggers","maxScrollTop","setListeners","elements","padding","prepend","offsetHeight","getDistanceToEnd","y","ScrollableX","splitCount","scrollHorizontally","deltaX","scrollWidth","clientWidth","scrollLeft","deltaY","getRichValue","field","withEntities","lines","line","join","combineSameEntities","CheckboxField","restriction","disabled","toggleDisability","stateKey","stateValue","stateValues","setByKey","textArgs","box","checkSvg","createElementNS","setAttributeNS","use","bg","withHover","disable","findUpTag","tag","closest","serverTimeManager","to","addTaskListener","task","payload","markdownTags","bold","match","entityName","underline","italic","monospace","strikethrough","link","mentionName","getRichElementValue","selNode","selOffset","offset","nodeType","nodeValue","substr","parentNode","getAttribute","href","user_id","dataset","follow","isSelected","isBlock","splice","alt","curChild","nextSibling","findUpAttribute","attribute","isInputEmpty","hasAttribute","bytesToHex","bytes","arr","i","toString","bytesFromHex","hexString","len","Uint8Array","ceil","start","parseInt","charAt","bytesToBase64","mod3","nLen","nUint24","nIdx","String","fromCharCode","uint6ToBase64","nUint6","bytesCmp","bytes1","bytes2","bufferConcats","reduce","acc","v","byteLength","tmp","lastLength","set","ArrayBuffer","blobSupported","fileWriter","write","mimeType","saveFileCallback","blobParts","part","truncate","finalize","saveToStorage","dbName","useStorage","STORAGES","openDatabase","openDbPromise","caches","open","entryName","timeoutOperation","cache","put","fileName","method","Response","headers","save","callback","reject","rejected","timeout","fakeWriter","getFakeFileWriter","saveFile","enabled","map","deleteAll","times","getLanguageChangeButton","appendTo","getConfig","config","suggested_lang_code","lastRequestedLangCode","getStrings","getCacheLangPack","strings","backup","string","backupString","btnChangeLanguage","getLangPack","TrackingMonkey","inputField","max","needFrame","playAnimation","frame","min","idleAnimation","canvas","direction","setDirection","setSpeed","play","loadPromise","loadAnimationFromURL","loop","autoplay","waitForFirstFrame","_animation","currentFrame","pause","CodeInputField"],"mappings":"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","file":"13.f0b27d519201c3d897b8.chunk.js","sourcesContent":["/*\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 { formatPhoneNumber, putPreloader } from \"../components/misc\";\r\nimport Scrollable from '../components/scrollable';\r\nimport Countries, { Country as _Country } from \"../countries\";\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 { isAppleMobile } from \"../helpers/userAgent\";\r\nimport fastSmoothScroll from \"../helpers/fastSmoothScroll\";\r\nimport { isTouchSupported } from \"../helpers/touchSupport\";\r\nimport App from \"../config/app\";\r\nimport Modes from \"../config/modes\";\r\nimport { _i18n, i18n } from \"../lib/langPack\";\r\nimport lottieLoader from \"../lib/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\n\r\ntype Country = _Country & {\r\n li?: HTMLLIElement[]\r\n};\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 name: 'Test Country',\r\n phoneCode: '999 66',\r\n code: 'TC',\r\n emoji: '🤔',\r\n pattern: '999 66 XXX XX'\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\r\n let lastCountrySelected: Country = null;\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 plainText: true\r\n });\r\n\r\n countryInputField.container.classList.add('input-select');\r\n\r\n const countryInput = countryInputField.input as HTMLInputElement;\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 = c.emoji;\r\n\r\n const liArr: Array<HTMLLIElement> = [];\r\n c.phoneCode.split(' and ').forEach((phoneCode: string) => {\r\n const li = document.createElement('li');\r\n\r\n let wrapped = RichTextProcessor.wrapEmojiText(emoji);\r\n if(RichTextProcessor.emojiSupported) {\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 li.append(c.name);\r\n\r\n const span = document.createElement('span');\r\n span.classList.add('phone-code');\r\n span.innerText = '+' + phoneCode;\r\n li.appendChild(span);\r\n\r\n liArr.push(li);\r\n selectList.append(li);\r\n });\r\n\r\n c.li = 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 let target = e.target as HTMLElement;\r\n if(target.tagName !== 'LI') target = findUpTag(target, 'LI');\r\n \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 countryName = target.childNodes[1].textContent;//target.innerText.split('\\n').shift();\r\n const phoneCode = target.querySelector<HTMLElement>('.phone-code').innerText;\r\n\r\n countryInput.value = countryName;\r\n lastCountrySelected = countries.find(c => c.name === countryName);\r\n \r\n telEl.value = lastValue = phoneCode;\r\n hidePicker();\r\n setTimeout(() => telEl.focus(), 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 c.li.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(page.pageEl.parentElement.parentElement, countryInput, 'start', 4);\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', function(this: typeof countryInput, e) {\r\n if(e.ctrlKey || e.key === 'Control') return false;\r\n\r\n //let i = new RegExp('^' + this.value, 'i');\r\n let _value = this.value.toLowerCase();\r\n let matches: Country[] = [];\r\n countries.forEach((c) => {\r\n let good = c.name.toLowerCase().indexOf(_value) !== -1/* === 0 */;//i.test(c.name);\r\n\r\n c.li.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 c.li.forEach(li => li.style.display = '');\r\n });\r\n } else if(matches.length === 1 && e.key === 'Enter') {\r\n selectCountryByTarget(matches[0].li[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 let pasted = false;\r\n let lastValue = '';\r\n \r\n const telInputField = new InputField({\r\n label: 'Login.PhoneLabel',\r\n plainText: true,\r\n name: 'phone'\r\n });\r\n let telEl = telInputField.input as HTMLInputElement;\r\n telEl.type = 'tel';\r\n telEl.autocomplete = 'rr55RandomRR55';\r\n telEl.addEventListener('input', function(this: typeof telEl, e) {\r\n //console.log('input', this.value);\r\n this.classList.remove('error');\r\n\r\n lottieLoader.loadLottieWorkers();\r\n\r\n const value = this.value;\r\n const diff = Math.abs(value.length - lastValue.length);\r\n if(diff > 1 && !pasted && isAppleMobile) {\r\n this.value = lastValue + value;\r\n }\r\n\r\n pasted = false;\r\n\r\n telInputField.setLabel();\r\n\r\n let formatted: string, country: Country;\r\n if(this.value.replace(/\\++/, '+') === '+') {\r\n this.value = '+';\r\n } else {\r\n const o = formatPhoneNumber(this.value);\r\n formatted = o.formatted;\r\n country = o.country;\r\n this.value = lastValue = formatted ? '+' + formatted : '';\r\n }\r\n\r\n //console.log(formatted, country);\r\n\r\n let countryName = country ? country.name : ''/* 'Unknown' */;\r\n if(countryName !== countryInput.value && (!lastCountrySelected || !country || lastCountrySelected.phoneCode !== country.phoneCode)) {\r\n countryInput.value = countryName;\r\n lastCountrySelected = country;\r\n }\r\n\r\n //if(country && (this.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {\r\n if(country || (this.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 telEl.addEventListener('paste', (e) => {\r\n pasted = true;\r\n //console.log('paste', telEl.value);\r\n });\r\n\r\n /* telEl.addEventListener('change', (e) => {\r\n console.log('change', telEl.value);\r\n }); */\r\n\r\n telEl.addEventListener('keypress', function(this: typeof telEl, 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 } else if(/\\D/.test(e.key) && !(e.metaKey || e.ctrlKey) && e.key !== 'Backspace' && !(e.key === '+' && e.shiftKey/* && !this.value */)) {\r\n e.preventDefault();\r\n return false;\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 = telEl.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 _i18n(h4, 'Login.Title');\r\n\r\n const subtitle = document.createElement('div');\r\n subtitle.classList.add('subtitle');\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 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 let country = countries.find((c) => c.code === nearestDcResult.country);\r\n if(country) {\r\n if(!countryInput.value.length && !telEl.value.length) {\r\n countryInput.value = country.name;\r\n lastCountrySelected = country;\r\n telEl.value = lastValue = '+' + country.phoneCode.split(' and ').shift();\r\n }\r\n }\r\n \r\n //console.log('woohoo', nearestDcResult, country);\r\n })//.catch(tryAgain);\r\n };\r\n\r\n if(!isTouchSupported) {\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 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 { pause } from '../helpers/schedulers';\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\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.setUserAuth(authorization.user.id);\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=\" + encoded.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/\\=+$/, \"\");\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.type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n console.warn('pageSignQR: SESSION_PASSWORD_NEEDED');\r\n err.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 mediaSizes from '../helpers/mediaSizes';\r\nimport { AuthSentCode, AuthSentCodeType, AuthSignIn } from '../layer';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport Page from './page';\r\nimport pageSignIn from './pageSignIn';\r\nimport TrackingMonkey from '../components/monkeys/tracking';\r\nimport CodeInputField from '../components/codeInputField';\r\nimport { i18n, LangPackKey } from '../lib/langPack';\r\nimport { randomLong } from '../helpers/random';\r\nimport replaceContent from '../helpers/dom/replaceContent';\r\n\r\nlet authCode: AuthSentCode.authSentCode = null;\r\n\r\nlet headerElement: HTMLHeadElement = null;\r\nlet sentTypeElement: HTMLParagraphElement = null;\r\nlet codeInput: HTMLInputElement;\r\n\r\nlet onFirstMount = (): Promise<any> => {\r\n const CODELENGTH = (authCode.type as AuthSentCodeType.authSentCodeTypeApp).length;\r\n\r\n const codeInputField = new CodeInputField({\r\n label: 'Code',\r\n name: randomLong(),\r\n length: CODELENGTH,\r\n onFill: (code) => {\r\n submitCode(code);\r\n }\r\n });\r\n\r\n codeInput = codeInputField.input as HTMLInputElement;\r\n\r\n page.pageEl.querySelector('.input-wrapper').append(codeInputField.container);\r\n\r\n const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement;\r\n\r\n editButton.addEventListener('click', function() {\r\n return pageSignIn.mount();\r\n });\r\n\r\n const cleanup = () => {\r\n setTimeout(() => {\r\n monkey.remove();\r\n }, 300);\r\n };\r\n\r\n const submitCode = (code: string) => {\r\n codeInput.setAttribute('disabled', 'true');\r\n\r\n const params: AuthSignIn = {\r\n phone_number: authCode.phone_number,\r\n phone_code_hash: authCode.phone_code_hash,\r\n phone_code: code\r\n };\r\n\r\n //console.log('invoking auth.signIn with params:', params);\r\n\r\n apiManager.invokeApi('auth.signIn', params, {ignoreErrors: true})\r\n .then((response) => {\r\n //console.log('auth.signIn response:', response);\r\n \r\n switch(response._) {\r\n case 'auth.authorization':\r\n apiManager.setUserAuth(response.user.id);\r\n\r\n import('./pageIm').then(m => {\r\n m.default.mount();\r\n });\r\n cleanup();\r\n break;\r\n case 'auth.authorizationSignUpRequired':\r\n //console.log('Registration needed!');\r\n\r\n import('./pageSignUp').then(m => {\r\n m.default.mount({\r\n 'phone_number': authCode.phone_number,\r\n 'phone_code_hash': authCode.phone_code_hash\r\n });\r\n });\r\n\r\n cleanup();\r\n break;\r\n /* default:\r\n codeInput.innerText = response._;\r\n break; */\r\n }\r\n }).catch(async(err) => {\r\n let good = false;\r\n switch(err.type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n //console.warn('pageAuthCode: SESSION_PASSWORD_NEEDED');\r\n good = true;\r\n err.handled = true;\r\n await (await import('./pagePassword')).default.mount(); // lol\r\n setTimeout(() => {\r\n codeInput.value = '';\r\n }, 300);\r\n break;\r\n case 'PHONE_CODE_EXPIRED':\r\n codeInput.classList.add('error');\r\n replaceContent(codeInputField.label, i18n('PHONE_CODE_EXPIRED'));\r\n break;\r\n case 'PHONE_CODE_EMPTY':\r\n case 'PHONE_CODE_INVALID':\r\n codeInput.classList.add('error');\r\n replaceContent(codeInputField.label, i18n('PHONE_CODE_INVALID'));\r\n break;\r\n default:\r\n codeInputField.label.innerText = err.type;\r\n break;\r\n }\r\n\r\n if(!good) {\r\n codeInputField.select();\r\n }\r\n\r\n codeInput.removeAttribute('disabled');\r\n });\r\n };\r\n\r\n const imageDiv = page.pageEl.querySelector('.auth-image') as HTMLDivElement;\r\n const size = mediaSizes.isMobile ? 100 : 166;\r\n const monkey = new TrackingMonkey(codeInputField, size);\r\n imageDiv.append(monkey.container);\r\n return monkey.load();\r\n};\r\n\r\nconst page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof authCode) => {\r\n authCode = _authCode;\r\n\r\n if(!headerElement) {\r\n headerElement = page.pageEl.getElementsByClassName('phone')[0] as HTMLHeadElement;\r\n sentTypeElement = page.pageEl.getElementsByClassName('sent-type')[0] as HTMLParagraphElement;\r\n } else {\r\n codeInput.value = '';\r\n\r\n const evt = document.createEvent('HTMLEvents');\r\n evt.initEvent('input', false, true);\r\n codeInput.dispatchEvent(evt);\r\n }\r\n\r\n headerElement.innerText = authCode.phone_number;\r\n let key: LangPackKey, args: any[];\r\n switch(authCode.type._) {\r\n case 'auth.sentCodeTypeSms':\r\n key = 'Login.Code.SentSms';\r\n break;\r\n case 'auth.sentCodeTypeApp': \r\n key = 'Login.Code.SentInApp';\r\n break;\r\n case 'auth.sentCodeTypeCall': \r\n key = 'Login.Code.SentCall';\r\n break;\r\n default:\r\n key = 'Login.Code.SentUnknown';\r\n args = [authCode.type._];\r\n break;\r\n }\r\n\r\n replaceContent(sentTypeElement, i18n(key, args));\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateAuthCode', sentCode: _authCode});\r\n}, () => {\r\n codeInput.focus();\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\nexport default function replaceContent(elem: HTMLElement, node: string | Node) {\r\n if(typeof(node) === 'string') {\r\n elem.innerHTML = node;\r\n return;\r\n }\r\n\r\n // * children.length doesn't count text nodes\r\n const firstChild = elem.firstChild;\r\n if(firstChild) {\r\n if(elem.lastChild === firstChild) {\r\n firstChild.replaceWith(node);\r\n } else {\r\n elem.textContent = '';\r\n elem.append(node);\r\n }\r\n } else {\r\n elem.append(node);\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 findUpAttribute from \"../helpers/dom/findUpAttribute\";\r\nimport getRichValue from \"../helpers/dom/getRichValue\";\r\nimport isInputEmpty from \"../helpers/dom/isInputEmpty\";\r\nimport { debounce } from \"../helpers/schedulers\";\r\nimport { i18n, LangPackKey, _i18n } from \"../lib/langPack\";\r\nimport RichTextProcessor from \"../lib/richtextprocessor\";\r\n\r\nlet init = () => {\r\n document.addEventListener('paste', (e) => {\r\n if(!findUpAttribute(e.target, 'contenteditable=\"true\"')) {\r\n return;\r\n }\r\n //console.log('document paste');\r\n\r\n //console.log('messageInput paste');\r\n\r\n e.preventDefault();\r\n // @ts-ignore\r\n let text = (e.originalEvent || e).clipboardData.getData('text/plain');\r\n\r\n let entities = RichTextProcessor.parseEntities(text);\r\n //console.log('messageInput paste', text, entities);\r\n entities = entities.filter(e => e._ === 'messageEntityEmoji' || e._ === 'messageEntityLinebreak');\r\n //text = RichTextProcessor.wrapEmojiText(text);\r\n text = RichTextProcessor.wrapRichText(text, {entities, noLinks: true, wrappingDraft: true});\r\n\r\n // console.log('messageInput paste after', text);\r\n\r\n // @ts-ignore\r\n //let html = (e.originalEvent || e).clipboardData.getData('text/html');\r\n\r\n // @ts-ignore\r\n //console.log('paste text', text, );\r\n window.document.execCommand('insertHTML', false, text);\r\n });\r\n\r\n init = null;\r\n};\r\n\r\n// ! it doesn't respect symbols other than strongs\r\n/* const checkAndSetRTL = (input: HTMLElement) => {\r\n //const isEmpty = isInputEmpty(input);\r\n //console.log('input', isEmpty);\r\n\r\n //const char = [...getRichValue(input)][0];\r\n const char = (input instanceof HTMLInputElement ? input.value : input.innerText)[0];\r\n let direction = 'ltr';\r\n if(char && checkRTL(char)) {\r\n direction = 'rtl';\r\n }\r\n\r\n //console.log('RTL', direction, char);\r\n\r\n input.style.direction = direction;\r\n}; */\r\n\r\nexport enum InputState {\r\n Neutral = 0,\r\n Valid = 1,\r\n Error = 2\r\n};\r\n\r\nexport type InputFieldOptions = {\r\n placeholder?: LangPackKey, \r\n label?: LangPackKey, \r\n labelOptions?: any[],\r\n labelText?: string,\r\n name?: string, \r\n maxLength?: number, \r\n showLengthOn?: number,\r\n plainText?: true,\r\n animate?: true\r\n};\r\n\r\nclass InputField {\r\n public container: HTMLElement;\r\n public input: HTMLElement;\r\n public inputFake: HTMLElement;\r\n public label: HTMLLabelElement;\r\n\r\n public originalValue: string;\r\n\r\n //public onLengthChange: (length: number, isOverflow: boolean) => void;\r\n protected wasInputFakeClientHeight: number;\r\n protected showScrollDebounced: () => void;\r\n\r\n constructor(public options: InputFieldOptions = {}) {\r\n this.container = document.createElement('div');\r\n this.container.classList.add('input-field');\r\n\r\n if(options.maxLength) {\r\n options.showLengthOn = Math.round(options.maxLength / 3);\r\n }\r\n\r\n const {placeholder, maxLength, showLengthOn, name, plainText} = options;\r\n\r\n let label = options.label || options.labelText;\r\n\r\n let input: HTMLElement;\r\n if(!plainText) {\r\n if(init) {\r\n init();\r\n }\r\n\r\n this.container.innerHTML = `\r\n <div contenteditable=\"true\" class=\"input-field-input\"></div>\r\n `;\r\n\r\n input = this.container.firstElementChild as HTMLElement;\r\n const observer = new MutationObserver(() => {\r\n //checkAndSetRTL(input);\r\n\r\n if(processInput) {\r\n processInput();\r\n }\r\n });\r\n\r\n // * because if delete all characters there will br left\r\n input.addEventListener('input', () => {\r\n if(isInputEmpty(input)) {\r\n input.innerHTML = '';\r\n }\r\n\r\n if(this.inputFake) {\r\n this.inputFake.innerHTML = input.innerHTML;\r\n this.onFakeInput();\r\n }\r\n });\r\n \r\n // ! childList for paste first symbol\r\n observer.observe(input, {characterData: true, childList: true, subtree: true});\r\n\r\n if(options.animate) {\r\n input.classList.add('scrollable', 'scrollable-y');\r\n this.wasInputFakeClientHeight = 0;\r\n this.showScrollDebounced = debounce(() => this.input.classList.remove('no-scrollbar'), 150, false, true);\r\n this.inputFake = document.createElement('div');\r\n this.inputFake.setAttribute('contenteditable', 'true');\r\n this.inputFake.className = input.className + ' input-field-input-fake';\r\n }\r\n } else {\r\n this.container.innerHTML = `\r\n <input type=\"text\" ${name ? `name=\"${name}\"` : ''} autocomplete=\"off\" ${label ? 'required=\"\"' : ''} class=\"input-field-input\">\r\n `;\r\n\r\n input = this.container.firstElementChild as HTMLElement;\r\n //input.addEventListener('input', () => checkAndSetRTL(input));\r\n }\r\n\r\n input.setAttribute('dir', 'auto');\r\n\r\n if(placeholder) {\r\n _i18n(input, placeholder, undefined, 'placeholder');\r\n\r\n if(this.inputFake) {\r\n _i18n(this.inputFake, placeholder, undefined, 'placeholder');\r\n }\r\n }\r\n\r\n if(label || placeholder) {\r\n const border = document.createElement('div');\r\n border.classList.add('input-field-border');\r\n this.container.append(border);\r\n }\r\n\r\n if(label) {\r\n this.label = document.createElement('label');\r\n this.setLabel();\r\n this.container.append(this.label);\r\n }\r\n\r\n let processInput: () => void;\r\n if(maxLength) {\r\n const labelEl = this.container.lastElementChild as HTMLLabelElement;\r\n let showingLength = false;\r\n\r\n processInput = () => {\r\n const wasError = input.classList.contains('error');\r\n // * https://stackoverflow.com/a/54369605 #2 to count emoji as 1 symbol\r\n const inputLength = plainText ? (input as HTMLInputElement).value.length : [...getRichValue(input, false).value].length;\r\n const diff = maxLength - inputLength;\r\n const isError = diff < 0;\r\n input.classList.toggle('error', isError);\r\n\r\n //this.onLengthChange && this.onLengthChange(inputLength, isError);\r\n\r\n if(isError || diff <= showLengthOn) {\r\n this.setLabel();\r\n labelEl.append(` (${maxLength - inputLength})`);\r\n if(!showingLength) showingLength = true;\r\n } else if((wasError && !isError) || showingLength) {\r\n this.setLabel();\r\n showingLength = false;\r\n }\r\n };\r\n\r\n input.addEventListener('input', processInput);\r\n }\r\n\r\n this.input = input;\r\n }\r\n\r\n public select() {\r\n if((this.input as HTMLInputElement).value) { // * avoid selecting whole empty field on iOS devices\r\n (this.input as HTMLInputElement).select(); // * select text\r\n }\r\n }\r\n\r\n public setLabel() {\r\n this.label.textContent = '';\r\n if(this.options.labelText) {\r\n this.label.innerHTML = this.options.labelText;\r\n } else {\r\n this.label.append(i18n(this.options.label, this.options.labelOptions));\r\n }\r\n }\r\n\r\n public onFakeInput() {\r\n const {scrollHeight, clientHeight} = this.inputFake;\r\n if(this.wasInputFakeClientHeight && this.wasInputFakeClientHeight !== clientHeight) {\r\n this.input.classList.add('no-scrollbar'); // ! в сафари может вообще не появиться скролл после анимации, так как ему нужен полный reflow блока с overflow.\r\n this.showScrollDebounced();\r\n }\r\n\r\n this.wasInputFakeClientHeight = clientHeight;\r\n this.input.style.height = scrollHeight ? scrollHeight + 'px' : '';\r\n }\r\n\r\n get value() {\r\n return this.options.plainText ? (this.input as HTMLInputElement).value : getRichValue(this.input, false).value;\r\n //return getRichValue(this.input);\r\n }\r\n\r\n set value(value: string) {\r\n this.setValueSilently(value, false);\r\n\r\n const event = new Event('input', {bubbles: true, cancelable: true});\r\n this.input.dispatchEvent(event);\r\n }\r\n\r\n public setValueSilently(value: string, fireFakeInput = true) {\r\n if(this.options.plainText) {\r\n (this.input as HTMLInputElement).value = value;\r\n } else {\r\n this.input.innerHTML = value;\r\n \r\n if(this.inputFake) {\r\n this.inputFake.innerHTML = value;\r\n\r\n if(fireFakeInput) {\r\n this.onFakeInput();\r\n }\r\n }\r\n }\r\n }\r\n\r\n public isValid() {\r\n return !this.input.classList.contains('error') && this.value !== this.originalValue;\r\n }\r\n\r\n public setOriginalValue(value: InputField['originalValue'] = '', silent = false) {\r\n this.originalValue = value;\r\n\r\n if(!this.options.plainText) {\r\n value = RichTextProcessor.wrapDraftText(value);\r\n }\r\n\r\n if(silent) {\r\n this.setValueSilently(value, false); \r\n } else {\r\n this.value = value;\r\n }\r\n }\r\n\r\n public setState(state: InputState, label?: LangPackKey) {\r\n if(label) {\r\n this.label.textContent = '';\r\n this.label.append(i18n(label, this.options.labelOptions));\r\n }\r\n\r\n this.input.classList.toggle('error', !!(state & InputState.Error));\r\n this.input.classList.toggle('valid', !!(state & InputState.Valid));\r\n }\r\n\r\n public setError(label?: LangPackKey) {\r\n this.setState(InputState.Error, label);\r\n }\r\n}\r\n\r\nexport default InputField;\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 { isTouchSupported } from \"../helpers/touchSupport\";\r\nimport { logger, LogTypes } from \"../lib/logger\";\r\nimport fastSmoothScroll, { FocusDirection } 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(\r\n element: HTMLElement,\r\n position: ScrollLogicalPosition,\r\n margin?: number,\r\n maxDistance?: number,\r\n forceDirection?: FocusDirection,\r\n forceDuration?: number,\r\n axis?: 'x' | 'y'\r\n ) {\r\n //return Promise.resolve();\r\n return fastSmoothScroll(this.container, element, position, margin, maxDistance, forceDirection, forceDuration, axis);\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 = null;\r\n public onScrolledTop: () => void = null;\r\n public onScrolledBottom: () => void = null;\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[]) {\r\n (this.splitUp || this.padding || this.container).prepend(...elements);\r\n }\r\n\r\n public append(...elements: HTMLElement[]) {\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(!isTouchSupported) {\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 * 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 { MOUNT_CLASS_TO } from \"../../config/debug\";\r\nimport { MessageEntity } from \"../../layer\";\r\nimport RichTextProcessor from \"../../lib/richtextprocessor\";\r\nimport getRichElementValue from \"./getRichElementValue\";\r\n\r\nexport default function getRichValue(field: HTMLElement, withEntities = true) {\r\n const lines: string[] = [];\r\n const line: string[] = [];\r\n\r\n const entities: MessageEntity[] = withEntities ? [] : undefined;\r\n getRichElementValue(field, lines, line, undefined, undefined, entities);\r\n if(line.length) {\r\n lines.push(line.join(''));\r\n }\r\n\r\n let value = lines.join('\\n');\r\n value = value.replace(/\\u00A0/g, ' ');\r\n\r\n if(entities) {\r\n RichTextProcessor.combineSameEntities(entities);\r\n }\r\n\r\n //console.log('getRichValue:', value, entities);\r\n\r\n return {value, entities};\r\n}\r\n\r\nMOUNT_CLASS_TO.getRichValue = getRichValue;\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.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) {\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\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 * 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 { MessageEntity } from \"../../layer\";\r\n\r\nexport type MarkdownType = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'monospace' | 'link' | 'mentionName';\r\nexport type MarkdownTag = {\r\n match: string,\r\n entityName: 'messageEntityBold' | 'messageEntityUnderline' | 'messageEntityItalic' | 'messageEntityPre' | 'messageEntityStrike' | 'messageEntityTextUrl' | 'messageEntityMentionName';\r\n};\r\nexport const markdownTags: {[type in MarkdownType]: MarkdownTag} = {\r\n bold: {\r\n match: '[style*=\"font-weight\"], b',\r\n entityName: 'messageEntityBold'\r\n },\r\n underline: {\r\n match: '[style*=\"underline\"], u',\r\n entityName: 'messageEntityUnderline'\r\n },\r\n italic: {\r\n match: '[style*=\"italic\"], i',\r\n entityName: 'messageEntityItalic'\r\n },\r\n monospace: {\r\n match: '[style*=\"monospace\"], [face=\"monospace\"]',\r\n entityName: 'messageEntityPre'\r\n },\r\n strikethrough: {\r\n match: '[style*=\"line-through\"], strike',\r\n entityName: 'messageEntityStrike'\r\n },\r\n link: {\r\n match: 'A:not(.follow)',\r\n entityName: 'messageEntityTextUrl'\r\n },\r\n mentionName: {\r\n match: 'A.follow',\r\n entityName: 'messageEntityMentionName'\r\n }\r\n};\r\n\r\nexport default function getRichElementValue(node: HTMLElement, lines: string[], line: string[], selNode?: Node, selOffset?: number, entities?: MessageEntity[], offset = {offset: 0}) {\r\n if(node.nodeType === 3) { // TEXT\r\n const nodeValue = node.nodeValue;\r\n\r\n if(selNode === node) {\r\n line.push(nodeValue.substr(0, selOffset) + '\\x01' + nodeValue.substr(selOffset));\r\n } else {\r\n line.push(nodeValue);\r\n }\r\n\r\n if(entities && nodeValue.trim()) {\r\n if(node.parentNode) {\r\n const parentElement = node.parentElement;\r\n \r\n for(const type in markdownTags) {\r\n const tag = markdownTags[type as MarkdownType];\r\n const closest = parentElement.closest(tag.match + ', [contenteditable]');\r\n if(closest && closest.getAttribute('contenteditable') === null) {\r\n if(tag.entityName === 'messageEntityTextUrl') {\r\n entities.push({\r\n _: tag.entityName,\r\n url: (parentElement as HTMLAnchorElement).href,\r\n offset: offset.offset,\r\n length: nodeValue.length\r\n });\r\n } else if(tag.entityName === 'messageEntityMentionName') {\r\n entities.push({\r\n _: tag.entityName,\r\n offset: offset.offset,\r\n length: nodeValue.length,\r\n user_id: +parentElement.dataset.follow\r\n });\r\n } else {\r\n entities.push({\r\n _: tag.entityName as any,\r\n offset: offset.offset,\r\n length: nodeValue.length\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n offset.offset += nodeValue.length;\r\n\r\n return;\r\n }\r\n\r\n if(node.nodeType !== 1) { // NON-ELEMENT\r\n return;\r\n }\r\n\r\n const isSelected = (selNode === node);\r\n const isBlock = node.tagName === 'DIV' || node.tagName === 'P';\r\n if(isBlock && line.length || node.tagName === 'BR') {\r\n lines.push(line.join(''));\r\n line.splice(0, line.length);\r\n } else if(node.tagName === 'IMG') {\r\n const alt = (node as HTMLImageElement).alt;\r\n if(alt) {\r\n line.push(alt);\r\n offset.offset += alt.length;\r\n }\r\n }\r\n\r\n if(isSelected && !selOffset) {\r\n line.push('\\x01');\r\n }\r\n\r\n let curChild = node.firstChild as HTMLElement;\r\n while(curChild) {\r\n getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);\r\n curChild = curChild.nextSibling as any;\r\n }\r\n\r\n if(isSelected && selOffset) {\r\n line.push('\\x01');\r\n }\r\n\r\n if(isBlock && line.length) {\r\n lines.push(line.join(''));\r\n line.splice(0, line.length);\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 findUpAttribute(el: any, attribute: string): HTMLElement {\r\n return el.closest(`[${attribute}]`);\r\n /* if(el.getAttribute(attribute) !== null) return el; // 03.02.2020\r\n\r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.getAttribute(attribute) !== null) \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 getRichValue from \"./getRichValue\";\r\n\r\nexport default function isInputEmpty(element: HTMLElement) {\r\n if(element.hasAttribute('contenteditable') || element.tagName !== 'INPUT') {\r\n /* const value = element.innerText;\r\n\r\n return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); */\r\n return !getRichValue(element, false).value.trim();\r\n } else {\r\n return !(element as HTMLInputElement).value.trim();\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 * 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 arr: string[] = new Array(bytes.length);\r\n for(let i = 0; i < bytes.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","/*\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 { blobConstruct, readBlobAsUint8Array } from \"../helpers/blob\";\r\n\r\nexport class FileManager {\r\n public blobSupported = true;\r\n \r\n constructor() {\r\n try {\r\n blobConstruct([], '');\r\n } catch(e) {\r\n this.blobSupported = false;\r\n }\r\n }\r\n \r\n public isAvailable() {\r\n return this.blobSupported;\r\n }\r\n \r\n public write(fileWriter: ReturnType<FileManager['getFakeFileWriter']>, bytes: Uint8Array | Blob | string): Promise<void> {\r\n if(bytes instanceof Blob) { // is file bytes\r\n return readBlobAsUint8Array(bytes).then(arr => {\r\n return fileWriter.write(arr);\r\n });\r\n } else {\r\n return fileWriter.write(bytes);\r\n }\r\n }\r\n\r\n public getFakeFileWriter(mimeType: string, saveFileCallback?: (blob: Blob) => Promise<Blob>) {\r\n const blobParts: Array<Uint8Array | string> = [];\r\n const fakeFileWriter = {\r\n write: async(part: Uint8Array | string) => {\r\n if(!this.blobSupported) {\r\n throw false;\r\n }\r\n \r\n blobParts.push(part);\r\n },\r\n truncate: () => {\r\n blobParts.length = 0;\r\n },\r\n finalize: (saveToStorage = true) => {\r\n const blob = blobConstruct(blobParts, mimeType);\r\n\r\n if(saveToStorage && saveFileCallback) {\r\n saveFileCallback(blob);\r\n }\r\n \r\n return blob;\r\n }\r\n };\r\n \r\n return fakeFileWriter;\r\n }\r\n}\r\n\r\nexport default new FileManager();\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 Modes from '../config/modes';\r\nimport { blobConstruct } from '../helpers/blob';\r\nimport FileManager from './filemanager';\r\n//import { MOUNT_CLASS_TO } from './mtproto/mtproto_config';\r\n//import { logger } from './polyfill';\r\n\r\nexport type CacheStorageDbName = 'cachedFiles' | 'cachedStreamChunks' | 'cachedAssets';\r\n\r\nexport default class CacheStorageController {\r\n private static STORAGES: CacheStorageController[] = [];\r\n private openDbPromise: Promise<Cache>;\r\n\r\n private useStorage = true;\r\n\r\n //private log: ReturnType<typeof logger> = logger('CS');\r\n\r\n constructor(private dbName: CacheStorageDbName) {\r\n if(Modes.test) {\r\n this.dbName += '_test';\r\n }\r\n\r\n if(CacheStorageController.STORAGES.length) {\r\n this.useStorage = CacheStorageController.STORAGES[0].useStorage;\r\n }\r\n \r\n this.openDatabase();\r\n CacheStorageController.STORAGES.push(this);\r\n }\r\n\r\n private openDatabase(): Promise<Cache> {\r\n return this.openDbPromise ?? (this.openDbPromise = caches.open(this.dbName));\r\n }\r\n\r\n public delete(entryName: string) {\r\n return this.timeoutOperation((cache) => cache.delete('/' + entryName));\r\n }\r\n\r\n public deleteAll() {\r\n return caches.delete(this.dbName);\r\n }\r\n\r\n public get(entryName: string) {\r\n return this.timeoutOperation((cache) => cache.match('/' + entryName));\r\n }\r\n\r\n public save(entryName: string, response: Response) {\r\n // return new Promise((resolve) => {}); // DEBUG\r\n return this.timeoutOperation((cache) => cache.put('/' + entryName, response));\r\n }\r\n\r\n public getFile(fileName: string, method: 'blob' | 'json' | 'text' = 'blob'): Promise<any> {\r\n /* if(method === 'blob') {\r\n return Promise.reject();\r\n } */\r\n\r\n // const str = `get fileName: ${fileName}`;\r\n // console.time(str);\r\n return this.get(fileName).then((response) => {\r\n if(!response) {\r\n //console.warn('getFile:', response, fileName);\r\n throw 'NO_ENTRY_FOUND';\r\n }\r\n\r\n const promise = response[method]();\r\n // promise.then(() => {\r\n // console.timeEnd(str);\r\n // });\r\n return promise;\r\n });\r\n }\r\n\r\n public saveFile(fileName: string, blob: Blob | Uint8Array) {\r\n //return Promise.resolve(blobConstruct([blob]));\r\n if(!(blob instanceof Blob)) {\r\n blob = blobConstruct(blob) as Blob;\r\n }\r\n\r\n const response = new Response(blob, {\r\n headers: {\r\n 'Content-Length': '' + blob.size\r\n }\r\n });\r\n \r\n return this.save(fileName, response).then(() => blob as Blob);\r\n }\r\n\r\n public timeoutOperation<T>(callback: (cache: Cache) => Promise<T>) {\r\n if(!this.useStorage) {\r\n return Promise.reject('STORAGE_OFFLINE');\r\n }\r\n\r\n return new Promise<T>(async(resolve, reject) => {\r\n let rejected = false;\r\n const timeout = setTimeout(() => {\r\n reject();\r\n //console.warn('CACHESTORAGE TIMEOUT');\r\n rejected = true;\r\n }, 15e3);\r\n\r\n try {\r\n const cache = await this.openDatabase();\r\n if(!cache) {\r\n this.useStorage = false;\r\n this.openDbPromise = undefined;\r\n throw 'no cache?';\r\n }\r\n\r\n const res = await callback(cache);\r\n\r\n if(rejected) return;\r\n resolve(res);\r\n } catch(err) {\r\n reject(err);\r\n }\r\n\r\n clearTimeout(timeout);\r\n });\r\n }\r\n\r\n public getFileWriter(fileName: string, mimeType: string) {\r\n const fakeWriter = FileManager.getFakeFileWriter(mimeType, (blob) => {\r\n return this.saveFile(fileName, blob).catch(() => blob);\r\n });\r\n\r\n return Promise.resolve(fakeWriter);\r\n }\r\n\r\n public static toggleStorage(enabled: boolean) {\r\n return Promise.all(this.STORAGES.map(storage => {\r\n storage.useStorage = enabled;\r\n \r\n if(!enabled) {\r\n return storage.deleteAll();\r\n }\r\n }));\r\n }\r\n}\r\n\r\n//const cacheStorage = new CacheStorageController(); \r\n//MOUNT_CLASS_TO.cacheStorage = cacheStorage;\r\n//export default cacheStorage;\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 { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\r\nimport loadFonts from \"../helpers/dom/loadFonts\";\r\nimport { Config, LangPackDifference, LangPackString } from \"../layer\";\r\nimport I18n, { LangPackKey } from \"../lib/langPack\";\r\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport Button from \"./button\";\r\nimport { putPreloader } from \"./misc\";\r\n\r\nlet set = false, times = 0;\r\nrootScope.addEventListener('language_change', () => {\r\n if(++times < 2) {\r\n return;\r\n }\r\n\r\n console.log('language_change');\r\n set = true;\r\n});\r\n\r\nfunction getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {\r\n if(cachedPromise) return cachedPromise;\r\n return cachedPromise = apiManager.getConfig().then(config => {\r\n if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {\r\n //I18n.loadLangPack(config.suggested_lang_code);\r\n\r\n return Promise.all([\r\n config,\r\n I18n.getStrings(config.suggested_lang_code, ['Login.ContinueOnLanguage']),\r\n I18n.getCacheLangPack()\r\n ]);\r\n } else {\r\n return [] as any;\r\n }\r\n });\r\n}\r\n\r\nlet cachedPromise: ReturnType<typeof getLang>;\r\n\r\nexport default function getLanguageChangeButton(appendTo: HTMLElement) {\r\n if(set) return;\r\n getLang().then(([config, strings]) => {\r\n if(!config) {\r\n return;\r\n }\r\n\r\n const backup: LangPackString[] = [];\r\n strings.forEach(string => {\r\n const backupString = I18n.strings.get(string.key as LangPackKey);\r\n if(!backupString) {\r\n return;\r\n }\r\n \r\n backup.push(backupString);\r\n I18n.strings.set(string.key as LangPackKey, string);\r\n });\r\n\r\n const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});\r\n loadFonts().then(() => {\r\n window.requestAnimationFrame(() => {\r\n appendTo.append(btnChangeLanguage);\r\n });\r\n });\r\n\r\n rootScope.addEventListener('language_change', () => {\r\n btnChangeLanguage.remove();\r\n }, {once: true});\r\n\r\n backup.forEach(string => {\r\n I18n.strings.set(string.key as LangPackKey, string);\r\n });\r\n \r\n attachClickEvent(btnChangeLanguage, (e) => {\r\n cancelEvent(e);\r\n\r\n btnChangeLanguage.disabled = true;\r\n putPreloader(btnChangeLanguage);\r\n\r\n I18n.getLangPack(config.suggested_lang_code);\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 InputField from \"../inputField\";\r\nimport lottieLoader, { RLottiePlayer } from \"../../lib/lottieLoader\";\r\n\r\nexport default class TrackingMonkey {\r\n public container: HTMLElement;\r\n\r\n protected max = 45;\r\n protected needFrame = 0;\r\n\r\n protected animation: RLottiePlayer;\r\n protected idleAnimation: RLottiePlayer;\r\n\r\n protected loadPromise: Promise<any>;\r\n\r\n constructor(protected inputField: InputField, protected size: number) {\r\n this.container = document.createElement('div');\r\n this.container.classList.add('media-sticker-wrapper');\r\n\r\n const input = inputField.input;\r\n\r\n input.addEventListener('blur', () => {\r\n this.playAnimation(0);\r\n });\r\n\r\n input.addEventListener('input', (e) => {\r\n this.playAnimation(inputField.value.length);\r\n });\r\n\r\n /* codeInput.addEventListener('focus', () => {\r\n playAnimation(Math.max(codeInput.value.length, 1));\r\n }); */\r\n }\r\n\r\n // 1st symbol = frame 15\r\n // end symbol = frame 165\r\n public playAnimation(length: number) {\r\n if(!this.animation) return;\r\n\r\n length = Math.min(length, 30);\r\n let frame: number;\r\n if(length) {\r\n frame = Math.round(Math.min(this.max, length) * (165 / this.max) + 11.33);\r\n\r\n if(this.idleAnimation) {\r\n this.idleAnimation.stop(true);\r\n this.idleAnimation.canvas.style.display = 'none';\r\n }\r\n \r\n this.animation.canvas.style.display = '';\r\n } else {\r\n /* const cb = (frameNo: number) => {\r\n if(frameNo <= 1) { */\r\n /* idleAnimation.play();\r\n idleAnimation.canvas.style.display = '';\r\n animation.canvas.style.display = 'none'; */\r\n /* animation.removeListener('enterFrame', cb);\r\n }\r\n };\r\n animation.addListener('enterFrame', cb); */\r\n \r\n frame = 0;\r\n }\r\n //animation.playSegments([1, 2]);\r\n\r\n const direction = this.needFrame > frame ? -1 : 1;\r\n //console.log('keydown', length, frame, direction);\r\n\r\n this.animation.setDirection(direction);\r\n if(this.needFrame !== 0 && frame === 0) {\r\n this.animation.setSpeed(7);\r\n }\r\n /* let diff = Math.abs(needFrame - frame * direction);\r\n if((diff / 20) > 1) animation.setSpeed(diff / 20 | 0); */\r\n this.needFrame = frame;\r\n \r\n this.animation.play();\r\n\r\n /* animation.goToAndStop(15, true); */\r\n //animation.goToAndStop(length / max * );\r\n }\r\n\r\n public load() {\r\n if(this.loadPromise) return this.loadPromise;\r\n return this.loadPromise = Promise.all([\r\n lottieLoader.loadAnimationFromURL({\r\n container: this.container,\r\n loop: true,\r\n autoplay: true,\r\n width: this.size,\r\n height: this.size\r\n }, 'assets/img/TwoFactorSetupMonkeyIdle.tgs').then(animation => {\r\n this.idleAnimation = animation;\r\n\r\n // ! animationIntersector will stop animation instantly\r\n if(!this.inputField.value.length) {\r\n animation.play();\r\n }\r\n\r\n return lottieLoader.waitForFirstFrame(animation);\r\n }),\r\n\r\n lottieLoader.loadAnimationFromURL({\r\n container: this.container,\r\n loop: false,\r\n autoplay: false,\r\n width: this.size,\r\n height: this.size\r\n }, 'assets/img/TwoFactorSetupMonkeyTracking.tgs').then(_animation => {\r\n this.animation = _animation;\r\n\r\n if(!this.inputField.value.length) {\r\n this.animation.canvas.style.display = 'none';\r\n }\r\n\r\n this.animation.addEventListener('enterFrame', currentFrame => {\r\n //console.log('enterFrame', currentFrame, needFrame);\r\n //let currentFrame = Math.round(e.currentTime);\r\n \r\n if((this.animation.direction === 1 && currentFrame >= this.needFrame) ||\r\n (this.animation.direction === -1 && currentFrame <= this.needFrame)) {\r\n this.animation.setSpeed(1);\r\n this.animation.pause();\r\n }\r\n\r\n if(currentFrame === 0 && this.needFrame === 0) {\r\n //animation.curFrame = 0;\r\n \r\n if(this.idleAnimation) {\r\n this.idleAnimation.canvas.style.display = '';\r\n this.idleAnimation.play();\r\n this.animation.canvas.style.display = 'none';\r\n }\r\n }\r\n });\r\n //console.log(animation.getDuration(), animation.getDuration(true));\r\n\r\n return lottieLoader.waitForFirstFrame(_animation);\r\n })\r\n ]);\r\n }\r\n\r\n public remove() {\r\n if(this.animation) this.animation.remove();\r\n if(this.idleAnimation) this.idleAnimation.remove();\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 InputField, { InputFieldOptions } from \"./inputField\";\r\n\r\nexport default class CodeInputField extends InputField {\r\n constructor(options: InputFieldOptions & {\r\n length: number,\r\n onFill: (code: string) => void\r\n }) {\r\n super({\r\n plainText: true,\r\n ...options\r\n });\r\n\r\n const input = this.input as HTMLInputElement;\r\n input.type = 'tel';\r\n input.setAttribute('required', '');\r\n input.autocomplete = 'off';\r\n\r\n let lastLength = 0;\r\n this.input.addEventListener('input', (e) => {\r\n this.input.classList.remove('error');\r\n this.setLabel();\r\n \r\n const value = this.value.replace(/\\D/g, '').slice(0, options.length);\r\n this.setValueSilently(value);\r\n \r\n const length = this.value.length;\r\n if(length === options.length) { // submit code\r\n options.onFill(this.value);\r\n } else if(length === lastLength) {\r\n return;\r\n }\r\n \r\n lastLength = length;\r\n });\r\n }\r\n}\r\n"],"sourceRoot":""} |