Lazy load queue refactored
This commit is contained in:
parent
904b4a7eb9
commit
0333ecfcce
@ -1,7 +1,7 @@
|
|||||||
import appProfileManager from "../lib/appManagers/appProfileManager";
|
import appProfileManager from "../lib/appManagers/appProfileManager";
|
||||||
import { $rootScope } from "../lib/utils";
|
import { $rootScope } from "../lib/utils";
|
||||||
|
|
||||||
$rootScope.$on('avatar_update', (e: CustomEvent) => {
|
$rootScope.$on('avatar_update', (e) => {
|
||||||
let peerID = e.detail;
|
let peerID = e.detail;
|
||||||
|
|
||||||
appProfileManager.removeFromAvatarsCache(peerID);
|
appProfileManager.removeFromAvatarsCache(peerID);
|
||||||
|
@ -46,7 +46,7 @@ export class ChatAudio {
|
|||||||
appMediaPlaybackController.toggle();
|
appMediaPlaybackController.toggle();
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('audio_play', (e: CustomEvent) => {
|
$rootScope.$on('audio_play', (e) => {
|
||||||
const {doc, mid} = e.detail;
|
const {doc, mid} = e.detail;
|
||||||
|
|
||||||
let title: string, subtitle: string;
|
let title: string, subtitle: string;
|
||||||
|
@ -81,7 +81,7 @@ export class EmoticonsDropdown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearTimeout(this.displayTimeout);
|
clearTimeout(this.displayTimeout);
|
||||||
this.displayTimeout = setTimeout(() => {
|
this.displayTimeout = window.setTimeout(() => {
|
||||||
this.toggle(false);
|
this.toggle(false);
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
@ -188,7 +188,7 @@ export class EmoticonsDropdown {
|
|||||||
if((this.element.style.display && enable === undefined) || enable) {
|
if((this.element.style.display && enable === undefined) || enable) {
|
||||||
this.events.onOpen.forEach(cb => cb());
|
this.events.onOpen.forEach(cb => cb());
|
||||||
|
|
||||||
EmoticonsDropdown.lazyLoadQueue.lockIntersection();
|
EmoticonsDropdown.lazyLoadQueue.lock();
|
||||||
//EmoticonsDropdown.lazyLoadQueue.unlock();
|
//EmoticonsDropdown.lazyLoadQueue.unlock();
|
||||||
animationIntersector.lockIntersectionGroup(EMOTICONSSTICKERGROUP);
|
animationIntersector.lockIntersectionGroup(EMOTICONSSTICKERGROUP);
|
||||||
|
|
||||||
@ -197,9 +197,10 @@ export class EmoticonsDropdown {
|
|||||||
this.element.classList.add('active');
|
this.element.classList.add('active');
|
||||||
|
|
||||||
clearTimeout(this.displayTimeout);
|
clearTimeout(this.displayTimeout);
|
||||||
this.displayTimeout = setTimeout(() => {
|
this.displayTimeout = window.setTimeout(() => {
|
||||||
animationIntersector.unlockIntersectionGroup(EMOTICONSSTICKERGROUP);
|
animationIntersector.unlockIntersectionGroup(EMOTICONSSTICKERGROUP);
|
||||||
EmoticonsDropdown.lazyLoadQueue.unlockIntersection();
|
EmoticonsDropdown.lazyLoadQueue.unlock();
|
||||||
|
EmoticonsDropdown.lazyLoadQueue.refresh();
|
||||||
|
|
||||||
this.events.onOpenAfter.forEach(cb => cb());
|
this.events.onOpenAfter.forEach(cb => cb());
|
||||||
}, touchSupport ? 0 : 200);
|
}, touchSupport ? 0 : 200);
|
||||||
@ -210,7 +211,7 @@ export class EmoticonsDropdown {
|
|||||||
} else {
|
} else {
|
||||||
this.events.onClose.forEach(cb => cb());
|
this.events.onClose.forEach(cb => cb());
|
||||||
|
|
||||||
EmoticonsDropdown.lazyLoadQueue.lockIntersection();
|
EmoticonsDropdown.lazyLoadQueue.lock();
|
||||||
//EmoticonsDropdown.lazyLoadQueue.lock();
|
//EmoticonsDropdown.lazyLoadQueue.lock();
|
||||||
|
|
||||||
// нужно залочить группу и выключить стикеры
|
// нужно залочить группу и выключить стикеры
|
||||||
@ -220,12 +221,13 @@ export class EmoticonsDropdown {
|
|||||||
this.element.classList.remove('active');
|
this.element.classList.remove('active');
|
||||||
|
|
||||||
clearTimeout(this.displayTimeout);
|
clearTimeout(this.displayTimeout);
|
||||||
this.displayTimeout = setTimeout(() => {
|
this.displayTimeout = window.setTimeout(() => {
|
||||||
this.element.style.display = 'none';
|
this.element.style.display = 'none';
|
||||||
|
|
||||||
// теперь можно убрать visible, чтобы они не включились после фокуса
|
// теперь можно убрать visible, чтобы они не включились после фокуса
|
||||||
animationIntersector.unlockIntersectionGroup(EMOTICONSSTICKERGROUP);
|
animationIntersector.unlockIntersectionGroup(EMOTICONSSTICKERGROUP);
|
||||||
EmoticonsDropdown.lazyLoadQueue.unlockIntersection();
|
EmoticonsDropdown.lazyLoadQueue.unlock();
|
||||||
|
EmoticonsDropdown.lazyLoadQueue.refresh();
|
||||||
|
|
||||||
this.events.onCloseAfter.forEach(cb => cb());
|
this.events.onCloseAfter.forEach(cb => cb());
|
||||||
}, touchSupport ? 0 : 200);
|
}, touchSupport ? 0 : 200);
|
||||||
|
@ -13,6 +13,7 @@ import apiManager from "../../../lib/mtproto/mtprotoworker";
|
|||||||
import StickyIntersector from "../../stickyIntersector";
|
import StickyIntersector from "../../stickyIntersector";
|
||||||
import appDocsManager, {MyDocument} from "../../../lib/appManagers/appDocsManager";
|
import appDocsManager, {MyDocument} from "../../../lib/appManagers/appDocsManager";
|
||||||
import animationIntersector from "../../animationIntersector";
|
import animationIntersector from "../../animationIntersector";
|
||||||
|
import LazyLoadQueue, { LazyLoadQueueRepeat } from "../../lazyLoadQueue";
|
||||||
|
|
||||||
export default class StickersTab implements EmoticonsTab {
|
export default class StickersTab implements EmoticonsTab {
|
||||||
public content: HTMLElement;
|
public content: HTMLElement;
|
||||||
@ -36,7 +37,7 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
private stickyIntersector: StickyIntersector;
|
private stickyIntersector: StickyIntersector;
|
||||||
|
|
||||||
private animatedDivs: Set<HTMLDivElement> = new Set();
|
private animatedDivs: Set<HTMLDivElement> = new Set();
|
||||||
private animatedIntersector: IntersectionObserver;
|
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');
|
||||||
@ -83,7 +84,11 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
|
|
||||||
if(doc.sticker == 2) {
|
if(doc.sticker == 2) {
|
||||||
this.animatedDivs.add(div);
|
this.animatedDivs.add(div);
|
||||||
this.animatedIntersector.observe(div);
|
|
||||||
|
this.lazyLoadQueue.observe({
|
||||||
|
div,
|
||||||
|
load: this.processVisibleDiv
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +168,58 @@ 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 promise = wrapSticker({
|
||||||
|
doc,
|
||||||
|
div: div as HTMLDivElement,
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
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;
|
||||||
@ -196,7 +253,7 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
}
|
}
|
||||||
}); */
|
}); */
|
||||||
|
|
||||||
$rootScope.$on('stickers_installed', (e: CustomEvent) => {
|
$rootScope.$on('stickers_installed', (e) => {
|
||||||
const set: StickerSet.stickerSet = e.detail;
|
const set: StickerSet.stickerSet = e.detail;
|
||||||
|
|
||||||
if(!this.stickerSets[set.id] && this.mounted) {
|
if(!this.stickerSets[set.id] && this.mounted) {
|
||||||
@ -204,7 +261,7 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('stickers_deleted', (e: CustomEvent) => {
|
$rootScope.$on('stickers_deleted', (e) => {
|
||||||
const set: StickerSet.stickerSet = e.detail;
|
const set: StickerSet.stickerSet = e.detail;
|
||||||
|
|
||||||
if(this.stickerSets[set.id] && this.mounted) {
|
if(this.stickerSets[set.id] && this.mounted) {
|
||||||
@ -256,98 +313,59 @@ export default class StickersTab implements EmoticonsTab {
|
|||||||
this.mounted = true;
|
this.mounted = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkAnimationDiv = (div: HTMLDivElement) => {
|
this.lazyLoadQueue = new LazyLoadQueueRepeat(undefined, (target, visible) => {
|
||||||
const players = animationIntersector.getAnimations(div);
|
if(!visible) {
|
||||||
players.forEach(player => {
|
this.processInvisibleDiv(target as HTMLDivElement);
|
||||||
if(!visible.has(div)) {
|
|
||||||
animationIntersector.checkAnimation(player, true, true);
|
|
||||||
} else {
|
|
||||||
animationIntersector.checkAnimation(player, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const processInvisibleDiv = (div: HTMLDivElement) => {
|
|
||||||
visible.delete(div);
|
|
||||||
//console.log('STICKER INvisible:', target, docID);
|
|
||||||
|
|
||||||
const docID = div.dataset.docID;
|
|
||||||
const doc = appDocsManager.getDoc(docID);
|
|
||||||
|
|
||||||
checkAnimationDiv(div);
|
|
||||||
|
|
||||||
div.innerHTML = '';
|
|
||||||
this.renderSticker(doc, div);
|
|
||||||
};
|
|
||||||
|
|
||||||
let locked = false;
|
|
||||||
const visible: Set<HTMLDivElement> = new Set();
|
|
||||||
this.animatedIntersector = new IntersectionObserver((entries) => {
|
|
||||||
if(locked) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entries.forEach(entry => {
|
|
||||||
const {target, isIntersecting} = entry;
|
|
||||||
|
|
||||||
const div = target as HTMLDivElement;
|
|
||||||
const docID = div.dataset.docID;
|
|
||||||
const doc = appDocsManager.getDoc(docID);
|
|
||||||
if(isIntersecting) {
|
|
||||||
//console.log('STICKER visible:', target, docID);
|
|
||||||
if(visible.has(div)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
visible.add(div);
|
|
||||||
|
|
||||||
wrapSticker({
|
|
||||||
doc,
|
|
||||||
div,
|
|
||||||
width: 80,
|
|
||||||
height: 80,
|
|
||||||
lazyLoadQueue: null,
|
|
||||||
group: EMOTICONSSTICKERGROUP,
|
|
||||||
onlyThumb: false,
|
|
||||||
play: true,
|
|
||||||
loop: true
|
|
||||||
}).then(() => {
|
|
||||||
checkAnimationDiv(div);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
processInvisibleDiv(div);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//animationIntersector.checkAnimations(true, EMOTICONSSTICKERGROUP, false);
|
/* let closed = true;
|
||||||
});
|
|
||||||
|
|
||||||
emoticonsDropdown.events.onClose.push(() => {
|
emoticonsDropdown.events.onClose.push(() => {
|
||||||
locked = true;
|
closed = false;
|
||||||
|
this.lazyLoadQueue.lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
emoticonsDropdown.events.onCloseAfter.push(() => {
|
emoticonsDropdown.events.onCloseAfter.push(() => {
|
||||||
const divs = [...visible];
|
const divs = this.lazyLoadQueue.intersector.getVisible();
|
||||||
|
|
||||||
for(const div of divs) {
|
for(const div of divs) {
|
||||||
processInvisibleDiv(div);
|
this.processInvisibleDiv(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
emoticonsDropdown.events.onOpenAfter.push(() => {
|
emoticonsDropdown.events.onOpenAfter.push(() => {
|
||||||
locked = false;
|
if(closed) {
|
||||||
|
this.lazyLoadQueue.unlockAndRefresh();
|
||||||
// refresh
|
closed = false;
|
||||||
this.animatedIntersector.disconnect();
|
} else {
|
||||||
const divs = [...this.animatedDivs];
|
this.lazyLoadQueue.unlock();
|
||||||
for(const div of divs) {
|
|
||||||
this.animatedIntersector.observe(div);
|
|
||||||
}
|
}
|
||||||
|
}); */
|
||||||
|
emoticonsDropdown.events.onClose.push(() => {
|
||||||
|
this.lazyLoadQueue.lock();
|
||||||
|
});
|
||||||
|
|
||||||
|
emoticonsDropdown.events.onCloseAfter.push(() => {
|
||||||
|
const divs = this.lazyLoadQueue.intersector.getVisible();
|
||||||
|
|
||||||
|
for(const div of divs) {
|
||||||
|
this.processInvisibleDiv(div);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lazyLoadQueue.intersector.clearVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
emoticonsDropdown.events.onOpenAfter.push(() => {
|
||||||
|
this.lazyLoadQueue.unlockAndRefresh();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* setInterval(() => {
|
/* setInterval(() => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
console.log('STICKERS RENDERED IN PANEL:', Object.values(lottieLoader.players).filter(p => p.width == 80).length);
|
const players = Object.values(lottieLoader.players).filter(p => p.width == 80);
|
||||||
|
|
||||||
|
console.log('STICKERS RENDERED IN PANEL:', players.length, players.filter(p => !p.paused).length, this.lazyLoadQueue.intersector.getVisible().length);
|
||||||
}, .25e3); */
|
}, .25e3); */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,67 +1,35 @@
|
|||||||
import { logger, LogLevels } from "../lib/logger";
|
import { logger, LogLevels } from "../lib/logger";
|
||||||
|
import VisibilityIntersector, { OnVisibilityChange } from "./visibilityIntersector";
|
||||||
|
|
||||||
type LazyLoadElement = {
|
type LazyLoadElementBase = {
|
||||||
div: HTMLDivElement,
|
div: HTMLDivElement,
|
||||||
load: () => Promise<any>,
|
load: (target?: HTMLDivElement) => Promise<any>
|
||||||
|
};
|
||||||
|
|
||||||
|
type LazyLoadElement = LazyLoadElementBase & {
|
||||||
wasSeen?: boolean
|
wasSeen?: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class LazyLoadQueue {
|
export class LazyLoadQueueBase {
|
||||||
private lazyLoadMedia: Array<LazyLoadElement> = [];
|
protected lazyLoadMedia: Array<LazyLoadElementBase> = [];
|
||||||
private inProcess: Array<LazyLoadElement> = [];
|
protected inProcess: Set<LazyLoadElementBase> = new Set();
|
||||||
|
|
||||||
private lockPromise: Promise<void> = null;
|
protected lockPromise: Promise<void> = null;
|
||||||
private unlockResolve: () => void = null;
|
protected unlockResolve: () => void = null;
|
||||||
|
|
||||||
private log = logger('LL', LogLevels.error);
|
protected log = logger('LL', LogLevels.error);
|
||||||
|
|
||||||
// Observer will call entry only 1 time per element
|
constructor(protected parallelLimit = 5) {
|
||||||
private observer: IntersectionObserver;
|
|
||||||
|
|
||||||
private intersectionLocked = false;
|
|
||||||
|
|
||||||
constructor(private parallelLimit = 5, private noObserver = false) {
|
|
||||||
if(noObserver) return;
|
|
||||||
|
|
||||||
this.observer = new IntersectionObserver(entries => {
|
|
||||||
if(this.lockPromise || this.intersectionLocked) return;
|
|
||||||
|
|
||||||
const intersecting = entries.filter(entry => entry.isIntersecting);
|
|
||||||
intersecting.forEachReverse(entry => {
|
|
||||||
const target = entry.target as HTMLElement;
|
|
||||||
|
|
||||||
this.log('isIntersecting', target);
|
|
||||||
|
|
||||||
// need for set element first if scrolled
|
|
||||||
const item = this.lazyLoadMedia.findAndSplice(i => i.div == target);
|
|
||||||
if(item) {
|
|
||||||
item.wasSeen = true;
|
|
||||||
this.lazyLoadMedia.unshift(item);
|
|
||||||
//this.processQueue(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(intersecting.length) {
|
|
||||||
this.processQueue();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear() {
|
public clear() {
|
||||||
this.inProcess.length = 0; // ацтеки забьются, будет плохо
|
this.inProcess.clear(); // ацтеки забьются, будет плохо
|
||||||
|
|
||||||
this.lazyLoadMedia.length = 0;
|
this.lazyLoadMedia.length = 0;
|
||||||
for(let item of this.inProcess) {
|
// unreachable code
|
||||||
|
/* for(let item of this.inProcess) {
|
||||||
this.lazyLoadMedia.push(item);
|
this.lazyLoadMedia.push(item);
|
||||||
}
|
} */
|
||||||
|
|
||||||
if(this.observer) {
|
|
||||||
this.observer.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public length() {
|
|
||||||
return this.lazyLoadMedia.length + this.inProcess.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public lock() {
|
public lock() {
|
||||||
@ -78,23 +46,14 @@ export default class LazyLoadQueue {
|
|||||||
this.unlockResolve = null;
|
this.unlockResolve = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async processQueue(item?: LazyLoadElement) {
|
public async processItem(item: LazyLoadElementBase) {
|
||||||
if(this.parallelLimit > 0 && this.inProcess.length >= this.parallelLimit) return;
|
this.inProcess.add(item);
|
||||||
|
|
||||||
if(item) {
|
|
||||||
this.lazyLoadMedia.findAndSplice(i => i == item);
|
|
||||||
} else {
|
|
||||||
item = this.lazyLoadMedia.findAndSplice(i => i.wasSeen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(item) {
|
|
||||||
this.inProcess.push(item);
|
|
||||||
|
|
||||||
this.log('will load media', this.lockPromise, item);
|
this.log('will load media', this.lockPromise, item);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(this.lockPromise/* && false */) {
|
if(this.lockPromise/* && false */) {
|
||||||
let perf = performance.now();
|
const perf = performance.now();
|
||||||
await this.lockPromise;
|
await this.lockPromise;
|
||||||
|
|
||||||
this.log('waited lock:', performance.now() - perf);
|
this.log('waited lock:', performance.now() - perf);
|
||||||
@ -102,16 +61,12 @@ export default class LazyLoadQueue {
|
|||||||
|
|
||||||
//await new Promise((resolve) => setTimeout(resolve, 2e3));
|
//await new Promise((resolve) => setTimeout(resolve, 2e3));
|
||||||
//await new Promise((resolve, reject) => window.requestAnimationFrame(() => window.requestAnimationFrame(resolve)));
|
//await new Promise((resolve, reject) => window.requestAnimationFrame(() => window.requestAnimationFrame(resolve)));
|
||||||
await item.load();
|
await item.load(item.div);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
this.log.error('loadMediaQueue error:', err/* , item */);
|
this.log.error('loadMediaQueue error:', err/* , item */);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.noObserver) {
|
this.inProcess.delete(item);
|
||||||
this.observer.unobserve(item.div);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.inProcess.findAndSplice(i => i == item);
|
|
||||||
|
|
||||||
this.log('loaded media', item);
|
this.log('loaded media', item);
|
||||||
|
|
||||||
@ -119,51 +74,172 @@ export default class LazyLoadQueue {
|
|||||||
this.processQueue();
|
this.processQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getItem() {
|
||||||
|
return this.lazyLoadMedia.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
public addElement(el: LazyLoadElement) {
|
protected addElement(el: LazyLoadElementBase) {
|
||||||
if(el.wasSeen) {
|
|
||||||
this.processQueue(el);
|
this.processQueue(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async processQueue(item?: LazyLoadElementBase) {
|
||||||
|
if(this.parallelLimit > 0 && this.inProcess.size >= this.parallelLimit) return;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(item) {
|
||||||
|
this.lazyLoadMedia.findAndSplice(i => i == item);
|
||||||
} else {
|
} else {
|
||||||
el.wasSeen = false;
|
item = this.getItem();
|
||||||
|
|
||||||
if(this.observer) {
|
|
||||||
this.observer.observe(el.div);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public push(el: LazyLoadElement) {
|
if(item) {
|
||||||
|
this.processItem(item);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = null;
|
||||||
|
} while(this.inProcess.size < this.parallelLimit && this.lazyLoadMedia.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public push(el: LazyLoadElementBase) {
|
||||||
this.lazyLoadMedia.push(el);
|
this.lazyLoadMedia.push(el);
|
||||||
this.addElement(el);
|
this.addElement(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unshift(el: LazyLoadElement) {
|
public unshift(el: LazyLoadElementBase) {
|
||||||
this.lazyLoadMedia.unshift(el);
|
this.lazyLoadMedia.unshift(el);
|
||||||
this.addElement(el);
|
this.addElement(el);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LazyLoadQueueIntersector extends LazyLoadQueueBase {
|
||||||
|
public intersector: VisibilityIntersector;
|
||||||
|
protected intersectorTimeout: number;
|
||||||
|
|
||||||
|
constructor(protected parallelLimit = 5) {
|
||||||
|
super(parallelLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public lock() {
|
||||||
|
super.lock();
|
||||||
|
this.intersector.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public unlock() {
|
||||||
|
super.unlock();
|
||||||
|
this.intersector.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public unlockAndRefresh() {
|
||||||
|
super.unlock();
|
||||||
|
this.intersector.unlockAndRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear() {
|
||||||
|
super.clear();
|
||||||
|
this.intersector.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
public refresh() {
|
public refresh() {
|
||||||
const items = this.lazyLoadMedia;
|
this.intersector.refresh();
|
||||||
if(items && items.length) {
|
}
|
||||||
items.forEach(item => {
|
|
||||||
this.observer.unobserve(item.div);
|
|
||||||
});
|
|
||||||
|
|
||||||
window.requestAnimationFrame(() => {
|
protected setProcessQueueTimeout() {
|
||||||
items.forEach(item => {
|
if(!this.intersectorTimeout) {
|
||||||
this.observer.observe(item.div);
|
this.intersectorTimeout = window.setTimeout(() => {
|
||||||
});
|
this.intersectorTimeout = 0;
|
||||||
});
|
this.processQueue();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public lockIntersection() {
|
export default class LazyLoadQueue extends LazyLoadQueueIntersector {
|
||||||
this.intersectionLocked = true;
|
protected lazyLoadMedia: Array<LazyLoadElement> = [];
|
||||||
|
protected inProcess: Set<LazyLoadElement> = new Set();
|
||||||
|
|
||||||
|
constructor(protected parallelLimit = 5) {
|
||||||
|
super(parallelLimit);
|
||||||
|
|
||||||
|
this.intersector = new VisibilityIntersector(this.onVisibilityChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unlockIntersection() {
|
private onVisibilityChange = (target: HTMLElement, visible: boolean) => {
|
||||||
this.intersectionLocked = false;
|
if(visible) {
|
||||||
this.refresh();
|
this.log('isIntersecting', target);
|
||||||
|
|
||||||
|
// need for set element first if scrolled
|
||||||
|
const item = this.lazyLoadMedia.findAndSplice(i => i.div == target);
|
||||||
|
if(item) {
|
||||||
|
item.wasSeen = true;
|
||||||
|
this.lazyLoadMedia.unshift(item);
|
||||||
|
//this.processQueue(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setProcessQueueTimeout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected getItem() {
|
||||||
|
return this.lazyLoadMedia.findAndSplice(item => item.wasSeen);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async processItem(item: LazyLoadElement) {
|
||||||
|
await super.processItem(item);
|
||||||
|
this.intersector.unobserve(item.div);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected addElement(el: LazyLoadElement) {
|
||||||
|
//super.addElement(el);
|
||||||
|
if(el.wasSeen) {
|
||||||
|
super.processQueue(el);
|
||||||
|
} else {
|
||||||
|
el.wasSeen = false;
|
||||||
|
this.intersector.observe(el.div);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public push(el: LazyLoadElement) {
|
||||||
|
super.push(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unshift(el: LazyLoadElement) {
|
||||||
|
super.unshift(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LazyLoadQueueRepeat extends LazyLoadQueueIntersector {
|
||||||
|
private _lazyLoadMedia: Map<HTMLElement, LazyLoadElementBase> = new Map();
|
||||||
|
|
||||||
|
constructor(protected parallelLimit = 5, protected onVisibilityChange?: OnVisibilityChange) {
|
||||||
|
super(parallelLimit);
|
||||||
|
|
||||||
|
this.intersector = new VisibilityIntersector((target, visible) => {
|
||||||
|
if(visible) {
|
||||||
|
const item = this.lazyLoadMedia.findAndSplice(i => i.div == target);
|
||||||
|
this.lazyLoadMedia.unshift(item || this._lazyLoadMedia.get(target));
|
||||||
|
} else {
|
||||||
|
this.lazyLoadMedia.findAndSplice(i => i.div == target);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onVisibilityChange && this.onVisibilityChange(target, visible);
|
||||||
|
this.setProcessQueueTimeout();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* public async processItem(item: LazyLoadElement) {
|
||||||
|
//await super.processItem(item);
|
||||||
|
await LazyLoadQueueBase.prototype.processItem.call(this, item);
|
||||||
|
|
||||||
|
if(this.lazyLoadMedia.length) {
|
||||||
|
this.processQueue();
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
public observe(el: LazyLoadElementBase) {
|
||||||
|
this._lazyLoadMedia.set(el.div, el);
|
||||||
|
this.intersector.observe(el.div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,19 @@ let closeBtnMenu = () => {
|
|||||||
window.removeEventListener('contextmenu', onClick);
|
window.removeEventListener('contextmenu', onClick);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
if(openedMenu) {
|
||||||
|
closeBtnMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if(openedMenu && (openedMenu.style.top || openedMenu.style.left)) {
|
||||||
|
const rect = openedMenu.getBoundingClientRect();
|
||||||
|
const {innerWidth, innerHeight} = window;
|
||||||
|
|
||||||
|
console.log(innerWidth, innerHeight, rect);
|
||||||
|
} */
|
||||||
|
});
|
||||||
|
|
||||||
let openedMenu: HTMLDivElement = null, openedMenuOnClose: () => void = null;
|
let openedMenu: HTMLDivElement = null, openedMenuOnClose: () => void = null;
|
||||||
export function openBtnMenu(menuElement: HTMLDivElement, onClose?: () => void) {
|
export function openBtnMenu(menuElement: HTMLDivElement, onClose?: () => void) {
|
||||||
closeBtnMenu();
|
closeBtnMenu();
|
||||||
@ -248,7 +261,7 @@ export function attachContextMenuListener(element: HTMLElement, callback: (e: To
|
|||||||
}
|
}
|
||||||
}; */
|
}; */
|
||||||
|
|
||||||
timeout = setTimeout(() => {
|
timeout = window.setTimeout(() => {
|
||||||
callback(e.touches[0]);
|
callback(e.touches[0]);
|
||||||
onCancel();
|
onCancel();
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ export const roundPercents = (percents: number[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const connectedPolls: {id: string, element: PollElement}[] = [];
|
const connectedPolls: {id: string, element: PollElement}[] = [];
|
||||||
$rootScope.$on('poll_update', (e: CustomEvent) => {
|
$rootScope.$on('poll_update', (e) => {
|
||||||
const {poll, results} = e.detail as {poll: Poll, results: PollResults};
|
const {poll, results} = e.detail as {poll: Poll, results: PollResults};
|
||||||
|
|
||||||
//console.log('poll_update', poll, results);
|
//console.log('poll_update', poll, results);
|
||||||
@ -123,7 +123,7 @@ const setQuizHint = (solution: string, solution_entities: any[], onHide: () => v
|
|||||||
|
|
||||||
prevQuizHint = element;
|
prevQuizHint = element;
|
||||||
prevQuizHintOnHide = onHide;
|
prevQuizHintOnHide = onHide;
|
||||||
prevQuizHintTimeout = setTimeout(() => {
|
prevQuizHintTimeout = window.setTimeout(() => {
|
||||||
hideQuizHint(element, onHide, prevQuizHintTimeout);
|
hideQuizHint(element, onHide, prevQuizHintTimeout);
|
||||||
}, touchSupport ? 5000 : 7000);
|
}, touchSupport ? 5000 : 7000);
|
||||||
};
|
};
|
||||||
@ -280,7 +280,7 @@ export default class PollElement extends HTMLElement {
|
|||||||
// circle.style.strokeDashoffset = circumference + percents * circumference;
|
// circle.style.strokeDashoffset = circumference + percents * circumference;
|
||||||
// circle.style.strokeDasharray = ${circumference} ${circumference};
|
// circle.style.strokeDasharray = ${circumference} ${circumference};
|
||||||
|
|
||||||
this.quizInterval = setInterval(() => {
|
this.quizInterval = window.setInterval(() => {
|
||||||
const time = Date.now();
|
const time = Date.now();
|
||||||
const percents = (closeTime - time) / period;
|
const percents = (closeTime - time) / period;
|
||||||
const timeLeft = (closeTime - time) / 1000 + 1 | 0;
|
const timeLeft = (closeTime - time) / 1000 + 1 | 0;
|
||||||
|
@ -118,8 +118,8 @@ export default class AppChatFoldersTab implements SliderTab {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('filter_update', (e: CustomEvent) => {
|
$rootScope.$on('filter_update', (e) => {
|
||||||
const filter: DialogFilter = e.detail;
|
const filter = e.detail;
|
||||||
if(this.filtersRendered.hasOwnProperty(filter.id)) {
|
if(this.filtersRendered.hasOwnProperty(filter.id)) {
|
||||||
this.renderFolder(filter, null, this.filtersRendered[filter.id]);
|
this.renderFolder(filter, null, this.filtersRendered[filter.id]);
|
||||||
} else {
|
} else {
|
||||||
@ -129,8 +129,8 @@ export default class AppChatFoldersTab implements SliderTab {
|
|||||||
this.getSuggestedFilters();
|
this.getSuggestedFilters();
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('filter_delete', (e: CustomEvent) => {
|
$rootScope.$on('filter_delete', (e) => {
|
||||||
const filter: DialogFilter = e.detail;
|
const filter = e.detail;
|
||||||
if(this.filtersRendered.hasOwnProperty(filter.id)) {
|
if(this.filtersRendered.hasOwnProperty(filter.id)) {
|
||||||
/* for(const suggested of this.suggestedFilters) {
|
/* for(const suggested of this.suggestedFilters) {
|
||||||
if(deepEqual(suggested.filter, filter)) {
|
if(deepEqual(suggested.filter, filter)) {
|
||||||
|
@ -26,7 +26,7 @@ export default class AppSettingsTab implements SliderTab {
|
|||||||
constructor() {
|
constructor() {
|
||||||
parseMenuButtonsTo(this.buttons, this.container.querySelector('.profile-buttons').children);
|
parseMenuButtonsTo(this.buttons, this.container.querySelector('.profile-buttons').children);
|
||||||
|
|
||||||
$rootScope.$on('user_auth', (e: CustomEvent) => {
|
$rootScope.$on('user_auth', (e) => {
|
||||||
this.fillElements();
|
this.fillElements();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
117
src/components/visibilityIntersector.ts
Normal file
117
src/components/visibilityIntersector.ts
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
type TargetType = HTMLElement;
|
||||||
|
export type OnVisibilityChange = (target: TargetType, visible: boolean) => void;
|
||||||
|
|
||||||
|
export default class VisibilityIntersector {
|
||||||
|
private observer: IntersectionObserver;
|
||||||
|
private items: Map<TargetType, boolean> = new Map();
|
||||||
|
private locked = false;
|
||||||
|
|
||||||
|
constructor(onVisibilityChange: OnVisibilityChange) {
|
||||||
|
this.observer = new IntersectionObserver((entries) => {
|
||||||
|
if(this.locked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const changed: {target: TargetType, visible: boolean}[] = [];
|
||||||
|
|
||||||
|
entries.forEach(entry => {
|
||||||
|
const target = entry.target as TargetType;
|
||||||
|
|
||||||
|
if(this.items.get(target) == entry.isIntersecting) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.items.set(target, entry.isIntersecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if(entry.isIntersecting) {
|
||||||
|
console.log('ooo', entry);
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* if(this.locked) {
|
||||||
|
return;
|
||||||
|
} */
|
||||||
|
|
||||||
|
changed[entry.isIntersecting ? 'unshift' : 'push']({target, visible: entry.isIntersecting});
|
||||||
|
|
||||||
|
//onVisibilityChange(target, entry.isIntersecting);
|
||||||
|
});
|
||||||
|
|
||||||
|
changed.forEach(smth => {
|
||||||
|
onVisibilityChange(smth.target, smth.visible);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getVisible() {
|
||||||
|
const items: TargetType[] = [];
|
||||||
|
this.items.forEach((value, key) => {
|
||||||
|
if(value) {
|
||||||
|
items.push(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearVisible() {
|
||||||
|
const visible = this.getVisible();
|
||||||
|
for(const target of visible) {
|
||||||
|
this.items.set(target, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isVisible(target: TargetType) {
|
||||||
|
return this.items.get(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnect() {
|
||||||
|
this.observer.disconnect();
|
||||||
|
this.items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public refresh() {
|
||||||
|
this.observer.disconnect();
|
||||||
|
|
||||||
|
//window.requestAnimationFrame(() => {
|
||||||
|
const targets = [...this.items.keys()];
|
||||||
|
for(const target of targets) {
|
||||||
|
//this.items.set(target, false);
|
||||||
|
this.observer.observe(target);
|
||||||
|
}
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
|
public refreshVisible() {
|
||||||
|
const visible = this.getVisible();
|
||||||
|
for(const target of visible) {
|
||||||
|
this.observer.unobserve(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const target of visible) {
|
||||||
|
this.observer.observe(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public observe(target: TargetType) {
|
||||||
|
this.items.set(target, false);
|
||||||
|
this.observer.observe(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unobserve(target: TargetType) {
|
||||||
|
this.observer.unobserve(target);
|
||||||
|
this.items.delete(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unlock() {
|
||||||
|
this.locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unlockAndRefresh() {
|
||||||
|
this.unlock();
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public lock() {
|
||||||
|
this.locked = true;
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ import webpWorkerController from '../lib/webp/webpWorkerController';
|
|||||||
import { readBlobAsText } from '../helpers/blob';
|
import { readBlobAsText } from '../helpers/blob';
|
||||||
import appMediaPlaybackController from './appMediaPlaybackController';
|
import appMediaPlaybackController from './appMediaPlaybackController';
|
||||||
import { PhotoSize } from '../layer';
|
import { PhotoSize } from '../layer';
|
||||||
|
import { deferredPromise } from '../lib/polyfill';
|
||||||
|
|
||||||
export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group}: {
|
export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group}: {
|
||||||
doc: MyDocument,
|
doc: MyDocument,
|
||||||
@ -595,12 +596,12 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
|
|
||||||
//appDocsManager.downloadDocNew(doc.id).promise.then(res => res.json()).then(async(json) => {
|
//appDocsManager.downloadDocNew(doc.id).promise.then(res => res.json()).then(async(json) => {
|
||||||
//fetch(doc.url).then(res => res.json()).then(async(json) => {
|
//fetch(doc.url).then(res => res.json()).then(async(json) => {
|
||||||
await appDocsManager.downloadDocNew(doc)
|
/* return */ await appDocsManager.downloadDocNew(doc)
|
||||||
.then(readBlobAsText)
|
.then(readBlobAsText)
|
||||||
.then(JSON.parse)
|
.then(JSON.parse)
|
||||||
.then(async(json) => {
|
.then(async(json) => {
|
||||||
//console.timeEnd('download sticker' + doc.id);
|
//console.timeEnd('download sticker' + doc.id);
|
||||||
//console.log('loaded sticker:', doc, div, blob);
|
//console.log('loaded sticker:', doc, div/* , blob */);
|
||||||
if(middleware && !middleware()) return;
|
if(middleware && !middleware()) return;
|
||||||
|
|
||||||
let animation = await LottieLoader.loadAnimationWorker/* loadAnimation */({
|
let animation = await LottieLoader.loadAnimationWorker/* loadAnimation */({
|
||||||
@ -612,12 +613,16 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
height
|
height
|
||||||
}, group, toneIndex);
|
}, group, toneIndex);
|
||||||
|
|
||||||
|
//const deferred = deferredPromise<void>();
|
||||||
|
|
||||||
animation.addListener('firstFrame', () => {
|
animation.addListener('firstFrame', () => {
|
||||||
if(div.firstElementChild && div.firstElementChild.tagName == 'IMG') {
|
if(div.firstElementChild && div.firstElementChild.tagName == 'IMG') {
|
||||||
div.firstElementChild.remove();
|
div.firstElementChild.remove();
|
||||||
} else {
|
} else {
|
||||||
animation.canvas.classList.add('fade-in');
|
animation.canvas.classList.add('fade-in');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//deferred.resolve();
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
if(emoji) {
|
if(emoji) {
|
||||||
@ -629,6 +634,8 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return deferred;
|
||||||
//await new Promise((resolve) => setTimeout(resolve, 5e3));
|
//await new Promise((resolve) => setTimeout(resolve, 5e3));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ export class AppChatsManager {
|
|||||||
public megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
|
public megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
// console.log('on apiUpdate', update)
|
// console.log('on apiUpdate', update)
|
||||||
const update = e.detail;
|
const update = e.detail;
|
||||||
switch(update._) {
|
switch(update._) {
|
||||||
|
@ -424,7 +424,7 @@ export class AppDialogsManager {
|
|||||||
(window as any).addElement = add;
|
(window as any).addElement = add;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
$rootScope.$on('user_update', (e: CustomEvent) => {
|
$rootScope.$on('user_update', (e) => {
|
||||||
let userID = e.detail;
|
let userID = e.detail;
|
||||||
|
|
||||||
let user = appUsersManager.getUser(userID);
|
let user = appUsersManager.getUser(userID);
|
||||||
@ -450,7 +450,7 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('dialog_top', (e: CustomEvent) => {
|
$rootScope.$on('dialog_top', (e) => {
|
||||||
let dialog: any = e.detail;
|
let dialog: any = e.detail;
|
||||||
|
|
||||||
this.setLastMessage(dialog);
|
this.setLastMessage(dialog);
|
||||||
@ -460,7 +460,7 @@ export class AppDialogsManager {
|
|||||||
this.setFiltersUnreadCount();
|
this.setFiltersUnreadCount();
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('dialog_flush', (e: CustomEvent) => {
|
$rootScope.$on('dialog_flush', (e) => {
|
||||||
let peerID: number = e.detail.peerID;
|
let peerID: number = e.detail.peerID;
|
||||||
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
|
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
|
||||||
if(dialog) {
|
if(dialog) {
|
||||||
@ -470,7 +470,7 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('dialogs_multiupdate', (e: CustomEvent) => {
|
$rootScope.$on('dialogs_multiupdate', (e) => {
|
||||||
const dialogs = e.detail;
|
const dialogs = e.detail;
|
||||||
|
|
||||||
for(const id in dialogs) {
|
for(const id in dialogs) {
|
||||||
@ -483,7 +483,7 @@ export class AppDialogsManager {
|
|||||||
this.setFiltersUnreadCount();
|
this.setFiltersUnreadCount();
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('dialog_drop', (e: CustomEvent) => {
|
$rootScope.$on('dialog_drop', (e) => {
|
||||||
let {peerID, dialog} = e.detail;
|
let {peerID, dialog} = e.detail;
|
||||||
|
|
||||||
let dom = this.getDialogDom(peerID);
|
let dom = this.getDialogDom(peerID);
|
||||||
@ -496,11 +496,8 @@ export class AppDialogsManager {
|
|||||||
this.setFiltersUnreadCount();
|
this.setFiltersUnreadCount();
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('dialog_unread', (e: CustomEvent) => {
|
$rootScope.$on('dialog_unread', (e) => {
|
||||||
let info: {
|
let info = e.detail;
|
||||||
peerID: number,
|
|
||||||
count: number
|
|
||||||
} = e.detail;
|
|
||||||
|
|
||||||
let dialog = appMessagesManager.getDialogByPeerID(info.peerID)[0];
|
let dialog = appMessagesManager.getDialogByPeerID(info.peerID)[0];
|
||||||
if(dialog) {
|
if(dialog) {
|
||||||
@ -522,7 +519,7 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('peer_changed', (e: CustomEvent) => {
|
$rootScope.$on('peer_changed', (e) => {
|
||||||
let peerID = e.detail;
|
let peerID = e.detail;
|
||||||
|
|
||||||
let lastPeerID = this.lastActiveListElement && +this.lastActiveListElement.getAttribute('data-peerID');
|
let lastPeerID = this.lastActiveListElement && +this.lastActiveListElement.getAttribute('data-peerID');
|
||||||
@ -540,7 +537,7 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('filter_update', (e: CustomEvent) => {
|
$rootScope.$on('filter_update', (e) => {
|
||||||
const filter: DialogFilter = e.detail;
|
const filter: DialogFilter = e.detail;
|
||||||
if(!this.filtersRendered[filter.id]) {
|
if(!this.filtersRendered[filter.id]) {
|
||||||
this.addFilter(filter);
|
this.addFilter(filter);
|
||||||
@ -560,7 +557,7 @@ export class AppDialogsManager {
|
|||||||
elements.title.innerHTML = RichTextProcessor.wrapEmojiText(filter.title);
|
elements.title.innerHTML = RichTextProcessor.wrapEmojiText(filter.title);
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('filter_delete', (e: CustomEvent) => {
|
$rootScope.$on('filter_delete', (e) => {
|
||||||
const filter: DialogFilter = e.detail;
|
const filter: DialogFilter = e.detail;
|
||||||
const elements = this.filtersRendered[filter.id];
|
const elements = this.filtersRendered[filter.id];
|
||||||
if(!elements) return;
|
if(!elements) return;
|
||||||
@ -580,7 +577,7 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* $rootScope.$on('filter_pinned_order', (e: CustomEvent) => {
|
/* $rootScope.$on('filter_pinned_order', (e) => {
|
||||||
const {order, id} = e.detail as {order: number[], id: number};
|
const {order, id} = e.detail as {order: number[], id: number};
|
||||||
if(this.prevTabID != id) {
|
if(this.prevTabID != id) {
|
||||||
return;
|
return;
|
||||||
|
@ -154,13 +154,13 @@ export class AppImManager {
|
|||||||
this.myID = $rootScope.myID = id;
|
this.myID = $rootScope.myID = id;
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('user_auth', (e: CustomEvent) => {
|
$rootScope.$on('user_auth', (e) => {
|
||||||
let userAuth = e.detail;
|
let userAuth = e.detail;
|
||||||
this.myID = $rootScope.myID = userAuth ? userAuth.id : 0;
|
this.myID = $rootScope.myID = userAuth ? userAuth.id : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// will call when message is sent (only 1)
|
// will call when message is sent (only 1)
|
||||||
$rootScope.$on('history_append', (e: CustomEvent) => {
|
$rootScope.$on('history_append', (e) => {
|
||||||
let details = e.detail;
|
let details = e.detail;
|
||||||
|
|
||||||
if(!this.scrolledAllDown) {
|
if(!this.scrolledAllDown) {
|
||||||
@ -171,7 +171,7 @@ export class AppImManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// will call when sent for update pos
|
// will call when sent for update pos
|
||||||
$rootScope.$on('history_update', (e: CustomEvent) => {
|
$rootScope.$on('history_update', (e) => {
|
||||||
let details = e.detail;
|
let details = e.detail;
|
||||||
|
|
||||||
if(details.mid && details.peerID == this.peerID) {
|
if(details.mid && details.peerID == this.peerID) {
|
||||||
@ -192,7 +192,7 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('history_multiappend', (e: CustomEvent) => {
|
$rootScope.$on('history_multiappend', (e) => {
|
||||||
let msgIDsByPeer = e.detail;
|
let msgIDsByPeer = e.detail;
|
||||||
if(!(this.peerID in msgIDsByPeer)) return;
|
if(!(this.peerID in msgIDsByPeer)) return;
|
||||||
|
|
||||||
@ -201,23 +201,20 @@ export class AppImManager {
|
|||||||
this.renderNewMessagesByIDs(msgIDs);
|
this.renderNewMessagesByIDs(msgIDs);
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('history_delete', (e: CustomEvent) => {
|
$rootScope.$on('history_delete', (e) => {
|
||||||
let detail: {
|
let detail = e.detail;
|
||||||
peerID: string,
|
|
||||||
msgs: {[x: number]: boolean}
|
|
||||||
} = e.detail;
|
|
||||||
|
|
||||||
this.deleteMessagesByIDs(Object.keys(detail.msgs).map(s => +s));
|
this.deleteMessagesByIDs(Object.keys(detail.msgs).map(s => +s));
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('dialog_flush', (e: CustomEvent) => {
|
$rootScope.$on('dialog_flush', (e) => {
|
||||||
let peerID: number = e.detail.peerID;
|
let peerID: number = e.detail.peerID;
|
||||||
if(this.peerID == peerID) {
|
if(this.peerID == peerID) {
|
||||||
this.deleteMessagesByIDs(Object.keys(this.bubbles).map(m => +m));
|
this.deleteMessagesByIDs(Object.keys(this.bubbles).map(m => +m));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('chat_update', (e: CustomEvent) => {
|
$rootScope.$on('chat_update', (e) => {
|
||||||
const peerID: number = e.detail;
|
const peerID: number = e.detail;
|
||||||
if(this.peerID == -peerID) {
|
if(this.peerID == -peerID) {
|
||||||
const chat = appChatsManager.getChat(peerID) as Channel | Chat;
|
const chat = appChatsManager.getChat(peerID) as Channel | Chat;
|
||||||
@ -227,7 +224,7 @@ export class AppImManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Calls when message successfully sent and we have an ID
|
// Calls when message successfully sent and we have an ID
|
||||||
$rootScope.$on('message_sent', (e: CustomEvent) => {
|
$rootScope.$on('message_sent', (e) => {
|
||||||
const {tempID, mid} = e.detail;
|
const {tempID, mid} = e.detail;
|
||||||
|
|
||||||
this.log('message_sent', e.detail);
|
this.log('message_sent', e.detail);
|
||||||
@ -236,14 +233,14 @@ export class AppImManager {
|
|||||||
const message = appMessagesManager.getMessage(mid);
|
const message = appMessagesManager.getMessage(mid);
|
||||||
if(message.media) {
|
if(message.media) {
|
||||||
if(message.media.photo) {
|
if(message.media.photo) {
|
||||||
const photo = appPhotosManager.getPhoto(tempID);
|
const photo = appPhotosManager.getPhoto('' + tempID);
|
||||||
if(/* photo._ != 'photoEmpty' */photo) {
|
if(/* photo._ != 'photoEmpty' */photo) {
|
||||||
const newPhoto = message.media.photo;
|
const newPhoto = message.media.photo;
|
||||||
newPhoto.downloaded = photo.downloaded;
|
newPhoto.downloaded = photo.downloaded;
|
||||||
newPhoto.url = photo.url;
|
newPhoto.url = photo.url;
|
||||||
}
|
}
|
||||||
} else if(message.media.document) {
|
} else if(message.media.document) {
|
||||||
const doc = appDocsManager.getDoc(tempID);
|
const doc = appDocsManager.getDoc('' + tempID);
|
||||||
if(/* doc._ != 'documentEmpty' && */doc?.type && doc.type != 'sticker') {
|
if(/* doc._ != 'documentEmpty' && */doc?.type && doc.type != 'sticker') {
|
||||||
const newDoc = message.media.document;
|
const newDoc = message.media.document;
|
||||||
newDoc.downloaded = doc.downloaded;
|
newDoc.downloaded = doc.downloaded;
|
||||||
@ -272,7 +269,7 @@ export class AppImManager {
|
|||||||
const pollElement = bubble.querySelector('poll-element');
|
const pollElement = bubble.querySelector('poll-element');
|
||||||
if(pollElement) {
|
if(pollElement) {
|
||||||
pollElement.setAttribute('poll-id', newPoll.id);
|
pollElement.setAttribute('poll-id', newPoll.id);
|
||||||
pollElement.setAttribute('message-id', mid);
|
pollElement.setAttribute('message-id', '' + mid);
|
||||||
delete appPollsManager.polls[tempID];
|
delete appPollsManager.polls[tempID];
|
||||||
delete appPollsManager.results[tempID];
|
delete appPollsManager.results[tempID];
|
||||||
}
|
}
|
||||||
@ -286,7 +283,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
bubble.classList.remove('is-sending');
|
bubble.classList.remove('is-sending');
|
||||||
bubble.classList.add('is-sent');
|
bubble.classList.add('is-sent');
|
||||||
bubble.dataset.mid = mid;
|
bubble.dataset.mid = '' + mid;
|
||||||
|
|
||||||
this.bubbleGroups.removeBubble(bubble, tempID);
|
this.bubbleGroups.removeBubble(bubble, tempID);
|
||||||
|
|
||||||
@ -301,7 +298,7 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('message_edit', (e: CustomEvent) => {
|
$rootScope.$on('message_edit', (e) => {
|
||||||
let {peerID, mid, id, justMedia} = e.detail;
|
let {peerID, mid, id, justMedia} = e.detail;
|
||||||
|
|
||||||
if(peerID != this.peerID) return;
|
if(peerID != this.peerID) return;
|
||||||
@ -318,7 +315,7 @@ export class AppImManager {
|
|||||||
this.renderMessage(message, true, false, bubble, false);
|
this.renderMessage(message, true, false, bubble, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('messages_downloaded', (e: CustomEvent) => {
|
$rootScope.$on('messages_downloaded', (e) => {
|
||||||
const mids: number[] = e.detail;
|
const mids: number[] = e.detail;
|
||||||
|
|
||||||
const pinnedMessage = appMessagesManager.getPinnedMessage(this.peerID);
|
const pinnedMessage = appMessagesManager.getPinnedMessage(this.peerID);
|
||||||
@ -351,7 +348,7 @@ export class AppImManager {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
let update = e.detail;
|
let update = e.detail;
|
||||||
|
|
||||||
this.handleUpdate(update);
|
this.handleUpdate(update);
|
||||||
|
@ -9,7 +9,7 @@ import appDocsManager, {MyDocument} from "./appDocsManager";
|
|||||||
import VideoPlayer from "../mediaPlayer";
|
import VideoPlayer from "../mediaPlayer";
|
||||||
import { renderImageFromUrl, parseMenuButtonsTo } from "../../components/misc";
|
import { renderImageFromUrl, parseMenuButtonsTo } from "../../components/misc";
|
||||||
import AvatarElement from "../../components/avatar";
|
import AvatarElement from "../../components/avatar";
|
||||||
import LazyLoadQueue from "../../components/lazyLoadQueue";
|
import LazyLoadQueue, { LazyLoadQueueBase } from "../../components/lazyLoadQueue";
|
||||||
import appForward from "../../components/appForward";
|
import appForward from "../../components/appForward";
|
||||||
import { isSafari, mediaSizes, touchSupport } from "../config";
|
import { isSafari, mediaSizes, touchSupport } from "../config";
|
||||||
import { deferredPromise } from "../polyfill";
|
import { deferredPromise } from "../polyfill";
|
||||||
@ -118,7 +118,7 @@ export class AppMediaViewer {
|
|||||||
private setMoverPromise: Promise<void>;
|
private setMoverPromise: Promise<void>;
|
||||||
private setMoverAnimationPromise: Promise<void>;
|
private setMoverAnimationPromise: Promise<void>;
|
||||||
|
|
||||||
private lazyLoadQueue: LazyLoadQueue;
|
private lazyLoadQueue: LazyLoadQueueBase;
|
||||||
|
|
||||||
private highlightSwitchersTimeout: number;
|
private highlightSwitchersTimeout: number;
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ export class AppMediaViewer {
|
|||||||
|
|
||||||
this.preloaderStreamable = new ProgressivePreloader(undefined, false, true);
|
this.preloaderStreamable = new ProgressivePreloader(undefined, false, true);
|
||||||
|
|
||||||
this.lazyLoadQueue = new LazyLoadQueue(undefined, true);
|
this.lazyLoadQueue = new LazyLoadQueueBase();
|
||||||
|
|
||||||
parseMenuButtonsTo(this.buttons, this.wholeDiv.querySelectorAll(`[class*='menu']`) as NodeListOf<HTMLElement>);
|
parseMenuButtonsTo(this.buttons, this.wholeDiv.querySelectorAll(`[class*='menu']`) as NodeListOf<HTMLElement>);
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ export class AppMediaViewer {
|
|||||||
this.wholeDiv.classList.add('highlight-switchers');
|
this.wholeDiv.classList.add('highlight-switchers');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.highlightSwitchersTimeout = setTimeout(() => {
|
this.highlightSwitchersTimeout = window.setTimeout(() => {
|
||||||
this.wholeDiv.classList.remove('highlight-switchers');
|
this.wholeDiv.classList.remove('highlight-switchers');
|
||||||
this.highlightSwitchersTimeout = 0;
|
this.highlightSwitchersTimeout = 0;
|
||||||
}, 3e3);
|
}, 3e3);
|
||||||
@ -1075,8 +1075,7 @@ export class AppMediaViewer {
|
|||||||
|
|
||||||
this.lazyLoadQueue.unshift({
|
this.lazyLoadQueue.unshift({
|
||||||
div: null,
|
div: null,
|
||||||
load,
|
load
|
||||||
wasSeen: true
|
|
||||||
});
|
});
|
||||||
//} else createPlayer();
|
//} else createPlayer();
|
||||||
});
|
});
|
||||||
@ -1140,8 +1139,7 @@ export class AppMediaViewer {
|
|||||||
|
|
||||||
this.lazyLoadQueue.unshift({
|
this.lazyLoadQueue.unshift({
|
||||||
div: null,
|
div: null,
|
||||||
load,
|
load
|
||||||
wasSeen: true
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { $rootScope, copy, tsNow, safeReplaceObject, dT, listMergeSorted, deepEqual, langPack } from "../utils";
|
import { $rootScope, copy, tsNow, safeReplaceObject, listMergeSorted, deepEqual, langPack } from "../utils";
|
||||||
import appMessagesIDsManager from "./appMessagesIDsManager";
|
import appMessagesIDsManager from "./appMessagesIDsManager";
|
||||||
import appChatsManager from "./appChatsManager";
|
import appChatsManager from "./appChatsManager";
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
@ -231,7 +231,7 @@ export class FiltersStorage {
|
|||||||
public orderIndex = 0;
|
public orderIndex = 0;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
this.handleUpdate(e.detail);
|
this.handleUpdate(e.detail);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -476,7 +476,7 @@ export class AppMessagesManager {
|
|||||||
public lastSearchFilter: any = {};
|
public lastSearchFilter: any = {};
|
||||||
public lastSearchResults: any = [];
|
public lastSearchResults: any = [];
|
||||||
|
|
||||||
public needSingleMessages: any = [];
|
public needSingleMessages: number[] = [];
|
||||||
public fetchSingleMessagesTimeout = 0;
|
public fetchSingleMessagesTimeout = 0;
|
||||||
private fetchSingleMessagesPromise: Promise<any> = null;
|
private fetchSingleMessagesPromise: Promise<any> = null;
|
||||||
|
|
||||||
@ -486,7 +486,7 @@ export class AppMessagesManager {
|
|||||||
public migratedToFrom: {[peerID: number]: number} = {};
|
public migratedToFrom: {[peerID: number]: number} = {};
|
||||||
|
|
||||||
public newMessagesHandlePromise = 0;
|
public newMessagesHandlePromise = 0;
|
||||||
public newMessagesToHandle: any = {};
|
public newMessagesToHandle: {[peerID: string]: number[]} = {};
|
||||||
public newDialogsHandlePromise = 0;
|
public newDialogsHandlePromise = 0;
|
||||||
public newDialogsToHandle: {[peerID: string]: {reload: true} | Dialog} = {};
|
public newDialogsToHandle: {[peerID: string]: {reload: true} | Dialog} = {};
|
||||||
public newUpdatesAfterReloadToHandle: any = {};
|
public newUpdatesAfterReloadToHandle: any = {};
|
||||||
@ -511,11 +511,11 @@ export class AppMessagesManager {
|
|||||||
public filtersStorage = new FiltersStorage();
|
public filtersStorage = new FiltersStorage();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
this.handleUpdate(e.detail);
|
this.handleUpdate(e.detail);
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('webpage_updated', (e: CustomEvent) => {
|
$rootScope.$on('webpage_updated', (e) => {
|
||||||
let eventData = e.detail;
|
let eventData = e.detail;
|
||||||
eventData.msgs.forEach((msgID: number) => {
|
eventData.msgs.forEach((msgID: number) => {
|
||||||
let message = this.getMessage(msgID);
|
let message = this.getMessage(msgID);
|
||||||
@ -529,7 +529,7 @@ export class AppMessagesManager {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('draft_updated', (e: CustomEvent) => {
|
/* $rootScope.$on('draft_updated', (e) => {
|
||||||
let eventData = e.detail;;
|
let eventData = e.detail;;
|
||||||
var peerID = eventData.peerID;
|
var peerID = eventData.peerID;
|
||||||
var draft = eventData.draft;
|
var draft = eventData.draft;
|
||||||
@ -558,12 +558,12 @@ export class AppMessagesManager {
|
|||||||
this.dialogsStorage.pushDialog(dialog);
|
this.dialogsStorage.pushDialog(dialog);
|
||||||
|
|
||||||
$rootScope.$broadcast('dialog_draft', {
|
$rootScope.$broadcast('dialog_draft', {
|
||||||
peerID: peerID,
|
peerID,
|
||||||
draft: draft,
|
draft,
|
||||||
index: dialog.index
|
index: dialog.index
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
}); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -847,7 +847,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
this.saveMessages([message]);
|
this.saveMessages([message]);
|
||||||
historyStorage.pending.unshift(messageID);
|
historyStorage.pending.unshift(messageID);
|
||||||
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true});
|
$rootScope.$broadcast('history_append', {peerID, messageID, my: true});
|
||||||
|
|
||||||
setTimeout(() => message.send(), 0);
|
setTimeout(() => message.send(), 0);
|
||||||
// setTimeout(function () {
|
// setTimeout(function () {
|
||||||
@ -1216,7 +1216,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
this.saveMessages([message]);
|
this.saveMessages([message]);
|
||||||
historyStorage.pending.unshift(messageID);
|
historyStorage.pending.unshift(messageID);
|
||||||
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true});
|
$rootScope.$broadcast('history_append', {peerID, messageID, my: true});
|
||||||
|
|
||||||
setTimeout(message.send.bind(this), 0);
|
setTimeout(message.send.bind(this), 0);
|
||||||
|
|
||||||
@ -1370,7 +1370,7 @@ export class AppMessagesManager {
|
|||||||
return message;
|
return message;
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messages[messages.length - 1].id, my: true});
|
$rootScope.$broadcast('history_append', {peerID, messageID: messages[messages.length - 1].id, my: true});
|
||||||
|
|
||||||
let toggleError = (message: any, on: boolean) => {
|
let toggleError = (message: any, on: boolean) => {
|
||||||
if(on) {
|
if(on) {
|
||||||
@ -1730,7 +1730,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
this.saveMessages([message]);
|
this.saveMessages([message]);
|
||||||
historyStorage.pending.unshift(messageID);
|
historyStorage.pending.unshift(messageID);
|
||||||
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true});
|
$rootScope.$broadcast('history_append', {peerID, messageID, my: true});
|
||||||
|
|
||||||
setTimeout(message.send, 0);
|
setTimeout(message.send, 0);
|
||||||
|
|
||||||
@ -1876,20 +1876,25 @@ export class AppMessagesManager {
|
|||||||
//flags |= 1; // means pinned already loaded
|
//flags |= 1; // means pinned already loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if(this.dialogsStorage.dialogsOffsetDate[0]) {
|
||||||
|
flags |= 1; // means pinned already loaded
|
||||||
|
} */
|
||||||
|
|
||||||
//if(folderID > 0) {
|
//if(folderID > 0) {
|
||||||
//flags |= 1;
|
//flags |= 1;
|
||||||
flags |= 2;
|
flags |= 2;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// ! ВНИМАНИЕ: ОЧЕНЬ СЛОЖНАЯ ЛОГИКА:
|
// ! ВНИМАНИЕ: ОЧЕНЬ СЛОЖНАЯ ЛОГИКА:
|
||||||
// ! если делать запрос сначала по папке 0, потом по папке 1, по индексу 0 в массиве будет один и тот же диалог, при условии что он закреплён в обеих папках, ЛОЛ???
|
// ! если делать запрос сначала по папке 0, потом по папке 1, по индексу 0 в массиве будет один и тот же диалог, с dialog.pFlags.pinned, ЛОЛ???
|
||||||
|
// ! т.е., с запросом folder_id: 1, и exclude_pinned: 0, в результате будут ещё и закреплённые с папки 0
|
||||||
return apiManager.invokeApi('messages.getDialogs', {
|
return apiManager.invokeApi('messages.getDialogs', {
|
||||||
flags: flags,
|
flags,
|
||||||
folder_id: folderID,
|
folder_id: folderID,
|
||||||
offset_date: offsetDate,
|
offset_date: offsetDate,
|
||||||
offset_id: appMessagesIDsManager.getMessageLocalID(offsetID),
|
offset_id: appMessagesIDsManager.getMessageLocalID(offsetID),
|
||||||
offset_peer: appPeersManager.getInputPeerByID(offsetPeerID),
|
offset_peer: appPeersManager.getInputPeerByID(offsetPeerID),
|
||||||
limit: limit,
|
limit,
|
||||||
hash: 0
|
hash: 0
|
||||||
}, {
|
}, {
|
||||||
//timeout: APITIMEOUT,
|
//timeout: APITIMEOUT,
|
||||||
@ -1897,7 +1902,7 @@ export class AppMessagesManager {
|
|||||||
}).then((dialogsResult) => {
|
}).then((dialogsResult) => {
|
||||||
if(dialogsResult._ == 'messages.dialogsNotModified') return null;
|
if(dialogsResult._ == 'messages.dialogsNotModified') return null;
|
||||||
|
|
||||||
//this.log.error('messages.getDialogs result:', {...dialogsResult.dialogs[0]});
|
//this.log.error('messages.getDialogs result:', dialogsResult.dialogs, {...dialogsResult.dialogs[0]});
|
||||||
|
|
||||||
if(!offsetDate) {
|
if(!offsetDate) {
|
||||||
telegramMeWebService.setAuthorized(true);
|
telegramMeWebService.setAuthorized(true);
|
||||||
@ -1909,7 +1914,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
let maxSeenIdIncremented = offsetDate ? true : false;
|
let maxSeenIdIncremented = offsetDate ? true : false;
|
||||||
let hasPrepend = false;
|
let hasPrepend = false;
|
||||||
let noIDsDialogs: {[peerID: number]: Dialog} = {};
|
const noIDsDialogs: {[peerID: number]: Dialog} = {};
|
||||||
(dialogsResult.dialogs as Dialog[]).forEachReverse(dialog => {
|
(dialogsResult.dialogs as Dialog[]).forEachReverse(dialog => {
|
||||||
//const d = Object.assign({}, dialog);
|
//const d = Object.assign({}, dialog);
|
||||||
// ! нужно передавать folderID, так как по папке != 0 нет свойства folder_id
|
// ! нужно передавать folderID, так как по папке != 0 нет свойства folder_id
|
||||||
@ -2561,7 +2566,7 @@ export class AppMessagesManager {
|
|||||||
$rootScope.$broadcast('dialog_drop', {peerID: migrateFrom, dialog: dropped[0]});
|
$rootScope.$broadcast('dialog_drop', {peerID: migrateFrom, dialog: dropped[0]});
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.$broadcast('dialog_migrate', {migrateFrom: migrateFrom, migrateTo: migrateTo});
|
$rootScope.$broadcast('dialog_migrate', {migrateFrom, migrateTo});
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2756,7 +2761,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
this.historiesStorage[peerID] = historyStorage;
|
this.historiesStorage[peerID] = historyStorage;
|
||||||
if(this.mergeReplyKeyboard(historyStorage, message)) {
|
if(this.mergeReplyKeyboard(historyStorage, message)) {
|
||||||
$rootScope.$broadcast('history_reply_markup', {peerID: peerID});
|
$rootScope.$broadcast('history_reply_markup', {peerID});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3209,7 +3214,7 @@ export class AppMessagesManager {
|
|||||||
apiPromise = apiManager.invokeApi('messages.readHistory', {
|
apiPromise = apiManager.invokeApi('messages.readHistory', {
|
||||||
peer: appPeersManager.getInputPeerByID(peerID),
|
peer: appPeersManager.getInputPeerByID(peerID),
|
||||||
max_id: maxID
|
max_id: maxID
|
||||||
}).then((affectedMessages: any) => {
|
}).then((affectedMessages) => {
|
||||||
apiUpdatesManager.processUpdateMessage({
|
apiUpdatesManager.processUpdateMessage({
|
||||||
_: 'updateShort',
|
_: 'updateShort',
|
||||||
update: {
|
update: {
|
||||||
@ -3299,7 +3304,7 @@ export class AppMessagesManager {
|
|||||||
} else {
|
} else {
|
||||||
apiManager.invokeApi('messages.readMessageContents', {
|
apiManager.invokeApi('messages.readMessageContents', {
|
||||||
id: msgIDs
|
id: msgIDs
|
||||||
}).then((affectedMessages: any) => {
|
}).then((affectedMessages) => {
|
||||||
apiUpdatesManager.processUpdateMessage({
|
apiUpdatesManager.processUpdateMessage({
|
||||||
_: 'updateShort',
|
_: 'updateShort',
|
||||||
update: {
|
update: {
|
||||||
@ -3385,7 +3390,7 @@ export class AppMessagesManager {
|
|||||||
var topMsgID = history[0];
|
var topMsgID = history[0];
|
||||||
history.unshift(message.mid);
|
history.unshift(message.mid);
|
||||||
if(message.mid > 0 && message.mid < topMsgID) {
|
if(message.mid > 0 && message.mid < topMsgID) {
|
||||||
history.sort((a: any, b: any) => {
|
history.sort((a, b) => {
|
||||||
return b - a;
|
return b - a;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3396,7 +3401,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(this.mergeReplyKeyboard(historyStorage, message)) {
|
if(this.mergeReplyKeyboard(historyStorage, message)) {
|
||||||
$rootScope.$broadcast('history_reply_markup', {peerID: peerID});
|
$rootScope.$broadcast('history_reply_markup', {peerID});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!message.pFlags.out && message.from_id) {
|
if(!message.pFlags.out && message.from_id) {
|
||||||
@ -3408,7 +3413,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
if(randomID) {
|
if(randomID) {
|
||||||
if(pendingMessage = this.finalizePendingMessage(randomID, message)) {
|
if(pendingMessage = this.finalizePendingMessage(randomID, message)) {
|
||||||
$rootScope.$broadcast('history_update', {peerID: peerID, mid: message.mid});
|
$rootScope.$broadcast('history_update', {peerID, mid: message.mid});
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.pendingByMessageID[message.mid];
|
delete this.pendingByMessageID[message.mid];
|
||||||
@ -3542,11 +3547,11 @@ export class AppMessagesManager {
|
|||||||
dialogsResult.dialogs.reverse();
|
dialogsResult.dialogs.reverse();
|
||||||
this.applyConversations(dialogsResult);
|
this.applyConversations(dialogsResult);
|
||||||
|
|
||||||
dialogsResult.dialogs.forEach((dialog: any) => {
|
dialogsResult.dialogs.forEach((dialog) => {
|
||||||
newPinned[dialog.peerID] = true;
|
newPinned[dialog.peerID] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dialogsStorage.getFolder(folderID).forEach((dialog: any) => {
|
this.dialogsStorage.getFolder(folderID).forEach((dialog) => {
|
||||||
const peerID = dialog.peerID;
|
const peerID = dialog.peerID;
|
||||||
if(dialog.pFlags.pinned && !newPinned[peerID]) {
|
if(dialog.pFlags.pinned && !newPinned[peerID]) {
|
||||||
this.newDialogsToHandle[peerID] = {reload: true};
|
this.newDialogsToHandle[peerID] = {reload: true};
|
||||||
@ -3626,7 +3631,7 @@ export class AppMessagesManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(isTopMessage) {
|
if(isTopMessage) {
|
||||||
var updatedDialogs: any = {};
|
var updatedDialogs: {[peerID: number]: Dialog} = {};
|
||||||
updatedDialogs[peerID] = dialog;
|
updatedDialogs[peerID] = dialog;
|
||||||
$rootScope.$broadcast('dialogs_multiupdate', updatedDialogs);
|
$rootScope.$broadcast('dialogs_multiupdate', updatedDialogs);
|
||||||
}
|
}
|
||||||
@ -3889,10 +3894,7 @@ export class AppMessagesManager {
|
|||||||
let message = this.getMessage(mid);
|
let message = this.getMessage(mid);
|
||||||
if(message && message.views && message.views < views) {
|
if(message && message.views && message.views < views) {
|
||||||
message.views = views;
|
message.views = views;
|
||||||
$rootScope.$broadcast('message_views', {
|
$rootScope.$broadcast('message_views', {mid, views});
|
||||||
mid: mid,
|
|
||||||
views: views
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3987,7 +3989,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
public finalizePendingMessageCallbacks(tempID: number, mid: number) {
|
public finalizePendingMessageCallbacks(tempID: number, mid: number) {
|
||||||
var callbacks = this.tempFinalizeCallbacks[tempID];
|
var callbacks = this.tempFinalizeCallbacks[tempID];
|
||||||
this.log.warn(dT(), callbacks, tempID);
|
this.log.warn(callbacks, tempID);
|
||||||
if(callbacks !== undefined) {
|
if(callbacks !== undefined) {
|
||||||
callbacks.forEach((callback: any) => {
|
callbacks.forEach((callback: any) => {
|
||||||
callback(mid);
|
callback(mid);
|
||||||
@ -4003,9 +4005,9 @@ export class AppMessagesManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppStorage.set({
|
this.maxSeenID = maxID;
|
||||||
max_seen_msg: maxID
|
|
||||||
});
|
AppStorage.set({max_seen_msg: maxID});
|
||||||
|
|
||||||
apiManager.invokeApi('messages.receivedMessages', {
|
apiManager.invokeApi('messages.receivedMessages', {
|
||||||
max_id: maxID
|
max_id: maxID
|
||||||
@ -4149,7 +4151,7 @@ export class AppMessagesManager {
|
|||||||
historyStorage.history.splice(offset, historyStorage.history.length - offset);
|
historyStorage.history.splice(offset, historyStorage.history.length - offset);
|
||||||
historyResult.messages.forEach((message: any) => {
|
historyResult.messages.forEach((message: any) => {
|
||||||
if(this.mergeReplyKeyboard(historyStorage, message)) {
|
if(this.mergeReplyKeyboard(historyStorage, message)) {
|
||||||
$rootScope.$broadcast('history_reply_markup', {peerID: peerID});
|
$rootScope.$broadcast('history_reply_markup', {peerID});
|
||||||
}
|
}
|
||||||
|
|
||||||
historyStorage.history.push(message.mid);
|
historyStorage.history.push(message.mid);
|
||||||
|
@ -75,7 +75,7 @@ class AppPollsManager {
|
|||||||
private log = logger('POLLS', LogLevels.error);
|
private log = logger('POLLS', LogLevels.error);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
let update = e.detail;
|
let update = e.detail;
|
||||||
|
|
||||||
this.handleUpdate(update);
|
this.handleUpdate(update);
|
||||||
|
@ -249,7 +249,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('dialogs_archived_unread', (e: CustomEvent) => {
|
$rootScope.$on('dialogs_archived_unread', (e) => {
|
||||||
this.archivedCount.innerText = '' + e.detail.count;
|
this.archivedCount.innerText = '' + e.detail.count;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class AppStickersManager {
|
|||||||
//}
|
//}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
const update = e.detail;
|
const update = e.detail;
|
||||||
|
|
||||||
switch(update._) {
|
switch(update._) {
|
||||||
@ -121,7 +121,7 @@ class AppStickersManager {
|
|||||||
|
|
||||||
//console.log('stickers wrote', this.stickerSets);
|
//console.log('stickers wrote', this.stickerSets);
|
||||||
if(this.saveSetsTimeout) return;
|
if(this.saveSetsTimeout) return;
|
||||||
this.saveSetsTimeout = setTimeout(() => {
|
this.saveSetsTimeout = window.setTimeout(() => {
|
||||||
const savedSets: {[id: string]: MessagesStickerSet} = {};
|
const savedSets: {[id: string]: MessagesStickerSet} = {};
|
||||||
for(const id in this.stickerSets) {
|
for(const id in this.stickerSets) {
|
||||||
const set = this.stickerSets[id];
|
const set = this.stickerSets[id];
|
||||||
|
@ -64,7 +64,7 @@ export class AppUsersManager {
|
|||||||
this.myID = id;
|
this.myID = id;
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on('user_auth', (e: CustomEvent) => {
|
$rootScope.$on('user_auth', (e) => {
|
||||||
let userAuth = e.detail;
|
let userAuth = e.detail;
|
||||||
this.myID = userAuth ? userAuth.id : 0;
|
this.myID = userAuth ? userAuth.id : 0;
|
||||||
});
|
});
|
||||||
@ -73,7 +73,7 @@ export class AppUsersManager {
|
|||||||
|
|
||||||
$rootScope.$on('stateSynchronized', this.updateUsersStatuses.bind(this));
|
$rootScope.$on('stateSynchronized', this.updateUsersStatuses.bind(this));
|
||||||
|
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
let update = e.detail;
|
let update = e.detail;
|
||||||
//console.log('on apiUpdate', update);
|
//console.log('on apiUpdate', update);
|
||||||
switch(update._) {
|
switch(update._) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { $rootScope, safeReplaceObject, copy } from "../utils";
|
import { $rootScope, safeReplaceObject } from "../utils";
|
||||||
import appPhotosManager from "./appPhotosManager";
|
import appPhotosManager from "./appPhotosManager";
|
||||||
import appDocsManager from "./appDocsManager";
|
import appDocsManager from "./appDocsManager";
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
@ -8,7 +8,7 @@ class AppWebPagesManager {
|
|||||||
pendingWebPages: any = {};
|
pendingWebPages: any = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
let update = e.detail;
|
let update = e.detail;
|
||||||
|
|
||||||
switch(update._) {
|
switch(update._) {
|
||||||
@ -91,9 +91,9 @@ class AppWebPagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!messageID && this.pendingWebPages[apiWebPage.id] !== undefined) {
|
if(!messageID && this.pendingWebPages[apiWebPage.id] !== undefined) {
|
||||||
var msgs = [];
|
const msgs: number[] = [];
|
||||||
for(let msgID in this.pendingWebPages[apiWebPage.id]) {
|
for(let msgID in this.pendingWebPages[apiWebPage.id]) {
|
||||||
msgs.push(msgID);
|
msgs.push(+msgID);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.$broadcast('webpage_updated', {
|
$rootScope.$broadcast('webpage_updated', {
|
||||||
|
@ -279,7 +279,7 @@ export class RLottiePlayer {
|
|||||||
|
|
||||||
if(delta < 0) {
|
if(delta < 0) {
|
||||||
if(this.rafId) clearTimeout(this.rafId);
|
if(this.rafId) clearTimeout(this.rafId);
|
||||||
return this.rafId = setTimeout(() => {
|
return this.rafId = window.setTimeout(() => {
|
||||||
this.renderFrame2(frame, frameNo);
|
this.renderFrame2(frame, frameNo);
|
||||||
}, this.frInterval > -delta ? -delta % this.frInterval : this.frInterval);
|
}, this.frInterval > -delta ? -delta % this.frInterval : this.frInterval);
|
||||||
//await new Promise((resolve) => setTimeout(resolve, -delta % this.frInterval));
|
//await new Promise((resolve) => setTimeout(resolve, -delta % this.frInterval));
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { Dialog } from "./appManagers/appMessagesManager";
|
import type { StickerSet } from "../layer";
|
||||||
|
import type { MyDocument } from "./appManagers/appDocsManager";
|
||||||
|
import type { Poll, PollResults } from "./appManagers/appPollsManager";
|
||||||
|
import type { AppMessagesManager, Dialog, MyDialogFilter } from "./appManagers/appMessagesManager";
|
||||||
/*!
|
/*!
|
||||||
* Webogram v0.7.0 - messaging web application for MTProto
|
* Webogram v0.7.0 - messaging web application for MTProto
|
||||||
* https://github.com/zhukov/webogram
|
* https://github.com/zhukov/webogram
|
||||||
@ -153,55 +156,58 @@ export function getRichElementValue(node: any, lines: string[], line: string[],
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
type BroadcastEvents = {
|
type BroadcastEvents = {
|
||||||
'download_progress': any,
|
'user_update': number,
|
||||||
'user_update': any,
|
'user_auth': {dcID?: number, id: number},
|
||||||
'user_auth': any,
|
'peer_changed': number,
|
||||||
'peer_changed': any,
|
|
||||||
|
|
||||||
'filter_delete': any,
|
'filter_delete': MyDialogFilter,
|
||||||
'filter_update': any,
|
'filter_update': MyDialogFilter,
|
||||||
|
|
||||||
'dialog_draft': any,
|
'dialog_draft': {peerID: number, draft: any, index: number},
|
||||||
'dialog_unread': {peerID: number, count?: number},
|
'dialog_unread': {peerID: number, count?: number},
|
||||||
'dialog_flush': {peerID: number},
|
'dialog_flush': {peerID: number},
|
||||||
'dialog_drop': {peerID: number, dialog?: Dialog},
|
'dialog_drop': {peerID: number, dialog?: Dialog},
|
||||||
'dialog_migrate': any,
|
'dialog_migrate': {migrateFrom: number, migrateTo: number},
|
||||||
'dialog_top': Dialog,
|
'dialog_top': Dialog,
|
||||||
'dialog_notify_settings': number,
|
'dialog_notify_settings': number,
|
||||||
'dialogs_multiupdate': {[peerID: string]: Dialog},
|
'dialogs_multiupdate': {[peerID: string]: Dialog},
|
||||||
'dialogs_archived_unread': any,
|
'dialogs_archived_unread': {count: number},
|
||||||
|
|
||||||
'history_append': any,
|
'history_append': {peerID: number, messageID: number, my?: boolean},
|
||||||
'history_update': any,
|
'history_update': {peerID: number, mid: number},
|
||||||
'history_reply_markup': any,
|
'history_reply_markup': {peerID: number},
|
||||||
'history_multiappend': any,
|
'history_multiappend': AppMessagesManager['newMessagesToHandle'],
|
||||||
'history_delete': {peerID: number, msgs: {[mid: number]: true}},
|
'history_delete': {peerID: number, msgs: {[mid: number]: true}},
|
||||||
'history_forbidden': number,
|
'history_forbidden': number,
|
||||||
'history_reload': number,
|
'history_reload': number,
|
||||||
'history_request': any,
|
'history_request': void,
|
||||||
|
|
||||||
'message_edit': any,
|
'message_edit': {peerID: number, id: number, mid: number, justMedia: boolean},
|
||||||
'message_views': any,
|
'message_views': {mid: number, views: number},
|
||||||
'message_sent': any,
|
'message_sent': {tempID: number, mid: number},
|
||||||
'messages_pending': void,
|
'messages_pending': void,
|
||||||
'messages_read': any,
|
'messages_read': void,
|
||||||
'messages_downloaded': any,
|
'messages_downloaded': number[],
|
||||||
|
|
||||||
|
'stickers_installed': StickerSet.stickerSet,
|
||||||
|
'stickers_deleted': StickerSet.stickerSet,
|
||||||
|
|
||||||
|
'audio_play': {doc: MyDocument, mid: number},
|
||||||
|
'audio_pause': void,
|
||||||
|
|
||||||
|
//'contacts_update': any,
|
||||||
|
'avatar_update': number,
|
||||||
|
'chat_full_update': number,
|
||||||
|
'peer_pinned_message': number,
|
||||||
|
'poll_update': {poll: Poll, results: PollResults},
|
||||||
|
'chat_update': number,
|
||||||
|
'stateSynchronized': void,
|
||||||
|
'channel_settings': {channelID: number},
|
||||||
|
'webpage_updated': {id: string, msgs: number[]},
|
||||||
|
|
||||||
'contacts_update': any,
|
|
||||||
'avatar_update': any,
|
|
||||||
'stickers_installed': any,
|
|
||||||
'stickers_deleted': any,
|
|
||||||
'chat_full_update': any,
|
|
||||||
'peer_pinned_message': any,
|
|
||||||
'poll_update': any,
|
|
||||||
'audio_play': any,
|
|
||||||
'audio_pause': any,
|
|
||||||
'chat_update': any,
|
|
||||||
'apiUpdate': any,
|
'apiUpdate': any,
|
||||||
'stateSynchronized': any,
|
'download_progress': any,
|
||||||
'channel_settings': any,
|
//'draft_updated': any,
|
||||||
'webpage_updated': any,
|
|
||||||
'draft_updated': any,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const $rootScope = {
|
export const $rootScope = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user