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.
 
 
 
 
 

171 lines
5.3 KiB

import { findUpTag, whichChild } from "../lib/utils";
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
const elements = [tabContent, prevTabContent];
if(toRight) elements.reverse();
elements[0].style.filter = `brightness(80%)`;
elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
tabContent.classList.add('active');
void tabContent.offsetWidth; // reflow
tabContent.style.transform = '';
tabContent.style.filter = '';
}
function slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
const elements = [tabContent, prevTabContent];
if(toRight) elements.reverse();
elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
tabContent.classList.add('active');
void tabContent.offsetWidth; // reflow
tabContent.style.transform = '';
}
export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?: (id: number, tabContent: HTMLDivElement) => void, onTransitionEnd?: () => void, transitionTime = 250) {
const hideTimeouts: {[id: number]: number} = {};
let transitionEndTimeout: number;
let prevTabContent: HTMLElement = null;
let prevId = -1;
const selectTab = (id: number, animate = true) => {
if(id == prevId) return false;
//console.log('selectTab id:', id);
const p = prevTabContent;
const tabContent = content.children[id] as HTMLElement;
// * means animation isn't needed
if(content.dataset.slider == 'none' || !animate) {
if(p) {
p.classList.remove('active');
}
tabContent.classList.add('active');
prevId = id;
prevTabContent = tabContent;
if(onTransitionEnd) onTransitionEnd();
return;
}
if(prevTabContent) {
prevTabContent.classList.remove('to');
}
const toRight = prevId < id;
if(!tabContent) {
//prevTabContent.classList.remove('active');
} else if(prevId != -1) {
const width = prevTabContent.getBoundingClientRect().width;
if(tabs || content.dataset.slider == 'tabs') {
slideTabs(tabContent, prevTabContent, width, toRight);
} else {
slideNavigation(tabContent, prevTabContent, width, toRight);
}
tabContent.classList.add('to');
} else {
tabContent.classList.add('active');
}
const _prevId = prevId;
if(hideTimeouts.hasOwnProperty(id)) clearTimeout(hideTimeouts[id]);
if(p/* && false */) {
hideTimeouts[_prevId] = window.setTimeout(() => {
p.style.transform = '';
p.style.filter = '';
p.classList.remove('active');
if(tabContent) {
tabContent.classList.remove('to');
}
delete hideTimeouts[_prevId];
}, /* 420 */transitionTime);
if(onTransitionEnd) {
if(transitionEndTimeout) clearTimeout(transitionEndTimeout);
transitionEndTimeout = window.setTimeout(() => {
onTransitionEnd();
transitionEndTimeout = 0;
}, transitionTime);
}
}
prevId = id;
prevTabContent = tabContent;
};
if(tabs) {
const useStripe = !tabs.classList.contains('no-stripe');
const tagName = 'LI';//tabs.firstElementChild.tagName;
tabs.addEventListener('click', function(e) {
let target = e.target as HTMLElement;
if(target.tagName != tagName) {
target = findUpTag(target, tagName);
}
//console.log('tabs click:', target);
if(!target) return false;
let id: number;
if(target.dataset.tab) {
id = +target.dataset.tab;
if(id == -1) {
return false;
}
} else {
id = whichChild(target);
}
const tabContent = content.children[id] as HTMLDivElement;
if(onClick) onClick(id, tabContent);
if(target.classList.contains('active') || id == prevId) {
return false;
}
const prev = tabs.querySelector(tagName.toLowerCase() + '.active') as HTMLElement;
prev && prev.classList.remove('active');
// stripe from ZINCHUK
if(useStripe && prevId != -1) {
const indicator = target.querySelector('i')!;
const currentIndicator = target.parentElement.children[prevId].querySelector('i')!;
currentIndicator.classList.remove('animate');
indicator.classList.remove('animate');
// We move and resize our indicator so it repeats the position and size of the previous one.
const shiftLeft = currentIndicator.parentElement.parentElement.offsetLeft - indicator.parentElement.parentElement.offsetLeft;
const scaleFactor = currentIndicator.clientWidth / indicator.clientWidth;
indicator.style.transform = `translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`;
//console.log(`translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`);
requestAnimationFrame(() => {
// Now we remove the transform to let it animate to its own position and size.
indicator.classList.add('animate');
indicator.style.transform = 'none';
});
}
// stripe END
target.classList.add('active');
selectTab(id);
});
}
return selectTab;
}