Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.4 KiB
138 lines
4.4 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import mediaSizes from "./mediaSizes"; |
|
|
|
export type MenuPositionPadding = { |
|
top?: number, |
|
right?: number, |
|
bottom?: number, |
|
left?: number |
|
}; |
|
|
|
const PADDING_TOP = 8; |
|
const PADDING_BOTTOM = PADDING_TOP; |
|
const PADDING_LEFT = 8; |
|
const PADDING_RIGHT = PADDING_LEFT; |
|
export default function positionMenu({pageX, pageY}: MouseEvent | Touch, elem: HTMLElement, side?: 'left' | 'right' | 'center', additionalPadding?: MenuPositionPadding) { |
|
//let {clientX, clientY} = e; |
|
|
|
// * side mean the OPEN side |
|
|
|
const getScrollWidthFromElement = (Array.from(elem.children) as HTMLElement[]).find((element) => element.classList.contains('btn-menu-item') && !element.classList.contains('hide')) || elem; |
|
|
|
let {scrollWidth: menuWidth} = getScrollWidthFromElement; |
|
let {scrollHeight: menuHeight} = elem; |
|
//let {innerWidth: windowWidth, innerHeight: windowHeight} = window; |
|
const rect = document.body.getBoundingClientRect(); |
|
const windowWidth = rect.width; |
|
const windowHeight = rect.height; |
|
|
|
let paddingTop = PADDING_TOP, paddingRight = PADDING_RIGHT, paddingBottom = PADDING_BOTTOM, paddingLeft = PADDING_LEFT; |
|
if(additionalPadding) { |
|
if(additionalPadding.top) paddingTop += additionalPadding.top; |
|
if(additionalPadding.right) paddingRight += additionalPadding.right; |
|
if(additionalPadding.bottom) paddingBottom += additionalPadding.bottom; |
|
if(additionalPadding.left) paddingLeft += additionalPadding.left; |
|
} |
|
|
|
side = mediaSizes.isMobile ? 'right' : 'left'; |
|
let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top'; |
|
|
|
const maxTop = windowHeight - menuHeight - paddingBottom; |
|
const maxLeft = windowWidth - menuWidth - paddingRight; |
|
const minTop = paddingTop; |
|
const minLeft = paddingLeft; |
|
|
|
const getSides = () => { |
|
return { |
|
x: { |
|
left: pageX, |
|
right: Math.min(maxLeft, pageX - menuWidth) |
|
}, |
|
intermediateX: side === 'right' ? minLeft : maxLeft, |
|
//intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT, |
|
y: { |
|
top: pageY, |
|
bottom: pageY - menuHeight |
|
}, |
|
//intermediateY: verticalSide === 'top' ? paddingTop : windowHeight - menuHeight - paddingTop, |
|
// intermediateY: pageY < (windowHeight / 2) ? paddingTop : windowHeight - menuHeight - paddingBottom, |
|
intermediateY: maxTop, |
|
}; |
|
}; |
|
|
|
const sides = getSides(); |
|
|
|
const possibleSides = { |
|
x: { |
|
left: (sides.x.left + menuWidth + paddingRight) <= windowWidth, |
|
right: sides.x.right >= paddingLeft |
|
}, |
|
y: { |
|
top: (sides.y.top + menuHeight + paddingBottom) <= windowHeight, |
|
bottom: (sides.y.bottom - paddingBottom) >= paddingBottom |
|
} |
|
}; |
|
|
|
/* if(side === undefined) { |
|
if((clientX + menuWidth + PADDING_LEFT) > windowWidth) { |
|
side = 'right'; |
|
} |
|
} */ |
|
|
|
{ |
|
/* const x = sides.x; |
|
|
|
const s = Object.keys(x) as (keyof typeof possibleSides.x)[]; |
|
if(side) { |
|
s.findAndSplice((s) => s === side); |
|
s.unshift(side); |
|
} |
|
|
|
const possibleSide = s.find((s) => possibleSides.x[s]); */ |
|
let left: number; |
|
/* if(possibleSide) { |
|
left = x[possibleSide]; |
|
side = possibleSide; |
|
} else { |
|
left = sides.intermediateX; |
|
side = undefined; |
|
} */ |
|
left = possibleSides.x[side] ? sides.x[side] : (side = 'center', sides.intermediateX); |
|
|
|
elem.style.left = left + 'px'; |
|
} |
|
|
|
/* if((clientY + menuHeight + PADDING_TOP) > windowHeight) { |
|
elem.style.top = clamp(clientY - menuHeight, PADDING_TOP, windowHeight - menuHeight - PADDING_TOP) + 'px'; |
|
// elem.style.top = (innerHeight - scrollHeight - PADDING_TOP) + 'px'; |
|
verticalSide = 'bottom'; |
|
} else { |
|
elem.style.top = Math.max(PADDING_TOP, clientY) + 'px'; |
|
verticalSide = 'top'; |
|
} */ |
|
|
|
{ |
|
let top: number; |
|
|
|
top = possibleSides.y[verticalSide] ? sides.y[verticalSide] : (verticalSide = 'center', sides.intermediateY); |
|
|
|
elem.style.top = top + 'px'; |
|
} |
|
|
|
elem.className = elem.className.replace(/(top|center|bottom)-(left|center|right)/g, ''); |
|
elem.classList.add( |
|
//(verticalSide === 'center' ? verticalSide : (verticalSide === 'bottom' ? 'top' : 'bottom')) + |
|
(verticalSide === 'center' ? verticalSide : 'bottom') + |
|
'-' + |
|
(side === 'center' ? side : (side === 'left' ? 'right' : 'left'))); |
|
|
|
return { |
|
width: menuWidth, |
|
height: menuHeight |
|
}; |
|
}
|
|
|