some fixes
This commit is contained in:
parent
df814f2a68
commit
5aa64caecc
@ -112,6 +112,7 @@ import paymentsWrapCurrencyAmount from '../../helpers/paymentsWrapCurrencyAmount
|
|||||||
import PopupPayment from '../popups/payment';
|
import PopupPayment from '../popups/payment';
|
||||||
import isInDOM from '../../helpers/dom/isInDOM';
|
import isInDOM from '../../helpers/dom/isInDOM';
|
||||||
import getStickerEffectThumb from '../../lib/appManagers/utils/stickers/getStickerEffectThumb';
|
import getStickerEffectThumb from '../../lib/appManagers/utils/stickers/getStickerEffectThumb';
|
||||||
|
import attachStickerViewerListeners from '../stickerViewer';
|
||||||
|
|
||||||
const USE_MEDIA_TAILS = false;
|
const USE_MEDIA_TAILS = false;
|
||||||
const IGNORE_ACTIONS: Set<Message.messageService['action']['_']> = new Set([
|
const IGNORE_ACTIONS: Set<Message.messageService['action']['_']> = new Set([
|
||||||
@ -667,6 +668,7 @@ export default class ChatBubbles {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
attachStickerViewerListeners({listenTo: this.scrollable.container, listenerSetter: this.listenerSetter});
|
||||||
attachClickEvent(this.scrollable.container, this.onBubblesClick, {listenerSetter: this.listenerSetter});
|
attachClickEvent(this.scrollable.container, this.onBubblesClick, {listenerSetter: this.listenerSetter});
|
||||||
// this.listenerSetter.add(this.bubblesContainer)('click', this.onBubblesClick/* , {capture: true, passive: false} */);
|
// this.listenerSetter.add(this.bubblesContainer)('click', this.onBubblesClick/* , {capture: true, passive: false} */);
|
||||||
|
|
||||||
@ -902,7 +904,7 @@ export default class ChatBubbles {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {
|
this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {
|
||||||
if(dialogs[this.peerId]) {
|
if(dialogs.has(this.peerId)) {
|
||||||
this.chat.input.setUnreadCount();
|
this.chat.input.setUnreadCount();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -735,7 +735,7 @@ export default class ChatInput {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {
|
this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {
|
||||||
if(dialogs[this.chat.peerId]) {
|
if(dialogs.has(this.chat.peerId)) {
|
||||||
if(this.startParam === BOT_START_PARAM) {
|
if(this.startParam === BOT_START_PARAM) {
|
||||||
this.setStartParam();
|
this.setStartParam();
|
||||||
} else { // updateNewMessage comes earlier than dialog appers
|
} else { // updateNewMessage comes earlier than dialog appers
|
||||||
|
@ -105,6 +105,7 @@ export class ChatReactionsMenu {
|
|||||||
callbackify(result, (reactions) => {
|
callbackify(result, (reactions) => {
|
||||||
if(!middleware() || !reactions.length) return;
|
if(!middleware() || !reactions.length) return;
|
||||||
reactions.forEach((reaction) => {
|
reactions.forEach((reaction) => {
|
||||||
|
if(reaction.pFlags.premium && !rootScope.premium) return;
|
||||||
this.renderReaction(reaction);
|
this.renderReaction(reaction);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ListenerSetter from '../../helpers/listenerSetter';
|
||||||
import mediaSizes from '../../helpers/mediaSizes';
|
import mediaSizes from '../../helpers/mediaSizes';
|
||||||
import preloadAnimatedEmojiSticker from '../../helpers/preloadAnimatedEmojiSticker';
|
import preloadAnimatedEmojiSticker from '../../helpers/preloadAnimatedEmojiSticker';
|
||||||
import {MyDocument} from '../../lib/appManagers/appDocsManager';
|
import {MyDocument} from '../../lib/appManagers/appDocsManager';
|
||||||
@ -14,6 +15,7 @@ import {EmoticonsDropdown} from '../emoticonsDropdown';
|
|||||||
import {SuperStickerRenderer} from '../emoticonsDropdown/tabs/stickers';
|
import {SuperStickerRenderer} from '../emoticonsDropdown/tabs/stickers';
|
||||||
import LazyLoadQueue from '../lazyLoadQueue';
|
import LazyLoadQueue from '../lazyLoadQueue';
|
||||||
import Scrollable from '../scrollable';
|
import Scrollable from '../scrollable';
|
||||||
|
import attachStickerViewerListeners from '../stickerViewer';
|
||||||
import AutocompleteHelper from './autocompleteHelper';
|
import AutocompleteHelper from './autocompleteHelper';
|
||||||
import AutocompleteHelperController from './autocompleteHelperController';
|
import AutocompleteHelperController from './autocompleteHelperController';
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ export default class StickersHelper extends AutocompleteHelper {
|
|||||||
private superStickerRenderer: SuperStickerRenderer;
|
private superStickerRenderer: SuperStickerRenderer;
|
||||||
private lazyLoadQueue: LazyLoadQueue;
|
private lazyLoadQueue: LazyLoadQueue;
|
||||||
private onChangeScreen: () => void;
|
private onChangeScreen: () => void;
|
||||||
|
private listenerSetter: ListenerSetter;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
appendTo: HTMLElement,
|
appendTo: HTMLElement,
|
||||||
@ -52,6 +55,9 @@ export default class StickersHelper extends AutocompleteHelper {
|
|||||||
if(this.onChangeScreen) {
|
if(this.onChangeScreen) {
|
||||||
mediaSizes.removeEventListener('changeScreen', this.onChangeScreen);
|
mediaSizes.removeEventListener('changeScreen', this.onChangeScreen);
|
||||||
this.onChangeScreen = undefined;
|
this.onChangeScreen = undefined;
|
||||||
|
|
||||||
|
this.listenerSetter.removeAll();
|
||||||
|
this.listenerSetter = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
rootScope.dispatchEvent('choosing_sticker', false);
|
rootScope.dispatchEvent('choosing_sticker', false);
|
||||||
@ -105,6 +111,9 @@ export default class StickersHelper extends AutocompleteHelper {
|
|||||||
this.list.style.width = width + 'px';
|
this.list.style.width = width + 'px';
|
||||||
};
|
};
|
||||||
mediaSizes.addEventListener('changeScreen', this.onChangeScreen);
|
mediaSizes.addEventListener('changeScreen', this.onChangeScreen);
|
||||||
|
|
||||||
|
this.listenerSetter = new ListenerSetter();
|
||||||
|
attachStickerViewerListeners({listenTo: this.container, listenerSetter: this.listenerSetter});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onChangeScreen();
|
this.onChangeScreen();
|
||||||
|
@ -32,6 +32,8 @@ import createStickersContextMenu from '../../../helpers/dom/createStickersContex
|
|||||||
import findUpAsChild from '../../../helpers/dom/findUpAsChild';
|
import findUpAsChild from '../../../helpers/dom/findUpAsChild';
|
||||||
import forEachReverse from '../../../helpers/array/forEachReverse';
|
import forEachReverse from '../../../helpers/array/forEachReverse';
|
||||||
import {MTAppConfig} from '../../../lib/mtproto/appConfig';
|
import {MTAppConfig} from '../../../lib/mtproto/appConfig';
|
||||||
|
import attachStickerViewerListeners from '../../stickerViewer';
|
||||||
|
import ListenerSetter from '../../../helpers/listenerSetter';
|
||||||
|
|
||||||
export class SuperStickerRenderer {
|
export class SuperStickerRenderer {
|
||||||
public lazyLoadQueue: LazyLoadQueueRepeat;
|
public lazyLoadQueue: LazyLoadQueueRepeat;
|
||||||
@ -567,6 +569,8 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
|
|
||||||
emoticonsDropdown.addEventListener('opened', resizeCategories);
|
emoticonsDropdown.addEventListener('opened', resizeCategories);
|
||||||
|
|
||||||
|
attachStickerViewerListeners({listenTo: this.content, listenerSetter: new ListenerSetter()});
|
||||||
|
|
||||||
createStickersContextMenu({
|
createStickersContextMenu({
|
||||||
listenTo: this.content,
|
listenTo: this.content,
|
||||||
verifyRecent: (target) => !!findUpAsChild(target, this.categories['recent'].elements.items),
|
verifyRecent: (target) => !!findUpAsChild(target, this.categories['recent'].elements.items),
|
||||||
|
@ -21,6 +21,7 @@ import {toastNew} from '../toast';
|
|||||||
import setInnerHTML from '../../helpers/dom/setInnerHTML';
|
import setInnerHTML from '../../helpers/dom/setInnerHTML';
|
||||||
import wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';
|
import wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';
|
||||||
import createStickersContextMenu from '../../helpers/dom/createStickersContextMenu';
|
import createStickersContextMenu from '../../helpers/dom/createStickersContextMenu';
|
||||||
|
import attachStickerViewerListeners from '../stickerViewer';
|
||||||
|
|
||||||
const ANIMATION_GROUP: AnimationItemGroup = 'STICKERS-POPUP';
|
const ANIMATION_GROUP: AnimationItemGroup = 'STICKERS-POPUP';
|
||||||
|
|
||||||
@ -64,6 +65,8 @@ export default class PopupStickers extends PopupElement {
|
|||||||
isStickerPack: true
|
isStickerPack: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
attachStickerViewerListeners({listenTo: this.stickersDiv, listenerSetter: this.listenerSetter});
|
||||||
|
|
||||||
this.loadStickerSet();
|
this.loadStickerSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,15 +229,16 @@ export default class ProgressivePreloader {
|
|||||||
this.attachPromise(promise);
|
this.attachPromise(promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let useRafs = 0;
|
||||||
if(this.detached || this.preloader.parentElement !== elem) {
|
if(this.detached || this.preloader.parentElement !== elem) {
|
||||||
const useRafs = isInDOM(this.preloader) ? 1 : 2;
|
useRafs = isInDOM(this.preloader) ? 1 : 2;
|
||||||
if(this.preloader.parentElement !== elem) {
|
if(this.preloader.parentElement !== elem) {
|
||||||
elem[this.attachMethod](this.preloader);
|
elem[this.attachMethod](this.preloader);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetTransition(this.preloader, 'is-visible', true, TRANSITION_TIME, undefined, useRafs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetTransition(this.preloader, 'is-visible', true, TRANSITION_TIME, undefined, useRafs);
|
||||||
|
|
||||||
if(this.cancelable && reset) {
|
if(this.cancelable && reset) {
|
||||||
this.setProgress(0);
|
this.setProgress(0);
|
||||||
}
|
}
|
||||||
@ -253,7 +254,7 @@ export default class ProgressivePreloader {
|
|||||||
|
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
if(this.preloader && this.preloader.parentElement) {
|
if(this.preloader?.parentElement) {
|
||||||
/* setTimeout(() => */// fastRaf(() => {
|
/* setTimeout(() => */// fastRaf(() => {
|
||||||
/* if(!this.detached) return;
|
/* if(!this.detached) return;
|
||||||
this.detached = true; */
|
this.detached = true; */
|
||||||
|
@ -19,6 +19,7 @@ import {attachClickEvent} from '../../../helpers/dom/clickEvent';
|
|||||||
import forEachReverse from '../../../helpers/array/forEachReverse';
|
import forEachReverse from '../../../helpers/array/forEachReverse';
|
||||||
import setInnerHTML from '../../../helpers/dom/setInnerHTML';
|
import setInnerHTML from '../../../helpers/dom/setInnerHTML';
|
||||||
import wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';
|
import wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';
|
||||||
|
import attachStickerViewerListeners from '../../stickerViewer';
|
||||||
|
|
||||||
export default class AppStickersTab extends SliderSuperTab {
|
export default class AppStickersTab extends SliderSuperTab {
|
||||||
private inputSearch: InputSearch;
|
private inputSearch: InputSearch;
|
||||||
@ -41,6 +42,8 @@ export default class AppStickersTab extends SliderSuperTab {
|
|||||||
this.setsDiv.classList.add('sticker-sets');
|
this.setsDiv.classList.add('sticker-sets');
|
||||||
this.scrollable.append(this.setsDiv);
|
this.scrollable.append(this.setsDiv);
|
||||||
|
|
||||||
|
attachStickerViewerListeners({listenTo: this.setsDiv, listenerSetter: this.listenerSetter});
|
||||||
|
|
||||||
attachClickEvent(this.setsDiv, (e) => {
|
attachClickEvent(this.setsDiv, (e) => {
|
||||||
const sticker = findUpClassName(e.target, 'sticker-set-sticker');
|
const sticker = findUpClassName(e.target, 'sticker-set-sticker');
|
||||||
if(sticker) {
|
if(sticker) {
|
||||||
|
303
src/components/stickerViewer.ts
Normal file
303
src/components/stickerViewer.ts
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
* https://github.com/morethanwords/tweb
|
||||||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
import IS_TOUCH_SUPPORTED from '../environment/touchSupport';
|
||||||
|
import cancelEvent from '../helpers/dom/cancelEvent';
|
||||||
|
import {simulateClickEvent, attachClickEvent} from '../helpers/dom/clickEvent';
|
||||||
|
import findUpClassName from '../helpers/dom/findUpClassName';
|
||||||
|
import getVisibleRect from '../helpers/dom/getVisibleRect';
|
||||||
|
import ListenerSetter from '../helpers/listenerSetter';
|
||||||
|
import {makeMediaSize} from '../helpers/mediaSize';
|
||||||
|
import {getMiddleware} from '../helpers/middleware';
|
||||||
|
import {doubleRaf} from '../helpers/schedulers';
|
||||||
|
import pause from '../helpers/schedulers/pause';
|
||||||
|
import windowSize from '../helpers/windowSize';
|
||||||
|
import {MyDocument} from '../lib/appManagers/appDocsManager';
|
||||||
|
import getStickerEffectThumb from '../lib/appManagers/utils/stickers/getStickerEffectThumb';
|
||||||
|
import wrapEmojiText from '../lib/richTextProcessor/wrapEmojiText';
|
||||||
|
import lottieLoader from '../lib/rlottie/lottieLoader';
|
||||||
|
import RLottiePlayer from '../lib/rlottie/rlottiePlayer';
|
||||||
|
import rootScope from '../lib/rootScope';
|
||||||
|
import animationIntersector, {AnimationItemGroup} from './animationIntersector';
|
||||||
|
import SetTransition from './singleTransition';
|
||||||
|
import {wrapSticker} from './wrappers';
|
||||||
|
import {STICKER_EFFECT_MULTIPLIER} from './wrappers/sticker';
|
||||||
|
|
||||||
|
let hasViewer = false;
|
||||||
|
export default function attachStickerViewerListeners({listenTo, listenerSetter}: {
|
||||||
|
listenerSetter: ListenerSetter,
|
||||||
|
listenTo: HTMLElement
|
||||||
|
}) {
|
||||||
|
if(IS_TOUCH_SUPPORTED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const managers = rootScope.managers;
|
||||||
|
const findClassName = 'media-sticker-wrapper';
|
||||||
|
|
||||||
|
listenerSetter.add(listenTo)('mousedown', (e) => {
|
||||||
|
if(hasViewer || e.buttons > 1 || e.button !== 0) return;
|
||||||
|
let mediaContainer = findUpClassName(e.target, findClassName);
|
||||||
|
if(!mediaContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// const img: HTMLImageElement = mediaContainer.querySelector('img.media-sticker');
|
||||||
|
|
||||||
|
const docId = mediaContainer.dataset.docId;
|
||||||
|
if(!docId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const className = 'sticker-viewer';
|
||||||
|
const group: AnimationItemGroup = 'STICKER-VIEWER';
|
||||||
|
const openDuration = 200;
|
||||||
|
const switchDuration = 200;
|
||||||
|
const previousGroup = animationIntersector.getOnlyOnePlayableGroup();
|
||||||
|
const _middleware = getMiddleware();
|
||||||
|
let container: HTMLElement, previousTransformer: HTMLElement;
|
||||||
|
|
||||||
|
const doThatSticker = async({mediaContainer, doc, middleware, lockGroups, isSwitching}: {
|
||||||
|
mediaContainer: HTMLElement,
|
||||||
|
doc: MyDocument,
|
||||||
|
middleware: () => boolean,
|
||||||
|
lockGroups?: boolean,
|
||||||
|
isSwitching?: boolean
|
||||||
|
}) => {
|
||||||
|
const effectThumb = getStickerEffectThumb(doc);
|
||||||
|
const mediaRect: DOMRect = mediaContainer.getBoundingClientRect();
|
||||||
|
const s = makeMediaSize(doc.w, doc.h);
|
||||||
|
const size = effectThumb ? 280 : 360;
|
||||||
|
const boxSize = makeMediaSize(size, size);
|
||||||
|
const fitted = mediaRect.width === mediaRect.height ? boxSize : s.aspectFitted(boxSize);
|
||||||
|
|
||||||
|
const bubble = findUpClassName(mediaContainer, 'bubble');
|
||||||
|
const isOut = bubble ? bubble.classList.contains('is-out') : true;
|
||||||
|
|
||||||
|
const transformer = document.createElement('div');
|
||||||
|
transformer.classList.add(className + '-transformer');
|
||||||
|
|
||||||
|
const stickerContainer = document.createElement('div');
|
||||||
|
stickerContainer.classList.add(className + '-sticker');
|
||||||
|
/* transformer.style.width = */stickerContainer.style.width = fitted.width + 'px';
|
||||||
|
/* transformer.style.height = */stickerContainer.style.height = fitted.height + 'px';
|
||||||
|
|
||||||
|
const stickerEmoji = document.createElement('div');
|
||||||
|
stickerEmoji.classList.add(className + '-emoji');
|
||||||
|
stickerEmoji.append(wrapEmojiText(doc.stickerEmojiRaw));
|
||||||
|
|
||||||
|
if(effectThumb) {
|
||||||
|
const margin = (size * STICKER_EFFECT_MULTIPLIER - size) / 3 * (isOut ? 1 : -1);
|
||||||
|
transformer.classList.add('has-effect');
|
||||||
|
// const property = `--margin-${isOut ? 'right' : 'left'}`;
|
||||||
|
// stickerContainer.style.setProperty(property, `${margin * 2}px`);
|
||||||
|
transformer.style.setProperty('--translateX', `${margin}px`);
|
||||||
|
stickerEmoji.style.setProperty('--translateX', `${-margin}px`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const overflowElement = findUpClassName(mediaContainer, 'scrollable');
|
||||||
|
const visibleRect = getVisibleRect(mediaContainer, overflowElement, true, mediaRect);
|
||||||
|
if(visibleRect.overflow.vertical || visibleRect.overflow.horizontal) {
|
||||||
|
stickerContainer.classList.add('is-overflow');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(img) {
|
||||||
|
// const ratio = img.naturalWidth / img.naturalHeight;
|
||||||
|
// if((mediaRect.width / mediaRect.height).toFixed(1) !== ratio.toFixed(1)) {
|
||||||
|
|
||||||
|
// mediaRect = mediaRect.toJSON();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const rect = mediaContainer.getBoundingClientRect();
|
||||||
|
const scaleX = rect.width / fitted.width;
|
||||||
|
const scaleY = rect.height / fitted.height;
|
||||||
|
const transformX = rect.left - (windowSize.width - rect.width) / 2;
|
||||||
|
const transformY = rect.top - (windowSize.height - rect.height) / 2;
|
||||||
|
transformer.style.transform = `translate(${transformX}px, ${transformY}px) scale(${scaleX}, ${scaleY})`;
|
||||||
|
if(isSwitching) transformer.classList.add('is-switching');
|
||||||
|
transformer.append(stickerContainer, stickerEmoji);
|
||||||
|
container.append(transformer);
|
||||||
|
|
||||||
|
const player = await wrapSticker({
|
||||||
|
doc,
|
||||||
|
div: stickerContainer,
|
||||||
|
group,
|
||||||
|
width: fitted.width,
|
||||||
|
height: fitted.height,
|
||||||
|
play: false,
|
||||||
|
loop: true,
|
||||||
|
middleware,
|
||||||
|
managers,
|
||||||
|
needFadeIn: false,
|
||||||
|
isOut,
|
||||||
|
withThumb: false,
|
||||||
|
relativeEffect: true,
|
||||||
|
loopEffect: true
|
||||||
|
}).then(({render}) => render);
|
||||||
|
if(!middleware()) return;
|
||||||
|
|
||||||
|
if(!container.parentElement) {
|
||||||
|
document.body.append(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstFramePromise = player instanceof RLottiePlayer ?
|
||||||
|
new Promise<void>((resolve) => player.addEventListener('firstFrame', resolve, {once: true})) :
|
||||||
|
Promise.resolve();
|
||||||
|
await Promise.all([firstFramePromise, doubleRaf()]);
|
||||||
|
await pause(0); // ! need it because firstFrame will be called just from the loop
|
||||||
|
if(!middleware()) return;
|
||||||
|
|
||||||
|
if(lockGroups) {
|
||||||
|
animationIntersector.setOnlyOnePlayableGroup(group);
|
||||||
|
animationIntersector.checkAnimations(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(player instanceof RLottiePlayer) {
|
||||||
|
const prevPlayer = lottieLoader.getAnimation(mediaContainer);
|
||||||
|
player.curFrame = prevPlayer.curFrame;
|
||||||
|
player.play();
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
let i = 0;
|
||||||
|
const c = () => {
|
||||||
|
if(++i === 2) {
|
||||||
|
resolve();
|
||||||
|
player.removeEventListener('enterFrame', c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
player.addEventListener('enterFrame', c);
|
||||||
|
});
|
||||||
|
player.pause();
|
||||||
|
} else if(player instanceof HTMLVideoElement) {
|
||||||
|
player.currentTime = (mediaContainer.querySelector('video') as HTMLVideoElement).currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ready: () => {
|
||||||
|
if(player instanceof RLottiePlayer || player instanceof HTMLVideoElement) {
|
||||||
|
player.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(effectThumb) {
|
||||||
|
simulateClickEvent(stickerContainer);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transformer
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const timeout = window.setTimeout(async() => {
|
||||||
|
document.removeEventListener('mousemove', onMousePreMove);
|
||||||
|
|
||||||
|
container = document.createElement('div');
|
||||||
|
container.classList.add(className);
|
||||||
|
hasViewer = true;
|
||||||
|
|
||||||
|
const middleware = _middleware.get();
|
||||||
|
const doc = await managers.appDocsManager.getDoc(docId);
|
||||||
|
if(!middleware()) return;
|
||||||
|
|
||||||
|
let result: Awaited<ReturnType<typeof doThatSticker>>;
|
||||||
|
try {
|
||||||
|
result = await doThatSticker({
|
||||||
|
doc,
|
||||||
|
mediaContainer,
|
||||||
|
middleware,
|
||||||
|
lockGroups: true
|
||||||
|
});
|
||||||
|
if(!result) return;
|
||||||
|
} catch(err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {ready, transformer} = result;
|
||||||
|
|
||||||
|
previousTransformer = transformer;
|
||||||
|
|
||||||
|
SetTransition(container, 'is-visible', true, openDuration, () => {
|
||||||
|
if(!middleware()) return;
|
||||||
|
ready();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', onMouseMove);
|
||||||
|
}, 125);
|
||||||
|
|
||||||
|
const onMouseMove = async(e: MouseEvent) => {
|
||||||
|
const newMediaContainer = findUpClassName(e.target, 'media-sticker-wrapper');
|
||||||
|
if(!newMediaContainer || mediaContainer === newMediaContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const docId = newMediaContainer.dataset.docId;
|
||||||
|
if(!docId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaContainer = newMediaContainer;
|
||||||
|
_middleware.clean();
|
||||||
|
const middleware = _middleware.get();
|
||||||
|
|
||||||
|
const doc = await managers.appDocsManager.getDoc(docId);
|
||||||
|
if(!middleware()) return;
|
||||||
|
|
||||||
|
let r: Awaited<ReturnType<typeof doThatSticker>>;
|
||||||
|
try {
|
||||||
|
r = await doThatSticker({
|
||||||
|
doc,
|
||||||
|
mediaContainer,
|
||||||
|
middleware,
|
||||||
|
isSwitching: true
|
||||||
|
});
|
||||||
|
if(!r) return;
|
||||||
|
} catch(err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {ready, transformer} = r;
|
||||||
|
|
||||||
|
const _previousTransformer = previousTransformer;
|
||||||
|
SetTransition(_previousTransformer, 'is-switching', true, switchDuration, () => {
|
||||||
|
_previousTransformer.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
previousTransformer = transformer;
|
||||||
|
|
||||||
|
SetTransition(transformer, 'is-switching', false, switchDuration, () => {
|
||||||
|
if(!middleware()) return;
|
||||||
|
ready();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMousePreMove = (e: MouseEvent) => {
|
||||||
|
if(!findUpClassName(e.target, findClassName)) {
|
||||||
|
onMouseUp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = () => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
_middleware.clean();
|
||||||
|
|
||||||
|
if(container) {
|
||||||
|
SetTransition(container, 'is-visible', false, openDuration, () => {
|
||||||
|
container.remove();
|
||||||
|
animationIntersector.setOnlyOnePlayableGroup(previousGroup);
|
||||||
|
animationIntersector.checkAnimations(false);
|
||||||
|
hasViewer = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
attachClickEvent(document.body, cancelEvent, {capture: true, once: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.removeEventListener('mousemove', onMousePreMove);
|
||||||
|
document.removeEventListener('mousemove', onMouseMove);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', onMousePreMove);
|
||||||
|
document.addEventListener('mouseup', onMouseUp, {once: true});
|
||||||
|
});
|
||||||
|
}
|
@ -199,12 +199,20 @@ export default async function wrapDocument({message, withTime, fontWeight, voice
|
|||||||
|
|
||||||
let downloadDiv: HTMLElement, preloader: ProgressivePreloader = null;
|
let downloadDiv: HTMLElement, preloader: ProgressivePreloader = null;
|
||||||
const onLoad = () => {
|
const onLoad = () => {
|
||||||
|
docDiv.classList.remove('downloading');
|
||||||
|
|
||||||
|
if(/* !hasThumb || */(doc.size > MAX_FILE_SAVE_SIZE && !uploadFileName)) {
|
||||||
|
preloader.setManual();
|
||||||
|
preloader.attach(downloadDiv);
|
||||||
|
preloader.preloader.classList.add('manual');
|
||||||
|
preloader.setDownloadFunction(load);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(doc.size <= MAX_FILE_SAVE_SIZE) {
|
if(doc.size <= MAX_FILE_SAVE_SIZE) {
|
||||||
docDiv.classList.add('downloaded');
|
docDiv.classList.add('downloaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
docDiv.classList.remove('downloading');
|
|
||||||
|
|
||||||
if(downloadDiv) {
|
if(downloadDiv) {
|
||||||
if(downloadDiv !== icoDiv) {
|
if(downloadDiv !== icoDiv) {
|
||||||
const _downloadDiv = downloadDiv;
|
const _downloadDiv = downloadDiv;
|
||||||
|
@ -518,8 +518,7 @@ export class AppDialogsManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
rootScope.addEventListener('dialogs_multiupdate', (dialogs) => {
|
rootScope.addEventListener('dialogs_multiupdate', (dialogs) => {
|
||||||
for(const peerId in dialogs) {
|
for(const [peerId, dialog] of dialogs) {
|
||||||
const dialog = dialogs[peerId];
|
|
||||||
this.updateDialog(dialog);
|
this.updateDialog(dialog);
|
||||||
|
|
||||||
if(this.processContact) {
|
if(this.processContact) {
|
||||||
|
@ -415,267 +415,6 @@ export class AppImManager extends EventListenerBase<{
|
|||||||
}, useRafs);
|
}, useRafs);
|
||||||
};
|
};
|
||||||
|
|
||||||
let hasViewer = false;
|
|
||||||
!IS_TOUCH_SUPPORTED && document.addEventListener('mousedown', (e) => {
|
|
||||||
if(hasViewer || e.buttons > 1 || e.button !== 0) return;
|
|
||||||
let mediaContainer = findUpClassName(e.target, 'media-sticker-wrapper');
|
|
||||||
if(!mediaContainer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// const img: HTMLImageElement = mediaContainer.querySelector('img.media-sticker');
|
|
||||||
|
|
||||||
const docId = mediaContainer.dataset.docId;
|
|
||||||
if(!docId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const className = 'sticker-viewer';
|
|
||||||
const group: AnimationItemGroup = 'STICKER-VIEWER';
|
|
||||||
const openDuration = 200;
|
|
||||||
const switchDuration = 200;
|
|
||||||
const previousGroup = animationIntersector.getOnlyOnePlayableGroup();
|
|
||||||
const _middleware = getMiddleware();
|
|
||||||
let container: HTMLElement, previousTransformer: HTMLElement;
|
|
||||||
|
|
||||||
const doThatSticker = async({mediaContainer, doc, middleware, lockGroups, isSwitching}: {
|
|
||||||
mediaContainer: HTMLElement,
|
|
||||||
doc: MyDocument,
|
|
||||||
middleware: () => boolean,
|
|
||||||
lockGroups?: boolean,
|
|
||||||
isSwitching?: boolean
|
|
||||||
}) => {
|
|
||||||
const effectThumb = getStickerEffectThumb(doc);
|
|
||||||
const mediaRect: DOMRect = mediaContainer.getBoundingClientRect();
|
|
||||||
const s = makeMediaSize(doc.w, doc.h);
|
|
||||||
const size = effectThumb ? 280 : 360;
|
|
||||||
const boxSize = makeMediaSize(size, size);
|
|
||||||
const fitted = mediaRect.width === mediaRect.height ? boxSize : s.aspectFitted(boxSize);
|
|
||||||
|
|
||||||
const bubble = findUpClassName(mediaContainer, 'bubble');
|
|
||||||
const isOut = bubble ? bubble.classList.contains('is-out') : true;
|
|
||||||
|
|
||||||
const transformer = document.createElement('div');
|
|
||||||
transformer.classList.add(className + '-transformer');
|
|
||||||
|
|
||||||
const stickerContainer = document.createElement('div');
|
|
||||||
stickerContainer.classList.add(className + '-sticker');
|
|
||||||
/* transformer.style.width = */stickerContainer.style.width = fitted.width + 'px';
|
|
||||||
/* transformer.style.height = */stickerContainer.style.height = fitted.height + 'px';
|
|
||||||
|
|
||||||
const stickerEmoji = document.createElement('div');
|
|
||||||
stickerEmoji.classList.add(className + '-emoji');
|
|
||||||
stickerEmoji.append(wrapEmojiText(doc.stickerEmojiRaw));
|
|
||||||
|
|
||||||
if(effectThumb) {
|
|
||||||
const margin = (size * STICKER_EFFECT_MULTIPLIER - size) / 3 * (isOut ? 1 : -1);
|
|
||||||
transformer.classList.add('has-effect');
|
|
||||||
// const property = `--margin-${isOut ? 'right' : 'left'}`;
|
|
||||||
// stickerContainer.style.setProperty(property, `${margin * 2}px`);
|
|
||||||
transformer.style.setProperty('--translateX', `${margin}px`);
|
|
||||||
stickerEmoji.style.setProperty('--translateX', `${-margin}px`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const overflowElement = findUpClassName(mediaContainer, 'scrollable');
|
|
||||||
const visibleRect = getVisibleRect(mediaContainer, overflowElement, true, mediaRect);
|
|
||||||
if(visibleRect.overflow.vertical || visibleRect.overflow.horizontal) {
|
|
||||||
stickerContainer.classList.add('is-overflow');
|
|
||||||
}
|
|
||||||
|
|
||||||
// if(img) {
|
|
||||||
// const ratio = img.naturalWidth / img.naturalHeight;
|
|
||||||
// if((mediaRect.width / mediaRect.height).toFixed(1) !== ratio.toFixed(1)) {
|
|
||||||
|
|
||||||
// mediaRect = mediaRect.toJSON();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
const rect = mediaContainer.getBoundingClientRect();
|
|
||||||
const scaleX = rect.width / fitted.width;
|
|
||||||
const scaleY = rect.height / fitted.height;
|
|
||||||
const transformX = rect.left - (windowSize.width - rect.width) / 2;
|
|
||||||
const transformY = rect.top - (windowSize.height - rect.height) / 2;
|
|
||||||
transformer.style.transform = `translate(${transformX}px, ${transformY}px) scale(${scaleX}, ${scaleY})`;
|
|
||||||
if(isSwitching) transformer.classList.add('is-switching');
|
|
||||||
transformer.append(stickerContainer, stickerEmoji);
|
|
||||||
container.append(transformer);
|
|
||||||
|
|
||||||
const player = await wrapSticker({
|
|
||||||
doc,
|
|
||||||
div: stickerContainer,
|
|
||||||
group,
|
|
||||||
width: fitted.width,
|
|
||||||
height: fitted.height,
|
|
||||||
play: false,
|
|
||||||
loop: true,
|
|
||||||
middleware,
|
|
||||||
managers: this.managers,
|
|
||||||
needFadeIn: false,
|
|
||||||
isOut,
|
|
||||||
withThumb: false,
|
|
||||||
relativeEffect: true,
|
|
||||||
loopEffect: true
|
|
||||||
}).then(({render}) => render);
|
|
||||||
if(!middleware()) return;
|
|
||||||
|
|
||||||
if(!container.parentElement) {
|
|
||||||
document.body.append(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstFramePromise = player instanceof RLottiePlayer ?
|
|
||||||
new Promise<void>((resolve) => player.addEventListener('firstFrame', resolve, {once: true})) :
|
|
||||||
Promise.resolve();
|
|
||||||
await Promise.all([firstFramePromise, doubleRaf()]);
|
|
||||||
await pause(0); // ! need it because firstFrame will be called just from the loop
|
|
||||||
if(!middleware()) return;
|
|
||||||
|
|
||||||
if(lockGroups) {
|
|
||||||
animationIntersector.setOnlyOnePlayableGroup(group);
|
|
||||||
animationIntersector.checkAnimations(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(player instanceof RLottiePlayer) {
|
|
||||||
const prevPlayer = lottieLoader.getAnimation(mediaContainer);
|
|
||||||
player.curFrame = prevPlayer.curFrame;
|
|
||||||
player.play();
|
|
||||||
await new Promise<void>((resolve) => {
|
|
||||||
let i = 0;
|
|
||||||
const c = () => {
|
|
||||||
if(++i === 2) {
|
|
||||||
resolve();
|
|
||||||
player.removeEventListener('enterFrame', c);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
player.addEventListener('enterFrame', c);
|
|
||||||
});
|
|
||||||
player.pause();
|
|
||||||
} else if(player instanceof HTMLVideoElement) {
|
|
||||||
player.currentTime = (mediaContainer.querySelector('video') as HTMLVideoElement).currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
ready: () => {
|
|
||||||
if(player instanceof RLottiePlayer || player instanceof HTMLVideoElement) {
|
|
||||||
player.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(effectThumb) {
|
|
||||||
simulateClickEvent(stickerContainer);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
transformer
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const timeout = window.setTimeout(async() => {
|
|
||||||
document.removeEventListener('mousemove', onMousePreMove);
|
|
||||||
|
|
||||||
container = document.createElement('div');
|
|
||||||
container.classList.add(className);
|
|
||||||
hasViewer = true;
|
|
||||||
|
|
||||||
const middleware = _middleware.get();
|
|
||||||
const doc = await this.managers.appDocsManager.getDoc(docId);
|
|
||||||
if(!middleware()) return;
|
|
||||||
|
|
||||||
let result: Awaited<ReturnType<typeof doThatSticker>>;
|
|
||||||
try {
|
|
||||||
result = await doThatSticker({
|
|
||||||
doc,
|
|
||||||
mediaContainer,
|
|
||||||
middleware,
|
|
||||||
lockGroups: true
|
|
||||||
});
|
|
||||||
if(!result) return;
|
|
||||||
} catch(err) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {ready, transformer} = result;
|
|
||||||
|
|
||||||
previousTransformer = transformer;
|
|
||||||
|
|
||||||
SetTransition(container, 'is-visible', true, openDuration, () => {
|
|
||||||
if(!middleware()) return;
|
|
||||||
ready();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', onMouseMove);
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
const onMouseMove = async(e: MouseEvent) => {
|
|
||||||
const newMediaContainer = findUpClassName(e.target, 'media-sticker-wrapper');
|
|
||||||
if(!newMediaContainer || mediaContainer === newMediaContainer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const docId = newMediaContainer.dataset.docId;
|
|
||||||
if(!docId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaContainer = newMediaContainer;
|
|
||||||
_middleware.clean();
|
|
||||||
const middleware = _middleware.get();
|
|
||||||
|
|
||||||
const doc = await this.managers.appDocsManager.getDoc(docId);
|
|
||||||
if(!middleware()) return;
|
|
||||||
|
|
||||||
let r: Awaited<ReturnType<typeof doThatSticker>>;
|
|
||||||
try {
|
|
||||||
r = await doThatSticker({
|
|
||||||
doc,
|
|
||||||
mediaContainer,
|
|
||||||
middleware,
|
|
||||||
isSwitching: true
|
|
||||||
});
|
|
||||||
if(!r) return;
|
|
||||||
} catch(err) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {ready, transformer} = r;
|
|
||||||
|
|
||||||
const _previousTransformer = previousTransformer;
|
|
||||||
SetTransition(_previousTransformer, 'is-switching', true, switchDuration, () => {
|
|
||||||
_previousTransformer.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
previousTransformer = transformer;
|
|
||||||
|
|
||||||
SetTransition(transformer, 'is-switching', false, switchDuration, () => {
|
|
||||||
if(!middleware()) return;
|
|
||||||
ready();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onMousePreMove = () => {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onMouseUp = () => {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
_middleware.clean();
|
|
||||||
|
|
||||||
if(container) {
|
|
||||||
SetTransition(container, 'is-visible', false, openDuration, () => {
|
|
||||||
container.remove();
|
|
||||||
animationIntersector.setOnlyOnePlayableGroup(previousGroup);
|
|
||||||
animationIntersector.checkAnimations(false);
|
|
||||||
hasViewer = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
attachClickEvent(document.body, cancelEvent, {capture: true, once: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
document.removeEventListener('mousemove', onMouseMove);
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', onMousePreMove, {once: true});
|
|
||||||
document.addEventListener('mouseup', onMouseUp, {once: true});
|
|
||||||
});
|
|
||||||
|
|
||||||
rootScope.addEventListener('sticker_updated', ({type, faved}) => {
|
rootScope.addEventListener('sticker_updated', ({type, faved}) => {
|
||||||
if(type === 'faved') {
|
if(type === 'faved') {
|
||||||
toastNew({
|
toastNew({
|
||||||
|
@ -196,7 +196,7 @@ export class AppMessagesManager extends AppManager {
|
|||||||
public migratedToFrom: {[peerId: PeerId]: PeerId} = {};
|
public migratedToFrom: {[peerId: PeerId]: PeerId} = {};
|
||||||
|
|
||||||
private newDialogsHandlePromise: Promise<any>;
|
private newDialogsHandlePromise: Promise<any>;
|
||||||
private newDialogsToHandle: {[peerId: PeerId]: Dialog} = {};
|
private newDialogsToHandle: Map<PeerId, Dialog> = new Map();
|
||||||
public newUpdatesAfterReloadToHandle: {[peerId: PeerId]: Set<Update>} = {};
|
public newUpdatesAfterReloadToHandle: {[peerId: PeerId]: Set<Update>} = {};
|
||||||
|
|
||||||
private notificationsHandlePromise = 0;
|
private notificationsHandlePromise = 0;
|
||||||
@ -1907,7 +1907,7 @@ export class AppMessagesManager extends AppManager {
|
|||||||
|
|
||||||
let maxSeenIdIncremented = offsetDate ? true : false;
|
let maxSeenIdIncremented = offsetDate ? true : false;
|
||||||
let hasPrepend = false;
|
let hasPrepend = false;
|
||||||
const noIdsDialogs: {[peerId: PeerId]: Dialog} = {};
|
const noIdsDialogs: Map<PeerId, Dialog> = new Map();
|
||||||
const setFolderId: REAL_FOLDER_ID = folderId === GLOBAL_FOLDER_ID ? FOLDER_ID_ALL : folderId;
|
const setFolderId: REAL_FOLDER_ID = folderId === GLOBAL_FOLDER_ID ? FOLDER_ID_ALL : folderId;
|
||||||
const saveGlobalOffset = folderId === GLOBAL_FOLDER_ID;
|
const saveGlobalOffset = folderId === GLOBAL_FOLDER_ID;
|
||||||
forEachReverse((dialogsResult.dialogs as Dialog[]), (dialog) => {
|
forEachReverse((dialogsResult.dialogs as Dialog[]), (dialog) => {
|
||||||
@ -1941,16 +1941,15 @@ export class AppMessagesManager extends AppManager {
|
|||||||
// ! это может случиться, если запрос идёт не по папке 0, а по 1. почему-то read'ов нет
|
// ! это может случиться, если запрос идёт не по папке 0, а по 1. почему-то read'ов нет
|
||||||
// ! в итоге, чтобы получить 1 диалог, делается первый запрос по папке 0, потом запрос для архивных по папке 1, и потом ещё перезагрузка архивного диалога
|
// ! в итоге, чтобы получить 1 диалог, делается первый запрос по папке 0, потом запрос для архивных по папке 1, и потом ещё перезагрузка архивного диалога
|
||||||
if(!getServerMessageId(dialog.read_inbox_max_id) && !getServerMessageId(dialog.read_outbox_max_id)) {
|
if(!getServerMessageId(dialog.read_inbox_max_id) && !getServerMessageId(dialog.read_outbox_max_id)) {
|
||||||
noIdsDialogs[dialog.peerId] = dialog;
|
noIdsDialogs.set(dialog.peerId, dialog);
|
||||||
|
|
||||||
this.log.error('noIdsDialogs', dialog, params);
|
this.log.error('noIdsDialogs', dialog, params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const keys = Object.keys(noIdsDialogs);
|
if(noIdsDialogs.size) {
|
||||||
if(keys.length) {
|
|
||||||
// setTimeout(() => { // test bad situation
|
// setTimeout(() => { // test bad situation
|
||||||
const peerIds = keys.map((key) => key.toPeerId());
|
const peerIds = [...noIdsDialogs.keys()];
|
||||||
const promises = peerIds.map((peerId) => this.reloadConversation(peerId));
|
const promises = peerIds.map((peerId) => this.reloadConversation(peerId));
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', noIdsDialogs);
|
this.rootScope.dispatchEvent('dialogs_multiupdate', noIdsDialogs);
|
||||||
@ -1988,7 +1987,7 @@ export class AppMessagesManager extends AppManager {
|
|||||||
if(hasPrepend) {
|
if(hasPrepend) {
|
||||||
this.scheduleHandleNewDialogs();
|
this.scheduleHandleNewDialogs();
|
||||||
} else {
|
} else {
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', {});
|
this.rootScope.dispatchEvent('dialogs_multiupdate', new Map());
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogs = (dialogsResult as MessagesDialogs.messagesDialogsSlice).dialogs;
|
const dialogs = (dialogsResult as MessagesDialogs.messagesDialogsSlice).dialogs;
|
||||||
@ -2402,31 +2401,7 @@ export class AppMessagesManager extends AppManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.doFlushHistory(this.appPeersManager.getInputPeerById(peerId), justClear, revoke).then(() => {
|
return this.doFlushHistory(this.appPeersManager.getInputPeerById(peerId), justClear, revoke).then(() => {
|
||||||
[
|
this.flushStoragesByPeerId(peerId);
|
||||||
this.historiesStorage,
|
|
||||||
this.threadsStorage,
|
|
||||||
this.searchesStorage,
|
|
||||||
this.pinnedMessages,
|
|
||||||
this.pendingAfterMsgs,
|
|
||||||
this.pendingTopMsgs
|
|
||||||
].forEach((s) => {
|
|
||||||
delete s[peerId];
|
|
||||||
});
|
|
||||||
|
|
||||||
const m = this.needSingleMessages.get(peerId);
|
|
||||||
if(m) {
|
|
||||||
m.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
[
|
|
||||||
this.messagesStorageByPeerId,
|
|
||||||
this.scheduledMessagesStorage
|
|
||||||
].forEach((s) => {
|
|
||||||
const ss = s[peerId];
|
|
||||||
if(ss) {
|
|
||||||
ss.clear();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(justClear) {
|
if(justClear) {
|
||||||
this.rootScope.dispatchEvent('dialog_flush', {peerId, dialog: this.getDialogOnly(peerId)});
|
this.rootScope.dispatchEvent('dialog_flush', {peerId, dialog: this.getDialogOnly(peerId)});
|
||||||
@ -2445,6 +2420,38 @@ export class AppMessagesManager extends AppManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private flushStoragesByPeerId(peerId: PeerId) {
|
||||||
|
[
|
||||||
|
this.historiesStorage,
|
||||||
|
this.threadsStorage,
|
||||||
|
this.searchesStorage,
|
||||||
|
this.pinnedMessages,
|
||||||
|
this.pendingAfterMsgs,
|
||||||
|
this.pendingTopMsgs
|
||||||
|
].forEach((s) => {
|
||||||
|
delete s[peerId];
|
||||||
|
});
|
||||||
|
|
||||||
|
const needSingleMessages = this.needSingleMessages.get(peerId);
|
||||||
|
if(needSingleMessages) {
|
||||||
|
for(const [mid, promise] of needSingleMessages) {
|
||||||
|
promise.resolve(this.generateEmptyMessage(mid));
|
||||||
|
}
|
||||||
|
|
||||||
|
needSingleMessages.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
this.messagesStorageByPeerId,
|
||||||
|
this.scheduledMessagesStorage
|
||||||
|
].forEach((s) => {
|
||||||
|
const ss = s[peerId];
|
||||||
|
if(ss) {
|
||||||
|
ss.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public hidePinnedMessages(peerId: PeerId) {
|
public hidePinnedMessages(peerId: PeerId) {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.appStateManager.getState(),
|
this.appStateManager.getState(),
|
||||||
@ -3558,12 +3565,11 @@ export class AppMessagesManager extends AppManager {
|
|||||||
|
|
||||||
private handleNewDialogs = () => {
|
private handleNewDialogs = () => {
|
||||||
let newMaxSeenId = 0;
|
let newMaxSeenId = 0;
|
||||||
const obj = this.newDialogsToHandle;
|
const map = this.newDialogsToHandle;
|
||||||
for(const peerId in obj) {
|
for(const [peerId, dialog] of map) {
|
||||||
const dialog = obj[peerId];
|
|
||||||
if(!dialog) {
|
if(!dialog) {
|
||||||
this.reloadConversation(peerId.toPeerId());
|
this.reloadConversation(peerId.toPeerId());
|
||||||
delete obj[peerId];
|
map.delete(peerId);
|
||||||
} else {
|
} else {
|
||||||
this.dialogsStorage.pushDialog(dialog);
|
this.dialogsStorage.pushDialog(dialog);
|
||||||
if(!this.appPeersManager.isChannel(peerId.toPeerId())) {
|
if(!this.appPeersManager.isChannel(peerId.toPeerId())) {
|
||||||
@ -3578,13 +3584,13 @@ export class AppMessagesManager extends AppManager {
|
|||||||
this.incrementMaxSeenId(newMaxSeenId);
|
this.incrementMaxSeenId(newMaxSeenId);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', obj);
|
this.rootScope.dispatchEvent('dialogs_multiupdate', map);
|
||||||
this.newDialogsToHandle = {};
|
this.newDialogsToHandle.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
public scheduleHandleNewDialogs(peerId?: PeerId, dialog?: Dialog) {
|
public scheduleHandleNewDialogs(peerId?: PeerId, dialog?: Dialog) {
|
||||||
if(peerId !== undefined) {
|
if(peerId !== undefined) {
|
||||||
this.newDialogsToHandle[peerId] = dialog;
|
this.newDialogsToHandle.set(peerId, dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.newDialogsHandlePromise) return this.newDialogsHandlePromise;
|
if(this.newDialogsHandlePromise) return this.newDialogsHandlePromise;
|
||||||
@ -4263,7 +4269,7 @@ export class AppMessagesManager extends AppManager {
|
|||||||
|
|
||||||
releaseUnreadCount();
|
releaseUnreadCount();
|
||||||
this.dialogsStorage.setDialogToState(dialog);
|
this.dialogsStorage.setDialogToState(dialog);
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', {[peerId]: dialog});
|
this.rootScope.dispatchEvent('dialogs_multiupdate', new Map([[peerId, dialog]]));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4321,10 +4327,8 @@ export class AppMessagesManager extends AppManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(isTopMessage || (message as Message.message).grouped_id) {
|
if(isTopMessage || (message as Message.message).grouped_id) {
|
||||||
const updatedDialogs: {[peerId: PeerId]: Dialog} = {};
|
|
||||||
updatedDialogs[peerId] = dialog;
|
|
||||||
this.dialogsStorage.setDialogToState(dialog);
|
this.dialogsStorage.setDialogToState(dialog);
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', updatedDialogs);
|
this.rootScope.dispatchEvent('dialogs_multiupdate', new Map([[peerId, dialog]]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -4599,9 +4603,7 @@ export class AppMessagesManager extends AppManager {
|
|||||||
private onUpdateChannelReload = (update: Update.updateChannelReload) => {
|
private onUpdateChannelReload = (update: Update.updateChannelReload) => {
|
||||||
const peerId = update.channel_id.toPeerId(true);
|
const peerId = update.channel_id.toPeerId(true);
|
||||||
|
|
||||||
this.dialogsStorage.dropDialog(peerId);
|
this.flushStoragesByPeerId(peerId);
|
||||||
|
|
||||||
delete this.historiesStorage[peerId];
|
|
||||||
this.reloadConversation(peerId).then(() => {
|
this.reloadConversation(peerId).then(() => {
|
||||||
this.rootScope.dispatchEvent('history_reload', peerId);
|
this.rootScope.dispatchEvent('history_reload', peerId);
|
||||||
});
|
});
|
||||||
@ -5651,9 +5653,7 @@ export class AppMessagesManager extends AppManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(this.isMessageIsTopMessage(message)) {
|
if(this.isMessageIsTopMessage(message)) {
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', {
|
this.rootScope.dispatchEvent('dialogs_multiupdate', new Map([[peerId, this.getDialogOnly(peerId)]]));
|
||||||
[peerId]: this.getDialogOnly(peerId)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import fixEmoji from '../richTextProcessor/fixEmoji';
|
|||||||
import ctx from '../../environment/ctx';
|
import ctx from '../../environment/ctx';
|
||||||
import {getEnvironment} from '../../environment/utils';
|
import {getEnvironment} from '../../environment/utils';
|
||||||
import getDocumentInput from './utils/docs/getDocumentInput';
|
import getDocumentInput from './utils/docs/getDocumentInput';
|
||||||
|
import getStickerEffectThumb from './utils/stickers/getStickerEffectThumb';
|
||||||
|
|
||||||
const CACHE_TIME = 3600e3;
|
const CACHE_TIME = 3600e3;
|
||||||
|
|
||||||
@ -673,7 +674,8 @@ export class AppStickersManager extends AppManager {
|
|||||||
const stickers = [...new Set(cachedStickersAnimated.concat(cachedStickersStatic, foundStickers))]/* .filter((doc) => !doc.animated) */;
|
const stickers = [...new Set(cachedStickersAnimated.concat(cachedStickersStatic, foundStickers))]/* .filter((doc) => !doc.animated) */;
|
||||||
|
|
||||||
forEachReverse(stickers, (sticker, idx, arr) => {
|
forEachReverse(stickers, (sticker, idx, arr) => {
|
||||||
if(sticker.sticker === 3 && !getEnvironment().IS_WEBM_SUPPORTED) {
|
if((sticker.sticker === 3 && !getEnvironment().IS_WEBM_SUPPORTED) ||
|
||||||
|
(!this.rootScope.premium && getStickerEffectThumb(sticker))) {
|
||||||
arr.splice(idx, 1);
|
arr.splice(idx, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -58,7 +58,7 @@ export type BroadcastEvents = {
|
|||||||
// 'dialog_top': Dialog,
|
// 'dialog_top': Dialog,
|
||||||
'dialog_notify_settings': Dialog,
|
'dialog_notify_settings': Dialog,
|
||||||
// 'dialog_order': {dialog: Dialog, pos: number},
|
// 'dialog_order': {dialog: Dialog, pos: number},
|
||||||
'dialogs_multiupdate': {[peerId: PeerId]: Dialog},
|
'dialogs_multiupdate': Map<PeerId, Dialog>,
|
||||||
|
|
||||||
'history_append': {storageKey: MessagesStorageKey, message: Message.message},
|
'history_append': {storageKey: MessagesStorageKey, message: Message.message},
|
||||||
'history_update': {storageKey: MessagesStorageKey, message: MyMessage, sequential?: boolean},
|
'history_update': {storageKey: MessagesStorageKey, message: MyMessage, sequential?: boolean},
|
||||||
|
@ -26,6 +26,8 @@ const downloadMap: Map<string, DownloadItem> = new Map();
|
|||||||
const DOWNLOAD_ERROR = makeError('UNKNOWN');
|
const DOWNLOAD_ERROR = makeError('UNKNOWN');
|
||||||
const DOWNLOAD_TEST = false;
|
const DOWNLOAD_TEST = false;
|
||||||
|
|
||||||
|
(self as any).downloadMap = downloadMap;
|
||||||
|
|
||||||
type A = Parameters<ServiceMessagePort<false>['addMultipleEventsListeners']>[0];
|
type A = Parameters<ServiceMessagePort<false>['addMultipleEventsListeners']>[0];
|
||||||
|
|
||||||
const events: A = {
|
const events: A = {
|
||||||
|
@ -20,7 +20,7 @@ import {getWindowClients} from '../../helpers/context';
|
|||||||
import {MessageSendPort} from '../mtproto/superMessagePort';
|
import {MessageSendPort} from '../mtproto/superMessagePort';
|
||||||
import handleDownload from './download';
|
import handleDownload from './download';
|
||||||
|
|
||||||
export const log = logger('SW', LogTypes.Error | LogTypes.Debug | LogTypes.Log | LogTypes.Warn);
|
export const log = logger('SW', LogTypes.Error | LogTypes.Debug | LogTypes.Log | LogTypes.Warn, true);
|
||||||
const ctx = self as any as ServiceWorkerGlobalScope;
|
const ctx = self as any as ServiceWorkerGlobalScope;
|
||||||
|
|
||||||
// #if !MTPROTO_SW
|
// #if !MTPROTO_SW
|
||||||
|
@ -18,7 +18,7 @@ const deferredPromises: Map<MessagePort, {[taskId: string]: CancellablePromise<M
|
|||||||
const cacheStorage = new CacheStorageController('cachedStreamChunks');
|
const cacheStorage = new CacheStorageController('cachedStreamChunks');
|
||||||
const CHUNK_TTL = 86400;
|
const CHUNK_TTL = 86400;
|
||||||
const CHUNK_CACHED_TIME_HEADER = 'Time-Cached';
|
const CHUNK_CACHED_TIME_HEADER = 'Time-Cached';
|
||||||
const USE_CACHE = false;
|
const USE_CACHE = true;
|
||||||
|
|
||||||
const clearOldChunks = () => {
|
const clearOldChunks = () => {
|
||||||
return cacheStorage.timeoutOperation((cache) => {
|
return cacheStorage.timeoutOperation((cache) => {
|
||||||
|
@ -361,16 +361,18 @@ export default class DialogsStorage extends AppManager {
|
|||||||
private setDialogIndexInFilter(dialog: Dialog, indexKey: ReturnType<typeof getDialogIndexKey>, filter: MyDialogFilter) {
|
private setDialogIndexInFilter(dialog: Dialog, indexKey: ReturnType<typeof getDialogIndexKey>, filter: MyDialogFilter) {
|
||||||
let index: number;
|
let index: number;
|
||||||
|
|
||||||
if(REAL_FOLDERS.has(filter.id)) {
|
const isRealFolder = REAL_FOLDERS.has(filter.id);
|
||||||
index = getDialogIndex(dialog, indexKey);
|
/* if(isRealFolder) {
|
||||||
} else if(this.filtersStorage.testDialogForFilter(dialog, filter)) {
|
// index = getDialogIndex(dialog, indexKey);
|
||||||
|
index = this.generateIndexForDialog(dialog, true);
|
||||||
|
} else */if(this.filtersStorage.testDialogForFilter(dialog, filter)) {
|
||||||
const pinnedIndex = filter.pinnedPeerIds.indexOf(dialog.peerId);
|
const pinnedIndex = filter.pinnedPeerIds.indexOf(dialog.peerId);
|
||||||
if(pinnedIndex !== -1) {
|
if(pinnedIndex !== -1) {
|
||||||
index = this.generateDialogIndex(this.generateDialogPinnedDateByIndex(filter.pinnedPeerIds.length - 1 - pinnedIndex), true);
|
index = this.generateDialogIndex(this.generateDialogPinnedDateByIndex(filter.pinnedPeerIds.length - 1 - pinnedIndex), true);
|
||||||
} else if(dialog.pFlags?.pinned) {
|
} else if(dialog.pFlags?.pinned || isRealFolder) {
|
||||||
index = this.generateIndexForDialog(dialog, true);
|
index = this.generateIndexForDialog(dialog, true, undefined, !isRealFolder);
|
||||||
} else {
|
} else {
|
||||||
index = getDialogIndex(dialog);
|
index = getDialogIndex(dialog) ?? this.generateIndexForDialog(dialog, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,13 +543,13 @@ export default class DialogsStorage extends AppManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public generateIndexForDialog(dialog: Dialog, justReturn = false, message?: MyMessage) {
|
public generateIndexForDialog(dialog: Dialog, justReturn?: boolean, message?: MyMessage, noPinnedOrderUpdate?: boolean) {
|
||||||
// if(!justReturn) {
|
if(!justReturn) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
let topDate = 0, isPinned: boolean;
|
let topDate = 0, isPinned: boolean;
|
||||||
if(dialog.pFlags.pinned && !justReturn) {
|
if(dialog.pFlags.pinned && !noPinnedOrderUpdate) {
|
||||||
topDate = this.generateDialogPinnedDate(dialog);
|
topDate = this.generateDialogPinnedDate(dialog);
|
||||||
isPinned = true;
|
isPinned = true;
|
||||||
} else {
|
} else {
|
||||||
@ -784,7 +786,7 @@ export default class DialogsStorage extends AppManager {
|
|||||||
|
|
||||||
// this.appMessagesManager.log('applyConversation', dialogsResult);
|
// this.appMessagesManager.log('applyConversation', dialogsResult);
|
||||||
|
|
||||||
const updatedDialogs: {[peerId: PeerId]: Dialog} = {};
|
const updatedDialogs: Map<PeerId, Dialog> = new Map();
|
||||||
(dialogsResult.dialogs as Dialog[]).forEach((dialog) => {
|
(dialogsResult.dialogs as Dialog[]).forEach((dialog) => {
|
||||||
const peerId = this.appPeersManager.getPeerId(dialog.peer);
|
const peerId = this.appPeersManager.getPeerId(dialog.peer);
|
||||||
let topMessage = dialog.top_message;
|
let topMessage = dialog.top_message;
|
||||||
@ -805,7 +807,7 @@ export default class DialogsStorage extends AppManager {
|
|||||||
|
|
||||||
if(topMessage || dialog.draft?._ === 'draftMessage') {
|
if(topMessage || dialog.draft?._ === 'draftMessage') {
|
||||||
this.saveDialog(dialog);
|
this.saveDialog(dialog);
|
||||||
updatedDialogs[peerId] = dialog;
|
updatedDialogs.set(peerId, dialog);
|
||||||
} else {
|
} else {
|
||||||
this.dropDialogWithEvent(peerId);
|
this.dropDialogWithEvent(peerId);
|
||||||
}
|
}
|
||||||
@ -823,7 +825,7 @@ export default class DialogsStorage extends AppManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(Object.keys(updatedDialogs).length) {
|
if(updatedDialogs.size) {
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', updatedDialogs);
|
this.rootScope.dispatchEvent('dialogs_multiupdate', updatedDialogs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1158,6 +1160,8 @@ export default class DialogsStorage extends AppManager {
|
|||||||
|
|
||||||
const handleOrder = (order: PeerId[]) => {
|
const handleOrder = (order: PeerId[]) => {
|
||||||
this.resetPinnedOrder(folderId);
|
this.resetPinnedOrder(folderId);
|
||||||
|
this.pinnedOrders[folderId].push(...order);
|
||||||
|
this.savePinnedOrders();
|
||||||
order.reverse(); // index must be higher
|
order.reverse(); // index must be higher
|
||||||
order.forEach((peerId) => {
|
order.forEach((peerId) => {
|
||||||
newPinned[peerId] = true;
|
newPinned[peerId] = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user