Clear recent stickers button
This commit is contained in:
parent
9b6fe590fa
commit
43adba8845
@ -25,6 +25,9 @@ import ButtonIcon from "../../buttonIcon";
|
|||||||
import positionElementByIndex from "../../../helpers/dom/positionElementByIndex";
|
import positionElementByIndex from "../../../helpers/dom/positionElementByIndex";
|
||||||
import VisibilityIntersector, { OnVisibilityChange } from "../../visibilityIntersector";
|
import VisibilityIntersector, { OnVisibilityChange } from "../../visibilityIntersector";
|
||||||
import findAndSplice from "../../../helpers/array/findAndSplice";
|
import findAndSplice from "../../../helpers/array/findAndSplice";
|
||||||
|
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
|
||||||
|
import confirmationPopup from "../../confirmationPopup";
|
||||||
|
import noop from "../../../helpers/noop";
|
||||||
|
|
||||||
export class SuperStickerRenderer {
|
export class SuperStickerRenderer {
|
||||||
public lazyLoadQueue: LazyLoadQueueRepeat;
|
public lazyLoadQueue: LazyLoadQueueRepeat;
|
||||||
@ -213,37 +216,49 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
this.categoriesMap.set(container, category);
|
this.categoriesMap.set(container, category);
|
||||||
|
|
||||||
this.categoriesIntersector.observe(container);
|
this.categoriesIntersector.observe(container);
|
||||||
|
this.stickyIntersector.observeStickyHeaderChanges(container);
|
||||||
|
|
||||||
return category;
|
return category;
|
||||||
}
|
}
|
||||||
|
|
||||||
private categoryPush(
|
private categoryAppendStickers(
|
||||||
category: StickersTabCategory,
|
category: StickersTabCategory,
|
||||||
promise: Promise<MyDocument[]>
|
promise: Promise<MyDocument[]>
|
||||||
) {
|
) {
|
||||||
const {container, items} = category.elements;
|
const {container} = category.elements;
|
||||||
this.stickyIntersector.observeStickyHeaderChanges(container);
|
|
||||||
|
|
||||||
promise.then((documents) => {
|
promise.then((documents) => {
|
||||||
|
const isVisible = this.isCategoryVisible(category);
|
||||||
|
|
||||||
documents.forEach((document) => {
|
documents.forEach((document) => {
|
||||||
const element = this.superStickerRenderer.renderSticker(document);
|
const element = this.superStickerRenderer.renderSticker(document);
|
||||||
category.items.push({document, element});
|
category.items.push({document, element});
|
||||||
// items.append(element);
|
|
||||||
|
if(isVisible) {
|
||||||
|
category.elements.items.append(element);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const containerWidth = 410;
|
this.setCategoryItemsHeight(category);
|
||||||
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');
|
container.classList.remove('hide');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isCategoryVisible(category: StickersTabCategory) {
|
||||||
|
return this.categoriesIntersector.getVisible().includes(category.elements.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setCategoryItemsHeight(category: StickersTabCategory) {
|
||||||
|
const containerWidth = this.content.getBoundingClientRect().width - 10;
|
||||||
|
const stickerSize = mediaSizes.active.esgSticker.width;
|
||||||
|
|
||||||
|
const itemsPerRow = Math.floor(containerWidth / stickerSize);
|
||||||
|
const rows = Math.ceil(category.items.length / itemsPerRow);
|
||||||
|
const height = rows * stickerSize;
|
||||||
|
|
||||||
|
category.elements.items.style.minHeight = height + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
private async renderStickerSet(set: StickerSet.stickerSet, prepend = false) {
|
private async renderStickerSet(set: StickerSet.stickerSet, prepend = false) {
|
||||||
const category = this.createCategory(set, wrapEmojiText(set.title));
|
const category = this.createCategory(set, wrapEmojiText(set.title));
|
||||||
const {menuTab, menuTabPadding, container} = category.elements;
|
const {menuTab, menuTabPadding, container} = category.elements;
|
||||||
@ -251,7 +266,7 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
positionElementByIndex(menuTab, this.menu, prepend ? 1 : 0xFFFF);
|
positionElementByIndex(menuTab, this.menu, prepend ? 1 : 0xFFFF);
|
||||||
|
|
||||||
const promise = this.managers.appStickersManager.getStickerSet(set);
|
const promise = this.managers.appStickersManager.getStickerSet(set);
|
||||||
this.categoryPush(
|
this.categoryAppendStickers(
|
||||||
category,
|
category,
|
||||||
promise.then((stickerSet) => stickerSet.documents as MyDocument[])
|
promise.then((stickerSet) => stickerSet.documents as MyDocument[])
|
||||||
);
|
);
|
||||||
@ -313,29 +328,21 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
const intersectionOptions: IntersectionObserverInit = {root: emoticonsDropdown.getElement()};
|
const intersectionOptions: IntersectionObserverInit = {root: emoticonsDropdown.getElement()};
|
||||||
this.categoriesIntersector = new VisibilityIntersector(onCategoryVisibility, intersectionOptions);
|
this.categoriesIntersector = new VisibilityIntersector(onCategoryVisibility, intersectionOptions);
|
||||||
|
|
||||||
rootScope.addEventListener('stickers_installed', (set) => {
|
const clearCategoryItems = (category: StickersTabCategory) => {
|
||||||
if(!this.categories[set.id] && this.mounted) {
|
category.elements.items.textContent = '';
|
||||||
this.renderStickerSet(set, true);
|
category.items.forEach(({element}) => this.superStickerRenderer.unobserveAnimated(element));
|
||||||
}
|
category.items.length = 0;
|
||||||
});
|
};
|
||||||
|
|
||||||
rootScope.addEventListener('stickers_deleted', ({id}) => {
|
|
||||||
const set = this.categories[id];
|
|
||||||
if(set && this.mounted) {
|
|
||||||
set.elements.container.remove();
|
|
||||||
set.elements.menuTab.remove();
|
|
||||||
this.categoriesIntersector.unobserve(set.elements.container);
|
|
||||||
set.items.forEach(({element}) => this.superStickerRenderer.unobserveAnimated(element));
|
|
||||||
delete this.categories[id];
|
|
||||||
this.categoriesMap.delete(set.elements.container);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.scroll.container.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 container = findUpClassName(target, 'emoji-category');
|
const container = findUpClassName(target, 'emoji-category');
|
||||||
const category = this.categoriesMap.get(container);
|
const category = this.categoriesMap.get(container);
|
||||||
|
if(category.set.id === 'recent') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
new PopupStickers({id: category.set.id, access_hash: category.set.access_hash}).show();
|
new PopupStickers({id: category.set.id, access_hash: category.set.access_hash}).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -355,7 +362,8 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
setTyping();
|
setTyping();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.stickyIntersector = EmoticonsDropdown.menuOnClick(this.menu, this.scroll, menuScroll).stickyIntersector;
|
const {stickyIntersector, setActive} = EmoticonsDropdown.menuOnClick(this.menu, this.scroll, menuScroll);
|
||||||
|
this.stickyIntersector = stickyIntersector;
|
||||||
|
|
||||||
const preloader = putPreloader(this.content, true);
|
const preloader = putPreloader(this.content, true);
|
||||||
|
|
||||||
@ -363,15 +371,34 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
recentCategory.elements.title.classList.add('disable-hover');
|
recentCategory.elements.title.classList.add('disable-hover');
|
||||||
recentCategory.elements.menuTab.classList.add('tgico-recent', 'active');
|
recentCategory.elements.menuTab.classList.add('tgico-recent', 'active');
|
||||||
recentCategory.elements.menuTabPadding.remove();
|
recentCategory.elements.menuTabPadding.remove();
|
||||||
positionElementByIndex(recentCategory.elements.container, this.scroll.container, 0);
|
this.toggleRecentCategory(recentCategory, false);
|
||||||
positionElementByIndex(recentCategory.elements.menuTab, this.menu, 0);
|
|
||||||
|
const clearButton = ButtonIcon('close', {noRipple: true});
|
||||||
|
recentCategory.elements.title.append(clearButton);
|
||||||
|
attachClickEvent(clearButton, () => {
|
||||||
|
confirmationPopup({
|
||||||
|
titleLangKey: 'ClearRecentStickersAlertTitle',
|
||||||
|
descriptionLangKey: 'ClearRecentStickersAlertMessage',
|
||||||
|
button: {
|
||||||
|
langKey: 'Clear'
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
this.managers.appStickersManager.clearRecentStickers();
|
||||||
|
}, noop);
|
||||||
|
});
|
||||||
|
|
||||||
|
const onRecentStickers = (stickers: MyDocument[]) => {
|
||||||
|
const sliced = stickers.slice(0, RECENT_STICKERS_COUNT) as MyDocument[];
|
||||||
|
|
||||||
|
clearCategoryItems(recentCategory);
|
||||||
|
this.toggleRecentCategory(recentCategory, !!sliced.length);
|
||||||
|
this.categoryAppendStickers(recentCategory, Promise.resolve(sliced));
|
||||||
|
};
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.managers.appStickersManager.getRecentStickers().then((stickers) => {
|
this.managers.appStickersManager.getRecentStickers().then((stickers) => {
|
||||||
const sliced = stickers.stickers.slice(0, RECENT_STICKERS_COUNT) as MyDocument[];
|
|
||||||
|
|
||||||
preloader.remove();
|
preloader.remove();
|
||||||
this.categoryPush(recentCategory, Promise.resolve(sliced));
|
onRecentStickers(stickers.stickers as MyDocument[]);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
this.managers.appStickersManager.getAllStickers().then((res) => {
|
this.managers.appStickersManager.getAllStickers().then((res) => {
|
||||||
@ -384,6 +411,7 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
]).finally(() => {
|
]).finally(() => {
|
||||||
this.mounted = true;
|
this.mounted = true;
|
||||||
setTyping();
|
setTyping();
|
||||||
|
setActive(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.superStickerRenderer = new SuperStickerRenderer(EmoticonsDropdown.lazyLoadQueue, EMOTICONSSTICKERGROUP, this.managers, intersectionOptions);
|
this.superStickerRenderer = new SuperStickerRenderer(EmoticonsDropdown.lazyLoadQueue, EMOTICONSSTICKERGROUP, this.managers, intersectionOptions);
|
||||||
@ -416,20 +444,66 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
// rendererLazyLoadQueue.intersector.getVisible().length
|
// rendererLazyLoadQueue.intersector.getVisible().length
|
||||||
// );
|
// );
|
||||||
// }, .25e3);
|
// }, .25e3);
|
||||||
|
|
||||||
|
rootScope.addEventListener('stickers_installed', (set) => {
|
||||||
|
if(!this.categories[set.id] && this.mounted) {
|
||||||
|
this.renderStickerSet(set, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rootScope.addEventListener('stickers_deleted', ({id}) => {
|
||||||
|
const category = this.categories[id];
|
||||||
|
if(category && this.mounted) {
|
||||||
|
category.elements.container.remove();
|
||||||
|
category.elements.menuTab.remove();
|
||||||
|
this.categoriesIntersector.unobserve(category.elements.container);
|
||||||
|
clearCategoryItems(category);
|
||||||
|
delete this.categories[id];
|
||||||
|
this.categoriesMap.delete(category.elements.container);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rootScope.addEventListener('stickers_recent', (stickers) => {
|
||||||
|
if(this.mounted) {
|
||||||
|
onRecentStickers(stickers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const resizeCategories = () => {
|
||||||
|
for(const [container, category] of this.categoriesMap) {
|
||||||
|
this.setCategoryItemsHeight(category);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaSizes.addEventListener('resize', resizeCategories);
|
||||||
|
|
||||||
|
emoticonsDropdown.addEventListener('opened', resizeCategories);
|
||||||
|
|
||||||
this.init = null;
|
this.init = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toggleRecentCategory(category: StickersTabCategory, visible: boolean) {
|
||||||
|
if(!visible) {
|
||||||
|
category.elements.menuTab.remove();
|
||||||
|
category.elements.container.remove();
|
||||||
|
} else {
|
||||||
|
positionElementByIndex(category.elements.menuTab, this.menu, 0);
|
||||||
|
positionElementByIndex(category.elements.container, this.scroll.container, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// category.elements.container.classList.toggle('hide', !visible);
|
||||||
|
}
|
||||||
|
|
||||||
public pushRecentSticker(doc: MyDocument) {
|
public pushRecentSticker(doc: MyDocument) {
|
||||||
this.managers.appStickersManager.pushRecentSticker(doc.id);
|
this.managers.appStickersManager.pushRecentSticker(doc.id);
|
||||||
|
|
||||||
const set = this.categories['recent'];
|
const category = this.categories['recent'];
|
||||||
if(!set) {
|
if(!category) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = set.elements.items;
|
const items = category.elements.items;
|
||||||
let item = findAndSplice(set.items, (item) => item.document.id === doc.id);
|
let item = findAndSplice(category.items, (item) => item.document.id === doc.id);
|
||||||
if(!item) {
|
if(!item) {
|
||||||
item = {
|
item = {
|
||||||
element: this.superStickerRenderer.renderSticker(doc),
|
element: this.superStickerRenderer.renderSticker(doc),
|
||||||
@ -437,11 +511,14 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
set.items.unshift(item);
|
category.items.unshift(item);
|
||||||
if(items.childElementCount) items.prepend(item.element);
|
if(items.childElementCount) items.prepend(item.element);
|
||||||
if(items.childElementCount > RECENT_STICKERS_COUNT) {
|
if(items.childElementCount > RECENT_STICKERS_COUNT) {
|
||||||
(Array.from(items.children) as HTMLElement[]).slice(RECENT_STICKERS_COUNT).forEach((el) => el.remove());
|
(Array.from(items.children) as HTMLElement[]).slice(RECENT_STICKERS_COUNT).forEach((el) => el.remove());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setCategoryItemsHeight(category);
|
||||||
|
this.toggleRecentCategory(category, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose() {
|
onClose() {
|
||||||
|
@ -48,7 +48,10 @@ export default class DropdownHover extends EventListenerBase<{
|
|||||||
listenerSetter.add(button)('mouseover', (e) => {
|
listenerSetter.add(button)('mouseover', (e) => {
|
||||||
//console.log('onmouseover button');
|
//console.log('onmouseover button');
|
||||||
if(firstTime) {
|
if(firstTime) {
|
||||||
listenerSetter.add(button)('mouseout', this.onMouseOut);
|
listenerSetter.add(button)('mouseout', (e) => {
|
||||||
|
clearTimeout(this.displayTimeout);
|
||||||
|
this.onMouseOut(e);
|
||||||
|
});
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,6 +750,8 @@ const lang = {
|
|||||||
"Clear": "Clear",
|
"Clear": "Clear",
|
||||||
"Save": "Save",
|
"Save": "Save",
|
||||||
"PaymentCheckoutName": "Name",
|
"PaymentCheckoutName": "Name",
|
||||||
|
"ClearRecentStickersAlertTitle": "Clear recent stickers",
|
||||||
|
"ClearRecentStickersAlertMessage": "Do you want to clear all your recent stickers?",
|
||||||
|
|
||||||
// * macos
|
// * macos
|
||||||
"AccountSettings.Filters": "Chat Folders",
|
"AccountSettings.Filters": "Chat Folders",
|
||||||
|
@ -72,6 +72,12 @@ export class AppStickersManager extends AppManager {
|
|||||||
const stickerSet = update.stickerset as MyMessagesStickerSet;
|
const stickerSet = update.stickerset as MyMessagesStickerSet;
|
||||||
this.saveStickerSet(stickerSet, stickerSet.set.id);
|
this.saveStickerSet(stickerSet, stickerSet.set.id);
|
||||||
this.rootScope.dispatchEvent('stickers_installed', stickerSet.set);
|
this.rootScope.dispatchEvent('stickers_installed', stickerSet.set);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateRecentStickers: () => {
|
||||||
|
this.getRecentStickers().then(({stickers}) => {
|
||||||
|
this.rootScope.dispatchEvent('stickers_recent', stickers as MyDocument[]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -576,4 +582,9 @@ export class AppStickersManager extends AppManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public clearRecentStickers() {
|
||||||
|
this.rootScope.dispatchEvent('stickers_recent', []);
|
||||||
|
return this.apiManager.invokeApi('messages.clearRecentStickers');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import type { AppManagers } from "./appManagers/managers";
|
|||||||
import type { State } from "../config/state";
|
import type { State } from "../config/state";
|
||||||
import type { Progress } from "./appManagers/appDownloadManager";
|
import type { Progress } from "./appManagers/appDownloadManager";
|
||||||
import type { CallId } from "./appManagers/appCallsManager";
|
import type { CallId } from "./appManagers/appCallsManager";
|
||||||
|
import type { MyDocument } from "./appManagers/appDocsManager";
|
||||||
import { NULL_PEER_ID, UserAuth } from "./mtproto/mtproto_config";
|
import { NULL_PEER_ID, UserAuth } from "./mtproto/mtproto_config";
|
||||||
import EventListenerBase from "../helpers/eventListenerBase";
|
import EventListenerBase from "../helpers/eventListenerBase";
|
||||||
import { MOUNT_CLASS_TO } from "../config/debug";
|
import { MOUNT_CLASS_TO } from "../config/debug";
|
||||||
@ -85,6 +86,7 @@ export type BroadcastEvents = {
|
|||||||
|
|
||||||
'stickers_installed': StickerSet.stickerSet,
|
'stickers_installed': StickerSet.stickerSet,
|
||||||
'stickers_deleted': StickerSet.stickerSet,
|
'stickers_deleted': StickerSet.stickerSet,
|
||||||
|
'stickers_recent': MyDocument[],
|
||||||
|
|
||||||
'state_cleared': void,
|
'state_cleared': void,
|
||||||
'state_synchronized': ChatId | void,
|
'state_synchronized': ChatId | void,
|
||||||
|
@ -84,6 +84,17 @@
|
|||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
padding: .8125rem .875rem .6875rem;
|
padding: .8125rem .875rem .6875rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.btn-icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 0.5rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 1.25rem;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs-container {
|
.tabs-container {
|
||||||
@ -152,10 +163,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.category-items {
|
.category-items {
|
||||||
width: 100%;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, var(--esg-sticker-size)); // 64px
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 .3125rem;
|
padding: 0 .3125rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user