Fix stickers panel performance & styles
This commit is contained in:
parent
8f6165164f
commit
9b6fe590fa
@ -203,8 +203,8 @@ export default class InlineHelper extends AutocompleteHelper {
|
|||||||
} else if(media.type === 'sticker') {
|
} else if(media.type === 'sticker') {
|
||||||
container.classList.add('super-sticker');
|
container.classList.add('super-sticker');
|
||||||
this.superStickerRenderer.renderSticker(media, container, loadPromises);
|
this.superStickerRenderer.renderSticker(media, container, loadPromises);
|
||||||
if(media.sticker === 2) {
|
if(media.animated) {
|
||||||
this.superStickerRenderer.observeAnimatedDiv(container);
|
this.superStickerRenderer.observeAnimated(container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(media) {
|
} else if(media) {
|
||||||
|
@ -187,6 +187,10 @@ export class EmoticonsDropdown extends DropdownHover {
|
|||||||
return super.init();
|
return super.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getElement() {
|
||||||
|
return this.element;
|
||||||
|
}
|
||||||
|
|
||||||
private onSelectTabClick = (id: number) => {
|
private onSelectTabClick = (id: number) => {
|
||||||
if(this.tabId === id) {
|
if(this.tabId === id) {
|
||||||
return;
|
return;
|
||||||
@ -248,11 +252,11 @@ export class EmoticonsDropdown extends DropdownHover {
|
|||||||
setActive(which);
|
setActive(which);
|
||||||
|
|
||||||
if(menuScroll) {
|
if(menuScroll) {
|
||||||
if(which < menu.childElementCount - 4) {
|
menuScroll.scrollIntoViewNew({
|
||||||
menuScroll.container.scrollLeft = (which - 3) * 47;
|
element: menu.children[which] as HTMLElement,
|
||||||
} else {
|
position: 'center',
|
||||||
menuScroll.container.scrollLeft = which * 47;
|
axis: 'x'
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import emoticonsDropdown, { EmoticonsDropdown, EMOTICONSSTICKERGROUP, EmoticonsTab } from "..";
|
import emoticonsDropdown, { EmoticonsDropdown, EMOTICONSSTICKERGROUP, EmoticonsTab } from "..";
|
||||||
import findUpAttribute from "../../../helpers/dom/findUpAttribute";
|
|
||||||
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
||||||
import mediaSizes from "../../../helpers/mediaSizes";
|
import mediaSizes from "../../../helpers/mediaSizes";
|
||||||
import { MessagesAllStickers, StickerSet } from "../../../layer";
|
import { MessagesAllStickers, StickerSet } from "../../../layer";
|
||||||
@ -22,62 +21,72 @@ import PopupStickers from "../../popups/stickers";
|
|||||||
import Scrollable, { ScrollableX } from "../../scrollable";
|
import Scrollable, { ScrollableX } from "../../scrollable";
|
||||||
import StickyIntersector from "../../stickyIntersector";
|
import StickyIntersector from "../../stickyIntersector";
|
||||||
import { wrapSticker, wrapStickerSetThumb } from "../../wrappers";
|
import { wrapSticker, wrapStickerSetThumb } from "../../wrappers";
|
||||||
|
import ButtonIcon from "../../buttonIcon";
|
||||||
|
import positionElementByIndex from "../../../helpers/dom/positionElementByIndex";
|
||||||
|
import VisibilityIntersector, { OnVisibilityChange } from "../../visibilityIntersector";
|
||||||
|
import findAndSplice from "../../../helpers/array/findAndSplice";
|
||||||
|
|
||||||
export class SuperStickerRenderer {
|
export class SuperStickerRenderer {
|
||||||
public lazyLoadQueue: LazyLoadQueueRepeat;
|
public lazyLoadQueue: LazyLoadQueueRepeat;
|
||||||
private animatedDivs: Set<HTMLDivElement> = new Set();
|
private animated: Set<HTMLElement> = new Set();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private regularLazyLoadQueue: LazyLoadQueue,
|
private regularLazyLoadQueue: LazyLoadQueue,
|
||||||
private group: string,
|
private group: string,
|
||||||
private managers: AppManagers
|
private managers: AppManagers,
|
||||||
|
private options?: IntersectionObserverInit
|
||||||
) {
|
) {
|
||||||
this.lazyLoadQueue = new LazyLoadQueueRepeat(undefined, (target, visible) => {
|
this.lazyLoadQueue = new LazyLoadQueueRepeat(undefined, ({target, visible}) => {
|
||||||
if(!visible) {
|
if(!visible) {
|
||||||
this.processInvisibleDiv(target as HTMLDivElement);
|
this.processInvisible(target);
|
||||||
}
|
}
|
||||||
});
|
}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear() {
|
public clear() {
|
||||||
this.lazyLoadQueue.clear();
|
this.lazyLoadQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderSticker(doc: MyDocument, div?: HTMLDivElement, loadPromises?: Promise<any>[]) {
|
public renderSticker(doc: MyDocument, element?: HTMLElement, loadPromises?: Promise<any>[]) {
|
||||||
if(!div) {
|
if(!element) {
|
||||||
div = document.createElement('div');
|
element = document.createElement('div');
|
||||||
div.classList.add('grid-item', 'super-sticker');
|
element.classList.add('grid-item', 'super-sticker');
|
||||||
|
element.dataset.docId = '' + doc.id;
|
||||||
|
|
||||||
if(doc.animated) {
|
if(doc.animated) {
|
||||||
this.observeAnimatedDiv(div);
|
this.observeAnimated(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// * This will wrap only a thumb
|
// * This will wrap only a thumb
|
||||||
wrapSticker({
|
/* !doc.animated && */wrapSticker({
|
||||||
doc,
|
doc,
|
||||||
div,
|
div: element,
|
||||||
lazyLoadQueue: this.regularLazyLoadQueue,
|
lazyLoadQueue: this.regularLazyLoadQueue,
|
||||||
group: this.group,
|
group: this.group,
|
||||||
onlyThumb: doc.animated,
|
onlyThumb: doc.animated,
|
||||||
loadPromises
|
loadPromises
|
||||||
});
|
});
|
||||||
|
|
||||||
return div;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
public observeAnimatedDiv(div: HTMLDivElement) {
|
public observeAnimated(element: HTMLElement) {
|
||||||
this.animatedDivs.add(div);
|
this.animated.add(element);
|
||||||
|
|
||||||
this.lazyLoadQueue.observe({
|
this.lazyLoadQueue.observe({
|
||||||
div,
|
div: element,
|
||||||
load: this.processVisibleDiv
|
load: this.processVisible
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkAnimationContainer = (div: HTMLElement, visible: boolean) => {
|
public unobserveAnimated(element: HTMLElement) {
|
||||||
|
this.animated.delete(element);
|
||||||
|
this.lazyLoadQueue.unobserve(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkAnimationContainer = (element: HTMLElement, visible: boolean) => {
|
||||||
//console.error('checkAnimationContainer', div, visible);
|
//console.error('checkAnimationContainer', div, visible);
|
||||||
const players = animationIntersector.getAnimations(div);
|
const players = animationIntersector.getAnimations(element);
|
||||||
players.forEach((player) => {
|
players.forEach((player) => {
|
||||||
if(!visible) {
|
if(!visible) {
|
||||||
animationIntersector.checkAnimation(player, true, true);
|
animationIntersector.checkAnimation(player, true, true);
|
||||||
@ -87,8 +96,8 @@ export class SuperStickerRenderer {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private processVisibleDiv = async(div: HTMLElement) => {
|
private processVisible = async(element: HTMLElement) => {
|
||||||
const docId = div.dataset.docId;
|
const docId = element.dataset.docId;
|
||||||
const doc = await this.managers.appDocsManager.getDoc(docId);
|
const doc = await this.managers.appDocsManager.getDoc(docId);
|
||||||
|
|
||||||
const size = mediaSizes.active.esgSticker.width;
|
const size = mediaSizes.active.esgSticker.width;
|
||||||
@ -97,7 +106,7 @@ export class SuperStickerRenderer {
|
|||||||
|
|
||||||
const promise = wrapSticker({
|
const promise = wrapSticker({
|
||||||
doc,
|
doc,
|
||||||
div: div as HTMLDivElement,
|
div: element,
|
||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
lazyLoadQueue: null,
|
lazyLoadQueue: null,
|
||||||
@ -109,7 +118,7 @@ export class SuperStickerRenderer {
|
|||||||
|
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
//clearTimeout(timeout);
|
//clearTimeout(timeout);
|
||||||
this.checkAnimationContainer(div, this.lazyLoadQueue.intersector.isVisible(div));
|
this.checkAnimationContainer(element, this.lazyLoadQueue.intersector.isVisible(element));
|
||||||
});
|
});
|
||||||
|
|
||||||
/* let timeout = window.setTimeout(() => {
|
/* let timeout = window.setTimeout(() => {
|
||||||
@ -119,123 +128,140 @@ export class SuperStickerRenderer {
|
|||||||
return promise;
|
return promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
public processInvisibleDiv = async(div: HTMLElement) => {
|
public processInvisible = async(element: HTMLElement) => {
|
||||||
const docId = div.dataset.docId;
|
const docId = element.dataset.docId;
|
||||||
const doc = await this.managers.appDocsManager.getDoc(docId);
|
const doc = await this.managers.appDocsManager.getDoc(docId);
|
||||||
|
|
||||||
//console.log('STICKER INvisible:', /* div, */docId);
|
//console.log('STICKER INvisible:', /* div, */docId);
|
||||||
|
|
||||||
this.checkAnimationContainer(div, false);
|
this.checkAnimationContainer(element, false);
|
||||||
|
|
||||||
div.innerHTML = '';
|
element.textContent = '';
|
||||||
this.renderSticker(doc, div as HTMLDivElement);
|
this.renderSticker(doc, element as HTMLDivElement);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StickersTabCategory = {
|
||||||
|
elements: {
|
||||||
|
container: HTMLElement,
|
||||||
|
title: HTMLElement,
|
||||||
|
items: HTMLElement,
|
||||||
|
menuTab: HTMLElement,
|
||||||
|
menuTabPadding: HTMLElement
|
||||||
|
},
|
||||||
|
set: StickerSet.stickerSet,
|
||||||
|
items: {
|
||||||
|
document: MyDocument,
|
||||||
|
element: HTMLElement
|
||||||
|
}[]
|
||||||
|
};
|
||||||
|
|
||||||
|
const RECENT_STICKERS_COUNT = 20;
|
||||||
|
|
||||||
export default class StickersTab implements EmoticonsTab {
|
export default class StickersTab implements EmoticonsTab {
|
||||||
private content: HTMLElement;
|
private content: HTMLElement;
|
||||||
private stickersDiv: HTMLElement;
|
|
||||||
|
|
||||||
private stickerSets: {[id: string]: {
|
private categories: {[id: string]: StickersTabCategory};
|
||||||
stickers: HTMLElement,
|
private categoriesMap: Map<HTMLElement, StickersTabCategory>;
|
||||||
tab: HTMLElement
|
private categoriesIntersector: VisibilityIntersector;
|
||||||
}} = {};
|
|
||||||
|
|
||||||
private recentDiv: HTMLElement;
|
|
||||||
private recentStickers: MyDocument[] = [];
|
|
||||||
|
|
||||||
private scroll: Scrollable;
|
private scroll: Scrollable;
|
||||||
|
|
||||||
private menu: HTMLElement;
|
private menu: HTMLElement;
|
||||||
|
|
||||||
private mounted = false;
|
private mounted = false;
|
||||||
|
|
||||||
private queueCategoryPush: {element: HTMLElement, prepend: boolean}[] = [];
|
|
||||||
|
|
||||||
private stickyIntersector: StickyIntersector;
|
private stickyIntersector: StickyIntersector;
|
||||||
|
|
||||||
private superStickerRenderer: SuperStickerRenderer;
|
private superStickerRenderer: SuperStickerRenderer;
|
||||||
|
|
||||||
constructor(private managers: AppManagers) {
|
constructor(private managers: AppManagers) {
|
||||||
|
this.categories = {};
|
||||||
|
this.categoriesMap = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryPush(categoryDiv: HTMLElement, categoryTitle: DocumentFragment | string = '', promise: Promise<MyDocument[]>, prepend?: boolean) {
|
private createCategory(stickerSet: StickerSet.stickerSet, _title: HTMLElement | DocumentFragment) {
|
||||||
//if((docs.length % 5) !== 0) categoryDiv.classList.add('not-full');
|
const container = document.createElement('div');
|
||||||
|
container.classList.add('emoji-category', 'hide');
|
||||||
|
|
||||||
const itemsDiv = document.createElement('div');
|
const items = document.createElement('div');
|
||||||
itemsDiv.classList.add('category-items', 'super-stickers');
|
items.classList.add('category-items', 'super-stickers');
|
||||||
|
|
||||||
const titleDiv = document.createElement('div');
|
const title = document.createElement('div');
|
||||||
titleDiv.classList.add('category-title');
|
title.classList.add('category-title');
|
||||||
|
title.append(_title);
|
||||||
|
|
||||||
if(categoryTitle) {
|
const menuTab = ButtonIcon(undefined, {noRipple: true});
|
||||||
if(typeof(categoryTitle) === 'string') titleDiv.innerHTML = categoryTitle;
|
menuTab.classList.add('menu-horizontal-div-item');
|
||||||
else titleDiv.append(categoryTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryDiv.append(titleDiv, itemsDiv);
|
const menuTabPadding = document.createElement('div');
|
||||||
|
menuTabPadding.classList.add('menu-horizontal-div-item-padding');
|
||||||
|
|
||||||
this.stickyIntersector.observeStickyHeaderChanges(categoryDiv);
|
menuTab.append(menuTabPadding);
|
||||||
|
|
||||||
this.queueCategoryPush.push({element: categoryDiv, prepend});
|
const category: StickersTabCategory = {
|
||||||
|
elements: {
|
||||||
promise.then((documents) => {
|
container,
|
||||||
documents.forEach((doc) => {
|
title,
|
||||||
//if(doc._ === 'documentEmpty') return;
|
items,
|
||||||
itemsDiv.append(this.superStickerRenderer.renderSticker(doc));
|
menuTab,
|
||||||
});
|
menuTabPadding
|
||||||
|
},
|
||||||
if(this.queueCategoryPush.length) {
|
set: stickerSet,
|
||||||
this.queueCategoryPush.forEach(({element, prepend}) => {
|
items: []
|
||||||
if(prepend) {
|
|
||||||
if(this.recentDiv.parentElement) {
|
|
||||||
this.stickersDiv.prepend(element);
|
|
||||||
this.stickersDiv.prepend(this.recentDiv);
|
|
||||||
} else {
|
|
||||||
this.stickersDiv.prepend(element);
|
|
||||||
}
|
|
||||||
} else this.stickersDiv.append(element);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.queueCategoryPush.length = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {titleDiv};
|
|
||||||
}
|
|
||||||
|
|
||||||
async renderStickerSet(set: StickerSet.stickerSet, prepend = false) {
|
|
||||||
const categoryDiv = document.createElement('div');
|
|
||||||
categoryDiv.classList.add('sticker-category');
|
|
||||||
categoryDiv.dataset.id = '' + set.id;
|
|
||||||
categoryDiv.dataset.access_hash = '' + set.access_hash;
|
|
||||||
|
|
||||||
const button = document.createElement('button');
|
|
||||||
button.classList.add('btn-icon', 'menu-horizontal-div-item');
|
|
||||||
|
|
||||||
this.stickerSets[set.id] = {
|
|
||||||
stickers: categoryDiv,
|
|
||||||
tab: button
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(prepend) {
|
container.append(title, items);
|
||||||
this.menu.insertBefore(button, this.menu.firstElementChild.nextSibling);
|
|
||||||
} else {
|
|
||||||
this.menu.append(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
//stickersScroll.append(categoryDiv);
|
this.categories[stickerSet.id] = category;
|
||||||
|
this.categoriesMap.set(container, category);
|
||||||
|
|
||||||
|
this.categoriesIntersector.observe(container);
|
||||||
|
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
private categoryPush(
|
||||||
|
category: StickersTabCategory,
|
||||||
|
promise: Promise<MyDocument[]>
|
||||||
|
) {
|
||||||
|
const {container, items} = category.elements;
|
||||||
|
this.stickyIntersector.observeStickyHeaderChanges(container);
|
||||||
|
|
||||||
|
promise.then((documents) => {
|
||||||
|
documents.forEach((document) => {
|
||||||
|
const element = this.superStickerRenderer.renderSticker(document);
|
||||||
|
category.items.push({document, element});
|
||||||
|
// items.append(element);
|
||||||
|
});
|
||||||
|
|
||||||
|
const containerWidth = 410;
|
||||||
|
const stickerSize = mediaSizes.active.esgSticker.width;
|
||||||
|
|
||||||
|
const itemsPerRow = Math.floor(containerWidth / stickerSize);
|
||||||
|
const rows = Math.ceil(documents.length / itemsPerRow);
|
||||||
|
const height = rows * stickerSize;
|
||||||
|
|
||||||
|
items.style.height = height + 'px';
|
||||||
|
|
||||||
|
container.classList.remove('hide');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async renderStickerSet(set: StickerSet.stickerSet, prepend = false) {
|
||||||
|
const category = this.createCategory(set, wrapEmojiText(set.title));
|
||||||
|
const {menuTab, menuTabPadding, container} = category.elements;
|
||||||
|
|
||||||
|
positionElementByIndex(menuTab, this.menu, prepend ? 1 : 0xFFFF);
|
||||||
|
|
||||||
const promise = this.managers.appStickersManager.getStickerSet(set);
|
const promise = this.managers.appStickersManager.getStickerSet(set);
|
||||||
this.categoryPush(categoryDiv, wrapEmojiText(set.title), promise.then((stickerSet) => stickerSet.documents as MyDocument[]), prepend);
|
this.categoryPush(
|
||||||
const stickerSet = await promise;
|
category,
|
||||||
|
promise.then((stickerSet) => stickerSet.documents as MyDocument[])
|
||||||
|
);
|
||||||
|
// const stickerSet = await promise;
|
||||||
|
|
||||||
//console.log('got stickerSet', stickerSet, li);
|
positionElementByIndex(container, this.scroll.container, prepend ? 1 : 0xFFFF, -1);
|
||||||
|
|
||||||
wrapStickerSetThumb({
|
wrapStickerSetThumb({
|
||||||
set,
|
set,
|
||||||
container: button,
|
container: menuTabPadding,
|
||||||
group: EMOTICONSSTICKERGROUP,
|
group: EMOTICONSSTICKERGROUP,
|
||||||
lazyLoadQueue: EmoticonsDropdown.lazyLoadQueue,
|
lazyLoadQueue: EmoticonsDropdown.lazyLoadQueue,
|
||||||
width: 32,
|
width: 32,
|
||||||
@ -244,21 +270,18 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
public init() {
|
||||||
this.content = document.getElementById('content-stickers');
|
this.content = document.getElementById('content-stickers');
|
||||||
//let stickersDiv = contentStickersDiv.querySelector('.os-content') as HTMLDivElement;
|
|
||||||
|
|
||||||
this.recentDiv = document.createElement('div');
|
const menuWrapper = this.content.previousElementSibling as HTMLDivElement;
|
||||||
this.recentDiv.classList.add('sticker-category', 'stickers-recent');
|
|
||||||
|
|
||||||
let menuWrapper = this.content.previousElementSibling as HTMLDivElement;
|
|
||||||
this.menu = menuWrapper.firstElementChild as HTMLUListElement;
|
this.menu = menuWrapper.firstElementChild as HTMLUListElement;
|
||||||
|
|
||||||
let menuScroll = new ScrollableX(menuWrapper);
|
const menuScroll = new ScrollableX(menuWrapper);
|
||||||
|
|
||||||
this.stickersDiv = document.createElement('div');
|
this.scroll = new Scrollable(this.content, 'STICKERS');
|
||||||
this.stickersDiv.classList.add('stickers-categories');
|
this.scroll.onAdditionalScroll = () => {
|
||||||
this.content.append(this.stickersDiv);
|
setTyping();
|
||||||
|
};
|
||||||
|
|
||||||
/* stickersDiv.addEventListener('mouseover', (e) => {
|
/* stickersDiv.addEventListener('mouseover', (e) => {
|
||||||
let target = e.target as HTMLElement;
|
let target = e.target as HTMLElement;
|
||||||
@ -277,30 +300,43 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
}
|
}
|
||||||
}); */
|
}); */
|
||||||
|
|
||||||
rootScope.addEventListener('stickers_installed', (e) => {
|
const onCategoryVisibility: OnVisibilityChange = ({target, visible, entry}) => {
|
||||||
const set: StickerSet.stickerSet = e;
|
const category = this.categoriesMap.get(target);
|
||||||
|
// console.log('roll the windows up', category, target, visible, entry);
|
||||||
|
if(!visible) {
|
||||||
|
category.elements.items.textContent = '';
|
||||||
|
} else {
|
||||||
|
category.elements.items.append(...category.items.map(({element}) => element));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if(!this.stickerSets[set.id] && this.mounted) {
|
const intersectionOptions: IntersectionObserverInit = {root: emoticonsDropdown.getElement()};
|
||||||
|
this.categoriesIntersector = new VisibilityIntersector(onCategoryVisibility, intersectionOptions);
|
||||||
|
|
||||||
|
rootScope.addEventListener('stickers_installed', (set) => {
|
||||||
|
if(!this.categories[set.id] && this.mounted) {
|
||||||
this.renderStickerSet(set, true);
|
this.renderStickerSet(set, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
rootScope.addEventListener('stickers_deleted', (e) => {
|
rootScope.addEventListener('stickers_deleted', ({id}) => {
|
||||||
const set: StickerSet.stickerSet = e;
|
const set = this.categories[id];
|
||||||
|
if(set && this.mounted) {
|
||||||
if(this.stickerSets[set.id] && this.mounted) {
|
set.elements.container.remove();
|
||||||
const elements = this.stickerSets[set.id];
|
set.elements.menuTab.remove();
|
||||||
elements.stickers.remove();
|
this.categoriesIntersector.unobserve(set.elements.container);
|
||||||
elements.tab.remove();
|
set.items.forEach(({element}) => this.superStickerRenderer.unobserveAnimated(element));
|
||||||
delete this.stickerSets[set.id];
|
delete this.categories[id];
|
||||||
|
this.categoriesMap.delete(set.elements.container);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.stickersDiv.addEventListener('click', (e) => {
|
this.scroll.container.addEventListener('click', (e) => {
|
||||||
const target = e.target as HTMLElement;
|
const target = e.target as HTMLElement;
|
||||||
if(findUpClassName(target, 'category-title')) {
|
if(findUpClassName(target, 'category-title')) {
|
||||||
const el = findUpAttribute(target, 'data-id');
|
const container = findUpClassName(target, 'emoji-category');
|
||||||
new PopupStickers({id: el.dataset.id, access_hash: el.dataset.access_hash}).show();
|
const category = this.categoriesMap.get(container);
|
||||||
|
new PopupStickers({id: category.set.id, access_hash: category.set.access_hash}).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,12 +347,6 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
rootScope.dispatchEvent('choosing_sticker', !cancel);
|
rootScope.dispatchEvent('choosing_sticker', !cancel);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.scroll = new Scrollable(this.content, 'STICKERS');
|
|
||||||
this.scroll.setVirtualContainer(this.stickersDiv);
|
|
||||||
this.scroll.onAdditionalScroll = () => {
|
|
||||||
setTyping();
|
|
||||||
};
|
|
||||||
|
|
||||||
emoticonsDropdown.addEventListener('closed', () => {
|
emoticonsDropdown.addEventListener('closed', () => {
|
||||||
setTyping(true);
|
setTyping(true);
|
||||||
});
|
});
|
||||||
@ -329,20 +359,19 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
|
|
||||||
const preloader = putPreloader(this.content, true);
|
const preloader = putPreloader(this.content, true);
|
||||||
|
|
||||||
|
const recentCategory = this.createCategory({id: 'recent'} as any, i18n('Stickers.Recent'));
|
||||||
|
recentCategory.elements.title.classList.add('disable-hover');
|
||||||
|
recentCategory.elements.menuTab.classList.add('tgico-recent', 'active');
|
||||||
|
recentCategory.elements.menuTabPadding.remove();
|
||||||
|
positionElementByIndex(recentCategory.elements.container, this.scroll.container, 0);
|
||||||
|
positionElementByIndex(recentCategory.elements.menuTab, this.menu, 0);
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.managers.appStickersManager.getRecentStickers().then((stickers) => {
|
this.managers.appStickersManager.getRecentStickers().then((stickers) => {
|
||||||
this.recentStickers = stickers.stickers.slice(0, 20) as MyDocument[];
|
const sliced = stickers.stickers.slice(0, RECENT_STICKERS_COUNT) as MyDocument[];
|
||||||
|
|
||||||
//stickersScroll.prepend(categoryDiv);
|
|
||||||
|
|
||||||
this.stickerSets['recent'] = {
|
|
||||||
stickers: this.recentDiv,
|
|
||||||
tab: this.menu.firstElementChild as HTMLElement
|
|
||||||
};
|
|
||||||
|
|
||||||
preloader.remove();
|
preloader.remove();
|
||||||
const {titleDiv} = this.categoryPush(this.recentDiv, '', Promise.resolve(this.recentStickers), true);
|
this.categoryPush(recentCategory, Promise.resolve(sliced));
|
||||||
titleDiv.append(i18n('Stickers.Recent'));
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
this.managers.appStickersManager.getAllStickers().then((res) => {
|
this.managers.appStickersManager.getAllStickers().then((res) => {
|
||||||
@ -357,38 +386,61 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
setTyping();
|
setTyping();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.superStickerRenderer = new SuperStickerRenderer(EmoticonsDropdown.lazyLoadQueue, EMOTICONSSTICKERGROUP, this.managers);
|
this.superStickerRenderer = new SuperStickerRenderer(EmoticonsDropdown.lazyLoadQueue, EMOTICONSSTICKERGROUP, this.managers, intersectionOptions);
|
||||||
|
|
||||||
emoticonsDropdown.addLazyLoadQueueRepeat(this.superStickerRenderer.lazyLoadQueue, this.superStickerRenderer.processInvisibleDiv);
|
const rendererLazyLoadQueue = this.superStickerRenderer.lazyLoadQueue;
|
||||||
|
emoticonsDropdown.addLazyLoadQueueRepeat(rendererLazyLoadQueue, this.superStickerRenderer.processInvisible);
|
||||||
|
|
||||||
/* setInterval(() => {
|
// emoticonsDropdown.addEventListener('close', () => {
|
||||||
// @ts-ignore
|
// this.categoriesIntersector.lock();
|
||||||
const players = Object.values(lottieLoader.players).filter((p) => p.width === 80);
|
// });
|
||||||
|
|
||||||
console.log('STICKERS RENDERED IN PANEL:', players.length, players.filter((p) => !p.paused).length, this.superStickerRenderer.lazyLoadQueue.intersector.getVisible().length);
|
// emoticonsDropdown.addEventListener('closed', () => {
|
||||||
}, .25e3); */
|
// for(const [container] of this.categoriesMap) {
|
||||||
|
// onCategoryVisibility(container, false);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// emoticonsDropdown.addEventListener('opened', () => {
|
||||||
|
// this.categoriesIntersector.unlockAndRefresh();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// setInterval(() => {
|
||||||
|
// // @ts-ignore
|
||||||
|
// const players = Object.values(lottieLoader.players).filter((p) => p.width >= 80);
|
||||||
|
|
||||||
|
// console.log(
|
||||||
|
// 'STICKERS RENDERED IN PANEL:',
|
||||||
|
// players.length,
|
||||||
|
// players.filter((p) => !p.paused).length,
|
||||||
|
// rendererLazyLoadQueue.intersector.getVisible().length
|
||||||
|
// );
|
||||||
|
// }, .25e3);
|
||||||
|
|
||||||
this.init = null;
|
this.init = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pushRecentSticker(doc: MyDocument) {
|
public pushRecentSticker(doc: MyDocument) {
|
||||||
this.managers.appStickersManager.pushRecentSticker(doc);
|
this.managers.appStickersManager.pushRecentSticker(doc.id);
|
||||||
|
|
||||||
if(!this.recentDiv?.parentElement) {
|
const set = this.categories['recent'];
|
||||||
|
if(!set) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let div = this.recentDiv.querySelector(`[data-doc-id="${doc.id}"]`);
|
const items = set.elements.items;
|
||||||
if(!div) {
|
let item = findAndSplice(set.items, (item) => item.document.id === doc.id);
|
||||||
div = this.superStickerRenderer.renderSticker(doc);
|
if(!item) {
|
||||||
|
item = {
|
||||||
|
element: this.superStickerRenderer.renderSticker(doc),
|
||||||
|
document: doc
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = this.recentDiv.querySelector('.category-items');
|
set.items.unshift(item);
|
||||||
items.prepend(div);
|
if(items.childElementCount) items.prepend(item.element);
|
||||||
|
if(items.childElementCount > RECENT_STICKERS_COUNT) {
|
||||||
if(items.childElementCount > 20) {
|
(Array.from(items.children) as HTMLElement[]).slice(RECENT_STICKERS_COUNT).forEach((el) => el.remove());
|
||||||
(Array.from(items.children) as HTMLElement[]).slice(20).forEach((el) => el.remove());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export default class GifsMasonry {
|
|||||||
) {
|
) {
|
||||||
this.managers = rootScope.managers;
|
this.managers = rootScope.managers;
|
||||||
|
|
||||||
this.lazyLoadQueue = new LazyLoadQueueRepeat2(undefined, (target, visible) => {
|
this.lazyLoadQueue = new LazyLoadQueueRepeat2(undefined, ({target, visible}) => {
|
||||||
if(visible) {
|
if(visible) {
|
||||||
this.processVisibleDiv(target);
|
this.processVisibleDiv(target);
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import VisibilityIntersector from "./visibilityIntersector";
|
import VisibilityIntersector, { OnVisibilityChangeItem } from "./visibilityIntersector";
|
||||||
import findAndSpliceAll from "../helpers/array/findAndSpliceAll";
|
import findAndSpliceAll from "../helpers/array/findAndSpliceAll";
|
||||||
import findAndSplice from "../helpers/array/findAndSplice";
|
import findAndSplice from "../helpers/array/findAndSplice";
|
||||||
import LazyLoadQueueIntersector, { LazyLoadElement } from "./lazyLoadQueueIntersector";
|
import LazyLoadQueueIntersector, { LazyLoadElement } from "./lazyLoadQueueIntersector";
|
||||||
@ -16,7 +16,7 @@ export default class LazyLoadQueue extends LazyLoadQueueIntersector {
|
|||||||
this.intersector = new VisibilityIntersector(this.onVisibilityChange);
|
this.intersector = new VisibilityIntersector(this.onVisibilityChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onVisibilityChange = (target: HTMLElement, visible: boolean) => {
|
private onVisibilityChange = ({target, visible}: OnVisibilityChangeItem) => {
|
||||||
if(visible) {
|
if(visible) {
|
||||||
/* if(DEBUG) {
|
/* if(DEBUG) {
|
||||||
this.log('isIntersecting', target);
|
this.log('isIntersecting', target);
|
||||||
|
@ -11,10 +11,11 @@ import VisibilityIntersector, { OnVisibilityChange } from "./visibilityIntersect
|
|||||||
export default class LazyLoadQueueRepeat extends LazyLoadQueueIntersector {
|
export default class LazyLoadQueueRepeat extends LazyLoadQueueIntersector {
|
||||||
private _queue: Map<HTMLElement, LazyLoadElement> = new Map();
|
private _queue: Map<HTMLElement, LazyLoadElement> = new Map();
|
||||||
|
|
||||||
constructor(parallelLimit?: number, protected onVisibilityChange?: OnVisibilityChange) {
|
constructor(parallelLimit?: number, protected onVisibilityChange?: OnVisibilityChange, options?: IntersectionObserverInit) {
|
||||||
super(parallelLimit);
|
super(parallelLimit);
|
||||||
|
|
||||||
this.intersector = new VisibilityIntersector((target, visible) => {
|
this.intersector = new VisibilityIntersector((item) => {
|
||||||
|
const {target, visible} = item;
|
||||||
const spliced = findAndSpliceAll(this.queue, (i) => i.div === target);
|
const spliced = findAndSpliceAll(this.queue, (i) => i.div === target);
|
||||||
if(visible) {
|
if(visible) {
|
||||||
const items = spliced.length ? spliced : [this._queue.get(target)];
|
const items = spliced.length ? spliced : [this._queue.get(target)];
|
||||||
@ -23,9 +24,9 @@ export default class LazyLoadQueueRepeat extends LazyLoadQueueIntersector {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onVisibilityChange && this.onVisibilityChange(target, visible);
|
this.onVisibilityChange && this.onVisibilityChange(item);
|
||||||
this.setProcessQueueTimeout();
|
this.setProcessQueueTimeout();
|
||||||
});
|
}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear() {
|
public clear() {
|
||||||
|
@ -12,7 +12,8 @@ export default class LazyLoadQueueRepeat2 extends LazyLoadQueueIntersector {
|
|||||||
constructor(parallelLimit?: number, protected onVisibilityChange?: OnVisibilityChange) {
|
constructor(parallelLimit?: number, protected onVisibilityChange?: OnVisibilityChange) {
|
||||||
super(parallelLimit);
|
super(parallelLimit);
|
||||||
|
|
||||||
this.intersector = new VisibilityIntersector((target, visible) => {
|
this.intersector = new VisibilityIntersector((item) => {
|
||||||
|
const {target, visible} = item;
|
||||||
const spliced = findAndSpliceAll(this.queue, (i) => i.div === target);
|
const spliced = findAndSpliceAll(this.queue, (i) => i.div === target);
|
||||||
if(visible && spliced.length) {
|
if(visible && spliced.length) {
|
||||||
spliced.forEach((item) => {
|
spliced.forEach((item) => {
|
||||||
@ -20,7 +21,7 @@ export default class LazyLoadQueueRepeat2 extends LazyLoadQueueIntersector {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onVisibilityChange && this.onVisibilityChange(target, visible);
|
this.onVisibilityChange && this.onVisibilityChange(item);
|
||||||
this.setProcessQueueTimeout();
|
this.setProcessQueueTimeout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
type TargetType = HTMLElement;
|
type TargetType = HTMLElement;
|
||||||
export type OnVisibilityChange = (target: TargetType, visible: boolean) => void;
|
export type OnVisibilityChangeItem = {target: TargetType, visible: boolean, entry: IntersectionObserverEntry};
|
||||||
|
export type OnVisibilityChange = (item: OnVisibilityChangeItem) => void;
|
||||||
|
|
||||||
export default class VisibilityIntersector {
|
export default class VisibilityIntersector {
|
||||||
private observer: IntersectionObserver;
|
private observer: IntersectionObserver;
|
||||||
private items: Map<TargetType, boolean> = new Map();
|
private items: Map<TargetType, boolean> = new Map();
|
||||||
private locked = false;
|
private locked = false;
|
||||||
|
|
||||||
constructor(onVisibilityChange: OnVisibilityChange) {
|
constructor(onVisibilityChange: OnVisibilityChange, options?: IntersectionObserverInit) {
|
||||||
this.observer = new IntersectionObserver((entries) => {
|
this.observer = new IntersectionObserver((entries) => {
|
||||||
if(this.locked) {
|
if(this.locked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const changed: {target: TargetType, visible: boolean}[] = [];
|
const changed: OnVisibilityChangeItem[] = [];
|
||||||
|
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
const target = entry.target as TargetType;
|
const target = entry.target as TargetType;
|
||||||
@ -37,15 +38,19 @@ export default class VisibilityIntersector {
|
|||||||
return;
|
return;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
changed[entry.isIntersecting ? 'unshift' : 'push']({target, visible: entry.isIntersecting});
|
const change: typeof changed[0] = {target, visible: entry.isIntersecting, entry};
|
||||||
|
|
||||||
|
// ! order will be incorrect so can't use it
|
||||||
|
// changed[entry.isIntersecting ? 'unshift' : 'push'](change);
|
||||||
|
changed.push(change);
|
||||||
|
|
||||||
//onVisibilityChange(target, entry.isIntersecting);
|
//onVisibilityChange(target, entry.isIntersecting);
|
||||||
});
|
});
|
||||||
|
|
||||||
changed.forEach((smth) => {
|
changed.forEach((item) => {
|
||||||
onVisibilityChange(smth.target, smth.visible);
|
onVisibilityChange(item);
|
||||||
});
|
});
|
||||||
});
|
}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getVisible() {
|
public getVisible() {
|
||||||
|
@ -11,6 +11,7 @@ import appDownloadManager from "../../lib/appManagers/appDownloadManager";
|
|||||||
import { AppManagers } from "../../lib/appManagers/managers";
|
import { AppManagers } from "../../lib/appManagers/managers";
|
||||||
import lottieLoader from "../../lib/rlottie/lottieLoader";
|
import lottieLoader from "../../lib/rlottie/lottieLoader";
|
||||||
import rootScope from "../../lib/rootScope";
|
import rootScope from "../../lib/rootScope";
|
||||||
|
import animationIntersector from "../animationIntersector";
|
||||||
import LazyLoadQueue from "../lazyLoadQueue";
|
import LazyLoadQueue from "../lazyLoadQueue";
|
||||||
import wrapSticker from "./sticker";
|
import wrapSticker from "./sticker";
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ export default async function wrapStickerSetThumb({set, lazyLoadQueue, container
|
|||||||
return promise.then((blob) => {
|
return promise.then((blob) => {
|
||||||
renderImageFromUrl(media, URL.createObjectURL(blob), () => {
|
renderImageFromUrl(media, URL.createObjectURL(blob), () => {
|
||||||
container.append(media);
|
container.append(media);
|
||||||
|
animationIntersector.addAnimation(media as HTMLVideoElement, group);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -79,7 +81,9 @@ export default async function wrapStickerSetThumb({set, lazyLoadQueue, container
|
|||||||
div: container,
|
div: container,
|
||||||
group: group,
|
group: group,
|
||||||
lazyLoadQueue,
|
lazyLoadQueue,
|
||||||
managers
|
managers,
|
||||||
|
width,
|
||||||
|
height
|
||||||
}); // kostil
|
}); // kostil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,8 @@ export default class DropdownHover extends EventListenerBase<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onMouseOut = (e: MouseEvent) => {
|
private onMouseOut = (e: MouseEvent) => {
|
||||||
if(KEEP_OPEN) return;
|
if(KEEP_OPEN || !this.isActive()) return;
|
||||||
clearTimeout(this.displayTimeout);
|
clearTimeout(this.displayTimeout);
|
||||||
if(!this.isActive()) return;
|
|
||||||
|
|
||||||
const toElement = (e as any).toElement as Element;
|
const toElement = (e as any).toElement as Element;
|
||||||
if(toElement && findUpAsChild(toElement, this.element)) {
|
if(toElement && findUpAsChild(toElement, this.element)) {
|
||||||
|
@ -158,9 +158,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tabs-tab stickers-padding">
|
<div class="tabs-tab stickers-padding">
|
||||||
<div class="menu-wrapper">
|
<div class="menu-wrapper">
|
||||||
<nav class="menu-horizontal-div no-stripe justify-start">
|
<nav class="menu-horizontal-div no-stripe justify-start"></nav>
|
||||||
<button class="menu-horizontal-div-item btn-icon tgico-recent active"></button>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="emoticons-content" id="content-stickers"></div>
|
<div class="emoticons-content" id="content-stickers"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -103,7 +103,7 @@ export class AppStickersManager extends AppManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveStickers(docs: Document[]) {
|
private saveStickers(docs: Document[]) {
|
||||||
forEachReverse(docs, (doc, idx) => {
|
forEachReverse(docs, (doc, idx) => {
|
||||||
doc = this.appDocsManager.saveDoc(doc);
|
doc = this.appDocsManager.saveDoc(doc);
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ export class AppStickersManager extends AppManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveStickerSet(res: Omit<MessagesStickerSet.messagesStickerSet, '_'>, id: DocId) {
|
private saveStickerSet(res: Omit<MessagesStickerSet.messagesStickerSet, '_'>, id: DocId) {
|
||||||
//console.log('stickers save set', res);w
|
//console.log('stickers save set', res);w
|
||||||
|
|
||||||
const newSet: MessagesStickerSet = {
|
const newSet: MessagesStickerSet = {
|
||||||
@ -401,6 +401,8 @@ export class AppStickersManager extends AppManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async toggleStickerSet(set: StickerSet.stickerSet) {
|
public async toggleStickerSet(set: StickerSet.stickerSet) {
|
||||||
|
set = this.storage.getFromCache(set.id).set;
|
||||||
|
|
||||||
if(set.installed_date) {
|
if(set.installed_date) {
|
||||||
const res = await this.apiManager.invokeApi('messages.uninstallStickerSet', {
|
const res = await this.apiManager.invokeApi('messages.uninstallStickerSet', {
|
||||||
stickerset: this.getStickerSetInput(set)
|
stickerset: this.getStickerSetInput(set)
|
||||||
@ -559,7 +561,8 @@ export class AppStickersManager extends AppManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public pushRecentSticker(doc: MyDocument) {
|
public pushRecentSticker(docId: DocId) {
|
||||||
|
const doc = this.appDocsManager.getDoc(docId);
|
||||||
const docEmoticon = fixEmoji(doc.stickerEmojiRaw);
|
const docEmoticon = fixEmoji(doc.stickerEmojiRaw);
|
||||||
for(const emoticon in this.getStickersByEmoticonsPromises) {
|
for(const emoticon in this.getStickersByEmoticonsPromises) {
|
||||||
const promise = this.getStickersByEmoticonsPromises[emoticon];
|
const promise = this.getStickersByEmoticonsPromises[emoticon];
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.emoji-dropdown {
|
.emoji-dropdown {
|
||||||
|
--menu-height: 3.0625rem;
|
||||||
display: flex/* !important */;
|
display: flex/* !important */;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -41,16 +42,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @include respond-to(handhelds) {
|
|
||||||
width: calc(100% + 1rem);
|
|
||||||
margin-left: -.5rem;
|
|
||||||
} */
|
|
||||||
|
|
||||||
.emoji-container {
|
.emoji-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
.menu-horizontal-div {
|
||||||
|
z-index: 4;
|
||||||
|
background-color: var(--surface-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-tabs {
|
.emoji-tabs {
|
||||||
@ -62,33 +63,31 @@
|
|||||||
&-search {
|
&-search {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
margin-left: 4px !important;
|
margin-left: .5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-delete {
|
&-delete {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin-right: 4px !important;
|
margin-right: .5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-horizontal-div-item {
|
||||||
|
margin: 0 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs-container {
|
.category-title {
|
||||||
/* width: 300%; */
|
font-size: var(--font-size-14);
|
||||||
height: 100%;
|
font-weight: var(--font-weight-bold);
|
||||||
|
line-height: var(--line-height-14);
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
padding: .8125rem .875rem .6875rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.category-title {
|
.tabs-container {
|
||||||
//position: sticky;
|
height: 100%;
|
||||||
top: 0;
|
|
||||||
//font-size: .85rem;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: var(--font-weight-bold);
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
//background: linear-gradient(to bottom,#fff 0,rgba(255,255,255,.9) 60%,rgba(255,255,255,0) 100%);
|
|
||||||
z-index: 2;
|
|
||||||
//padding: .53333rem 6PX .66667rem;
|
|
||||||
padding: 12px 6px 6px 6px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sticky_sentinel {
|
.sticky_sentinel {
|
||||||
&--top {
|
&--top {
|
||||||
@ -110,173 +109,83 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--surface-color);
|
background-color: var(--surface-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollable {
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-padding.active {
|
.emoji-padding {
|
||||||
|
.super-emojis {
|
||||||
|
padding: 0 .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
.menu-horizontal-div .menu-horizontal-div-item {
|
.menu-horizontal-div-item {
|
||||||
flex: unset;
|
flex: unset;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-items {
|
|
||||||
grid-template-columns: repeat(auto-fill, 40px);
|
|
||||||
|
|
||||||
> span {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
justify-self: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-title {
|
|
||||||
padding: 12px 6px 6px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrollable {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-category .category-items {
|
|
||||||
grid-column-gap: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-padding,
|
|
||||||
.stickers-padding {
|
|
||||||
.menu-horizontal-div {
|
|
||||||
// padding: 2px;
|
|
||||||
z-index: 4;
|
|
||||||
background-color: var(--surface-color);
|
|
||||||
|
|
||||||
.menu-horizontal-div-item {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-category {
|
.emoji-category {
|
||||||
//padding-top: 1px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0 -.125rem;
|
|
||||||
|
|
||||||
/* &:first-child {
|
|
||||||
//padding-top: 5px;
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* &::after {
|
|
||||||
content: "";
|
|
||||||
flex: auto;
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sticker-category {
|
.menu-horizontal-div {
|
||||||
position: relative;
|
width: 100%;
|
||||||
|
height: var(--menu-height);
|
||||||
|
min-height: var(--menu-height);
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.category-title {
|
&-item {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stickers-padding {
|
||||||
|
.category-title {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.stickers-recent {
|
|
||||||
.category-title {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* &::after {
|
|
||||||
content: "";
|
|
||||||
flex: auto;
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* &.not-full::after {
|
|
||||||
content: "";
|
|
||||||
flex: auto;
|
|
||||||
} */
|
|
||||||
|
|
||||||
.category-items {
|
.category-items {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, var(--esg-sticker-size)); // 64px
|
grid-template-columns: repeat(auto-fill, var(--esg-sticker-size)); // 64px
|
||||||
grid-column-gap: 1px;
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
padding: 0 .3125rem;
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#content-stickers {
|
|
||||||
.scrollable {
|
|
||||||
padding: 0px 5px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-horizontal-div {
|
|
||||||
width: 100%;
|
|
||||||
height: 48px;
|
|
||||||
|
|
||||||
.menu-horizontal-div-item {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin: 0 12px;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
line-height: 48px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stickers-padding {
|
|
||||||
&.active {
|
|
||||||
.scrollable {
|
|
||||||
padding: 0;
|
|
||||||
//box-shadow: 0px 1px 5px -1px rgba(0, 0, 0, .21);
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-horizontal-div {
|
|
||||||
.menu-horizontal-div-item {
|
|
||||||
height: 48px;
|
|
||||||
width: 48px;
|
|
||||||
padding: 0;
|
|
||||||
margin-right: 1px;
|
|
||||||
margin-left: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-wrapper {
|
.menu-wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 48px;
|
height: var(--menu-height);
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
background-color: var(--surface-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-horizontal-div-item {
|
.menu-horizontal-div {
|
||||||
/* width: calc(100% / 7); */
|
&-item {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
padding: .25rem;
|
||||||
|
margin: 0 .3125rem;
|
||||||
|
|
||||||
&.active {
|
&-padding {
|
||||||
&:not(.tgico-recent) {
|
width: 100%;
|
||||||
background-color: var(--light-secondary-text-color);
|
height: 100%;
|
||||||
}
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
> canvas, > img {
|
&.active {
|
||||||
//padding: .75rem;
|
&:not(.tgico-recent) {
|
||||||
padding: 8px;
|
background-color: var(--light-secondary-text-color);
|
||||||
max-width: 100%;
|
}
|
||||||
max-height: 100%;
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
> canvas {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -968,13 +968,13 @@ img.emoji {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, var(--esg-sticker-size)); // 64px
|
grid-template-columns: repeat(auto-fill, var(--esg-sticker-size)); // 64px
|
||||||
grid-column-gap: 1px;
|
// grid-column-gap: 1px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.super-sticker {
|
.super-sticker {
|
||||||
@include hover-background-effect() {
|
@include hover-background-effect() {
|
||||||
border-radius: 10px;
|
border-radius: $border-radius-medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* &:nth-child(5n+5) {
|
/* &:nth-child(5n+5) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user