|
|
@ -71,6 +71,8 @@ import whichChild from "../../helpers/dom/whichChild"; |
|
|
|
import { cancelAnimationByKey } from "../../helpers/animation"; |
|
|
|
import { cancelAnimationByKey } from "../../helpers/animation"; |
|
|
|
import assumeType from "../../helpers/assumeType"; |
|
|
|
import assumeType from "../../helpers/assumeType"; |
|
|
|
import { EmoticonsDropdown } from "../emoticonsDropdown"; |
|
|
|
import { EmoticonsDropdown } from "../emoticonsDropdown"; |
|
|
|
|
|
|
|
import debounce from "../../helpers/schedulers/debounce"; |
|
|
|
|
|
|
|
import { formatNumber } from "../../helpers/number"; |
|
|
|
|
|
|
|
|
|
|
|
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([ |
|
|
@ -162,6 +164,10 @@ export default class ChatBubbles { |
|
|
|
private resolveLadderAnimation: () => Promise<any>; |
|
|
|
private resolveLadderAnimation: () => Promise<any>; |
|
|
|
private emptyPlaceholderMid: number; |
|
|
|
private emptyPlaceholderMid: number; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private viewsObserver: IntersectionObserver; |
|
|
|
|
|
|
|
private viewsMids: Set<number> = new Set(); |
|
|
|
|
|
|
|
private sendViewCountersDebounced: () => Promise<void>; |
|
|
|
|
|
|
|
|
|
|
|
constructor(private chat: Chat, |
|
|
|
constructor(private chat: Chat, |
|
|
|
private appMessagesManager: AppMessagesManager, |
|
|
|
private appMessagesManager: AppMessagesManager, |
|
|
|
private appStickersManager: AppStickersManager, |
|
|
|
private appStickersManager: AppStickersManager, |
|
|
@ -580,6 +586,27 @@ export default class ChatBubbles { |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.listenerSetter.add(rootScope)('message_views', (e) => { |
|
|
|
|
|
|
|
if(this.peerId !== e.peerId) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fastRaf(() => { |
|
|
|
|
|
|
|
const bubble = this.bubbles[e.mid]; |
|
|
|
|
|
|
|
if(!bubble) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const postViewsElements = Array.from(bubble.querySelectorAll('.post-views')) as HTMLElement[]; |
|
|
|
|
|
|
|
if(postViewsElements.length) { |
|
|
|
|
|
|
|
const str = formatNumber(e.views, 1); |
|
|
|
|
|
|
|
let different = false; |
|
|
|
|
|
|
|
postViewsElements.forEach(postViews => { |
|
|
|
|
|
|
|
if(different || postViews.innerHTML !== str) { |
|
|
|
|
|
|
|
different = true; |
|
|
|
|
|
|
|
postViews.innerHTML = str; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.unreadedObserver = new IntersectionObserver((entries) => { |
|
|
|
this.unreadedObserver = new IntersectionObserver((entries) => { |
|
|
|
entries.forEach(entry => { |
|
|
|
entries.forEach(entry => { |
|
|
|
if(entry.isIntersecting) { |
|
|
|
if(entry.isIntersecting) { |
|
|
@ -590,6 +617,23 @@ export default class ChatBubbles { |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.viewsObserver = new IntersectionObserver((entries) => { |
|
|
|
|
|
|
|
entries.forEach(entry => { |
|
|
|
|
|
|
|
if(entry.isIntersecting) { |
|
|
|
|
|
|
|
this.viewsMids.add(+(entry.target as HTMLElement).dataset.mid); |
|
|
|
|
|
|
|
this.viewsObserver.unobserve(entry.target); |
|
|
|
|
|
|
|
this.sendViewCountersDebounced(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.sendViewCountersDebounced = debounce(() => { |
|
|
|
|
|
|
|
const mids = [...this.viewsMids]; |
|
|
|
|
|
|
|
this.viewsMids.clear(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.appMessagesManager.incrementMessageViews(this.peerId, mids); |
|
|
|
|
|
|
|
}, 1000, false, true); |
|
|
|
|
|
|
|
|
|
|
|
if('ResizeObserver' in window) { |
|
|
|
if('ResizeObserver' in window) { |
|
|
|
let wasHeight = this.scrollable.container.offsetHeight; |
|
|
|
let wasHeight = this.scrollable.container.offsetHeight; |
|
|
|
let resizing = false; |
|
|
|
let resizing = false; |
|
|
@ -1291,6 +1335,10 @@ export default class ChatBubbles { |
|
|
|
this.unreadedObserver.unobserve(bubble); |
|
|
|
this.unreadedObserver.unobserve(bubble); |
|
|
|
this.unreaded.delete(bubble); |
|
|
|
this.unreaded.delete(bubble); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(this.viewsObserver) { |
|
|
|
|
|
|
|
this.viewsObserver.unobserve(bubble); |
|
|
|
|
|
|
|
this.viewsMids.delete(mid); |
|
|
|
|
|
|
|
} |
|
|
|
//this.unreaded.findAndSplice(mid => mid === id);
|
|
|
|
//this.unreaded.findAndSplice(mid => mid === id);
|
|
|
|
bubble.remove(); |
|
|
|
bubble.remove(); |
|
|
|
//bubble.remove();
|
|
|
|
//bubble.remove();
|
|
|
@ -1515,10 +1563,12 @@ export default class ChatBubbles { |
|
|
|
|
|
|
|
|
|
|
|
this.lazyLoadQueue.clear(); |
|
|
|
this.lazyLoadQueue.clear(); |
|
|
|
this.unreadedObserver && this.unreadedObserver.disconnect(); |
|
|
|
this.unreadedObserver && this.unreadedObserver.disconnect(); |
|
|
|
|
|
|
|
this.viewsObserver && this.viewsObserver.disconnect(); |
|
|
|
this.stickyIntersector && this.stickyIntersector.disconnect(); |
|
|
|
this.stickyIntersector && this.stickyIntersector.disconnect(); |
|
|
|
|
|
|
|
|
|
|
|
delete this.lazyLoadQueue; |
|
|
|
delete this.lazyLoadQueue; |
|
|
|
this.unreadedObserver && delete this.unreadedObserver; |
|
|
|
this.unreadedObserver && delete this.unreadedObserver; |
|
|
|
|
|
|
|
this.viewsObserver && delete this.viewsObserver; |
|
|
|
this.stickyIntersector && delete this.stickyIntersector; |
|
|
|
this.stickyIntersector && delete this.stickyIntersector; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1570,6 +1620,11 @@ export default class ChatBubbles { |
|
|
|
this.readPromise = undefined; |
|
|
|
this.readPromise = undefined; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(this.viewsObserver) { |
|
|
|
|
|
|
|
this.viewsObserver.disconnect(); |
|
|
|
|
|
|
|
this.viewsMids.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.loadedTopTimes = this.loadedBottomTimes = 0; |
|
|
|
this.loadedTopTimes = this.loadedBottomTimes = 0; |
|
|
|
|
|
|
|
|
|
|
|
this.middleware.clean(); |
|
|
|
this.middleware.clean(); |
|
|
@ -2012,7 +2067,11 @@ export default class ChatBubbles { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.bubbleGroups.addBubble(bubble, message, reverse); |
|
|
|
if(message._ === 'message') { |
|
|
|
|
|
|
|
this.bubbleGroups.addBubble(bubble, message, reverse); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
bubble.classList.add('is-group-first', 'is-group-last'); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public getMiddleware() { |
|
|
|
public getMiddleware() { |
|
|
@ -2227,6 +2286,10 @@ export default class ChatBubbles { |
|
|
|
bubbleContainer.prepend(messageDiv); |
|
|
|
bubbleContainer.prepend(messageDiv); |
|
|
|
//bubble.prepend(timeSpan, messageDiv); // that's bad
|
|
|
|
//bubble.prepend(timeSpan, messageDiv); // that's bad
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(message.views && !message.pFlags.is_outgoing && this.viewsObserver) { |
|
|
|
|
|
|
|
this.viewsObserver.observe(bubble); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(message.reply_markup && message.reply_markup._ === 'replyInlineMarkup' && message.reply_markup.rows && message.reply_markup.rows.length) { |
|
|
|
if(message.reply_markup && message.reply_markup._ === 'replyInlineMarkup' && message.reply_markup.rows && message.reply_markup.rows.length) { |
|
|
|
const rows = (message.reply_markup as ReplyMarkup.replyKeyboardMarkup).rows; |
|
|
|
const rows = (message.reply_markup as ReplyMarkup.replyKeyboardMarkup).rows; |
|
|
|
|
|
|
|
|
|
|
@ -2421,9 +2484,9 @@ export default class ChatBubbles { |
|
|
|
case 'messageMediaWebPage': { |
|
|
|
case 'messageMediaWebPage': { |
|
|
|
processingWebPage = true; |
|
|
|
processingWebPage = true; |
|
|
|
|
|
|
|
|
|
|
|
let webpage: WebPage.webPage | WebPage.webPageEmpty = messageMedia.webpage; |
|
|
|
let webpage: WebPage = messageMedia.webpage; |
|
|
|
////////this.log('messageMediaWebPage', webpage);
|
|
|
|
////////this.log('messageMediaWebPage', webpage);
|
|
|
|
if(webpage._ === 'webPageEmpty') { |
|
|
|
if(webpage._ !== 'webPage') { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2445,10 +2508,8 @@ export default class ChatBubbles { |
|
|
|
previewResizer.append(preview); |
|
|
|
previewResizer.append(preview); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let doc: any = null; |
|
|
|
const doc = webpage.document as MyDocument; |
|
|
|
if(webpage.document) { |
|
|
|
if(doc) { |
|
|
|
doc = webpage.document; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(doc.type === 'gif' || doc.type === 'video') { |
|
|
|
if(doc.type === 'gif' || doc.type === 'video') { |
|
|
|
//if(doc.size <= 20e6) {
|
|
|
|
//if(doc.size <= 20e6) {
|
|
|
|
bubble.classList.add('video'); |
|
|
|
bubble.classList.add('video'); |
|
|
|