1 line
113 KiB
Plaintext
1 line
113 KiB
Plaintext
{"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":""} |