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

/*
* 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
};
}