tweb/public/14.0a9c2a5a1b393dfdfb0d.chu...

1 line
113 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"version":3,"sources":["webpack:///./src/helpers/dom/fullScreen.ts","webpack:///./src/helpers/blob/readBlobAsUint8Array.ts","webpack:///./src/helpers/blob/readBlobAsArrayBuffer.ts","webpack:///./src/lib/fileManager.ts","webpack:///./src/lib/cacheStorage.ts","webpack:///./src/helpers/fileName.ts","webpack:///./src/lib/cropper.ts","webpack:///./src/components/popups/avatar.ts","webpack:///./src/helpers/dom/isSendShortcutPressed.ts","webpack:///./src/helpers/blob/readBlobAsDataURL.ts","webpack:///./src/pages/pageSignUp.ts","webpack:///./src/helpers/dom/replaceContent.ts","webpack:///./src/components/inputField.ts","webpack:///./src/helpers/dom/selectElementContents.ts","webpack:///./src/components/singleTransition.ts","webpack:///./src/components/popups/index.ts","webpack:///./src/helpers/dom/getRichValue.ts","webpack:///./src/helpers/listenerSetter.ts","webpack:///./src/helpers/dom/findUpAttribute.ts","webpack:///./src/helpers/dom/getRichElementValue.ts","webpack:///./src/lib/appManagers/appDownloadManager.ts","webpack:///./src/helpers/dom/isInputEmpty.ts","webpack:///./src/helpers/blob/readBlobAs.ts","webpack:///./src/pages/loginPage.ts"],"names":["requestFullScreen","element","requestFullscreen","mozRequestFullScreen","webkitRequestFullscreen","msRequestFullscreen","cancelFullScreen","document","mozCancelFullScreen","webkitCancelFullScreen","msExitFullscreen","addFullScreenListener","callback","listenerSetter","addListener","add","addEventListener","bind","split","forEach","eventName","getFullScreenElement","fullscreenElement","mozFullScreenElement","webkitFullscreenElement","msFullscreenElement","isFullScreen","readBlobAsUint8Array","blob","readBlobAs","readBlobAsArrayBuffer","then","buffer","Uint8Array","blobSupported","blobConstruct","e","this","fileWriter","bytes","Blob","arr","write","mimeType","saveFileCallback","blobParts","part","push","truncate","length","finalize","saveToStorage","dbName","useStorage","test","STORAGES","openDatabase","openDbPromise","caches","open","entryName","timeoutOperation","cache","delete","match","response","put","fileName","method","get","Response","headers","size","save","Promise","resolve","reject","rejected","timeout","setTimeout","undefined","res","err","clearTimeout","fakeWriter","getFakeFileWriter","saveFile","catch","enabled","all","map","storage","deleteAll","getFileNameByLocation","location","options","ext","str","_","id","thumb_size","filter","Boolean","join","photo_id","pFlags","big","stickerset","short_name","emoticon","thumb_version","volume_id","local_id","url","console","error","getFileURL","type","encodeURIComponent","JSON","stringify","originalImage","canvas","cropComponent","container","cropImage","event_state","cropLeft","cropTop","cropWidth","cropHeight","scaledRatio","init","classList","draggable","Image","src","createElement","overlayColor","appendChild","parentNode","style","maxWidth","width","naturalWidth","offsetWidth","left","CROPWIDTH","top","offsetHeight","CROPHEIGHT","updateCropSize","updateCropImage","updateContainer","startMoving","resizing","keyHandler","height","imgZoom","zoom","Math","PI","right","bottom","newWidth","floor","clientWidth","newHeight","clientHeight","w","h","offsetLeft","offsetTop","preventDefault","String","fromCharCode","charCode","deltaY","stopPropagation","container_width","container_height","container_left","container_top","mouse_x","clientX","pageX","touches","window","scrollX","mouse_y","clientY","pageY","scrollY","saveEventState","moving","endMoving","removeEventListener","currentTouch","x","y","complete","onload","crop","getContext","drawImage","removeHandlers","remove","super","closable","withConfirm","image","cropper","h6","btnClose","header","append","cropContainer","input","display","file","target","files","readBlobAsDataURL","contents","show","value","btnConfirm","className","hide","toBlob","darkenCanvas","onCrop","appDownloadManager","upload","postCanvas","click","ctx","fillStyle","fillRect","isSendShortcutPressed","key","isComposing","settings","sendShortcut","shiftKey","ctrlKey","metaKey","secondaryKey","authCode","page","imported","withInputWrapper","titleLangKey","subtitleLangKey","imageDiv","title","avatarPreview","addIco","appProfileManager","default","uploadAvatar","_uploadAvatar","handleInput","name","nameInputField","lastName","lastNameInputField","fullName","trim","wrapEmojiText","label","maxLength","btnSignUp","btnI18n","IntlElement","inputWrapper","contains","disabled","params","phone_number","phone_code_hash","first_name","last_name","update","preloader","invokeApi","setUser","user","inputFile","uploadProfilePhoto","finally","m","mount","removeAttribute","requestAnimationFrame","_authCode","pushToState","replaceContent","elem","node","innerHTML","firstChild","lastChild","replaceWith","textContent","findUpAttribute","text","entities","plainText","originalEvent","clipboardData","getData","usePlainText","html","replace","span","curChild","nextSibling","nodeType","nodeValue","richValue","getRichValue","entities2","parseEntities","mergeEntities","wrapDraftText","execCommand","InputState","required","validate","showLengthOn","min","round","placeholder","canBeEdited","processInput","labelText","firstElementChild","observer","MutationObserver","isInputEmpty","inputFake","onFakeInput","observe","characterData","childList","subtree","animate","setAttribute","border","setLabel","labelEl","lastElementChild","showingLength","wasError","inputLength","diff","isError","toggle","select","el","range","createRange","selectNodeContents","sel","getSelection","removeAllRanges","addRange","selectElementContents","labelOptions","setHeight","scrollHeight","currentHeight","transitionDuration","log","abs","setValueSilently","fireFakeInput","originalValue","isValid","isChanged","silent","setDraftValue","state","Error","Valid","setState","SetTransition","forwards","duration","onTransitionEnd","useRafs","raf","dataset","cancelAnimationFrame","animationsEnabled","afterTimeout","DEFAULT_APPEND_TO","body","appendPopupTo","onFullScreenChange","PopupElement","reAppend","buttons","onEscape","backByItem","navigationItem","confirmShortcutIsSendShortcut","prepend","once","withoutOverlay","overlayClosable","btnConfirmOnEnter","buttonsDiv","buttonsEl","buttonsElements","b","button","isDanger","langKey","langArgs","destroy","find","isCancel","POPUPS","onPop","pushItem","isOverlayActive","checkAnimations","dispatchEvent","removeAll","removeItem","cleanup","popup","parentElement","popupConstructor","addCancelButton","field","withEntities","lines","line","combineSameEntities","sortEntities","ListenerSetter","listeners","Set","event","listener","addManual","onceCallback","onceFired","_listener","attribute","closest","markdownTags","bold","entityName","underline","italic","monospace","strikethrough","link","mentionName","spoiler","BLOCK_TAG_NAMES","getRichElementValue","selNode","selOffset","offset","substr","tag","getAttribute","href","user_id","follow","toUserId","isSelected","isBlock","has","tagName","splice","HTMLImageElement","alt","isTableCell","matches","wasEntitiesLength","i","wasLength","cacheStorage","downloads","progress","progressCallbacks","uploadId","thumbsCache","photo","details","callbacks","download","notifyAll","deferred","cancel","cancelDownload","clearDownload","getNewDeferred","fetch","hasOwnProperty","onError","worker","onlyCache","promise","getFile","downloadFile","tryDownload","indexOf","uploadFile","onRemove","a","position","clickEvent","createEvent","initMouseEvent","discFileName","objectURL","URL","createObjectURL","createDownloadAnchor","revokeObjectURL","media","thumbSize","downloaded","hasAttribute","reader","FileReader","result","LoginPage","querySelector","subtitle"],"mappings":"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","file":"14.0a9c2a5a1b393dfdfb0d.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 type ListenerSetter from \"../listenerSetter\";\n\nexport function requestFullScreen(element: HTMLElement) {\n if(element.requestFullscreen) {\n element.requestFullscreen();\n // @ts-ignore\n } else if(element.mozRequestFullScreen) {\n // @ts-ignore\n element.mozRequestFullScreen(); // Firefox\n // @ts-ignore\n } else if(element.webkitRequestFullscreen) {\n // @ts-ignore\n element.webkitRequestFullscreen(); // Chrome and Safari\n // @ts-ignore\n } else if(element.msRequestFullscreen) {\n // @ts-ignore\n element.msRequestFullscreen();\n }\n}\n\nexport function cancelFullScreen() {\n // @ts-ignore\n if(document.cancelFullScreen) {\n // @ts-ignore\n document.cancelFullScreen();\n // @ts-ignore\n } else if(document.mozCancelFullScreen) {\n // @ts-ignore\n document.mozCancelFullScreen();\n // @ts-ignore\n } else if(document.webkitCancelFullScreen) {\n // @ts-ignore\n document.webkitCancelFullScreen();\n // @ts-ignore\n } else if(document.msExitFullscreen) {\n // @ts-ignore\n document.msExitFullscreen();\n }\n}\n\nexport function addFullScreenListener(element: HTMLElement, callback: (e: Event) => any, listenerSetter?: ListenerSetter) {\n const addListener = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\n 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange'.split(' ').forEach(eventName => {\n addListener(eventName, callback, false);\n });\n}\n\nexport function getFullScreenElement(): HTMLElement {\n // @ts-ignore\n return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;\n}\n\nexport function isFullScreen() {\n return !!getFullScreenElement();\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 readBlobAsArrayBuffer from \"./readBlobAsArrayBuffer\";\n\nexport default function readBlobAsUint8Array(blob: Blob) {\n return readBlobAsArrayBuffer(blob).then(buffer => new Uint8Array(buffer));\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 readBlobAs from \"./readBlobAs\";\n\nexport default function readBlobAsArrayBuffer(blob: Blob) {\n return readBlobAs(blob, 'readAsArrayBuffer');\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 * 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 from \"../helpers/blob/blobConstruct\";\r\nimport readBlobAsUint8Array from \"../helpers/blob/readBlobAsUint8Array\";\r\n\r\nexport class FileManager {\r\n private 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/blobConstruct';\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 type { InputFileLocation, InputStickerSet, InputWebFileLocation } from \"../layer\";\r\nimport type { DownloadOptions } from \"../lib/mtproto/apiFileManager\";\r\n\r\nconst FILENAME_JOINER = '_';\r\n\r\nexport function getFileNameByLocation(location: InputFileLocation | InputWebFileLocation, options?: Partial<{\r\n fileName: string\r\n}>) {\r\n const fileName = '';//(options?.fileName || '').split('.');\r\n const ext = fileName[fileName.length - 1] || '';\r\n\r\n let str: string;\r\n switch(location._) {\r\n case 'inputPhotoFileLocation': {\r\n str = ['photo', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n case 'inputDocumentFileLocation': {\r\n str = ['document', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n case 'inputPeerPhotoFileLocation':\r\n str = ['peerPhoto', location.photo_id, location.pFlags.big ? 'big' : 'small'].join(FILENAME_JOINER);\r\n break;\r\n \r\n case 'inputStickerSetThumb': {\r\n const id = (location.stickerset as InputStickerSet.inputStickerSetID).id || \r\n (location.stickerset as InputStickerSet.inputStickerSetShortName).short_name || \r\n (location.stickerset as InputStickerSet.inputStickerSetDice).emoticon || \r\n location.stickerset._;\r\n str = ['stickerSetThumb', id, location.thumb_version].join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n case 'inputFileLocation': {\r\n str = location.volume_id + '_' + location.local_id;\r\n break;\r\n }\r\n\r\n case 'inputWebFileLocation': {\r\n str = ['webFile', location.url].join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n default: {\r\n console.error('Unrecognized location:', location);\r\n str = '';\r\n break;\r\n }\r\n }\r\n\r\n return str + (ext ? '.' + ext : ext);\r\n}\r\n\r\nexport type FileURLType = 'photo' | 'thumb' | 'document' | 'stream' | 'download';\r\nexport function getFileURL(type: FileURLType, options: DownloadOptions) {\r\n //console.log('getFileURL', location);\r\n //const perf = performance.now();\r\n const encoded = encodeURIComponent(JSON.stringify(options));\r\n //console.log('getFileURL encode:', performance.now() - perf, encoded);\r\n\r\n return '/' + type + '/' + encoded;\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\nfunction resizeableImage(originalImage: HTMLImageElement, canvas?: HTMLCanvasElement) {\r\n let cropComponent: HTMLDivElement, \r\n container: HTMLDivElement, \r\n cropImage: HTMLImageElement, \r\n event_state: Partial<{ \r\n mouse_x: number, \r\n mouse_y: number, \r\n container_width: number, \r\n container_height: number, \r\n container_left: number, \r\n container_top: number\r\n }> = {}, \r\n keyZoomValue = 4.0, \r\n MINWIDTH = 50, \r\n MINHEIGHT = 50, \r\n CROPWIDTH = 200, \r\n CROPHEIGHT = 200, \r\n cropLeft = 0, \r\n cropTop = 0, \r\n cropWidth = 0, \r\n cropHeight = 0,\r\n scaledRatio = 0;\r\n \r\n if(originalImage.complete) init();\r\n else originalImage.onload = init;\r\n \r\n function removeHandlers() {\r\n container.removeEventListener('mousedown', startMoving);\r\n container.removeEventListener('touchstart', startMoving);\r\n container.removeEventListener('wheel', resizing);\r\n \r\n document.removeEventListener('mouseup', endMoving);\r\n document.removeEventListener('touchend', endMoving);\r\n document.removeEventListener('mousemove', moving);\r\n document.removeEventListener('touchmove', moving);\r\n document.removeEventListener('keypress', keyHandler);\r\n\r\n cropComponent.remove();\r\n container.remove();\r\n cropImage.remove();\r\n }\r\n \r\n function addHandlers() {\r\n container.addEventListener('mousedown', startMoving, false);\r\n container.addEventListener('touchstart', startMoving, false);\r\n container.addEventListener('wheel', resizing, false);\r\n \r\n document.addEventListener('keypress', keyHandler, false);\r\n //document.querySelector('.btn-crop').addEventListener('click', openCropCanvasImg);\r\n }\r\n \r\n function init() {\r\n originalImage.classList.add('crop-blur');\r\n originalImage.draggable = false;\r\n \r\n cropImage = new Image();\r\n cropImage.src = originalImage.src;\r\n cropImage.draggable = false;\r\n cropImage.classList.add('crop-overlay-image');\r\n \r\n if(!canvas) {\r\n canvas = document.createElement('canvas');\r\n }\r\n \r\n cropComponent = document.createElement('div');\r\n cropComponent.classList.add('crop-component');\r\n \r\n container = document.createElement('div');\r\n container.classList.add('crop-overlay');\r\n \r\n const overlayColor = document.createElement('div');\r\n overlayColor.classList.add('crop-overlay-color');\r\n \r\n cropComponent.appendChild(container);\r\n const wrapper = originalImage.parentNode as HTMLElement;\r\n wrapper.appendChild(cropComponent);\r\n cropComponent.appendChild(cropImage);\r\n cropComponent.appendChild(originalImage);\r\n cropComponent.appendChild(overlayColor);\r\n container.appendChild(cropImage);\r\n\r\n cropImage.style.maxWidth = originalImage.width + 'px';\r\n\r\n scaledRatio = originalImage.naturalWidth / originalImage.offsetWidth;\r\n \r\n const left = originalImage.offsetWidth / 2 - CROPWIDTH / 2;\r\n const top = originalImage.offsetHeight / 2 - CROPHEIGHT / 2;\r\n \r\n updateCropSize(CROPWIDTH, CROPHEIGHT);\r\n updateCropImage(left, top);\r\n updateContainer(left, top);\r\n addHandlers();\r\n //crop();\r\n }\r\n \r\n function updateCropSize(width: number, height: number) {\r\n cropWidth = width * scaledRatio;\r\n cropHeight = height * scaledRatio;\r\n\r\n container.style.width = width + 'px';\r\n container.style.height = height + 'px';\r\n }\r\n \r\n function updateCropImage(left: number, top: number) {\r\n cropTop = top * scaledRatio;\r\n cropLeft = left * scaledRatio;\r\n\r\n cropImage.style.top = -top + 'px';\r\n cropImage.style.left = -left + 'px';\r\n }\r\n \r\n function updateContainer(left: number, top: number) {\r\n container.style.top = top + 'px';\r\n container.style.left = left + 'px';\r\n }\r\n \r\n // Save the initial event details and container state\r\n function saveEventState(e: any) {\r\n event_state.container_width = container.offsetWidth;\r\n event_state.container_height = container.offsetHeight;\r\n \r\n event_state.container_left = container.offsetLeft;\r\n event_state.container_top = container.offsetTop;\r\n \r\n event_state.mouse_x = (e.clientX || e.pageX || e.touches && e.touches[0].clientX) + window.scrollX;\r\n event_state.mouse_y = (e.clientY || e.pageY || e.touches && e.touches[0].clientY) + window.scrollY;\r\n }\r\n \r\n function imgZoom(zoom: number) {\r\n zoom = zoom * Math.PI * 2\r\n let newWidth = Math.floor(container.clientWidth + zoom), \r\n newHeight = Math.floor(container.clientHeight + zoom), \r\n w = cropImage.clientWidth, \r\n h = cropImage.clientHeight, \r\n left: number, \r\n top: number, \r\n right: number, \r\n bottom: number;\r\n \r\n if(newWidth < MINWIDTH) {\r\n return;\r\n } else if(newWidth > w) {\r\n return;\r\n }\r\n \r\n left = container.offsetLeft - (zoom / 2);\r\n top = container.offsetTop - (zoom / 2);\r\n right = left + newWidth;\r\n bottom = top + newHeight;\r\n \r\n if(left < 0) left = 0;\r\n if(top < 0) top = 0;\r\n\r\n if(right > w) return;\r\n if(bottom > h) return;\r\n\r\n updateCropSize(newWidth, newWidth);\r\n updateCropImage(left, top);\r\n updateContainer(left, top);\r\n //crop();\r\n }\r\n \r\n function keyHandler(e: KeyboardEvent) {\r\n e.preventDefault();\r\n \r\n switch (String.fromCharCode(e.charCode)) {\r\n case '+' :\r\n imgZoom(keyZoomValue);\r\n break;\r\n case '-' :\r\n imgZoom(-keyZoomValue);\r\n break;\r\n }\r\n }\r\n \r\n function resizing(e: any) {\r\n e.preventDefault();\r\n imgZoom(e.deltaY > 0 ? 1 : -1);\r\n }\r\n \r\n function startMoving(e: MouseEvent | TouchEvent) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n saveEventState(e);\r\n \r\n document.addEventListener('mousemove', moving);\r\n document.addEventListener('touchmove', moving);\r\n document.addEventListener('mouseup', endMoving);\r\n document.addEventListener('touchend', endMoving);\r\n }\r\n \r\n function endMoving(e: MouseEvent | TouchEvent) {\r\n e.preventDefault();\r\n \r\n document.removeEventListener('mouseup', endMoving);\r\n document.removeEventListener('touchend', endMoving);\r\n document.removeEventListener('mousemove', moving);\r\n document.removeEventListener('touchmove', moving);\r\n }\r\n \r\n function moving(e: any) {\r\n let currentTouch = {x: 0, y: 0}, \r\n left: number, \r\n top: number, \r\n w: number, \r\n h: number;\r\n \r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n currentTouch.x = e.pageX || e.touches && e.touches[0].pageX;\r\n currentTouch.y = e.pageY || e.touches && e.touches[0].pageY;\r\n \r\n left = currentTouch.x - (event_state.mouse_x - event_state.container_left);\r\n top = currentTouch.y - (event_state.mouse_y - event_state.container_top);\r\n w = container.offsetWidth;\r\n h = container.offsetHeight;\r\n \r\n if(left < 0) left = 0;\r\n else if(left > cropImage.offsetWidth - w) left = cropImage.offsetWidth - w;\r\n\r\n if(top < 0) top = 0;\r\n else if(top > cropImage.offsetHeight - h) top = cropImage.offsetHeight - h;\r\n \r\n updateCropImage(left, top);\r\n updateContainer(left, top);\r\n //crop();\r\n }\r\n\r\n function crop() {\r\n canvas.width = cropWidth;\r\n canvas.height = cropHeight;\r\n \r\n const ctx = canvas.getContext('2d');\r\n ctx.drawImage(originalImage,\r\n cropLeft, cropTop,\r\n cropWidth, cropHeight,\r\n 0, 0,\r\n cropWidth, cropHeight\r\n );\r\n }\r\n \r\n return {crop, removeHandlers};\r\n}\r\n\r\nexport default resizeableImage;\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 appDownloadManager from \"../../lib/appManagers/appDownloadManager\";\r\nimport resizeableImage from \"../../lib/cropper\";\r\nimport PopupElement from \".\";\r\nimport { _i18n } from \"../../lib/langPack\";\r\nimport { attachClickEvent } from \"../../helpers/dom/clickEvent\";\r\nimport readBlobAsDataURL from \"../../helpers/blob/readBlobAsDataURL\";\r\n\r\nexport default class PopupAvatar extends PopupElement {\r\n private cropContainer: HTMLElement;\r\n private input: HTMLInputElement;\r\n private h6: HTMLElement;\r\n\r\n private image = new Image();\r\n\r\n private canvas: HTMLCanvasElement;\r\n private blob: Blob;\r\n private cropper = {\r\n crop: () => {},\r\n removeHandlers: () => {}\r\n };\r\n\r\n private onCrop: (upload: () => ReturnType<typeof appDownloadManager.upload>) => void;\r\n\r\n constructor() {\r\n super('popup-avatar', null, {closable: true, withConfirm: true});\r\n\r\n this.h6 = document.createElement('h6');\r\n _i18n(this.h6, 'Popup.Avatar.Title');\r\n\r\n this.btnClose.classList.remove('btn-icon');\r\n\r\n this.header.append(this.h6);\r\n\r\n this.cropContainer = document.createElement('div');\r\n this.cropContainer.classList.add('crop');\r\n this.cropContainer.append(this.image);\r\n\r\n this.input = document.createElement('input');\r\n this.input.type = 'file';\r\n this.input.style.display = 'none';\r\n this.listenerSetter.add(this.input)('change', (e: any) => {\r\n const file = e.target.files[0];\r\n if(!file) {\r\n return;\r\n }\r\n\r\n readBlobAsDataURL(file).then(contents => {\r\n this.image = new Image();\r\n this.cropContainer.append(this.image);\r\n this.image.src = contents;\r\n \r\n this.image.onload = () => {\r\n /* let {w, h} = calcImageInBox(this.image.naturalWidth, this.image.naturalHeight, 460, 554);\r\n cropContainer.style.width = w + 'px';\r\n cropContainer.style.height = h + 'px'; */\r\n this.show();\r\n \r\n this.cropper = resizeableImage(this.image, this.canvas);\r\n this.input.value = '';\r\n };\r\n });\r\n }, false);\r\n\r\n this.btnConfirm.className = 'btn-primary btn-color-primary btn-circle btn-crop btn-icon tgico-check z-depth-1';\r\n attachClickEvent(this.btnConfirm, () => {\r\n this.cropper.crop();\r\n this.hide();\r\n\r\n this.canvas.toBlob(blob => {\r\n this.blob = blob; // save blob to send after reg\r\n this.darkenCanvas();\r\n this.resolve();\r\n }, 'image/jpeg', 1);\r\n }, {listenerSetter: this.listenerSetter});\r\n\r\n this.container.append(this.cropContainer, this.btnConfirm, this.input);\r\n\r\n this.addEventListener('closeAfterTimeout', () => {\r\n this.cropper.removeHandlers();\r\n if(this.image) {\r\n this.image.remove();\r\n }\r\n });\r\n }\r\n\r\n private resolve() {\r\n this.onCrop(() => {\r\n return appDownloadManager.upload(this.blob);\r\n });\r\n }\r\n\r\n public open(postCanvas: HTMLCanvasElement, onCrop: PopupAvatar['onCrop']) {\r\n this.canvas = postCanvas;\r\n this.onCrop = onCrop;\r\n\r\n this.input.click();\r\n }\r\n\r\n public darkenCanvas() {\r\n let ctx = this.canvas.getContext('2d');\r\n ctx.fillStyle = \"rgba(0, 0, 0, 0.3)\";\r\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\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 rootScope from \"../../lib/rootScope\";\r\nimport { IS_MOBILE, IS_APPLE } from \"../../environment/userAgent\";\r\n\r\nexport default function isSendShortcutPressed(e: KeyboardEvent) {\r\n if(e.key === 'Enter' && !IS_MOBILE && !e.isComposing) {\r\n /* if(e.ctrlKey || e.metaKey) {\r\n this.messageInput.innerHTML += '<br>';\r\n placeCaretAtEnd(this.message)\r\n return;\r\n } */\r\n\r\n if(rootScope.settings.sendShortcut === 'enter') {\r\n if(e.shiftKey || e.ctrlKey || e.metaKey) {\r\n return;\r\n }\r\n\r\n return true;\r\n } else {\r\n const secondaryKey = IS_APPLE ? e.metaKey : e.ctrlKey;\r\n if(e.shiftKey || (IS_APPLE ? e.ctrlKey : e.metaKey)) {\r\n return;\r\n }\r\n\r\n if(secondaryKey) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\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 readBlobAs from \"./readBlobAs\";\n\nexport default function readBlobAsDataURL(blob: Blob) {\n return readBlobAs(blob, 'readAsDataURL');\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 type { CancellablePromise } from '../helpers/cancellablePromise';\r\nimport type { InputFile } from '../layer';\r\nimport type { AuthState } from '../types';\r\nimport Button from '../components/button';\r\nimport InputField from '../components/inputField';\r\nimport { putPreloader } from '../components/misc';\r\nimport PopupAvatar from '../components/popups/avatar';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport I18n, { i18n } from '../lib/langPack';\r\n//import apiManager from '../lib/mtproto/apiManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport RichTextProcessor from '../lib/richtextprocessor';\r\nimport LoginPage from './loginPage';\r\nimport Page from './page';\r\nimport blurActiveElement from '../helpers/dom/blurActiveElement';\r\nimport replaceContent from '../helpers/dom/replaceContent';\r\n\r\nlet authCode: AuthState.signUp['authCode'] = null;\r\n\r\nconst onFirstMount = () => import('../lib/appManagers/appProfileManager').then(imported => {\r\n const page = new LoginPage({\r\n className: 'page-signUp',\r\n withInputWrapper: true,\r\n titleLangKey: 'YourName',\r\n subtitleLangKey: 'Login.Register.Subtitle'\r\n });\r\n\r\n page.imageDiv.classList.add('avatar-edit');\r\n\r\n page.title.classList.add('fullName');\r\n\r\n const avatarPreview = document.createElement('canvas');\r\n avatarPreview.id = 'canvas-avatar';\r\n avatarPreview.className = 'avatar-edit-canvas';\r\n\r\n const addIco = document.createElement('span');\r\n addIco.className = 'tgico tgico-cameraadd';\r\n\r\n page.imageDiv.append(avatarPreview, addIco);\r\n \r\n const appProfileManager = imported.default;\r\n\r\n let uploadAvatar: () => CancellablePromise<InputFile>;\r\n page.imageDiv.addEventListener('click', () => {\r\n new PopupAvatar().open(avatarPreview, (_uploadAvatar) => {\r\n uploadAvatar = _uploadAvatar;\r\n });\r\n });\r\n\r\n const handleInput = (e: Event) => {\r\n const name = nameInputField.value || '';\r\n const lastName = lastNameInputField.value || '';\r\n\r\n const fullName = name || lastName \r\n ? (name + ' ' + lastName).trim() \r\n : '';\r\n \r\n if(fullName) replaceContent(page.title, RichTextProcessor.wrapEmojiText(fullName));\r\n else replaceContent(page.title, i18n('YourName'));\r\n };\r\n\r\n let sendAvatar = () => new Promise<void>((resolve, reject) => {\r\n if(!uploadAvatar) {\r\n //console.log('User has not selected avatar');\r\n return resolve();\r\n }\r\n\r\n //console.log('invoking uploadFile...');\r\n uploadAvatar().then((inputFile) => {\r\n //console.log('uploaded smthn', inputFile);\r\n \r\n appProfileManager.uploadProfilePhoto(inputFile).then(resolve, reject);\r\n }, reject);\r\n });\r\n\r\n const nameInputField = new InputField({\r\n label: 'FirstName',\r\n maxLength: 70\r\n });\r\n\r\n const lastNameInputField = new InputField({\r\n label: 'LastName',\r\n maxLength: 64\r\n });\r\n\r\n const btnSignUp = Button('btn-primary btn-color-primary');\r\n const btnI18n = new I18n.IntlElement({key: 'StartMessaging'});\r\n btnSignUp.append(btnI18n.element);\r\n\r\n page.inputWrapper.append(nameInputField.container, lastNameInputField.container, btnSignUp);\r\n\r\n nameInputField.input.addEventListener('input', handleInput);\r\n lastNameInputField.input.addEventListener('input', handleInput);\r\n\r\n btnSignUp.addEventListener('click', function(this: typeof btnSignUp, e) {\r\n if(nameInputField.input.classList.contains('error') || lastNameInputField.input.classList.contains('error')) {\r\n return false;\r\n }\r\n\r\n if(!nameInputField.value.length) {\r\n nameInputField.input.classList.add('error');\r\n return false;\r\n }\r\n\r\n this.disabled = true;\r\n\r\n const name = nameInputField.value.trim();\r\n const lastName = lastNameInputField.value.trim();\r\n\r\n const params = {\r\n phone_number: authCode.phone_number,\r\n phone_code_hash: authCode.phone_code_hash,\r\n first_name: name,\r\n last_name: lastName\r\n };\r\n\r\n //console.log('invoking auth.signUp with params:', params);\r\n\r\n btnI18n.update({key: 'PleaseWait'});\r\n const preloader = putPreloader(this);\r\n\r\n apiManager.invokeApi('auth.signUp', params)\r\n .then((response) => {\r\n //console.log('auth.signUp response:', response);\r\n \r\n switch(response._) {\r\n case 'auth.authorization': // success\r\n apiManager.setUser(response.user);\r\n\r\n sendAvatar().finally(() => {\r\n import('./pageIm').then(m => {\r\n m.default.mount();\r\n });\r\n });\r\n \r\n break;\r\n default:\r\n btnI18n.update({key: response._ as any});\r\n this.removeAttribute('disabled');\r\n preloader.remove();\r\n break;\r\n }\r\n\r\n /* (document.body.getElementsByClassName('page-sign')[0] as HTMLDivElement).style.display = 'none';\r\n pageAuthCode(Object.assign(code, {phoneNumber})); */\r\n }).catch(err => {\r\n this.removeAttribute('disabled');\r\n preloader.remove();\r\n\r\n switch(err.type) {\r\n default:\r\n btnI18n.update({key: err.type});\r\n break;\r\n }\r\n });\r\n });\r\n\r\n blurActiveElement();\r\n return new Promise((resolve) => {\r\n window.requestAnimationFrame(resolve);\r\n });\r\n});\r\n\r\nconst page = new Page('page-signUp', true, onFirstMount, (_authCode: typeof authCode) => {\r\n authCode = _authCode;\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignUp', authCode: _authCode});\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 simulateEvent from \"../helpers/dom/dispatchEvent\";\r\nimport findUpAttribute from \"../helpers/dom/findUpAttribute\";\r\nimport getRichValue from \"../helpers/dom/getRichValue\";\r\nimport isInputEmpty from \"../helpers/dom/isInputEmpty\";\r\nimport selectElementContents from \"../helpers/dom/selectElementContents\";\r\nimport { MessageEntity } from \"../layer\";\r\nimport { i18n, LangPackKey, _i18n } from \"../lib/langPack\";\r\nimport RichTextProcessor from \"../lib/richtextprocessor\";\r\nimport SetTransition from \"./singleTransition\";\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\r\n e.preventDefault();\r\n let text: string, entities: MessageEntity[];\r\n\r\n // @ts-ignore\r\n let plainText: string = (e.originalEvent || e).clipboardData.getData('text/plain');\r\n let usePlainText = true;\r\n\r\n // @ts-ignore\r\n let html: string = (e.originalEvent || e).clipboardData.getData('text/html');\r\n if(html.trim()) {\r\n html = html.replace(/<style([\\s\\S]*)<\\/style>/, '');\r\n html = html.replace(/<!--([\\s\\S]*)-->/, '');\r\n\r\n const match = html.match(/<body>([\\s\\S]*)<\\/body>/);\r\n if(match) {\r\n html = match[1].trim();\r\n }\r\n\r\n let span: HTMLElement = document.createElement('span');\r\n span.innerHTML = html;\r\n\r\n let curChild = span.firstChild;\r\n while(curChild) { // * fix whitespace between elements like <p>asd</p>\\n<p>zxc</p>\r\n let nextSibling = curChild.nextSibling;\r\n if(curChild.nodeType === 3) {\r\n if(!curChild.nodeValue.trim()) {\r\n curChild.remove();\r\n }\r\n }\r\n\r\n curChild = nextSibling;\r\n }\r\n\r\n const richValue = getRichValue(span, true);\r\n if(richValue.value.replace(/\\s/g, '').length === plainText.replace(/\\s/g, '').length) {\r\n text = richValue.value;\r\n entities = richValue.entities;\r\n usePlainText = false;\r\n \r\n let entities2 = RichTextProcessor.parseEntities(text);\r\n entities2 = entities2.filter(e => e._ === 'messageEntityEmoji' || e._ === 'messageEntityLinebreak');\r\n RichTextProcessor.mergeEntities(entities, entities2);\r\n }\r\n }\r\n \r\n if(usePlainText) {\r\n text = plainText;\r\n entities = RichTextProcessor.parseEntities(text);\r\n entities = entities.filter(e => e._ === 'messageEntityEmoji' || e._ === 'messageEntityLinebreak');\r\n }\r\n\r\n text = RichTextProcessor.wrapDraftText(text, {entities});\r\n \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?: boolean,\r\n required?: boolean,\r\n canBeEdited?: boolean,\r\n validate?: () => boolean\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 required: boolean;\r\n public validate: () => boolean;\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 this.required = options.required;\r\n this.validate = options.validate;\r\n\r\n if(options.maxLength !== undefined && options.showLengthOn === undefined) {\r\n options.showLengthOn = Math.min(40, Math.round(options.maxLength / 3));\r\n }\r\n\r\n const {placeholder, maxLength, showLengthOn, name, plainText, canBeEdited = true} = 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=\"${String(!!canBeEdited)}\" 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.value) { // * avoid selecting whole empty field on iOS devices\r\n return;\r\n }\r\n\r\n if(this.options.plainText) {\r\n (this.input as HTMLInputElement).select(); // * select text\r\n } else {\r\n selectElementContents(this.input);\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(setHeight = true) {\r\n const {scrollHeight: newHeight/* , 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 const currentHeight = +this.input.style.height.replace('px', '');\r\n if(currentHeight === newHeight) {\r\n return;\r\n }\r\n\r\n const TRANSITION_DURATION_FACTOR = 50;\r\n const transitionDuration = Math.round(\r\n TRANSITION_DURATION_FACTOR * Math.log(Math.abs(newHeight - currentHeight)),\r\n );\r\n\r\n // this.wasInputFakeClientHeight = clientHeight;\r\n this.input.style.transitionDuration = `${transitionDuration}ms`;\r\n\r\n if(setHeight) {\r\n this.input.style.height = newHeight ? newHeight + 'px' : '';\r\n }\r\n\r\n const className = 'is-changing-height';\r\n SetTransition(this.input, className, true, transitionDuration, () => {\r\n this.input.classList.remove(className);\r\n });\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 simulateEvent(this.input, 'input');\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 isChanged() {\r\n return this.value !== this.originalValue;\r\n }\r\n\r\n public isValid() {\r\n return !this.input.classList.contains('error') && \r\n (!this.validate || this.validate()) && \r\n (!this.required || !isInputEmpty(this.input));\r\n }\r\n\r\n public isValidToChange() {\r\n return this.isValid() && this.isChanged();\r\n }\r\n\r\n public setDraftValue(value = '', silent = false) {\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 setOriginalValue(value: InputField['originalValue'] = '', silent = false) {\r\n this.originalValue = value;\r\n this.setDraftValue(value, silent);\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","// https://stackoverflow.com/a/6150060\nexport default function selectElementContents(el: HTMLElement) {\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\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 rootScope from \"../lib/rootScope\";\r\n\r\nconst SetTransition = (\r\n element: HTMLElement, \r\n className: string, \r\n forwards: boolean, \r\n duration: number, \r\n onTransitionEnd?: () => void, \r\n useRafs?: number\r\n) => {\r\n const {timeout, raf} = element.dataset;\r\n if(timeout !== undefined) {\r\n clearTimeout(+timeout);\r\n }\r\n\r\n if(raf !== undefined) {\r\n window.cancelAnimationFrame(+raf);\r\n if(!useRafs) {\r\n delete element.dataset.raf;\r\n }\r\n }\r\n\r\n // if(forwards && className && element.classList.contains(className) && !element.classList.contains('animating')) {\r\n // return;\r\n // }\r\n\r\n if(useRafs && rootScope.settings.animationsEnabled && duration) {\r\n element.dataset.raf = '' + window.requestAnimationFrame(() => {\r\n delete element.dataset.raf;\r\n SetTransition(element, className, forwards, duration, onTransitionEnd, useRafs - 1);\r\n });\r\n\r\n return;\r\n }\r\n\r\n if(forwards && className) {\r\n element.classList.add(className);\r\n }\r\n\r\n const afterTimeout = () => {\r\n delete element.dataset.timeout;\r\n if(!forwards && className) {\r\n element.classList.remove('backwards', className);\r\n }\r\n\r\n element.classList.remove('animating');\r\n \r\n onTransitionEnd && onTransitionEnd();\r\n };\r\n\r\n if(!rootScope.settings.animationsEnabled || !duration) {\r\n element.classList.remove('animating', 'backwards');\r\n afterTimeout();\r\n return;\r\n }\r\n\r\n element.classList.add('animating');\r\n\r\n element.classList.toggle('backwards', !forwards);\r\n element.dataset.timeout = '' + setTimeout(afterTimeout, duration);\r\n};\r\n\r\nexport default SetTransition;\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 rootScope from \"../../lib/rootScope\";\r\nimport { ripple } from \"../ripple\";\r\nimport animationIntersector from \"../animationIntersector\";\r\nimport appNavigationController, { NavigationItem } from \"../appNavigationController\";\r\nimport { i18n, LangPackKey } from \"../../lib/langPack\";\r\nimport findUpClassName from \"../../helpers/dom/findUpClassName\";\r\nimport blurActiveElement from \"../../helpers/dom/blurActiveElement\";\r\nimport ListenerSetter from \"../../helpers/listenerSetter\";\r\nimport { attachClickEvent, simulateClickEvent } from \"../../helpers/dom/clickEvent\";\r\nimport isSendShortcutPressed from \"../../helpers/dom/isSendShortcutPressed\";\r\nimport { cancelEvent } from \"../../helpers/dom/cancelEvent\";\r\nimport EventListenerBase, { EventListenerListeners } from \"../../helpers/eventListenerBase\";\r\nimport { addFullScreenListener, getFullScreenElement } from \"../../helpers/dom/fullScreen\";\r\nimport indexOfAndSplice from \"../../helpers/array/indexOfAndSplice\";\r\n\r\nexport type PopupButton = {\r\n text?: string,\r\n callback?: () => void,\r\n langKey?: LangPackKey,\r\n langArgs?: any[],\r\n isDanger?: true,\r\n isCancel?: true,\r\n element?: HTMLButtonElement\r\n};\r\n\r\nexport type PopupOptions = Partial<{\r\n closable: true, \r\n overlayClosable: true, \r\n withConfirm: LangPackKey | true, \r\n body: true,\r\n confirmShortcutIsSendShortcut: boolean,\r\n withoutOverlay: boolean\r\n}>;\r\n\r\nexport interface PopupElementConstructable {\r\n new(...args: any[]): PopupElement;\r\n}\r\n\r\nconst DEFAULT_APPEND_TO = document.body;\r\nlet appendPopupTo = DEFAULT_APPEND_TO;\r\n\r\nconst onFullScreenChange = () => {\r\n appendPopupTo = getFullScreenElement() || DEFAULT_APPEND_TO;\r\n PopupElement.reAppend();\r\n};\r\n\r\naddFullScreenListener(DEFAULT_APPEND_TO, onFullScreenChange);\r\n\r\ntype PopupListeners = {\r\n close: () => void,\r\n closeAfterTimeout: () => void\r\n};\r\n\r\nexport default class PopupElement<T extends EventListenerListeners = {}> extends EventListenerBase<PopupListeners & T> {\r\n private static POPUPS: PopupElement<any>[] = [];\r\n protected element = document.createElement('div');\r\n protected container = document.createElement('div');\r\n protected header = document.createElement('div');\r\n protected title = document.createElement('div');\r\n protected btnClose: HTMLElement;\r\n protected btnConfirm: HTMLButtonElement;\r\n protected body: HTMLElement;\r\n protected buttonsEl: HTMLElement;\r\n\r\n protected onEscape: () => boolean = () => true;\r\n\r\n protected navigationItem: NavigationItem;\r\n\r\n protected listenerSetter: ListenerSetter;\r\n\r\n protected confirmShortcutIsSendShortcut: boolean;\r\n protected btnConfirmOnEnter: HTMLButtonElement;\r\n\r\n protected withoutOverlay: boolean;\r\n\r\n constructor(className: string, protected buttons?: Array<PopupButton>, options: PopupOptions = {}) {\r\n super(false);\r\n this.element.classList.add('popup');\r\n this.element.className = 'popup' + (className ? ' ' + className : '');\r\n this.container.classList.add('popup-container', 'z-depth-1');\r\n\r\n this.header.classList.add('popup-header');\r\n this.title.classList.add('popup-title');\r\n\r\n this.header.append(this.title);\r\n\r\n this.listenerSetter = new ListenerSetter();\r\n\r\n this.confirmShortcutIsSendShortcut = options.confirmShortcutIsSendShortcut;\r\n\r\n if(options.closable) {\r\n this.btnClose = document.createElement('span');\r\n this.btnClose.classList.add('btn-icon', 'popup-close', 'tgico-close');\r\n //ripple(this.closeBtn);\r\n this.header.prepend(this.btnClose);\r\n\r\n attachClickEvent(this.btnClose, this.hide, {listenerSetter: this.listenerSetter, once: true});\r\n }\r\n\r\n this.withoutOverlay = options.withoutOverlay;\r\n if(this.withoutOverlay) {\r\n this.element.classList.add('no-overlay');\r\n }\r\n\r\n if(options.overlayClosable) {\r\n attachClickEvent(this.element, (e: MouseEvent) => {\r\n if(!findUpClassName(e.target, 'popup-container')) {\r\n this.hide();\r\n }\r\n }, {listenerSetter: this.listenerSetter});\r\n }\r\n\r\n if(options.withConfirm) {\r\n this.btnConfirm = document.createElement('button');\r\n this.btnConfirm.classList.add('btn-primary', 'btn-color-primary');\r\n if(options.withConfirm !== true) {\r\n this.btnConfirm.append(i18n(options.withConfirm));\r\n }\r\n this.header.append(this.btnConfirm);\r\n ripple(this.btnConfirm);\r\n }\r\n\r\n this.container.append(this.header);\r\n if(options.body) {\r\n this.body = document.createElement('div');\r\n this.body.classList.add('popup-body');\r\n this.container.append(this.body);\r\n }\r\n\r\n let btnConfirmOnEnter = this.btnConfirm;\r\n if(buttons?.length) {\r\n const buttonsDiv = this.buttonsEl = document.createElement('div');\r\n buttonsDiv.classList.add('popup-buttons');\r\n\r\n if(buttons.length === 2) {\r\n buttonsDiv.classList.add('popup-buttons-row');\r\n }\r\n \r\n const buttonsElements = buttons.map(b => {\r\n const button = document.createElement('button');\r\n button.className = 'btn' + (b.isDanger ? ' danger' : ' primary');\r\n \r\n ripple(button);\r\n \r\n if(b.text) {\r\n button.innerHTML = b.text;\r\n } else {\r\n button.append(i18n(b.langKey, b.langArgs));\r\n }\r\n \r\n attachClickEvent(button, () => {\r\n b.callback && b.callback();\r\n this.destroy();\r\n }, {listenerSetter: this.listenerSetter, once: true});\r\n \r\n return b.element = button;\r\n });\r\n \r\n if(!btnConfirmOnEnter && buttons.length === 2) {\r\n const button = buttons.find(button => !button.isCancel);\r\n if(button) {\r\n btnConfirmOnEnter = button.element;\r\n }\r\n }\r\n\r\n buttonsDiv.append(...buttonsElements);\r\n this.container.append(buttonsDiv);\r\n }\r\n\r\n this.btnConfirmOnEnter = btnConfirmOnEnter;\r\n\r\n this.element.append(this.container);\r\n\r\n PopupElement.POPUPS.push(this);\r\n }\r\n\r\n public show() {\r\n this.navigationItem = {\r\n type: 'popup',\r\n onPop: () => this.destroy(),\r\n onEscape: this.onEscape\r\n };\r\n\r\n appNavigationController.pushItem(this.navigationItem);\r\n\r\n blurActiveElement(); // * hide mobile keyboard\r\n appendPopupTo.append(this.element);\r\n void this.element.offsetWidth; // reflow\r\n this.element.classList.add('active');\r\n\r\n if(!this.withoutOverlay) {\r\n rootScope.isOverlayActive = true;\r\n animationIntersector.checkAnimations(true);\r\n }\r\n\r\n // cannot add event instantly because keydown propagation will fire it\r\n if(this.btnConfirmOnEnter) {\r\n setTimeout(() => {\r\n this.listenerSetter.add(document.body)('keydown', (e) => {\r\n if(this.confirmShortcutIsSendShortcut ? isSendShortcutPressed(e) : e.key === 'Enter') {\r\n simulateClickEvent(this.btnConfirmOnEnter);\r\n cancelEvent(e);\r\n }\r\n });\r\n }, 0);\r\n }\r\n }\r\n\r\n public hide = () => {\r\n appNavigationController.backByItem(this.navigationItem);\r\n };\r\n\r\n protected destroy() {\r\n this.dispatchEvent<PopupListeners>('close');\r\n this.element.classList.add('hiding');\r\n this.element.classList.remove('active');\r\n this.listenerSetter.removeAll();\r\n\r\n if(!this.withoutOverlay) {\r\n rootScope.isOverlayActive = false;\r\n }\r\n\r\n appNavigationController.removeItem(this.navigationItem);\r\n this.navigationItem = undefined;\r\n\r\n indexOfAndSplice(PopupElement.POPUPS, this);\r\n\r\n // ! calm\r\n onFullScreenChange();\r\n\r\n setTimeout(() => {\r\n this.element.remove();\r\n this.dispatchEvent<PopupListeners>('closeAfterTimeout');\r\n this.cleanup();\r\n\r\n if(!this.withoutOverlay) {\r\n animationIntersector.checkAnimations(false);\r\n }\r\n }, 150);\r\n }\r\n\r\n public static reAppend() {\r\n this.POPUPS.forEach(popup => {\r\n const {element, container} = popup;\r\n const parentElement = element.parentElement;\r\n if(parentElement && parentElement !== appendPopupTo && appendPopupTo !== container) {\r\n appendPopupTo.append(element);\r\n }\r\n });\r\n }\r\n\r\n public static getPopups(popupConstructor: PopupElementConstructable) {\r\n return this.POPUPS.filter(element => element instanceof popupConstructor);\r\n }\r\n}\r\n\r\nexport const addCancelButton = (buttons: PopupButton[]) => {\r\n const button = buttons.find(b => b.isCancel);\r\n if(!button) {\r\n buttons.push({\r\n langKey: 'Cancel',\r\n isCancel: true\r\n });\r\n }\r\n\r\n return buttons;\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?.length) {\r\n // ! cannot do that here because have the same check before the sending in RichTextProcessor.parseMarkdown\r\n /* const entity = entities[entities.length - 1];\r\n const length = value.length;\r\n const trimmedLength = value.trimRight().length;\r\n if(length !== trimmedLength) {\r\n entity.length -= length - trimmedLength;\r\n } */\r\n\r\n RichTextProcessor.combineSameEntities(entities);\r\n RichTextProcessor.sortEntities(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 type EventListenerBase from \"./eventListenerBase\";\r\n\r\nexport type Listener = {\r\n element: ListenerElement, \r\n event: ListenerEvent, \r\n callback: ListenerCallback, \r\n options?: ListenerOptions,\r\n\r\n onceFired?: true, // will be set only when options.once is set\r\n onceCallback?: () => void,\r\n};\r\n\r\nexport type ListenerElement = Window | Document | HTMLElement | Element | EventListenerBase<any>;\r\nexport type ListenerEvent = string;\r\nexport type ListenerCallback = Function;\r\nexport type ListenerOptions = AddEventListenerOptions;\r\n\r\n/* const originalAddEventListener = HTMLElement.prototype.addEventListener;\r\nHTMLElement.prototype.addEventListener = function(this, name: string, callback: EventListenerOrEventListenerObject, options: AddEventListenerOptions) {\r\n console.log('nu zdarova', name);\r\n originalAddEventListener.call(this, name, callback, options);\r\n\r\n if(options?.ls) {\r\n return options.ls.addFromElement(this, name, callback as any, options);\r\n }\r\n}; */\r\n\r\nexport default class ListenerSetter {\r\n private listeners: Set<Listener> = new Set();\r\n\r\n public add<T extends ListenerElement>(element: T): T['addEventListener'] {\r\n return ((event: string, callback: Function, options: ListenerOptions) => {\r\n const listener: Listener = {element, event, callback, options};\r\n this.addManual(listener);\r\n return listener;\r\n }) as any;\r\n }\r\n\r\n /* public addFromElement<T extends ListenerElement>(element: T, event: ListenerEvent, callback: ListenerCallback, options: ListenerOptions) {\r\n const listener: Listener = {element, event, callback, options};\r\n this.addManual(listener);\r\n return listener;\r\n } */\r\n\r\n public addManual(listener: Listener) {\r\n // @ts-ignore\r\n listener.element.addEventListener(listener.event, listener.callback, listener.options);\r\n\r\n if(listener.options?.once) { // remove listener when its called\r\n listener.onceCallback = () => {\r\n this.remove(listener);\r\n listener.onceFired = true;\r\n };\r\n \r\n // @ts-ignore\r\n listener.element.addEventListener(listener.event, listener.onceCallback, listener.options);\r\n }\r\n\r\n this.listeners.add(listener);\r\n }\r\n\r\n public remove(listener: Listener) {\r\n if(!listener.onceFired) {\r\n // @ts-ignore\r\n listener.element.removeEventListener(listener.event, listener.callback, listener.options);\r\n\r\n if(listener.onceCallback) {\r\n // @ts-ignore\r\n listener.element.removeEventListener(listener.event, listener.onceCallback, listener.options);\r\n }\r\n }\r\n\r\n this.listeners.delete(listener);\r\n }\r\n\r\n public removeManual<T extends ListenerElement>(\r\n element: T, \r\n event: ListenerEvent, \r\n callback: ListenerCallback, \r\n options?: ListenerOptions\r\n ) {\r\n let listener: Listener;\r\n for(const _listener of this.listeners) {\r\n if(_listener.element === element && \r\n _listener.event === event && \r\n _listener.callback === callback && \r\n _listener.options === options) {\r\n listener = _listener;\r\n break;\r\n }\r\n }\r\n\r\n if(listener) {\r\n this.remove(listener);\r\n }\r\n }\r\n\r\n public removeAll() {\r\n this.listeners.forEach(listener => {\r\n this.remove(listener);\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\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 * 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' | 'spoiler';\r\nexport type MarkdownTag = {\r\n match: string,\r\n entityName: Extract<MessageEntity['_'], 'messageEntityBold' | 'messageEntityUnderline' | 'messageEntityItalic' | 'messageEntityPre' | 'messageEntityStrike' | 'messageEntityTextUrl' | 'messageEntityMentionName' | 'messageEntitySpoiler'>;\r\n};\r\n\r\n// https://core.telegram.org/bots/api#html-style\r\nexport const markdownTags: {[type in MarkdownType]: MarkdownTag} = {\r\n bold: {\r\n match: '[style*=\"bold\"], [style*=\"font-weight: 700\"], [style*=\"font-weight: 600\"], [style*=\"font-weight:700\"], [style*=\"font-weight:600\"], b, strong',\r\n entityName: 'messageEntityBold'\r\n },\r\n underline: {\r\n match: '[style*=\"underline\"], u, ins',\r\n entityName: 'messageEntityUnderline'\r\n },\r\n italic: {\r\n match: '[style*=\"italic\"], i, em',\r\n entityName: 'messageEntityItalic'\r\n },\r\n monospace: {\r\n match: '[style*=\"monospace\"], [face=\"monospace\"], pre',\r\n entityName: 'messageEntityPre'\r\n },\r\n strikethrough: {\r\n match: '[style*=\"line-through\"], strike, del, s',\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 spoiler: {\r\n match: '[style*=\"spoiler\"]',\r\n entityName: 'messageEntitySpoiler'\r\n }\r\n};\r\n\r\nconst tabulationMatch = '[style*=\"table-cell\"], th, td';\r\n\r\n/* export function getDepth(child: Node, container?: Node) {\r\n let depth = 0;\r\n\r\n do {\r\n if(child === container) {\r\n return depth;\r\n }\r\n\r\n ++depth;\r\n } while((child = child.parentNode) !== null);\r\n\r\n return depth;\r\n} */\r\n\r\nconst BLOCK_TAG_NAMES = new Set([\r\n 'DIV',\r\n 'P',\r\n 'BR',\r\n 'LI',\r\n 'SECTION',\r\n 'H6',\r\n 'H5',\r\n 'H4',\r\n 'H3',\r\n 'H2',\r\n 'H1',\r\n 'TR'\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 let nodeValue = node.nodeValue;\r\n\r\n /* const tabulation = node.parentElement?.closest(tabulationMatch + ', [contenteditable]');\r\n if(tabulation?.getAttribute('contenteditable') === null) {\r\n nodeValue += ' ';\r\n // line.push('\\t');\r\n // ++offset.offset;\r\n } */\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.length) {\r\n if(node.parentNode) {\r\n const parentElement = node.parentElement;\r\n \r\n // let closestTag: MarkdownTag, closestElementByTag: Element, closestDepth = Infinity;\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?.getAttribute('contenteditable') !== null) {\r\n /* const depth = getDepth(closest, parentElement.closest('[contenteditable]'));\r\n if(closestDepth > depth) {\r\n closestDepth = depth;\r\n closestTag = tag;\r\n closestElementByTag = closest;\r\n } */\r\n continue;\r\n }\r\n\r\n if(tag.entityName === 'messageEntityTextUrl') {\r\n entities.push({\r\n _: tag.entityName,\r\n url: (closest 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: (closest as HTMLElement).dataset.follow.toUserId()\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 offset.offset += nodeValue.length;\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 = BLOCK_TAG_NAMES.has(node.tagName);\r\n if(isBlock && line.length) {\r\n lines.push(line.join(''));\r\n line.splice(0, line.length);\r\n ++offset.offset;\r\n } else if(node instanceof HTMLImageElement) {\r\n const alt = node.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 const isTableCell = node.matches(tabulationMatch);\r\n const wasEntitiesLength = entities?.length;\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(isTableCell && node.nextSibling) {\r\n line.push(' ');\r\n ++offset.offset;\r\n\r\n // * combine entities such as url after adding space\r\n if(wasEntitiesLength !== undefined) {\r\n for(let i = wasEntitiesLength, length = entities.length; i < length; ++i) {\r\n ++entities[i].length;\r\n }\r\n }\r\n }\r\n\r\n const wasLength = line.length;\r\n if(isBlock && wasLength) {\r\n lines.push(line.join(''));\r\n line.splice(0, wasLength);\r\n ++offset.offset;\r\n }\r\n\r\n if(wasLength && node.tagName === 'P' && node.nextSibling) {\r\n lines.push('');\r\n ++offset.offset;\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 type { DownloadOptions } from \"../mtproto/apiFileManager\";\r\nimport type { ApiError } from \"../mtproto/apiManager\";\r\nimport type { MyDocument } from \"./appDocsManager\";\r\nimport type { MyPhoto } from \"./appPhotosManager\";\r\nimport rootScope from \"../rootScope\";\r\nimport apiManager from \"../mtproto/mtprotoworker\";\r\nimport { deferredPromise, CancellablePromise } from \"../../helpers/cancellablePromise\";\r\nimport { InputFile } from \"../../layer\";\r\nimport { getFileNameByLocation } from \"../../helpers/fileName\";\r\nimport CacheStorageController from \"../cacheStorage\";\r\nimport { MOUNT_CLASS_TO } from \"../../config/debug\";\r\n\r\nexport type ResponseMethodBlob = 'blob';\r\nexport type ResponseMethodJson = 'json';\r\nexport type ResponseMethod = ResponseMethodBlob | ResponseMethodJson;\r\n\r\n/* export type DownloadBlob = {promise: Promise<Blob>, controller: AbortController};\r\nexport type DownloadJson = {promise: Promise<any>, controller: AbortController}; */\r\nexport type DownloadBlob = CancellablePromise<Blob>;\r\nexport type DownloadJson = CancellablePromise<any>;\r\n//export type Download = DownloadBlob/* | DownloadJson */;\r\nexport type Download = DownloadBlob/* | DownloadJson */;\r\n\r\nexport type Progress = {done: number, fileName: string, total: number, offset: number};\r\nexport type ProgressCallback = (details: Progress) => void;\r\n\r\nexport type ThumbCache = {\r\n downloaded: number, \r\n url: string\r\n};\r\n\r\nexport type ThumbsCache = {\r\n [id: string]: {\r\n [size: string]: ThumbCache\r\n }\r\n};\r\n\r\nexport class AppDownloadManager {\r\n public cacheStorage = new CacheStorageController('cachedFiles');\r\n private downloads: {[fileName: string]: Download} = {};\r\n private progress: {[fileName: string]: Progress} = {};\r\n private progressCallbacks: {[fileName: string]: Array<ProgressCallback>} = {};\r\n\r\n private uploadId = 0;\r\n\r\n private thumbsCache: {\r\n photo: ThumbsCache,\r\n document: ThumbsCache\r\n } = {\r\n photo: {},\r\n document: {}\r\n };\r\n\r\n constructor() {\r\n rootScope.addEventListener('download_progress', (e) => {\r\n const details = e as {done: number, fileName: string, total: number, offset: number};\r\n this.progress[details.fileName] = details;\r\n\r\n const callbacks = this.progressCallbacks[details.fileName];\r\n if(callbacks) {\r\n callbacks.forEach(callback => callback(details));\r\n }\r\n\r\n const download = this.downloads[details.fileName];\r\n if(download) {\r\n download.notifyAll(details);\r\n }\r\n });\r\n }\r\n\r\n private getNewDeferred<T>(fileName: string) {\r\n const deferred = deferredPromise<T>();\r\n\r\n deferred.cancel = () => {\r\n //try {\r\n const error = new Error('Download canceled');\r\n error.name = 'AbortError';\r\n \r\n apiManager.cancelDownload(fileName);\r\n \r\n deferred.reject(error);\r\n deferred.cancel = () => {};\r\n /* } catch(err) {\r\n\r\n } */\r\n };\r\n\r\n deferred.finally(() => {\r\n delete this.progress[fileName];\r\n delete this.progressCallbacks[fileName];\r\n });\r\n\r\n deferred.catch(() => {\r\n this.clearDownload(fileName);\r\n });\r\n\r\n return this.downloads[fileName] = deferred as any;\r\n }\r\n\r\n private clearDownload(fileName: string) {\r\n delete this.downloads[fileName];\r\n }\r\n\r\n public fakeDownload(fileName: string, value: Blob | string) {\r\n const deferred = this.getNewDeferred<Blob>(fileName);\r\n if(typeof(value) === 'string') {\r\n fetch(value)\r\n .then(response => response.blob())\r\n .then(blob => deferred.resolve(blob));\r\n } else {\r\n deferred.resolve(value);\r\n }\r\n\r\n return deferred;\r\n }\r\n\r\n public download(options: DownloadOptions): DownloadBlob {\r\n const fileName = getFileNameByLocation(options.location, {fileName: options.fileName});\r\n if(this.downloads.hasOwnProperty(fileName)) return this.downloads[fileName];\r\n\r\n const deferred = this.getNewDeferred<Blob>(fileName);\r\n\r\n const onError = (err: ApiError) => {\r\n deferred.reject(err);\r\n };\r\n\r\n const tryDownload = (): Promise<unknown> => {\r\n //return Promise.resolve();\r\n\r\n if(!apiManager.worker || options.onlyCache) {\r\n const promise = this.cacheStorage.getFile(fileName).then((blob) => {\r\n if(blob.size < options.size) throw 'wrong size';\r\n else deferred.resolve(blob);\r\n });\r\n \r\n if(options.onlyCache) return promise.catch(onError);\r\n return promise.catch(() => {\r\n return apiManager.downloadFile(options).then(deferred.resolve, onError);\r\n });\r\n } else {\r\n /* return apiManager.downloadFile(options).then(res => {\r\n setTimeout(() => deferred.resolve(res), 5e3);\r\n }, onError); */\r\n\r\n return apiManager.downloadFile(options).then(deferred.resolve, onError);\r\n }\r\n };\r\n\r\n tryDownload();\r\n\r\n //console.log('Will download file:', fileName, url);\r\n return deferred;\r\n }\r\n\r\n public upload(file: File | Blob, fileName?: string) {\r\n if(!fileName) {\r\n const mimeType = file?.type;\r\n if(mimeType) { // the same like apiFileName in appMessagesManager for upload!\r\n const ext = this.uploadId++ + '.' + mimeType.split('/')[1];\r\n \r\n if(['image/jpeg', 'image/png', 'image/bmp'].indexOf(mimeType) >= 0) {\r\n fileName = 'photo' + ext;\r\n } else if(mimeType.indexOf('audio/') === 0 || ['video/ogg'].indexOf(mimeType) >= 0) {\r\n fileName = 'audio' + ext;\r\n } else if(mimeType.indexOf('video/') === 0) {\r\n fileName = 'video' + ext;\r\n } else {\r\n fileName = 'document' + ext;\r\n }\r\n \r\n } else {\r\n fileName = 'upload-' + this.uploadId++;\r\n }\r\n }\r\n\r\n const deferred = this.getNewDeferred<InputFile>(fileName);\r\n apiManager.uploadFile({file, fileName}).then(deferred.resolve, deferred.reject);\r\n\r\n deferred.finally(() => {\r\n this.clearDownload(fileName);\r\n });\r\n\r\n return deferred as any as CancellablePromise<InputFile>;\r\n }\r\n\r\n public getDownload(fileName: string) {\r\n return this.downloads[fileName];\r\n }\r\n\r\n public addProgressCallback(fileName: string, callback: ProgressCallback) {\r\n const progress = this.progress[fileName];\r\n (this.progressCallbacks[fileName] ?? (this.progressCallbacks[fileName] = [])).push(callback);\r\n\r\n if(progress) {\r\n callback(progress);\r\n }\r\n }\r\n\r\n public createDownloadAnchor(url: string, fileName: string, onRemove?: () => void) {\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = fileName;\r\n a.target = '_blank';\r\n \r\n a.style.position = 'absolute';\r\n a.style.top = '1px';\r\n a.style.left = '1px';\r\n \r\n document.body.append(a);\r\n \r\n try {\r\n var clickEvent = document.createEvent('MouseEvents');\r\n clickEvent.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\r\n a.dispatchEvent(clickEvent);\r\n } catch (e) {\r\n console.error('Download click error', e);\r\n try {\r\n a.click();\r\n } catch (e) {\r\n window.open(url as string, '_blank');\r\n }\r\n }\r\n \r\n setTimeout(() => {\r\n a.remove();\r\n onRemove && onRemove();\r\n }, 100);\r\n }\r\n\r\n /* public downloadToDisc(fileName: string, url: string) {\r\n this.createDownloadAnchor(url);\r\n \r\n return this.download(fileName, url);\r\n } */\r\n\r\n public downloadToDisc(options: DownloadOptions, discFileName: string) {\r\n const download = this.download(options);\r\n download/* .promise */.then(blob => {\r\n const objectURL = URL.createObjectURL(blob);\r\n this.createDownloadAnchor(objectURL, discFileName, () => {\r\n URL.revokeObjectURL(objectURL);\r\n });\r\n });\r\n \r\n return download;\r\n }\r\n\r\n public getCacheContext(media: MyPhoto | MyDocument, thumbSize: string = 'full'): ThumbCache {\r\n /* if(media._ === 'photo' && thumbSize !== 'i') {\r\n thumbSize = 'full';\r\n } */\r\n\r\n const cache = this.thumbsCache[media._][media.id] ?? (this.thumbsCache[media._][media.id] = {});\r\n return cache[thumbSize] ?? (cache[thumbSize] = {downloaded: 0, url: ''});\r\n }\r\n}\r\n\r\nconst appDownloadManager = new AppDownloadManager();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.appDownloadManager = appDownloadManager);\r\nexport default appDownloadManager;\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","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// import { IS_WEB_WORKER } from \"../context\";\n\n// const id = IS_WEB_WORKER ? Math.random() * 0x1000 | 0 : 0;\nexport default function readBlobAs(blob: Blob, method: 'readAsText'): Promise<string>;\nexport default function readBlobAs(blob: Blob, method: 'readAsDataURL'): Promise<string>;\nexport default function readBlobAs(blob: Blob, method: 'readAsArrayBuffer'): Promise<ArrayBuffer>;\nexport default function readBlobAs(blob: Blob, method: 'readAsArrayBuffer' | 'readAsText' | 'readAsDataURL'): Promise<any> {\n // const perf = performance.now();\n return new Promise<any>((resolve) => {\n const reader = new FileReader();\n reader.addEventListener('loadend', (e) => {\n // console.log(`readBlobAs [${id}] ${method} time ${performance.now() - perf}`);\n resolve(e.target.result);\n });\n reader[method](blob);\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 { LangPackKey, i18n } from \"../lib/langPack\";\r\n\r\nexport default class LoginPage {\r\n public element: HTMLElement;\r\n public container: HTMLElement;\r\n public imageDiv: HTMLElement;\r\n public inputWrapper: HTMLElement;\r\n public title: HTMLElement;\r\n public subtitle: HTMLParagraphElement;\r\n\r\n constructor(options: {\r\n className: string,\r\n withInputWrapper?: boolean,\r\n titleLangKey?: LangPackKey,\r\n subtitleLangKey?: LangPackKey,\r\n }) {\r\n this.element = document.body.querySelector('.' + options.className) as HTMLDivElement;\r\n //this.element = document.createElement('div');\r\n //this.element.className = 'page-' + options.className;\r\n\r\n this.container = document.createElement('div');\r\n this.container.className = 'container center-align';\r\n\r\n this.imageDiv = document.createElement('div');\r\n this.imageDiv.className = 'auth-image';\r\n\r\n this.title = document.createElement('h4');\r\n if(options.titleLangKey) {\r\n this.title.append(i18n(options.titleLangKey));\r\n }\r\n\r\n this.subtitle = document.createElement('p');\r\n this.subtitle.className = 'subtitle';\r\n if(options.subtitleLangKey) {\r\n this.subtitle.append(i18n(options.subtitleLangKey));\r\n }\r\n \r\n this.container.append(this.imageDiv, this.title, this.subtitle);\r\n\r\n if(options.withInputWrapper) {\r\n this.inputWrapper = document.createElement('div');\r\n this.inputWrapper.className = 'input-wrapper';\r\n this.container.append(this.inputWrapper);\r\n }\r\n\r\n this.element.append(this.container);\r\n }\r\n}\r\n"],"sourceRoot":""}