Stickers helper
Hashable invokeApi
This commit is contained in:
parent
dbd5bda736
commit
9b811795f5
@ -1,8 +1,8 @@
|
|||||||
import Recorder from '../../../public/recorder.min';
|
import Recorder from '../../../public/recorder.min';
|
||||||
import { isTouchSupported } from "../../helpers/touchSupport";
|
import { isTouchSupported } from "../../helpers/touchSupport";
|
||||||
import appChatsManager from '../../lib/appManagers/appChatsManager';
|
import appChatsManager from '../../lib/appManagers/appChatsManager';
|
||||||
import appDocsManager from "../../lib/appManagers/appDocsManager";
|
import appDocsManager, { MyDocument } from "../../lib/appManagers/appDocsManager";
|
||||||
import appImManager from "../../lib/appManagers/appImManager";
|
import appImManager, { CHAT_ANIMATION_GROUP } from "../../lib/appManagers/appImManager";
|
||||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||||
import appPeersManager from '../../lib/appManagers/appPeersManager';
|
import appPeersManager from '../../lib/appManagers/appPeersManager';
|
||||||
import appWebPagesManager from "../../lib/appManagers/appWebPagesManager";
|
import appWebPagesManager from "../../lib/appManagers/appWebPagesManager";
|
||||||
@ -11,9 +11,9 @@ import apiManager from "../../lib/mtproto/mtprotoworker";
|
|||||||
import opusDecodeController from "../../lib/opusDecodeController";
|
import opusDecodeController from "../../lib/opusDecodeController";
|
||||||
import { RichTextProcessor } from "../../lib/richtextprocessor";
|
import { RichTextProcessor } from "../../lib/richtextprocessor";
|
||||||
import rootScope from '../../lib/rootScope';
|
import rootScope from '../../lib/rootScope';
|
||||||
import { blurActiveElement, cancelEvent, CLICK_EVENT_NAME, findUpClassName, getRichValue, getSelectedNodes, isInputEmpty, isSelectionSingle, markdownTags, MarkdownType, placeCaretAtEnd, serializeNodes } from "../../helpers/dom";
|
import { blurActiveElement, cancelEvent, CLICK_EVENT_NAME, findUpClassName, getRichValue, getSelectedNodes, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, serializeNodes } from "../../helpers/dom";
|
||||||
import ButtonMenu, { ButtonMenuItemOptions } from '../buttonMenu';
|
import ButtonMenu, { ButtonMenuItemOptions } from '../buttonMenu';
|
||||||
import emoticonsDropdown from "../emoticonsDropdown";
|
import emoticonsDropdown, { EmoticonsDropdown } from "../emoticonsDropdown";
|
||||||
import PopupCreatePoll from "../popupCreatePoll";
|
import PopupCreatePoll from "../popupCreatePoll";
|
||||||
import PopupForward from '../popupForward';
|
import PopupForward from '../popupForward';
|
||||||
import PopupNewMedia from '../popupNewMedia';
|
import PopupNewMedia from '../popupNewMedia';
|
||||||
@ -24,12 +24,97 @@ import { wrapReply } from "../wrappers";
|
|||||||
import InputField from '../inputField';
|
import InputField from '../inputField';
|
||||||
import { MessageEntity } from '../../layer';
|
import { MessageEntity } from '../../layer';
|
||||||
import ButtonIcon from '../buttonIcon';
|
import ButtonIcon from '../buttonIcon';
|
||||||
|
import appStickersManager from '../../lib/appManagers/appStickersManager';
|
||||||
|
import SetTransition from '../singleTransition';
|
||||||
|
import { SuperStickerRenderer } from '../emoticonsDropdown/tabs/stickers';
|
||||||
|
import LazyLoadQueue from '../lazyLoadQueue';
|
||||||
|
|
||||||
const RECORD_MIN_TIME = 500;
|
const RECORD_MIN_TIME = 500;
|
||||||
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
|
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
|
||||||
|
|
||||||
type ChatInputHelperType = 'edit' | 'webpage' | 'forward' | 'reply';
|
type ChatInputHelperType = 'edit' | 'webpage' | 'forward' | 'reply';
|
||||||
|
|
||||||
|
export class StickersHelper {
|
||||||
|
private container: HTMLElement;
|
||||||
|
private stickersContainer: HTMLElement;
|
||||||
|
private scrollable: Scrollable;
|
||||||
|
private superStickerRenderer: SuperStickerRenderer;
|
||||||
|
private lazyLoadQueue: LazyLoadQueue;
|
||||||
|
private lastEmoticon = '';
|
||||||
|
|
||||||
|
constructor(private appendTo: HTMLElement) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public checkEmoticon(emoticon: string) {
|
||||||
|
if(this.lastEmoticon == emoticon) return;
|
||||||
|
|
||||||
|
if(this.lastEmoticon && !emoticon) {
|
||||||
|
if(this.container) {
|
||||||
|
SetTransition(this.container, 'is-visible', false, 200/* , () => {
|
||||||
|
this.stickersContainer.innerHTML = '';
|
||||||
|
} */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastEmoticon = emoticon;
|
||||||
|
if(this.lazyLoadQueue) {
|
||||||
|
this.lazyLoadQueue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!emoticon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appStickersManager.getStickersByEmoticon(emoticon)
|
||||||
|
.then(stickers => {
|
||||||
|
if(this.lastEmoticon != emoticon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.init) {
|
||||||
|
this.init();
|
||||||
|
this.init = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stickersContainer.innerHTML = '';
|
||||||
|
this.lazyLoadQueue.clear();
|
||||||
|
if(stickers.length) {
|
||||||
|
stickers.forEach(sticker => {
|
||||||
|
this.stickersContainer.append(this.superStickerRenderer.renderSticker(sticker as MyDocument));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTransition(this.container, 'is-visible', true, 200);
|
||||||
|
this.scrollable.scrollTop = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private init() {
|
||||||
|
this.container = document.createElement('div');
|
||||||
|
this.container.classList.add('stickers-helper', 'z-depth-1');
|
||||||
|
|
||||||
|
this.stickersContainer = document.createElement('div');
|
||||||
|
this.stickersContainer.classList.add('stickers-helper-stickers', 'super-stickers');
|
||||||
|
this.stickersContainer.addEventListener('click', (e) => {
|
||||||
|
if(!findUpClassName(e.target, 'super-sticker')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appImManager.chatInputC.clearInput();
|
||||||
|
EmoticonsDropdown.onMediaClick(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.container.append(this.stickersContainer);
|
||||||
|
|
||||||
|
this.scrollable = new Scrollable(this.container);
|
||||||
|
this.lazyLoadQueue = new LazyLoadQueue();
|
||||||
|
this.superStickerRenderer = new SuperStickerRenderer(this.lazyLoadQueue, CHAT_ANIMATION_GROUP);
|
||||||
|
|
||||||
|
this.appendTo.append(this.container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class MarkupTooltip {
|
export class MarkupTooltip {
|
||||||
public container: HTMLElement;
|
public container: HTMLElement;
|
||||||
private wrapper: HTMLElement;
|
private wrapper: HTMLElement;
|
||||||
@ -323,6 +408,7 @@ export class ChatInput {
|
|||||||
private canUndoFromHTML = '';
|
private canUndoFromHTML = '';
|
||||||
|
|
||||||
public markupTooltip: MarkupTooltip;
|
public markupTooltip: MarkupTooltip;
|
||||||
|
public stickersHelper: StickersHelper;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
if(!isTouchSupported) {
|
if(!isTouchSupported) {
|
||||||
@ -382,6 +468,8 @@ export class ChatInput {
|
|||||||
this.replyElements.titleEl = this.replyElements.container.querySelector('.reply-title') as HTMLDivElement;
|
this.replyElements.titleEl = this.replyElements.container.querySelector('.reply-title') as HTMLDivElement;
|
||||||
this.replyElements.subtitleEl = this.replyElements.container.querySelector('.reply-subtitle') as HTMLDivElement;
|
this.replyElements.subtitleEl = this.replyElements.container.querySelector('.reply-subtitle') as HTMLDivElement;
|
||||||
|
|
||||||
|
this.stickersHelper = new StickersHelper(this.replyElements.container.parentElement);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.recorder = new Recorder({
|
this.recorder = new Recorder({
|
||||||
//encoderBitRate: 32,
|
//encoderBitRate: 32,
|
||||||
@ -789,11 +877,24 @@ export class ChatInput {
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
//console.log('messageInput input', this.messageInput.innerText, this.serializeNodes(Array.from(this.messageInput.childNodes)));
|
//console.log('messageInput input', this.messageInput.innerText, this.serializeNodes(Array.from(this.messageInput.childNodes)));
|
||||||
const value = this.messageInput.innerText;
|
//const value = this.messageInput.innerText;
|
||||||
|
const value = getRichValue(this.messageInput);
|
||||||
|
|
||||||
const entities = RichTextProcessor.parseEntities(value);
|
const entities = RichTextProcessor.parseEntities(value);
|
||||||
//console.log('messageInput entities', entities);
|
//console.log('messageInput entities', entities);
|
||||||
|
|
||||||
|
if(this.stickersHelper) {
|
||||||
|
let emoticon = '';
|
||||||
|
if(entities.length && entities[0]._ == 'messageEntityEmoji') {
|
||||||
|
const entity = entities[0];
|
||||||
|
if(entity.length == value.length && !entity.offset) {
|
||||||
|
emoticon = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stickersHelper.checkEmoticon(emoticon);
|
||||||
|
}
|
||||||
|
|
||||||
const html = this.messageInput.innerHTML;
|
const html = this.messageInput.innerHTML;
|
||||||
if(this.canRedoFromHTML && html != this.canRedoFromHTML && !this.lockRedo) {
|
if(this.canRedoFromHTML && html != this.canRedoFromHTML && !this.lockRedo) {
|
||||||
this.canRedoFromHTML = '';
|
this.canRedoFromHTML = '';
|
||||||
@ -1014,6 +1115,8 @@ export class ChatInput {
|
|||||||
this.executedHistory.length = 0;
|
this.executedHistory.length = 0;
|
||||||
this.canUndoFromHTML = '';
|
this.canUndoFromHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.onMessageInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
public isInputEmpty() {
|
public isInputEmpty() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import emoticonsDropdown, { EmoticonsDropdown, EMOTICONSSTICKERGROUP, EmoticonsTab } from "..";
|
import emoticonsDropdown, { EmoticonsDropdown, EMOTICONSSTICKERGROUP, EmoticonsTab } from "..";
|
||||||
import { readBlobAsText } from "../../../helpers/blob";
|
import { readBlobAsText } from "../../../helpers/blob";
|
||||||
import mediaSizes from "../../../helpers/mediaSizes";
|
import mediaSizes from "../../../helpers/mediaSizes";
|
||||||
import { StickerSet } from "../../../layer";
|
import { MessagesAllStickers, StickerSet } from "../../../layer";
|
||||||
import appDocsManager, { MyDocument } from "../../../lib/appManagers/appDocsManager";
|
import appDocsManager, { MyDocument } from "../../../lib/appManagers/appDocsManager";
|
||||||
import appDownloadManager from "../../../lib/appManagers/appDownloadManager";
|
import appDownloadManager from "../../../lib/appManagers/appDownloadManager";
|
||||||
import appStickersManager from "../../../lib/appManagers/appStickersManager";
|
import appStickersManager from "../../../lib/appManagers/appStickersManager";
|
||||||
@ -10,12 +10,106 @@ import apiManager from "../../../lib/mtproto/mtprotoworker";
|
|||||||
import { RichTextProcessor } from "../../../lib/richtextprocessor";
|
import { RichTextProcessor } from "../../../lib/richtextprocessor";
|
||||||
import rootScope from "../../../lib/rootScope";
|
import rootScope from "../../../lib/rootScope";
|
||||||
import animationIntersector from "../../animationIntersector";
|
import animationIntersector from "../../animationIntersector";
|
||||||
import { LazyLoadQueueRepeat } from "../../lazyLoadQueue";
|
import LazyLoadQueue, { LazyLoadQueueRepeat } from "../../lazyLoadQueue";
|
||||||
import { putPreloader, renderImageFromUrl } from "../../misc";
|
import { putPreloader, renderImageFromUrl } from "../../misc";
|
||||||
import Scrollable, { ScrollableX } from "../../scrollable";
|
import Scrollable, { ScrollableX } from "../../scrollable";
|
||||||
import StickyIntersector from "../../stickyIntersector";
|
import StickyIntersector from "../../stickyIntersector";
|
||||||
import { wrapSticker } from "../../wrappers";
|
import { wrapSticker } from "../../wrappers";
|
||||||
|
|
||||||
|
export class SuperStickerRenderer {
|
||||||
|
lazyLoadQueue: LazyLoadQueueRepeat;
|
||||||
|
animatedDivs: Set<HTMLDivElement> = new Set();
|
||||||
|
|
||||||
|
constructor(private regularLazyLoadQueue: LazyLoadQueue, private group: string) {
|
||||||
|
this.lazyLoadQueue = new LazyLoadQueueRepeat(undefined, (target, visible) => {
|
||||||
|
if(!visible) {
|
||||||
|
this.processInvisibleDiv(target as HTMLDivElement);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSticker(doc: MyDocument, div?: HTMLDivElement) {
|
||||||
|
if(!div) {
|
||||||
|
div = document.createElement('div');
|
||||||
|
div.classList.add('grid-item', 'super-sticker');
|
||||||
|
|
||||||
|
if(doc.sticker == 2) {
|
||||||
|
this.animatedDivs.add(div);
|
||||||
|
|
||||||
|
this.lazyLoadQueue.observe({
|
||||||
|
div,
|
||||||
|
load: this.processVisibleDiv
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// * This will wrap only a thumb
|
||||||
|
wrapSticker({
|
||||||
|
doc,
|
||||||
|
div,
|
||||||
|
lazyLoadQueue: this.regularLazyLoadQueue,
|
||||||
|
group: this.group,
|
||||||
|
onlyThumb: doc.sticker == 2
|
||||||
|
});
|
||||||
|
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAnimationContainer = (div: HTMLElement, visible: boolean) => {
|
||||||
|
//console.error('checkAnimationContainer', div, visible);
|
||||||
|
const players = animationIntersector.getAnimations(div);
|
||||||
|
players.forEach(player => {
|
||||||
|
if(!visible) {
|
||||||
|
animationIntersector.checkAnimation(player, true, true);
|
||||||
|
} else {
|
||||||
|
animationIntersector.checkAnimation(player, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
processVisibleDiv = (div: HTMLElement) => {
|
||||||
|
const docID = div.dataset.docID;
|
||||||
|
const doc = appDocsManager.getDoc(docID);
|
||||||
|
|
||||||
|
const size = mediaSizes.active.esgSticker.width;
|
||||||
|
|
||||||
|
const promise = wrapSticker({
|
||||||
|
doc,
|
||||||
|
div: div as HTMLDivElement,
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
lazyLoadQueue: null,
|
||||||
|
group: this.group,
|
||||||
|
onlyThumb: false,
|
||||||
|
play: true,
|
||||||
|
loop: true
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.then(() => {
|
||||||
|
//clearTimeout(timeout);
|
||||||
|
this.checkAnimationContainer(div, this.lazyLoadQueue.intersector.isVisible(div));
|
||||||
|
});
|
||||||
|
|
||||||
|
/* let timeout = window.setTimeout(() => {
|
||||||
|
console.error('processVisibleDiv timeout', div, doc);
|
||||||
|
}, 1e3); */
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
processInvisibleDiv = (div: HTMLElement) => {
|
||||||
|
const docID = div.dataset.docID;
|
||||||
|
const doc = appDocsManager.getDoc(docID);
|
||||||
|
|
||||||
|
//console.log('STICKER INvisible:', /* div, */docID);
|
||||||
|
|
||||||
|
this.checkAnimationContainer(div, false);
|
||||||
|
|
||||||
|
div.innerHTML = '';
|
||||||
|
this.renderSticker(doc, div as HTMLDivElement);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export default class StickersTab implements EmoticonsTab {
|
export default class StickersTab implements EmoticonsTab {
|
||||||
public content: HTMLElement;
|
public content: HTMLElement;
|
||||||
private stickersDiv: HTMLElement;
|
private stickersDiv: HTMLElement;
|
||||||
@ -38,14 +132,13 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
|
|
||||||
private stickyIntersector: StickyIntersector;
|
private stickyIntersector: StickyIntersector;
|
||||||
|
|
||||||
private animatedDivs: Set<HTMLDivElement> = new Set();
|
private superStickerRenderer: SuperStickerRenderer;
|
||||||
private lazyLoadQueue: LazyLoadQueueRepeat;
|
|
||||||
|
|
||||||
categoryPush(categoryDiv: HTMLElement, categoryTitle: string, promise: Promise<MyDocument[]>, prepend?: boolean) {
|
categoryPush(categoryDiv: HTMLElement, categoryTitle: string, promise: Promise<MyDocument[]>, prepend?: boolean) {
|
||||||
//if((docs.length % 5) != 0) categoryDiv.classList.add('not-full');
|
//if((docs.length % 5) != 0) categoryDiv.classList.add('not-full');
|
||||||
|
|
||||||
const itemsDiv = document.createElement('div');
|
const itemsDiv = document.createElement('div');
|
||||||
itemsDiv.classList.add('category-items');
|
itemsDiv.classList.add('category-items', 'super-stickers');
|
||||||
|
|
||||||
const titleDiv = document.createElement('div');
|
const titleDiv = document.createElement('div');
|
||||||
titleDiv.classList.add('category-title');
|
titleDiv.classList.add('category-title');
|
||||||
@ -60,7 +153,7 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
promise.then(documents => {
|
promise.then(documents => {
|
||||||
documents.forEach(doc => {
|
documents.forEach(doc => {
|
||||||
//if(doc._ == 'documentEmpty') return;
|
//if(doc._ == 'documentEmpty') return;
|
||||||
itemsDiv.append(this.renderSticker(doc));
|
itemsDiv.append(this.superStickerRenderer.renderSticker(doc));
|
||||||
});
|
});
|
||||||
|
|
||||||
if(this.queueCategoryPush.length) {
|
if(this.queueCategoryPush.length) {
|
||||||
@ -80,33 +173,6 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSticker(doc: MyDocument, div?: HTMLDivElement) {
|
|
||||||
if(!div) {
|
|
||||||
div = document.createElement('div');
|
|
||||||
div.classList.add('grid-item');
|
|
||||||
|
|
||||||
if(doc.sticker == 2) {
|
|
||||||
this.animatedDivs.add(div);
|
|
||||||
|
|
||||||
this.lazyLoadQueue.observe({
|
|
||||||
div,
|
|
||||||
load: this.processVisibleDiv
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// * This will wrap only a thumb
|
|
||||||
wrapSticker({
|
|
||||||
doc,
|
|
||||||
div,
|
|
||||||
lazyLoadQueue: EmoticonsDropdown.lazyLoadQueue,
|
|
||||||
group: EMOTICONSSTICKERGROUP,
|
|
||||||
onlyThumb: doc.sticker == 2
|
|
||||||
});
|
|
||||||
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
|
|
||||||
async renderStickerSet(set: StickerSet.stickerSet, prepend = false) {
|
async renderStickerSet(set: StickerSet.stickerSet, prepend = false) {
|
||||||
const categoryDiv = document.createElement('div');
|
const categoryDiv = document.createElement('div');
|
||||||
categoryDiv.classList.add('sticker-category');
|
categoryDiv.classList.add('sticker-category');
|
||||||
@ -169,60 +235,6 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAnimationContainer = (div: HTMLElement, visible: boolean) => {
|
|
||||||
//console.error('checkAnimationContainer', div, visible);
|
|
||||||
const players = animationIntersector.getAnimations(div);
|
|
||||||
players.forEach(player => {
|
|
||||||
if(!visible) {
|
|
||||||
animationIntersector.checkAnimation(player, true, true);
|
|
||||||
} else {
|
|
||||||
animationIntersector.checkAnimation(player, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
processVisibleDiv = (div: HTMLElement) => {
|
|
||||||
const docID = div.dataset.docID;
|
|
||||||
const doc = appDocsManager.getDoc(docID);
|
|
||||||
|
|
||||||
const size = mediaSizes.active.esgSticker.width;
|
|
||||||
|
|
||||||
const promise = wrapSticker({
|
|
||||||
doc,
|
|
||||||
div: div as HTMLDivElement,
|
|
||||||
width: size,
|
|
||||||
height: size,
|
|
||||||
lazyLoadQueue: null,
|
|
||||||
group: EMOTICONSSTICKERGROUP,
|
|
||||||
onlyThumb: false,
|
|
||||||
play: true,
|
|
||||||
loop: true
|
|
||||||
});
|
|
||||||
|
|
||||||
promise.then(() => {
|
|
||||||
//clearTimeout(timeout);
|
|
||||||
this.checkAnimationContainer(div, this.lazyLoadQueue.intersector.isVisible(div));
|
|
||||||
});
|
|
||||||
|
|
||||||
/* let timeout = window.setTimeout(() => {
|
|
||||||
console.error('processVisibleDiv timeout', div, doc);
|
|
||||||
}, 1e3); */
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
processInvisibleDiv = (div: HTMLElement) => {
|
|
||||||
const docID = div.dataset.docID;
|
|
||||||
const doc = appDocsManager.getDoc(docID);
|
|
||||||
|
|
||||||
//console.log('STICKER INvisible:', /* div, */docID);
|
|
||||||
|
|
||||||
this.checkAnimationContainer(div, false);
|
|
||||||
|
|
||||||
div.innerHTML = '';
|
|
||||||
this.renderSticker(doc, div as HTMLDivElement);
|
|
||||||
};
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.content = document.getElementById('content-stickers');
|
this.content = document.getElementById('content-stickers');
|
||||||
//let stickersDiv = contentStickersDiv.querySelector('.os-content') as HTMLDivElement;
|
//let stickersDiv = contentStickersDiv.querySelector('.os-content') as HTMLDivElement;
|
||||||
@ -299,16 +311,10 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
this.categoryPush(this.recentDiv, 'Recent', Promise.resolve(this.recentStickers), true);
|
this.categoryPush(this.recentDiv, 'Recent', Promise.resolve(this.recentStickers), true);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
apiManager.invokeApi('messages.getAllStickers', {hash: 0}).then(async(res) => {
|
appStickersManager.getAllStickers().then((res) => {
|
||||||
let stickers: {
|
|
||||||
_: 'messages.allStickers',
|
|
||||||
hash: number,
|
|
||||||
sets: Array<StickerSet.stickerSet>
|
|
||||||
} = res as any;
|
|
||||||
|
|
||||||
preloader.remove();
|
preloader.remove();
|
||||||
|
|
||||||
for(let set of stickers.sets) {
|
for(let set of (res as MessagesAllStickers.messagesAllStickers).sets) {
|
||||||
this.renderStickerSet(set);
|
this.renderStickerSet(set);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -316,13 +322,9 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
this.mounted = true;
|
this.mounted = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.lazyLoadQueue = new LazyLoadQueueRepeat(undefined, (target, visible) => {
|
this.superStickerRenderer = new SuperStickerRenderer(EmoticonsDropdown.lazyLoadQueue, EMOTICONSSTICKERGROUP);
|
||||||
if(!visible) {
|
|
||||||
this.processInvisibleDiv(target as HTMLDivElement);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
emoticonsDropdown.addLazyLoadQueueRepeat(this.lazyLoadQueue, this.processInvisibleDiv);
|
emoticonsDropdown.addLazyLoadQueueRepeat(this.superStickerRenderer.lazyLoadQueue, this.superStickerRenderer.processInvisibleDiv);
|
||||||
|
|
||||||
/* setInterval(() => {
|
/* setInterval(() => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -342,7 +344,7 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
|
|
||||||
let div = this.recentDiv.querySelector(`[data-doc-i-d="${doc.id}"]`);
|
let div = this.recentDiv.querySelector(`[data-doc-i-d="${doc.id}"]`);
|
||||||
if(!div) {
|
if(!div) {
|
||||||
div = this.renderSticker(doc);
|
div = this.superStickerRenderer.renderSticker(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = this.recentDiv.querySelector('.category-items');
|
const items = this.recentDiv.querySelector('.category-items');
|
||||||
|
@ -565,7 +565,7 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
const toneIndex = emoji ? getEmojiToneIndex(emoji) : -1;
|
const toneIndex = emoji ? getEmojiToneIndex(emoji) : -1;
|
||||||
|
|
||||||
if((doc.thumbs?.length || doc.stickerCachedThumbs) && !div.firstElementChild && (!doc.downloaded || stickerType == 2 || onlyThumb)/* && doc.thumbs[0]._ != 'photoSizeEmpty' */) {
|
if((doc.thumbs?.length || doc.stickerCachedThumbs) && !div.firstElementChild && (!doc.downloaded || stickerType == 2 || onlyThumb)/* && doc.thumbs[0]._ != 'photoSizeEmpty' */) {
|
||||||
const thumb = doc.stickerCachedThumbs && doc.stickerCachedThumbs[toneIndex] || doc.thumbs[0];
|
let thumb = doc.stickerCachedThumbs && doc.stickerCachedThumbs[toneIndex] || doc.thumbs[0];
|
||||||
|
|
||||||
//console.log('wrap sticker', thumb, div);
|
//console.log('wrap sticker', thumb, div);
|
||||||
|
|
||||||
@ -581,23 +581,33 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
renderImageFromUrl(img, thumb.url, afterRender);
|
renderImageFromUrl(img, thumb.url, afterRender);
|
||||||
} else if('bytes' in thumb) {
|
} else if('bytes' in thumb) {
|
||||||
if(thumb._ == 'photoPathSize') {
|
if(thumb._ == 'photoPathSize') {
|
||||||
//if(!doc.w) console.error('no w', doc);
|
if(thumb.bytes.length) {
|
||||||
div.innerHTML = `<svg class="rlottie-vector" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 ${doc.w || 512} ${doc.h || 512}" xml:space="preserve">
|
//if(!doc.w) console.error('no w', doc);
|
||||||
<path d="${appPhotosManager.getPathFromPhotoPathSize(thumb)}"/>
|
const d = appPhotosManager.getPathFromPhotoPathSize(thumb);
|
||||||
</svg>`;
|
/* if(d == 'Mz' || d.includes('151,48,349,33z')) {
|
||||||
} else if(toneIndex <= 0) {
|
console.error('no path', doc);
|
||||||
|
} */
|
||||||
|
div.innerHTML = `<svg class="rlottie-vector" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 ${doc.w || 512} ${doc.h || 512}" xml:space="preserve">
|
||||||
|
<path d="${d}"/>
|
||||||
|
</svg>`;
|
||||||
|
} else {
|
||||||
|
thumb = doc.thumbs.find(t => (t as PhotoSize.photoStrippedSize).bytes?.length) || thumb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(thumb && thumb._ != 'photoPathSize' && toneIndex <= 0) {
|
||||||
img = new Image();
|
img = new Image();
|
||||||
if((webpWorkerController.isWebpSupported() || doc.pFlags.stickerThumbConverted || thumb.url)/* && false */) {
|
if((webpWorkerController.isWebpSupported() || doc.pFlags.stickerThumbConverted || thumb.url)/* && false */) {
|
||||||
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
|
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb as PhotoSize.photoStrippedSize, true), afterRender);
|
||||||
} else {
|
} else {
|
||||||
webpWorkerController.convert(doc.id, thumb.bytes as Uint8Array).then(bytes => {
|
webpWorkerController.convert(doc.id, (thumb as PhotoSize.photoStrippedSize).bytes as Uint8Array).then(bytes => {
|
||||||
thumb.bytes = bytes;
|
(thumb as PhotoSize.photoStrippedSize).bytes = bytes;
|
||||||
doc.pFlags.stickerThumbConverted = true;
|
doc.pFlags.stickerThumbConverted = true;
|
||||||
|
|
||||||
if(middleware && !middleware()) return;
|
if(middleware && !middleware()) return;
|
||||||
|
|
||||||
if(!div.childElementCount) {
|
if(!div.childElementCount) {
|
||||||
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
|
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb as PhotoSize.photoStrippedSize, true), afterRender);
|
||||||
}
|
}
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
}
|
}
|
||||||
@ -610,14 +620,14 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
|
|
||||||
const r = () => {
|
const r = () => {
|
||||||
if(div.childElementCount || (middleware && !middleware())) return;
|
if(div.childElementCount || (middleware && !middleware())) return;
|
||||||
renderImageFromUrl(img, thumb.url, afterRender);
|
renderImageFromUrl(img, (thumb as PhotoSize.photoStrippedSize).url, afterRender);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(thumb.url) {
|
if((thumb as PhotoSize.photoStrippedSize).url) {
|
||||||
r();
|
r();
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else {
|
} else {
|
||||||
return appDocsManager.getThumbURL(doc, thumb).promise.then(r);
|
return appDocsManager.getThumbURL(doc, thumb as PhotoSize.photoStrippedSize).promise.then(r);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Document, InputFileLocation, InputStickerSet, MessagesRecentStickers, MessagesStickerSet, PhotoSize, StickerSet, StickerSetCovered } from '../../layer';
|
import { Document, InputFileLocation, InputStickerSet, MessagesAllStickers, MessagesFeaturedStickers, MessagesFoundStickerSets, MessagesRecentStickers, MessagesStickers, MessagesStickerSet, PhotoSize, StickerPack, StickerSet, StickerSetCovered } from '../../layer';
|
||||||
import { Modify } from '../../types';
|
import { Modify } from '../../types';
|
||||||
import apiManager from '../mtproto/mtprotoworker';
|
import apiManager from '../mtproto/mtprotoworker';
|
||||||
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
||||||
@ -15,18 +15,8 @@ export class AppStickersManager {
|
|||||||
|
|
||||||
private saveSetsTimeout: number;
|
private saveSetsTimeout: number;
|
||||||
|
|
||||||
private hashes: Partial<{
|
private getStickerSetPromises: {[setID: string]: Promise<MessagesStickerSet>} = {};
|
||||||
featured: Partial<{hash: number, result: StickerSetCovered[]}>,
|
private getStickersByEmoticonsPromises: {[emoticon: string]: Promise<Document[]>} = {};
|
||||||
search: {
|
|
||||||
[query: string]: Partial<{
|
|
||||||
hash: number,
|
|
||||||
result: StickerSetCovered[]
|
|
||||||
}>
|
|
||||||
}
|
|
||||||
}> = {
|
|
||||||
featured: {},
|
|
||||||
search: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
appStateManager.getState().then(({stickerSets}) => {
|
appStateManager.getState().then(({stickerSets}) => {
|
||||||
@ -74,25 +64,29 @@ export class AppStickersManager {
|
|||||||
}> = {}): Promise<MessagesStickerSet> {
|
}> = {}): Promise<MessagesStickerSet> {
|
||||||
if(this.stickerSets[set.id] && !params.overwrite && this.stickerSets[set.id].documents?.length) return this.stickerSets[set.id];
|
if(this.stickerSets[set.id] && !params.overwrite && this.stickerSets[set.id].documents?.length) return this.stickerSets[set.id];
|
||||||
|
|
||||||
const stickerSet = await apiManager.invokeApi('messages.getStickerSet', {
|
if(this.getStickerSetPromises[set.id]) {
|
||||||
|
return this.getStickerSetPromises[set.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
const promise = this.getStickerSetPromises[set.id] = apiManager.invokeApi('messages.getStickerSet', {
|
||||||
stickerset: this.getStickerSetInput(set)
|
stickerset: this.getStickerSetInput(set)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stickerSet = await promise;
|
||||||
|
delete this.getStickerSetPromises[set.id];
|
||||||
this.saveStickerSet(stickerSet, set.id);
|
this.saveStickerSet(stickerSet, set.id);
|
||||||
|
|
||||||
return stickerSet as any;
|
return stickerSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getRecentStickers(): Promise<Modify<MessagesRecentStickers.messagesRecentStickers, {
|
public async getRecentStickers(): Promise<Modify<MessagesRecentStickers.messagesRecentStickers, {
|
||||||
stickers: Document[]
|
stickers: Document[]
|
||||||
}>> {
|
}>> {
|
||||||
const res = await apiManager.invokeApi('messages.getRecentStickers') as MessagesRecentStickers.messagesRecentStickers;
|
const res = await apiManager.invokeApiHashable('messages.getRecentStickers') as MessagesRecentStickers.messagesRecentStickers;
|
||||||
|
|
||||||
if(res._ == 'messages.recentStickers') {
|
this.saveStickers(res.stickers);
|
||||||
this.saveStickers(res.stickers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res as any;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAnimatedEmojiSticker(emoji: string) {
|
public getAnimatedEmojiSticker(emoji: string) {
|
||||||
@ -185,21 +179,13 @@ export class AppStickersManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getFeaturedStickers() {
|
public async getFeaturedStickers() {
|
||||||
const res = await apiManager.invokeApi('messages.getFeaturedStickers', {
|
const res = await apiManager.invokeApiHashable('messages.getFeaturedStickers') as MessagesFeaturedStickers.messagesFeaturedStickers;
|
||||||
hash: this.hashes.featured?.hash || 0
|
|
||||||
});
|
|
||||||
|
|
||||||
const hashed = this.hashes.featured ?? (this.hashes.featured = {});
|
res.sets.forEach(covered => {
|
||||||
if(res._ != 'messages.featuredStickersNotModified') {
|
|
||||||
hashed.hash = res.hash;
|
|
||||||
hashed.result = res.sets;
|
|
||||||
}
|
|
||||||
|
|
||||||
hashed.result.forEach(covered => {
|
|
||||||
this.saveStickerSet({set: covered.set, documents: [], packs: []}, covered.set.id);
|
this.saveStickerSet({set: covered.set, documents: [], packs: []}, covered.set.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
return hashed.result;
|
return res.sets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async toggleStickerSet(set: StickerSet.stickerSet) {
|
public async toggleStickerSet(set: StickerSet.stickerSet) {
|
||||||
@ -231,20 +217,13 @@ export class AppStickersManager {
|
|||||||
|
|
||||||
public async searchStickerSets(query: string, excludeFeatured = true) {
|
public async searchStickerSets(query: string, excludeFeatured = true) {
|
||||||
const flags = excludeFeatured ? 1 : 0;
|
const flags = excludeFeatured ? 1 : 0;
|
||||||
const res = await apiManager.invokeApi('messages.searchStickerSets', {
|
const res = await apiManager.invokeApiHashable('messages.searchStickerSets', {
|
||||||
flags,
|
flags,
|
||||||
exclude_featured: excludeFeatured || undefined,
|
exclude_featured: excludeFeatured || undefined,
|
||||||
q: query,
|
q: query
|
||||||
hash: this.hashes.search[query]?.hash || 0
|
}) as MessagesFoundStickerSets.messagesFoundStickerSets;
|
||||||
});
|
|
||||||
|
|
||||||
const hashed = this.hashes.search[query] ?? (this.hashes.search[query] = {});
|
res.sets.forEach(covered => {
|
||||||
if(res._ != 'messages.foundStickerSetsNotModified') {
|
|
||||||
hashed.hash = res.hash;
|
|
||||||
hashed.result = res.sets;
|
|
||||||
}
|
|
||||||
|
|
||||||
hashed.result.forEach(covered => {
|
|
||||||
this.saveStickerSet({set: covered.set, documents: [], packs: []}, covered.set.id);
|
this.saveStickerSet({set: covered.set, documents: [], packs: []}, covered.set.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -252,12 +231,60 @@ export class AppStickersManager {
|
|||||||
for(let id in this.stickerSets) {
|
for(let id in this.stickerSets) {
|
||||||
const {set} = this.stickerSets[id];
|
const {set} = this.stickerSets[id];
|
||||||
|
|
||||||
if(set.title.toLowerCase().includes(query.toLowerCase()) && !hashed.result.find(c => c.set.id == set.id)) {
|
if(set.title.toLowerCase().includes(query.toLowerCase()) && !res.sets.find(c => c.set.id == set.id)) {
|
||||||
foundSaved.push({_: 'stickerSetCovered', set, cover: null});
|
foundSaved.push({_: 'stickerSetCovered', set, cover: null});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashed.result.concat(foundSaved);
|
return res.sets.concat(foundSaved);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAllStickers() {
|
||||||
|
return apiManager.invokeApiHashable('messages.getAllStickers');
|
||||||
|
}
|
||||||
|
|
||||||
|
public preloadStickerSets() {
|
||||||
|
return this.getAllStickers().then(allStickers => {
|
||||||
|
return Promise.all((allStickers as MessagesAllStickers.messagesAllStickers).sets.map(set => this.getStickerSet(set)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getStickersByEmoticon(emoticon: string) {
|
||||||
|
if(this.getStickersByEmoticonsPromises[emoticon]) return this.getStickersByEmoticonsPromises[emoticon];
|
||||||
|
|
||||||
|
return this.getStickersByEmoticonsPromises[emoticon] = Promise.all([
|
||||||
|
apiManager.invokeApiHashable('messages.getStickers', {
|
||||||
|
emoticon
|
||||||
|
}),
|
||||||
|
this.preloadStickerSets(),
|
||||||
|
this.getRecentStickers()
|
||||||
|
]).then(([messagesStickers, installedSets, recentStickers]) => {
|
||||||
|
const foundStickers = (messagesStickers as MessagesStickers.messagesStickers).stickers.map(sticker => appDocsManager.saveDoc(sticker));
|
||||||
|
const cachedStickersAnimated: Document.document[] = [], cachedStickersStatic: Document.document[] = [];
|
||||||
|
|
||||||
|
//console.log('getStickersByEmoticon', messagesStickers, installedSets, recentStickers);
|
||||||
|
|
||||||
|
const iteratePacks = (packs: StickerPack.stickerPack[]) => {
|
||||||
|
for(const pack of packs) {
|
||||||
|
if(pack.emoticon.includes(emoticon)) {
|
||||||
|
for(const docID of pack.documents) {
|
||||||
|
const doc = appDocsManager.getDoc(docID);
|
||||||
|
(doc.animated ? cachedStickersAnimated : cachedStickersStatic).push(doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
iteratePacks(recentStickers.packs);
|
||||||
|
|
||||||
|
for(const set of installedSets) {
|
||||||
|
iteratePacks(set.packs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const stickers = [...new Set(cachedStickersAnimated.concat(cachedStickersStatic, foundStickers))];
|
||||||
|
|
||||||
|
return stickers;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,15 @@ type Task = {
|
|||||||
|
|
||||||
const USEWORKERASWORKER = true;
|
const USEWORKERASWORKER = true;
|
||||||
|
|
||||||
|
type HashResult = {
|
||||||
|
hash: number,
|
||||||
|
result: any
|
||||||
|
};
|
||||||
|
|
||||||
|
type HashOptions = {
|
||||||
|
[queryJSON: string]: HashResult
|
||||||
|
};
|
||||||
|
|
||||||
export class ApiManagerProxy extends CryptoWorkerMethods {
|
export class ApiManagerProxy extends CryptoWorkerMethods {
|
||||||
public worker: Worker;
|
public worker: Worker;
|
||||||
public postMessage: (...args: any[]) => void;
|
public postMessage: (...args: any[]) => void;
|
||||||
@ -41,6 +50,8 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
|
|
||||||
private log = logger('API-PROXY');
|
private log = logger('API-PROXY');
|
||||||
|
|
||||||
|
private hashes: {[method: string]: HashOptions} = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.log('constructor');
|
this.log('constructor');
|
||||||
@ -230,6 +241,36 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
return this.performTaskWorker('invokeApi', method, params, o);
|
return this.performTaskWorker('invokeApi', method, params, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public invokeApiHashable<T extends keyof MethodDeclMap>(method: T, params: Omit<MethodDeclMap[T]['req'], 'hash'> = {} as any, options: InvokeApiOptions = {}): Promise<MethodDeclMap[T]['res']> {
|
||||||
|
//console.log('will invokeApi:', method, params, options);
|
||||||
|
|
||||||
|
const queryJSON = JSON.stringify(params);
|
||||||
|
let cached: HashResult;
|
||||||
|
if(this.hashes[method]) {
|
||||||
|
cached = this.hashes[method][queryJSON];
|
||||||
|
if(cached) {
|
||||||
|
(params as any).hash = cached.hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.performTaskWorker('invokeApi', method, params, options).then((result: any) => {
|
||||||
|
if(result._.includes('NotModified')) {
|
||||||
|
//this.log.warn('NotModified saved!', method, queryJSON);
|
||||||
|
return cached.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.hash) {
|
||||||
|
if(!this.hashes[method]) this.hashes[method] = {};
|
||||||
|
this.hashes[method][queryJSON] = {
|
||||||
|
hash: result.hash,
|
||||||
|
result: result
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public setBaseDcID(dcID: number) {
|
public setBaseDcID(dcID: number) {
|
||||||
return this.performTaskWorker('setBaseDcID', dcID);
|
return this.performTaskWorker('setBaseDcID', dcID);
|
||||||
}
|
}
|
||||||
|
@ -768,7 +768,7 @@ $chat-helper-size: 39px;
|
|||||||
|
|
||||||
.btn-menu {
|
.btn-menu {
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
right: -8px;
|
right: -11px;
|
||||||
bottom: calc(100% + 16px);
|
bottom: calc(100% + 16px);
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
@ -1420,3 +1420,45 @@ $chat-helper-size: 39px;
|
|||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stickers-helper {
|
||||||
|
position: absolute !important;
|
||||||
|
bottom: calc(100% + 10px);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity .2s ease-in-out;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
|
> .scrollable {
|
||||||
|
position: relative;
|
||||||
|
max-height: 220px;
|
||||||
|
min-height: var(--esg-sticker-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-stickers {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-sticker {
|
||||||
|
position: relative;
|
||||||
|
width: var(--esg-sticker-size);
|
||||||
|
height: var(--esg-sticker-size);
|
||||||
|
margin: 5px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.is-visible) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-visible {
|
||||||
|
&:not(.backwards) {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,19 +12,19 @@
|
|||||||
@include respond-to(esg-top) {
|
@include respond-to(esg-top) {
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
left: 1rem;
|
left: 1rem;
|
||||||
bottom: calc(85px);
|
bottom: 85px;
|
||||||
width: 420px !important;
|
width: 420px !important;
|
||||||
height: 420px;
|
height: 420px;
|
||||||
max-height: 420px;
|
max-height: 420px;
|
||||||
box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, .14);
|
box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, .14);
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
transition: all .2s ease-out;
|
transition: transform .2s ease-out;
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
transform-origin: 0 100%;
|
transform-origin: 0 100%;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
transition: all .2s ease-in;
|
transition: transform .2s ease-in;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,29 +225,7 @@
|
|||||||
grid-column-gap: 1px;
|
grid-column-gap: 1px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
> .grid-item {
|
|
||||||
html.no-touch &:hover {
|
|
||||||
border-radius: 12px;
|
|
||||||
background-color: var(--color-gray-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* &:nth-child(5n+5) {
|
|
||||||
margin-right: 0;
|
|
||||||
} */
|
|
||||||
|
|
||||||
> img, > .rlottie {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
> img {
|
|
||||||
animation: fade-in-opacity .2s ease forwards;
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,6 +613,7 @@
|
|||||||
&-sticker {
|
&-sticker {
|
||||||
width: 68px;
|
width: 68px;
|
||||||
height: 68px;
|
height: 68px;
|
||||||
|
position: relative;
|
||||||
//padding: 0 5px;
|
//padding: 0 5px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -721,6 +721,38 @@ img.emoji {
|
|||||||
fill: rgba(0, 0, 0, .08);
|
fill: rgba(0, 0, 0, .08);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.super-stickers {
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, var(--esg-sticker-size)); // 64px
|
||||||
|
grid-column-gap: 1px;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.super-sticker {
|
||||||
|
html.no-touch &:hover {
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: var(--color-gray-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* &:nth-child(5n+5) {
|
||||||
|
margin-right: 0;
|
||||||
|
} */
|
||||||
|
|
||||||
|
> img, > .rlottie {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
> img {
|
||||||
|
animation: fade-in-opacity .2s ease forwards;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.fade-in-transition {
|
.fade-in-transition {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity .2s ease;
|
transition: opacity .2s ease;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user