tweb/public/1.f63fd3ceb28384c193a9.chun...

1 line
45 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/dispatchEvent.ts","webpack:///./src/helpers/sequentialDom.ts","webpack:///./src/helpers/dom/isSwipingBackSafari.ts","webpack:///./src/helpers/dom/clickEvent.ts","webpack:///./src/components/button.ts","webpack:///./src/components/misc.ts","webpack:///./src/components/ripple.ts","webpack:///./src/components/appNavigationController.ts"],"names":["simulateEvent","elem","name","event","Event","bubbles","cancelable","dispatchEvent","sequentialDom","promises","raf","bind","scheduled","kind","callback","promise","this","scheduleFlush","undefined","then","do","element","isConnected","mutate","Promise","resolve","read","write","isSwipingBackSafari","e","TouchEvent","touches","clientX","CLICK_EVENT_NAME","attachClickEvent","options","add","listenerSetter","addEventListener","touchMouseDown","detachClickEvent","removeEventListener","simulateClickEvent","className","button","document","createElement","asDiv","icon","noRipple","rippleSquare","classList","onlyMobile","disabled","setAttribute","text","append","putPreloader","returnDiv","html","div","innerHTML","appendChild","insertAdjacentHTML","lastElementChild","setButtonLoader","remove","removeAttribute","onMouseMove","rect","openedMenu","getBoundingClientRect","clientY","diffX","right","left","diffY","bottom","top","closeBtnMenu","onClick","parentElement","menuOverlay","openedMenuOnClose","window","removeByType","openBtnMenu","menuElement","onClose","pushItem","type","onPop","canAnimate","insertBefore","once","positionMenu","pageX","pageY","side","additionalPadding","getScrollWidthFromElement","Array","from","children","find","contains","scrollWidth","menuWidth","scrollHeight","menuHeight","body","windowWidth","width","windowHeight","height","paddingTop","paddingRight","paddingBottom","paddingLeft","isMobile","verticalSide","maxTop","maxLeft","minLeft","sides","x","Math","min","intermediateX","y","intermediateY","possibleSides","style","replace","_cancelContextMenuOpening","_cancelContextMenuOpeningTimeout","cancelContextMenuOpening","clearTimeout","setTimeout","attachContextMenuListener","removeManual","timeout","capture","onCancel","length","rippleClickId","ripple","onEnd","prepend","attachListenerTo","querySelector","r","handler","drawRipple","startTime","Date","now","clickId","duration","getComputedStyle","getPropertyValue","elapsedTime","cb","delay","max","touchStartFired","requestAnimationFrame","clickX","clickY","size","sqrt","abs","isRippleUnneeded","target","includes","tagName","touchEnd","settings","animationsEnabled","cancelBubble","stopPropagation","passive","dataset","appNavigationController","navigations","id","manual","log","debug","currentHash","location","hash","isPossibleSwipe","onHashChange","replaceState","state","pushState","item","pop","handleItem","key","onEscape","back","history","scrollRestoration","good","noBlurOnPop","i","index","ret","findItemByType","backByItem","indexOf","splice","noHistory","push","onItemAdded","unshift","origin","pathname","single"],"mappings":"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","file":"1.f63fd3ceb28384c193a9.chunk.js","sourcesContent":["export default function simulateEvent(elem: EventTarget, name: string) {\n const event = new Event(name, {bubbles: true, cancelable: true});\n elem.dispatchEvent(event);\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { fastRaf } from \"./schedulers\";\r\nimport deferredPromise, { CancellablePromise } from \"./cancellablePromise\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport isInDOM from \"./dom/isInDOM\";\r\n\r\nclass SequentialDom {\r\n private promises: Partial<{\r\n read: CancellablePromise<void>,\r\n write: CancellablePromise<void>\r\n }> = {};\r\n private raf = fastRaf.bind(null);\r\n private scheduled = false;\r\n\r\n private do(kind: keyof SequentialDom['promises'], callback?: VoidFunction) {\r\n let promise = this.promises[kind];\r\n if(!promise) {\r\n this.scheduleFlush();\r\n promise = this.promises[kind] = deferredPromise<void>();\r\n }\r\n\r\n if(callback !== undefined) {\r\n promise.then(() => callback());\r\n }\r\n \r\n return promise;\r\n }\r\n\r\n public measure(callback?: VoidFunction) {\r\n return this.do('read', callback);\r\n }\r\n\r\n public mutate(callback?: VoidFunction) {\r\n return this.do('write', callback);\r\n }\r\n\r\n /**\r\n * Will fire instantly if element is not connected\r\n * @param element \r\n * @param callback \r\n */\r\n public mutateElement(element: HTMLElement, callback?: VoidFunction) {\r\n const isConnected = isInDOM(element);\r\n const promise = isConnected ? this.mutate() : Promise.resolve();\r\n\r\n if(callback !== undefined) {\r\n if(isConnected) {\r\n callback();\r\n } else {\r\n promise.then(() => callback());\r\n }\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n private scheduleFlush() {\r\n if(!this.scheduled) {\r\n this.scheduled = true;\r\n\r\n this.raf(() => {\r\n this.promises.read && this.promises.read.resolve();\r\n this.promises.write && this.promises.write.resolve();\r\n\r\n this.scheduled = false;\r\n this.promises = {};\r\n });\r\n }\r\n }\r\n}\r\n\r\nconst sequentialDom = new SequentialDom();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.sequentialDom = sequentialDom);\r\nexport default sequentialDom;\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport { IS_MOBILE_SAFARI } from \"../../environment/userAgent\";\n\nexport default function isSwipingBackSafari(e: TouchEvent | MouseEvent) {\n return IS_MOBILE_SAFARI && e instanceof TouchEvent && e.touches[0].clientX < 30;\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport type ListenerSetter from \"../listenerSetter\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../../environment/touchSupport\";\r\nimport simulateEvent from \"./dispatchEvent\";\r\n\r\nexport const CLICK_EVENT_NAME: 'mousedown' /* | 'touchend' */ | 'click' = (IS_TOUCH_SUPPORTED ? 'mousedown' : 'click') as any;\r\nexport type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;\r\nexport function attachClickEvent(elem: HTMLElement | Window, callback: (e: /* TouchEvent | */MouseEvent) => void, options: AttachClickOptions = {}) {\r\n const add = options.listenerSetter ? options.listenerSetter.add(elem) : elem.addEventListener.bind(elem);\r\n // const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);\r\n\r\n options.touchMouseDown = true;\r\n /* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {\r\n add('mousedown', callback, options);\r\n } else if(CLICK_EVENT_NAME === 'touchend') {\r\n const o = {...options, once: true};\r\n\r\n const onTouchStart = (e: TouchEvent) => {\r\n const onTouchMove = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n remove('touchend', onTouchEnd, o);\r\n };\r\n \r\n const onTouchEnd = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n callback(e);\r\n if(options.once) {\r\n remove('touchstart', onTouchStart);\r\n }\r\n };\r\n \r\n add('touchend', onTouchEnd, o);\r\n add('touchmove', onTouchMove, o);\r\n };\r\n\r\n add('touchstart', onTouchStart);\r\n } else {\r\n add(CLICK_EVENT_NAME, callback, options);\r\n } */\r\n add(CLICK_EVENT_NAME, callback, options);\r\n}\r\n\r\nexport function detachClickEvent(elem: HTMLElement, callback: (e: /* TouchEvent | */MouseEvent) => void, options?: AddEventListenerOptions) {\r\n // if(CLICK_EVENT_NAME === 'touchend') {\r\n // elem.removeEventListener('touchstart', callback, options);\r\n // } else {\r\n elem.removeEventListener(CLICK_EVENT_NAME, callback, options);\r\n // }\r\n}\r\n\r\nexport function simulateClickEvent(elem: HTMLElement) {\r\n simulateEvent(elem, CLICK_EVENT_NAME);\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { i18n, LangPackKey } from \"../lib/langPack\";\r\nimport ripple from \"./ripple\";\r\n\r\nexport type ButtonOptions = Partial<{\r\n noRipple: true, \r\n onlyMobile: true, \r\n icon: string, \r\n rippleSquare: true, \r\n text: LangPackKey, \r\n disabled: boolean,\r\n asDiv: boolean\r\n}>;\r\n\r\nconst Button = (className: string, options: ButtonOptions = {}) => {\r\n const button: HTMLButtonElement = document.createElement(options.asDiv ? 'div' : 'button') as any;\r\n button.className = className + (options.icon ? ' tgico-' + options.icon : '');\r\n\r\n if(!options.noRipple) {\r\n if(options.rippleSquare) {\r\n button.classList.add('rp-square');\r\n }\r\n\r\n ripple(button);\r\n }\r\n\r\n if(options.onlyMobile) {\r\n button.classList.add('only-handhelds');\r\n }\r\n\r\n if(options.disabled) {\r\n button.setAttribute('disabled', 'true');\r\n }\r\n\r\n if(options.text) {\r\n button.append(i18n(options.text));\r\n }\r\n\r\n return button;\r\n};\r\n\r\nexport default Button;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport cancelEvent from \"../helpers/dom/cancelEvent\";\r\nimport { CLICK_EVENT_NAME } from \"../helpers/dom/clickEvent\";\r\nimport ListenerSetter from \"../helpers/listenerSetter\";\r\nimport mediaSizes from \"../helpers/mediaSizes\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport { IS_APPLE, IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport appNavigationController from \"./appNavigationController\";\r\n\r\nexport function putPreloader(elem: Element, returnDiv = false): HTMLElement {\r\n const html = `\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"preloader-circular\" viewBox=\"25 25 50 50\">\r\n <circle class=\"preloader-path\" cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-miterlimit=\"10\"/>\r\n </svg>`;\r\n\r\n if(returnDiv) {\r\n const div = document.createElement('div');\r\n div.classList.add('preloader');\r\n div.innerHTML = html;\r\n\r\n if(elem) {\r\n elem.appendChild(div);\r\n }\r\n\r\n return div;\r\n }\r\n \r\n elem.insertAdjacentHTML('beforeend', html);\r\n return elem.lastElementChild as HTMLElement;\r\n}\r\n\r\nMOUNT_CLASS_TO.putPreloader = putPreloader;\r\n\r\nexport function setButtonLoader(elem: HTMLButtonElement, icon = 'check') {\r\n elem.classList.remove('tgico-' + icon);\r\n elem.disabled = true;\r\n putPreloader(elem);\r\n\r\n return () => {\r\n elem.innerHTML = '';\r\n elem.classList.add('tgico-' + icon);\r\n elem.removeAttribute('disabled');\r\n };\r\n}\r\n\r\n/* export function parseMenuButtonsTo(to: {[name: string]: HTMLElement}, elements: HTMLCollection | NodeListOf<HTMLElement>) {\r\n Array.from(elements).forEach(el => {\r\n const match = el.className.match(/(?:^|\\s)menu-(.+?)(?:$|\\s)/);\r\n if(!match) return;\r\n to[match[1]] = el as HTMLElement;\r\n });\r\n} */\r\n\r\nlet onMouseMove = (e: MouseEvent) => {\r\n let rect = openedMenu.getBoundingClientRect();\r\n let {clientX, clientY} = e;\r\n \r\n let diffX = clientX >= rect.right ? clientX - rect.right : rect.left - clientX;\r\n let diffY = clientY >= rect.bottom ? clientY - rect.bottom : rect.top - clientY;\r\n \r\n if(diffX >= 100 || diffY >= 100) {\r\n closeBtnMenu();\r\n //openedMenu.parentElement.click();\r\n }\r\n //console.log('mousemove', diffX, diffY);\r\n};\r\n\r\nconst onClick = (e: MouseEvent | TouchEvent) => {\r\n //cancelEvent(e);\r\n closeBtnMenu();\r\n};\r\n\r\n// ! no need in this due to the same handler in appNavigationController\r\n/* const onKeyDown = (e: KeyboardEvent) => {\r\n if(e.key === 'Escape') {\r\n closeBtnMenu();\r\n cancelEvent(e);\r\n }\r\n}; */\r\n\r\nexport const closeBtnMenu = () => {\r\n if(openedMenu) {\r\n openedMenu.classList.remove('active');\r\n openedMenu.parentElement.classList.remove('menu-open');\r\n //openedMenu.previousElementSibling.remove(); // remove overlay\r\n if(menuOverlay) menuOverlay.remove();\r\n openedMenu = null;\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', false);\r\n }\r\n \r\n if(openedMenuOnClose) {\r\n openedMenuOnClose();\r\n openedMenuOnClose = null;\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('mousemove', onMouseMove);\r\n //window.removeEventListener('keydown', onKeyDown, {capture: true});\r\n window.removeEventListener('contextmenu', onClick);\r\n }\r\n\r\n document.removeEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.removeByType('menu');\r\n }\r\n};\r\n\r\nwindow.addEventListener('resize', () => {\r\n if(openedMenu) {\r\n closeBtnMenu();\r\n }\r\n \r\n /* if(openedMenu && (openedMenu.style.top || openedMenu.style.left)) {\r\n const rect = openedMenu.getBoundingClientRect();\r\n const {innerWidth, innerHeight} = window;\r\n\r\n console.log(innerWidth, innerHeight, rect);\r\n } */\r\n});\r\n\r\nlet openedMenu: HTMLElement = null, openedMenuOnClose: () => void = null, menuOverlay: HTMLElement = null;\r\nexport function openBtnMenu(menuElement: HTMLElement, onClose?: () => void) {\r\n closeBtnMenu();\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.pushItem({\r\n type: 'menu',\r\n onPop: (canAnimate) => {\r\n closeBtnMenu();\r\n }\r\n });\r\n }\r\n \r\n openedMenu = menuElement;\r\n openedMenu.classList.add('active');\r\n openedMenu.parentElement.classList.add('menu-open');\r\n\r\n if(!menuOverlay) {\r\n menuOverlay = document.createElement('div');\r\n menuOverlay.classList.add('btn-menu-overlay');\r\n\r\n // ! because this event must be canceled, and can't cancel on menu click (below)\r\n menuOverlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n });\r\n }\r\n\r\n openedMenu.parentElement.insertBefore(menuOverlay, openedMenu);\r\n\r\n //document.body.classList.add('disable-hover');\r\n \r\n openedMenuOnClose = onClose;\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.addEventListener('mousemove', onMouseMove);\r\n //window.addEventListener('keydown', onKeyDown, {capture: true});\r\n window.addEventListener('contextmenu', onClick, {once: true});\r\n }\r\n\r\n /* // ! because this event must be canceled, and can't cancel on menu click (below)\r\n overlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n }); */\r\n \r\n // ! safari iOS doesn't handle window click event on overlay, idk why\r\n document.addEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', true);\r\n}\r\n\r\nexport type MenuPositionPadding = {\r\n top?: number, \r\n right?: number, \r\n bottom?: number, \r\n left?: number\r\n};\r\n\r\nconst PADDING_TOP = 8;\r\nconst PADDING_BOTTOM = PADDING_TOP;\r\nconst PADDING_LEFT = 8;\r\nconst PADDING_RIGHT = PADDING_LEFT;\r\nexport function positionMenu({pageX, pageY}: MouseEvent | Touch, elem: HTMLElement, side?: 'left' | 'right' | 'center', additionalPadding?: MenuPositionPadding) {\r\n //let {clientX, clientY} = e;\r\n\r\n // * side mean the OPEN side\r\n\r\n const getScrollWidthFromElement = (Array.from(elem.children) as HTMLElement[]).find(element => element.classList.contains('btn-menu-item') && !element.classList.contains('hide')) || elem;\r\n\r\n let {scrollWidth: menuWidth} = getScrollWidthFromElement;\r\n let {scrollHeight: menuHeight} = elem;\r\n //let {innerWidth: windowWidth, innerHeight: windowHeight} = window;\r\n const rect = document.body.getBoundingClientRect();\r\n const windowWidth = rect.width;\r\n const windowHeight = rect.height;\r\n\r\n let paddingTop = PADDING_TOP, paddingRight = PADDING_RIGHT, paddingBottom = PADDING_BOTTOM, paddingLeft = PADDING_LEFT;\r\n if(additionalPadding) {\r\n if(additionalPadding.top) paddingTop += additionalPadding.top;\r\n if(additionalPadding.right) paddingRight += additionalPadding.right;\r\n if(additionalPadding.bottom) paddingBottom += additionalPadding.bottom;\r\n if(additionalPadding.left) paddingLeft += additionalPadding.left;\r\n }\r\n\r\n side = mediaSizes.isMobile ? 'right' : 'left';\r\n let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top';\r\n\r\n const maxTop = windowHeight - menuHeight - paddingBottom;\r\n const maxLeft = windowWidth - menuWidth - paddingRight;\r\n const minTop = paddingTop;\r\n const minLeft = paddingLeft;\r\n\r\n const getSides = () => {\r\n return {\r\n x: {\r\n left: pageX,\r\n right: Math.min(maxLeft, pageX - menuWidth)\r\n },\r\n intermediateX: side === 'right' ? minLeft : maxLeft,\r\n //intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,\r\n y: {\r\n top: pageY,\r\n bottom: pageY - menuHeight\r\n },\r\n //intermediateY: verticalSide === 'top' ? paddingTop : windowHeight - menuHeight - paddingTop,\r\n // intermediateY: pageY < (windowHeight / 2) ? paddingTop : windowHeight - menuHeight - paddingBottom,\r\n intermediateY: maxTop,\r\n };\r\n };\r\n\r\n const sides = getSides();\r\n\r\n const possibleSides = {\r\n x: {\r\n left: (sides.x.left + menuWidth + paddingRight) <= windowWidth,\r\n right: sides.x.right >= paddingLeft\r\n },\r\n y: {\r\n top: (sides.y.top + menuHeight + paddingBottom) <= windowHeight,\r\n bottom: (sides.y.bottom - paddingBottom) >= paddingBottom\r\n }\r\n };\r\n\r\n /* if(side === undefined) {\r\n if((clientX + menuWidth + PADDING_LEFT) > windowWidth) {\r\n side = 'right';\r\n }\r\n } */\r\n\r\n {\r\n /* const x = sides.x;\r\n\r\n const s = Object.keys(x) as (keyof typeof possibleSides.x)[];\r\n if(side) {\r\n s.findAndSplice(s => s === side);\r\n s.unshift(side);\r\n }\r\n\r\n const possibleSide = s.find(s => possibleSides.x[s]); */\r\n let left: number;\r\n /* if(possibleSide) {\r\n left = x[possibleSide];\r\n side = possibleSide;\r\n } else {\r\n left = sides.intermediateX;\r\n side = undefined;\r\n } */\r\n left = possibleSides.x[side] ? sides.x[side] : (side = 'center', sides.intermediateX);\r\n \r\n elem.style.left = left + 'px';\r\n }\r\n\r\n /* if((clientY + menuHeight + PADDING_TOP) > windowHeight) {\r\n elem.style.top = clamp(clientY - menuHeight, PADDING_TOP, windowHeight - menuHeight - PADDING_TOP) + 'px';\r\n // elem.style.top = (innerHeight - scrollHeight - PADDING_TOP) + 'px';\r\n verticalSide = 'bottom';\r\n } else {\r\n elem.style.top = Math.max(PADDING_TOP, clientY) + 'px';\r\n verticalSide = 'top';\r\n } */\r\n\r\n {\r\n let top: number;\r\n\r\n top = possibleSides.y[verticalSide] ? sides.y[verticalSide] : (verticalSide = 'center', sides.intermediateY);\r\n \r\n elem.style.top = top + 'px';\r\n }\r\n \r\n elem.className = elem.className.replace(/(top|center|bottom)-(left|center|right)/g, '');\r\n elem.classList.add(\r\n //(verticalSide === 'center' ? verticalSide : (verticalSide === 'bottom' ? 'top' : 'bottom')) +\r\n (verticalSide === 'center' ? verticalSide : 'bottom') +\r\n '-' +\r\n (side === 'center' ? side : (side === 'left' ? 'right' : 'left')));\r\n\r\n return {\r\n width: menuWidth,\r\n height: menuHeight\r\n };\r\n}\r\n\r\nlet _cancelContextMenuOpening = false, _cancelContextMenuOpeningTimeout = 0;\r\nexport function cancelContextMenuOpening() {\r\n if(_cancelContextMenuOpeningTimeout) {\r\n clearTimeout(_cancelContextMenuOpeningTimeout);\r\n }\r\n \r\n _cancelContextMenuOpeningTimeout = window.setTimeout(() => {\r\n _cancelContextMenuOpeningTimeout = 0;\r\n _cancelContextMenuOpening = false;\r\n }, .4e3);\r\n\r\n _cancelContextMenuOpening = true;\r\n}\r\n\r\nexport function attachContextMenuListener(element: HTMLElement, callback: (e: Touch | MouseEvent) => void, listenerSetter?: ListenerSetter) {\r\n const add = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\r\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, element) : element.removeEventListener.bind(element);\r\n\r\n if(IS_APPLE && IS_TOUCH_SUPPORTED) {\r\n let timeout: number;\r\n\r\n const options: EventListenerOptions = {capture: true};\r\n\r\n const onCancel = () => {\r\n clearTimeout(timeout);\r\n // @ts-ignore\r\n remove('touchmove', onCancel, options);\r\n // @ts-ignore\r\n remove('touchend', onCancel, options);\r\n // @ts-ignore\r\n remove('touchcancel', onCancel, options);\r\n };\r\n\r\n add('touchstart', (e: TouchEvent) => {\r\n if(e.touches.length > 1) {\r\n onCancel();\r\n return;\r\n }\r\n \r\n add('touchmove', onCancel, options);\r\n add('touchend', onCancel, options);\r\n add('touchcancel', onCancel, options);\r\n\r\n timeout = window.setTimeout(() => {\r\n if(_cancelContextMenuOpening) {\r\n onCancel();\r\n return;\r\n }\r\n\r\n callback(e.touches[0]);\r\n onCancel();\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n }, .4e3);\r\n });\r\n\r\n /* if(!isSafari) {\r\n add('contextmenu', (e: any) => {\r\n cancelEvent(e);\r\n }, {passive: false, capture: true});\r\n } */\r\n } else {\r\n add('contextmenu', IS_TOUCH_SUPPORTED ? (e: any) => {\r\n callback(e);\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n } : callback);\r\n }\r\n};\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport sequentialDom from \"../helpers/sequentialDom\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport findUpAsChild from \"../helpers/dom/findUpAsChild\";\r\n\r\nlet rippleClickId = 0;\r\nexport default function ripple(\r\n elem: HTMLElement, \r\n callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(), \r\n onEnd: (id: number) => void = null, \r\n prepend = false,\r\n attachListenerTo = elem\r\n) {\r\n //return;\r\n if(elem.querySelector('.c-ripple')) return;\r\n elem.classList.add('rp');\r\n \r\n let r = document.createElement('div');\r\n r.classList.add('c-ripple');\r\n\r\n const isSquare = elem.classList.contains('rp-square');\r\n if(isSquare) {\r\n r.classList.add('is-square');\r\n }\r\n\r\n elem[prepend ? 'prepend' : 'append'](r);\r\n\r\n let handler: () => void;\r\n //let animationEndPromise: Promise<number>;\r\n const drawRipple = (clientX: number, clientY: number) => {\r\n const startTime = Date.now();\r\n const elem = document.createElement('div');\r\n\r\n const clickId = rippleClickId++;\r\n \r\n //console.log('ripple drawRipple');\r\n \r\n const duration = +window.getComputedStyle(r).getPropertyValue('--ripple-duration').replace('s', '') * 1000;\r\n //console.log('ripple duration', duration);\r\n\r\n handler = () => {\r\n //handler = () => animationEndPromise.then((duration) => {\r\n //console.log('ripple animation was:', duration);\r\n\r\n //const duration = isSquare || mediaSizes.isMobile ? 200 : 700;\r\n //return;\r\n let elapsedTime = Date.now() - startTime;\r\n const cb = () => {\r\n //console.log('ripple elapsedTime total pre-remove:', Date.now() - startTime);\r\n sequentialDom.mutate(() => {\r\n elem.remove();\r\n });\r\n \r\n if(onEnd) onEnd(clickId);\r\n };\r\n if(elapsedTime < duration) {\r\n let delay = Math.max(duration - elapsedTime, duration / 2);\r\n setTimeout(() => elem.classList.add('hiding'), Math.max(delay - duration / 2, 0));\r\n\r\n setTimeout(cb, delay);\r\n } else {\r\n elem.classList.add('hiding');\r\n setTimeout(cb, duration / 2);\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('contextmenu', handler);\r\n }\r\n\r\n handler = null;\r\n touchStartFired = false;\r\n };\r\n //});\r\n\r\n callback && callback(clickId);\r\n\r\n /* callback().then((bad) => {\r\n if(bad) {\r\n span.remove();\r\n return;\r\n } */\r\n \r\n //console.log('ripple after promise', Date.now() - startTime);\r\n //console.log('ripple tooSlow:', tooSlow);\r\n /* if(tooSlow) {\r\n span.remove();\r\n return;\r\n } */\r\n\r\n window.requestAnimationFrame(() => {\r\n const rect = r.getBoundingClientRect();\r\n elem.classList.add('c-ripple__circle');\r\n\r\n const clickX = clientX - rect.left;\r\n const clickY = clientY - rect.top;\r\n\r\n const radius = Math.sqrt((Math.abs(clickY - rect.height / 2) + rect.height / 2) ** 2 + (Math.abs(clickX - rect.width / 2) + rect.width / 2) ** 2);\r\n const size = radius;\r\n\r\n // center of circle\r\n const x = clickX - size / 2;\r\n const y = clickY - size / 2;\r\n\r\n //console.log('ripple click', offsetFromCenter, size, clickX, clickY);\r\n\r\n elem.style.width = elem.style.height = size + 'px';\r\n elem.style.left = x + 'px';\r\n elem.style.top = y + 'px';\r\n\r\n // нижний код выполняется с задержкой\r\n /* animationEndPromise = new Promise((resolve) => {\r\n span.addEventListener('animationend', () => {\r\n // 713 -> 700\r\n resolve(((Date.now() - startTime) / 100 | 0) * 100);\r\n }, {once: true});\r\n }); */\r\n \r\n // нижний код не всегда включает анимацию ПРИ КЛИКЕ НА ТАЧПАД БЕЗ ТАПТИК ЭНЖИНА\r\n /* span.style.display = 'none';\r\n r.append(span);\r\n duration = +window.getComputedStyle(span).getPropertyValue('animation-duration').replace('s', '') * 1000;\r\n span.style.display = ''; */\r\n\r\n r.append(elem);\r\n\r\n //r.classList.add('active');\r\n //handler();\r\n });\r\n //});\r\n };\r\n\r\n const isRippleUnneeded = (e: Event) => e.target !== elem && (\r\n ['BUTTON', 'A'].includes((e.target as HTMLElement).tagName) \r\n || findUpClassName(e.target as HTMLElement, 'c-ripple') !== r\r\n ) && (\r\n attachListenerTo === elem \r\n || !findUpAsChild(e.target, attachListenerTo)\r\n );\r\n\r\n // TODO: rename this variable\r\n let touchStartFired = false;\r\n if(IS_TOUCH_SUPPORTED) {\r\n let touchEnd = () => {\r\n handler && handler();\r\n };\r\n \r\n attachListenerTo.addEventListener('touchstart', (e) => {\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n\r\n //console.log('ripple touchstart', e);\r\n if(e.touches.length > 1 || touchStartFired || isRippleUnneeded(e)) {\r\n return;\r\n }\r\n \r\n //console.log('touchstart', e);\r\n touchStartFired = true;\r\n \r\n let {clientX, clientY} = e.touches[0];\r\n drawRipple(clientX, clientY);\r\n attachListenerTo.addEventListener('touchend', touchEnd, {once: true});\r\n \r\n window.addEventListener('touchmove', (e) => {\r\n e.cancelBubble = true;\r\n e.stopPropagation();\r\n touchEnd();\r\n attachListenerTo.removeEventListener('touchend', touchEnd);\r\n }, {once: true});\r\n }, {passive: true});\r\n } else {\r\n attachListenerTo.addEventListener('mousedown', (e) => {\r\n if(![0, 2].includes(e.button)) { // only left and right buttons\r\n return;\r\n }\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n //console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') === r);\r\n\r\n if(attachListenerTo.dataset.ripple === '0' || isRippleUnneeded(e)) {\r\n return;\r\n } else if(touchStartFired) {\r\n touchStartFired = false;\r\n return;\r\n }\r\n \r\n let {clientX, clientY} = e;\r\n drawRipple(clientX, clientY);\r\n window.addEventListener('mouseup', handler, {once: true, passive: true});\r\n window.addEventListener('contextmenu', handler, {once: true, passive: true});\r\n }, {passive: true});\r\n }\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport { IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport { logger } from \"../lib/logger\";\r\nimport blurActiveElement from \"../helpers/dom/blurActiveElement\";\r\nimport cancelEvent from \"../helpers/dom/cancelEvent\";\r\nimport isSwipingBackSafari from \"../helpers/dom/isSwipingBackSafari\";\r\nimport indexOfAndSplice from \"../helpers/array/indexOfAndSplice\";\r\n\r\nexport type NavigationItem = {\r\n type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' | \r\n 'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' | \r\n 'global-search' | 'voice' | 'mobile-search' | 'filters' | 'global-search-focus',\r\n onPop: (canAnimate: boolean) => boolean | void,\r\n onEscape?: () => boolean,\r\n noHistory?: boolean,\r\n noBlurOnPop?: boolean,\r\n};\r\n\r\nexport class AppNavigationController {\r\n private navigations: Array<NavigationItem> = [];\r\n private id = Date.now();\r\n private manual = false;\r\n private log = logger('NC');\r\n private debug = true;\r\n private currentHash = window.location.hash;\r\n public onHashChange: () => void;\r\n\r\n constructor() {\r\n let isPossibleSwipe = false;\r\n window.addEventListener('popstate', (e) => {\r\n this.debug && this.log('popstate', e, isPossibleSwipe);\r\n\r\n if(window.location.hash !== this.currentHash) {\r\n this.onHashChange && this.onHashChange();\r\n this.replaceState();\r\n return;\r\n }\r\n this.currentHash = window.location.hash;\r\n\r\n const id: number = e.state;\r\n if(id !== this.id/* && !this.navigations.length */) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n const item = this.navigations.pop();\r\n if(!item) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n this.manual = !isPossibleSwipe;\r\n this.handleItem(item);\r\n //this.pushState(); // * prevent adding forward arrow\r\n });\r\n\r\n window.addEventListener('keydown', (e) => {\r\n const item = this.navigations[this.navigations.length - 1];\r\n if(!item) return;\r\n if(e.key === 'Escape' && (item.onEscape ? item.onEscape() : true)) {\r\n cancelEvent(e);\r\n this.back(item.type);\r\n }\r\n }, {capture: true, passive: false});\r\n\r\n if(IS_MOBILE_SAFARI) {\r\n const options = {passive: true};\r\n window.addEventListener('touchstart', (e) => {\r\n if(e.touches.length > 1) return;\r\n this.debug && this.log('touchstart');\r\n\r\n if(isSwipingBackSafari(e)) {\r\n isPossibleSwipe = true;\r\n\r\n window.addEventListener('touchend', () => {\r\n setTimeout(() => {\r\n isPossibleSwipe = false;\r\n }, 100);\r\n }, {passive: true, once: true});\r\n }\r\n\r\n /* const detach = () => {\r\n window.removeEventListener('touchend', onTouchEnd);\r\n window.removeEventListener('touchmove', onTouchMove);\r\n };\r\n\r\n let moved = false;\r\n const onTouchMove = (e: TouchEvent) => {\r\n this.debug && this.log('touchmove');\r\n if(e.touches.length > 1) {\r\n detach();\r\n return;\r\n }\r\n\r\n moved = true;\r\n };\r\n\r\n const onTouchEnd = (e: TouchEvent) => {\r\n this.debug && this.log('touchend');\r\n if(e.touches.length > 1 || !moved) {\r\n detach();\r\n return;\r\n }\r\n\r\n isPossibleSwipe = true;\r\n doubleRaf().then(() => {\r\n isPossibleSwipe = false;\r\n });\r\n\r\n detach();\r\n };\r\n\r\n window.addEventListener('touchend', onTouchEnd, options);\r\n window.addEventListener('touchmove', onTouchMove, options); */\r\n }, options);\r\n }\r\n\r\n history.scrollRestoration = 'manual';\r\n\r\n this.pushState(); // * push init state\r\n }\r\n\r\n private handleItem(item: NavigationItem) {\r\n const good = item.onPop(!this.manual ? false : undefined);\r\n this.debug && this.log('popstate, navigation:', item, this.navigations);\r\n if(good === false) {\r\n this.pushItem(item);\r\n } else if(!item.noBlurOnPop) {\r\n blurActiveElement(); // no better place for it\r\n }\r\n\r\n this.manual = false;\r\n }\r\n\r\n public findItemByType(type: NavigationItem['type']) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n return {item, index: i};\r\n }\r\n }\r\n }\r\n\r\n public back(type?: NavigationItem['type']) {\r\n if(type) {\r\n const ret = this.findItemByType(type);\r\n if(ret) {\r\n this.backByItem(ret.item, ret.index);\r\n return;\r\n }\r\n }\r\n\r\n history.back();\r\n }\r\n\r\n public backByItem(item: NavigationItem, index = this.navigations.indexOf(item)) {\r\n this.manual = true;\r\n // ! commented because 'popstate' event will be fired with delay\r\n //if(index !== (this.navigations.length - 1)) {\r\n this.navigations.splice(index, 1);\r\n this.handleItem(item);\r\n //}\r\n }\r\n\r\n private onItemAdded(item: NavigationItem) {\r\n this.debug && this.log('pushstate', item, this.navigations);\r\n\r\n if(!item.noHistory) {\r\n this.pushState();\r\n }\r\n }\r\n\r\n public pushItem(item: NavigationItem) {\r\n this.navigations.push(item);\r\n this.onItemAdded(item);\r\n }\r\n\r\n public unshiftItem(item: NavigationItem) {\r\n this.navigations.unshift(item);\r\n this.onItemAdded(item);\r\n }\r\n\r\n private pushState() {\r\n this.manual = false;\r\n history.pushState(this.id, '');\r\n }\r\n\r\n public replaceState() {\r\n history.replaceState(this.id, '', location.origin + location.pathname);\r\n }\r\n\r\n public removeItem(item: NavigationItem) {\r\n if(!item) {\r\n return;\r\n }\r\n \r\n indexOfAndSplice(this.navigations, item);\r\n }\r\n\r\n public removeByType(type: NavigationItem['type'], single = false) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n this.navigations.splice(i, 1);\r\n\r\n if(single) {\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst appNavigationController = new AppNavigationController();\r\nMOUNT_CLASS_TO.appNavigationController = appNavigationController;\r\nexport default appNavigationController;\r\n"],"sourceRoot":""}