tweb-i2p/src/components/horizontalMenu.ts
Eduard Kuzmenko 198eea41ee Fix moving avatars after chat jump
Handle instant peer changing correctly
Display unread badge only in chats
Delay opening on ESG hover
Lazy load sticker sets thumbs
Fix onchanging profile info flick
Hide shared media menu tabs
Scroll on click to shared media tab
Fix media tabs scroll position
Fix voice messages playback in search on iOS
Hover & play on waveform
Better input fields border animation
Don't lock scroll on horizontal scrollables if unnecessary
Restrict editing & deleting outgoing messages
Display avatars in notifications
Open chat on notification click
Don't close country selector on scrolling
Select single country by enter
Fix jumping text in context menus
Changed preloader color
2021-04-18 15:55:56 +04:00

121 lines
4.1 KiB
TypeScript

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { whichChild } from "../helpers/dom";
import { TransitionSlider } from "./transition";
import { ScrollableX } from "./scrollable";
import rootScope from "../lib/rootScope";
import { fastRaf } from "../helpers/schedulers";
import { FocusDirection } from "../helpers/fastSmoothScroll";
import findUpAsChild from "../helpers/dom/findUpAsChild";
export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?: (id: number, tabContent: HTMLDivElement, animate: boolean) => void | boolean, onTransitionEnd?: () => void, transitionTime = 250, scrollableX?: ScrollableX) {
const selectTab = TransitionSlider(content, tabs || content.dataset.animation === 'tabs' ? 'tabs' : 'navigation', transitionTime, onTransitionEnd);
if(tabs) {
const proxy = new Proxy(selectTab, {
apply: (target, that, args) => {
const id = +args[0];
const animate = args[1] !== undefined ? args[1] : true;
const el = (tabs.querySelector(`[data-tab="${id}"]`) || tabs.children[id]) as HTMLElement;
selectTarget(el, id, animate);
}
});
const selectTarget = (target: HTMLElement, id: number, animate = true) => {
const tabContent = content.children[id] as HTMLDivElement;
if(onClick) {
const canChange = onClick(id, tabContent, animate);
if(canChange !== undefined && !canChange) {
return;
}
}
if(scrollableX) {
scrollableX.scrollIntoViewNew(target.parentElement.children[id] as HTMLElement, 'center', undefined, undefined, animate ? undefined : FocusDirection.Static, transitionTime, 'x');
}
if(!rootScope.settings.animationsEnabled) {
animate = false;
}
const prevId = selectTab.prevId();
if(target.classList.contains('active') || id === prevId) {
return false;
}
const prev = tabs.querySelector(tagName.toLowerCase() + '.active') as HTMLElement;
fastRaf(() => {
prev && prev.classList.remove('active');
});
// stripe from ZINCHUK
if(useStripe && prevId !== -1 && animate) {
fastRaf(() => {
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
fastRaf(() => {
target.classList.add('active');
});
selectTab(id, animate);
};
const useStripe = !tabs.classList.contains('no-stripe');
//const tagName = tabs.classList.contains('menu-horizontal-div') ? 'BUTTON' : 'LI';
const tagName = tabs.firstElementChild.tagName;
tabs.addEventListener('click', function(e) {
let target = e.target as HTMLElement;
target = findUpAsChild(target, tabs);
//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);
}
selectTarget(target, id);
});
return proxy;
}
return selectTab;
}