{"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,\r\n write: CancellablePromise\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();\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 \r\n \r\n `;\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) {\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 = () => 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;\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 = [];\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":""}