added more emoji's & coloring animated emoji stickers & dates chat fix
This commit is contained in:
parent
22ceba971d
commit
f903f8a1c7
@ -447,6 +447,7 @@ export class ChatInput {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let emoticonsDisplayTimeout = 0;
|
||||||
this.toggleEmoticons.onmouseover = (e) => {
|
this.toggleEmoticons.onmouseover = (e) => {
|
||||||
clearTimeout(this.emoticonsTimeout);
|
clearTimeout(this.emoticonsTimeout);
|
||||||
this.emoticonsTimeout = setTimeout(() => {
|
this.emoticonsTimeout = setTimeout(() => {
|
||||||
@ -464,6 +465,11 @@ export class ChatInput {
|
|||||||
this.toggleEmoticons.classList.remove('active');
|
this.toggleEmoticons.classList.remove('active');
|
||||||
lottieLoader.checkAnimations(true, EMOTICONSSTICKERGROUP);
|
lottieLoader.checkAnimations(true, EMOTICONSSTICKERGROUP);
|
||||||
this.emoticonsLazyLoadQueue.lock();
|
this.emoticonsLazyLoadQueue.lock();
|
||||||
|
|
||||||
|
clearTimeout(emoticonsDisplayTimeout);
|
||||||
|
emoticonsDisplayTimeout = setTimeout(() => {
|
||||||
|
this.emoticonsDropdown.style.display = 'none';
|
||||||
|
}, 200);
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -471,8 +477,11 @@ export class ChatInput {
|
|||||||
clearTimeout(this.emoticonsTimeout);
|
clearTimeout(this.emoticonsTimeout);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
this.emoticonsDropdown.style.display = '';
|
||||||
|
void this.emoticonsDropdown.offsetLeft; // reflow
|
||||||
this.emoticonsDropdown.classList.add('active');
|
this.emoticonsDropdown.classList.add('active');
|
||||||
this.emoticonsLazyLoadQueue.unlock();
|
this.emoticonsLazyLoadQueue.unlock();
|
||||||
|
clearTimeout(emoticonsDisplayTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.toggleEmoticons.classList.add('active');
|
this.toggleEmoticons.classList.add('active');
|
||||||
|
@ -290,7 +290,13 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
|
|
||||||
docs.forEach(doc => {
|
docs.forEach(doc => {
|
||||||
let div = document.createElement('div');
|
let div = document.createElement('div');
|
||||||
wrapSticker(doc, div, undefined, lazyLoadQueue, EMOTICONSSTICKERGROUP, true, false, true);
|
wrapSticker({
|
||||||
|
doc,
|
||||||
|
div,
|
||||||
|
lazyLoadQueue,
|
||||||
|
group: EMOTICONSSTICKERGROUP,
|
||||||
|
onlyThumb: true
|
||||||
|
});
|
||||||
|
|
||||||
itemsDiv.append(div);
|
itemsDiv.append(div);
|
||||||
});
|
});
|
||||||
@ -408,7 +414,11 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else { // as thumb will be used first sticker
|
} else { // as thumb will be used first sticker
|
||||||
wrapSticker(stickerSet.documents[0], li as any, undefined, undefined, EMOTICONSSTICKERGROUP); // kostil
|
wrapSticker({
|
||||||
|
doc: stickerSet.documents[0],
|
||||||
|
div: li as any,
|
||||||
|
group: EMOTICONSSTICKERGROUP
|
||||||
|
}); // kostil
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryPush(categoryDiv, stickerSet.set.title, stickerSet.documents, false);
|
categoryPush(categoryDiv, stickerSet.set.title, stickerSet.documents, false);
|
||||||
|
@ -128,10 +128,10 @@ export default class PollElement extends HTMLElement {
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="poll-answer-percents"></div>
|
<div class="poll-answer-percents"></div>
|
||||||
|
<div class="poll-answer-text">${RichTextProcessor.wrapEmojiText(answer.text)}</div>
|
||||||
<svg version="1.1" class="poll-line" style="display: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 480 35" xml:space="preserve">
|
<svg version="1.1" class="poll-line" style="display: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 480 35" xml:space="preserve">
|
||||||
<use href="#poll-line"></use>
|
<use href="#poll-line"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="poll-answer-text">${RichTextProcessor.wrapEmojiText(answer.text)}</div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
@ -44,7 +44,7 @@ export default class ProgressivePreloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public attach(elem: Element, reset = true, promise?: CancellablePromise<any>) {
|
public attach(elem: Element, reset = true, promise?: CancellablePromise<any>, append = true) {
|
||||||
if(promise) {
|
if(promise) {
|
||||||
this.promise = promise;
|
this.promise = promise;
|
||||||
|
|
||||||
@ -75,7 +75,8 @@ export default class ProgressivePreloader {
|
|||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(() => {
|
||||||
if(this.detached) return;
|
if(this.detached) return;
|
||||||
this.detached = false;
|
this.detached = false;
|
||||||
elem.append(this.preloader);
|
|
||||||
|
elem[append ? 'append' : 'prepend'](this.preloader);
|
||||||
});
|
});
|
||||||
/* let isIn = isInDOM(this.preloader);
|
/* let isIn = isInDOM(this.preloader);
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ export default class Scrollable {
|
|||||||
public scrollIntoView(element: HTMLElement, smooth = true) {
|
public scrollIntoView(element: HTMLElement, smooth = true) {
|
||||||
if(element.parentElement && !this.scrollLocked) {
|
if(element.parentElement && !this.scrollLocked) {
|
||||||
let isFirstUnread = element.classList.contains('is-first-unread');
|
let isFirstUnread = element.classList.contains('is-first-unread');
|
||||||
let offsetTop = element.offsetTop;
|
let offsetTop = element.getBoundingClientRect().top - this.container.getBoundingClientRect().top;
|
||||||
if(!smooth && isFirstUnread) {
|
if(!smooth && isFirstUnread) {
|
||||||
this.scrollTo(offsetTop, false);
|
this.scrollTo(offsetTop, false);
|
||||||
return;
|
return;
|
||||||
@ -373,7 +373,8 @@ export default class Scrollable {
|
|||||||
let clientHeight = this.container.clientHeight;
|
let clientHeight = this.container.clientHeight;
|
||||||
let height = element.scrollHeight;
|
let height = element.scrollHeight;
|
||||||
|
|
||||||
offsetTop -= (clientHeight - height) / 2;
|
let d = (clientHeight - height) / 2;
|
||||||
|
offsetTop = this.container.scrollTop + offsetTop - d;
|
||||||
|
|
||||||
this.scrollTo(offsetTop, smooth);
|
this.scrollTo(offsetTop, smooth);
|
||||||
}
|
}
|
||||||
|
76
src/components/stickyIntersector.ts
Normal file
76
src/components/stickyIntersector.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
export default class StickyIntersector {
|
||||||
|
private headersObserver: IntersectionObserver;
|
||||||
|
private elementsObserver: IntersectionObserver;
|
||||||
|
|
||||||
|
constructor(private container: HTMLElement, private handler: (stuck: boolean, target: HTMLElement) => void) {
|
||||||
|
this.observeHeaders();
|
||||||
|
this.observeElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up an intersection observer to notify when elements with the class
|
||||||
|
* `.sticky_sentinel--top` become visible/invisible at the top of the container.
|
||||||
|
* @param {!Element} container
|
||||||
|
*/
|
||||||
|
private observeHeaders() {
|
||||||
|
this.headersObserver = new IntersectionObserver((entries) => {
|
||||||
|
for(const entry of entries) {
|
||||||
|
const targetInfo = entry.boundingClientRect;
|
||||||
|
const stickyTarget = entry.target.parentElement;
|
||||||
|
const rootBoundsInfo = entry.rootBounds;
|
||||||
|
|
||||||
|
// Started sticking.
|
||||||
|
if(targetInfo.bottom < rootBoundsInfo.top) {
|
||||||
|
this.handler(true, stickyTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stopped sticking.
|
||||||
|
if(targetInfo.bottom >= rootBoundsInfo.top &&
|
||||||
|
targetInfo.bottom < rootBoundsInfo.bottom) {
|
||||||
|
this.handler(false, stickyTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {threshold: 0, root: this.container});
|
||||||
|
}
|
||||||
|
|
||||||
|
private observeElements() {
|
||||||
|
this.elementsObserver = new IntersectionObserver((entries) => {
|
||||||
|
let entry = entries.filter(entry => entry.boundingClientRect.top < 0).sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top)[0];
|
||||||
|
if(!entry) return;
|
||||||
|
let container = entry.isIntersecting ? entry.target : entry.target.nextElementSibling;
|
||||||
|
this.handler(true, container as HTMLElement);
|
||||||
|
}, {root: this.container});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!Element} container
|
||||||
|
* @param {string} className
|
||||||
|
*/
|
||||||
|
private addSentinel(container: HTMLElement, className: string) {
|
||||||
|
const sentinel = document.createElement('div');
|
||||||
|
sentinel.classList.add('sticky_sentinel', className);
|
||||||
|
return container.appendChild(sentinel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies when elements w/ the `sticky` class begin to stick or stop sticking.
|
||||||
|
* Note: the elements should be children of `container`.
|
||||||
|
* @param {!Element} container
|
||||||
|
*/
|
||||||
|
public observeStickyHeaderChanges(element: HTMLElement) {
|
||||||
|
const headerSentinel = this.addSentinel(element, 'sticky_sentinel--top');
|
||||||
|
this.headersObserver.observe(headerSentinel);
|
||||||
|
|
||||||
|
this.elementsObserver.observe(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnect() {
|
||||||
|
this.headersObserver.disconnect();
|
||||||
|
this.elementsObserver.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public unobserve(element: HTMLElement, headerSentinel: HTMLElement) {
|
||||||
|
this.elementsObserver.unobserve(element);
|
||||||
|
this.headersObserver.unobserve(headerSentinel);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ import apiManager from '../lib/mtproto/mtprotoworker';
|
|||||||
import LottieLoader from '../lib/lottieLoader';
|
import LottieLoader from '../lib/lottieLoader';
|
||||||
import appStickersManager from "../lib/appManagers/appStickersManager";
|
import appStickersManager from "../lib/appManagers/appStickersManager";
|
||||||
import appDocsManager from "../lib/appManagers/appDocsManager";
|
import appDocsManager from "../lib/appManagers/appDocsManager";
|
||||||
import { formatBytes } from "../lib/utils";
|
import { formatBytes, getEmojiToneIndex } from "../lib/utils";
|
||||||
import ProgressivePreloader from './preloader';
|
import ProgressivePreloader from './preloader';
|
||||||
import LazyLoadQueue from './lazyLoadQueue';
|
import LazyLoadQueue from './lazyLoadQueue';
|
||||||
import apiFileManager from '../lib/mtproto/apiFileManager';
|
import apiFileManager from '../lib/mtproto/apiFileManager';
|
||||||
@ -108,7 +108,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
|||||||
container.append(video);
|
container.append(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
let span: HTMLSpanElement;
|
let span: HTMLSpanElement, spanPlay: HTMLSpanElement;
|
||||||
if(doc.type != 'round') {
|
if(doc.type != 'round') {
|
||||||
span = document.createElement('span');
|
span = document.createElement('span');
|
||||||
span.classList.add('video-time');
|
span.classList.add('video-time');
|
||||||
@ -117,7 +117,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
|||||||
if(doc.type != 'gif') {
|
if(doc.type != 'gif') {
|
||||||
span.innerText = (doc.duration + '').toHHMMSS(false);
|
span.innerText = (doc.duration + '').toHHMMSS(false);
|
||||||
|
|
||||||
let spanPlay = document.createElement('span');
|
spanPlay = document.createElement('span');
|
||||||
spanPlay.classList.add('video-play', 'tgico-largeplay', 'btn-circle', 'position-center');
|
spanPlay.classList.add('video-play', 'tgico-largeplay', 'btn-circle', 'position-center');
|
||||||
container.append(spanPlay);
|
container.append(spanPlay);
|
||||||
} else {
|
} else {
|
||||||
@ -127,11 +127,11 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
|||||||
|
|
||||||
let loadVideo = async() => {
|
let loadVideo = async() => {
|
||||||
if(message.media.preloader) { // means upload
|
if(message.media.preloader) { // means upload
|
||||||
message.media.preloader.attach(container);
|
(message.media.preloader as ProgressivePreloader).attach(container, undefined, undefined, false);
|
||||||
} else if(!doc.downloaded) {
|
} else if(!doc.downloaded) {
|
||||||
let preloader = new ProgressivePreloader(container, true);
|
let preloader = new ProgressivePreloader(container, true);
|
||||||
let promise = appDocsManager.downloadDoc(doc);
|
let promise = appDocsManager.downloadDoc(doc);
|
||||||
preloader.attach(container, true, promise);
|
preloader.attach(container, true, promise, false);
|
||||||
await promise;
|
await promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,7 +684,16 @@ export function wrapPhoto(photoID: string, message: any, container: HTMLDivEleme
|
|||||||
return photo.downloaded ? load() : lazyLoadQueue.push({div: container, load: load, wasSeen: true});
|
return photo.downloaded ? load() : lazyLoadQueue.push({div: container, load: load, wasSeen: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: () => boolean, lazyLoadQueue?: LazyLoadQueue, group?: string, canvas?: boolean, play = false, onlyThumb = false) {
|
export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, onlyThumb, emoji}: {
|
||||||
|
doc: MTDocument,
|
||||||
|
div: HTMLDivElement,
|
||||||
|
middleware?: () => boolean,
|
||||||
|
lazyLoadQueue?: LazyLoadQueue,
|
||||||
|
group?: string,
|
||||||
|
play?: boolean,
|
||||||
|
onlyThumb?: boolean,
|
||||||
|
emoji?: string
|
||||||
|
}) {
|
||||||
let stickerType = doc.sticker;
|
let stickerType = doc.sticker;
|
||||||
|
|
||||||
if(stickerType == 2 && !LottieLoader.loaded) {
|
if(stickerType == 2 && !LottieLoader.loaded) {
|
||||||
@ -700,6 +709,8 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: (
|
|||||||
|
|
||||||
//console.log('wrap sticker', doc, div, onlyThumb);
|
//console.log('wrap sticker', doc, div, onlyThumb);
|
||||||
|
|
||||||
|
const toneIndex = emoji ? getEmojiToneIndex(emoji) : -1;
|
||||||
|
|
||||||
if(doc.thumbs && !div.firstElementChild && (!doc.downloaded || stickerType == 2)) {
|
if(doc.thumbs && !div.firstElementChild && (!doc.downloaded || stickerType == 2)) {
|
||||||
let thumb = doc.thumbs[0];
|
let thumb = doc.thumbs[0];
|
||||||
|
|
||||||
@ -777,29 +788,30 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: (
|
|||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
reader.addEventListener('loadend', async(e) => {
|
reader.addEventListener('loadend', async(e) => {
|
||||||
console.time('decompress sticker' + doc.id);
|
//console.time('decompress sticker' + doc.id);
|
||||||
console.time('render sticker' + doc.id);
|
//console.time('render sticker' + doc.id);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const text = e.srcElement.result;
|
const text = e.srcElement.result;
|
||||||
let json = await apiManager.gzipUncompress<string>(text, true);
|
let json = await apiManager.gzipUncompress<string>(text, true);
|
||||||
|
|
||||||
console.timeEnd('decompress sticker' + doc.id);
|
//console.timeEnd('decompress sticker' + doc.id);
|
||||||
|
|
||||||
|
console.log('sticker json:', json);
|
||||||
|
|
||||||
let animation = await LottieLoader.loadAnimation({
|
let animation = await LottieLoader.loadAnimation({
|
||||||
container: div,
|
container: div,
|
||||||
loop: false,
|
loop: false,
|
||||||
autoplay: false,
|
autoplay: false,
|
||||||
animationData: JSON.parse(json),
|
animationData: JSON.parse(json),
|
||||||
renderer: canvas ? 'canvas' : 'svg'
|
renderer: 'svg'
|
||||||
}, group);
|
}, group, toneIndex);
|
||||||
|
|
||||||
console.timeEnd('render sticker' + doc.id);
|
//console.timeEnd('render sticker' + doc.id);
|
||||||
|
|
||||||
if(div.firstElementChild && div.firstElementChild.tagName == 'IMG') {
|
if(div.firstElementChild && div.firstElementChild.tagName == 'IMG') {
|
||||||
div.firstElementChild.remove();
|
div.firstElementChild.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!canvas) {
|
|
||||||
div.addEventListener('mouseover', (e) => {
|
div.addEventListener('mouseover', (e) => {
|
||||||
let animation = LottieLoader.getAnimation(div, group);
|
let animation = LottieLoader.getAnimation(div, group);
|
||||||
|
|
||||||
@ -822,7 +834,6 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: (
|
|||||||
}, {once: true});
|
}, {once: true});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if(play) {
|
if(play) {
|
||||||
animation.play();
|
animation.play();
|
||||||
|
File diff suppressed because one or more lines are too long
@ -48,6 +48,7 @@ if(false) {
|
|||||||
{
|
{
|
||||||
let categories = {
|
let categories = {
|
||||||
"Smileys & Emotion": 1
|
"Smileys & Emotion": 1
|
||||||
|
, "People & Body": 1
|
||||||
, "Animals & Nature": 2
|
, "Animals & Nature": 2
|
||||||
, "Food & Drink": 3
|
, "Food & Drink": 3
|
||||||
, "Travel & Places": 4
|
, "Travel & Places": 4
|
||||||
@ -58,18 +59,23 @@ if(false) {
|
|||||||
, "Skin Tones": 8
|
, "Skin Tones": 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let concatCategories = [['Objects', 'Symbols'], ['Smileys & Emotion', 'People & Body']];
|
||||||
|
let maxIndexes = {};
|
||||||
|
|
||||||
let maxObjectsIndex = -1;
|
let maxObjectsIndex = -1;
|
||||||
formatted.forEach(e => {
|
formatted.forEach(e => {
|
||||||
if(e.category == 'Objects') {
|
if(concatCategories.findIndex(c => c[0] == e.category) === -1) return;
|
||||||
if(e.sort_order > maxObjectsIndex) {
|
|
||||||
maxObjectsIndex = e.sort_order;
|
if(!maxIndexes.hasOwnProperty(e.category)) maxIndexes[e.category] = 0;
|
||||||
}
|
if(e.sort_order > maxIndexes[e.category]) {
|
||||||
|
maxIndexes[e.category] = e.sort_order;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
formatted.forEach(e => {
|
formatted.forEach(e => {
|
||||||
if(e.category == 'Symbols') {
|
let concatDetails = concatCategories.find(c => c[1] == e.category);
|
||||||
e.sort_order += maxObjectsIndex;
|
if(!concatDetails) return;
|
||||||
}
|
|
||||||
|
e.sort_order += maxIndexes[concatDetails[0]];
|
||||||
});
|
});
|
||||||
|
|
||||||
formatted.forEach(e => {
|
formatted.forEach(e => {
|
||||||
|
@ -649,7 +649,7 @@ export class AppDialogsManager {
|
|||||||
if(onFound) onFound();
|
if(onFound) onFound();
|
||||||
|
|
||||||
let peerID = +elem.getAttribute('data-peerID');
|
let peerID = +elem.getAttribute('data-peerID');
|
||||||
let lastMsgID = +elem.dataset.mid || 0;
|
let lastMsgID = +elem.dataset.mid || undefined;
|
||||||
|
|
||||||
if(!samePeer) {
|
if(!samePeer) {
|
||||||
elem.classList.add('active');
|
elem.classList.add('active');
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import apiManager from '../mtproto/mtprotoworker';
|
import apiManager from '../mtproto/mtprotoworker';
|
||||||
import { $rootScope, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, findUpTag, langPack, whichChild } from "../utils";
|
import { $rootScope, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, findUpTag, langPack, whichChild } from "../utils";
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
import appMessagesManager from "./appMessagesManager";
|
import appMessagesManager, { Dialog } from "./appMessagesManager";
|
||||||
import appPeersManager from "./appPeersManager";
|
import appPeersManager from "./appPeersManager";
|
||||||
import appProfileManager from "./appProfileManager";
|
import appProfileManager from "./appProfileManager";
|
||||||
import appDialogsManager from "./appDialogsManager";
|
import appDialogsManager from "./appDialogsManager";
|
||||||
@ -30,6 +30,7 @@ import appForward from '../../components/appForward';
|
|||||||
import appStickersManager from './appStickersManager';
|
import appStickersManager from './appStickersManager';
|
||||||
import AvatarElement from '../../components/avatar';
|
import AvatarElement from '../../components/avatar';
|
||||||
import appInlineBotsManager from './AppInlineBotsManager';
|
import appInlineBotsManager from './AppInlineBotsManager';
|
||||||
|
import StickyIntersector from '../../components/stickyIntersector';
|
||||||
|
|
||||||
console.log('appImManager included!');
|
console.log('appImManager included!');
|
||||||
|
|
||||||
@ -37,6 +38,8 @@ appSidebarLeft; // just to include
|
|||||||
|
|
||||||
let testScroll = false;
|
let testScroll = false;
|
||||||
|
|
||||||
|
const IGNOREACTIONS = ['messageActionChannelMigrateFrom'];
|
||||||
|
|
||||||
export class AppImManager {
|
export class AppImManager {
|
||||||
public pageEl = document.getElementById('page-chats') as HTMLDivElement;
|
public pageEl = document.getElementById('page-chats') as HTMLDivElement;
|
||||||
public btnMute = this.pageEl.querySelector('.tool-mute') as HTMLButtonElement;
|
public btnMute = this.pageEl.querySelector('.tool-mute') as HTMLButtonElement;
|
||||||
@ -111,10 +114,8 @@ export class AppImManager {
|
|||||||
private onScrollRAF = 0;
|
private onScrollRAF = 0;
|
||||||
private isScrollingTimeout = 0;
|
private isScrollingTimeout = 0;
|
||||||
|
|
||||||
private datesIntersectionObserver: IntersectionObserver = null;
|
|
||||||
private lastDateMessageDiv: HTMLDivElement = null;
|
|
||||||
|
|
||||||
private unreadedObserver: IntersectionObserver = null;
|
private unreadedObserver: IntersectionObserver = null;
|
||||||
|
private unreaded: number[] = [];
|
||||||
|
|
||||||
private loadedTopTimes = 0;
|
private loadedTopTimes = 0;
|
||||||
private loadedBottomTimes = 0;
|
private loadedBottomTimes = 0;
|
||||||
@ -126,6 +127,8 @@ export class AppImManager {
|
|||||||
private peerChanged: boolean;
|
private peerChanged: boolean;
|
||||||
private firstUnreadBubble: HTMLDivElement = null;
|
private firstUnreadBubble: HTMLDivElement = null;
|
||||||
|
|
||||||
|
private stickyIntersector: StickyIntersector = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
/* if(!lottieLoader.loaded) {
|
/* if(!lottieLoader.loaded) {
|
||||||
lottieLoader.loadLottie();
|
lottieLoader.loadLottie();
|
||||||
@ -156,10 +159,7 @@ export class AppImManager {
|
|||||||
let details = e.detail;
|
let details = e.detail;
|
||||||
|
|
||||||
if(!this.scrolledAllDown) {
|
if(!this.scrolledAllDown) {
|
||||||
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0];
|
this.setPeer(this.peerID, 0);
|
||||||
if(dialog) {
|
|
||||||
this.setPeer(this.peerID, dialog.top_message);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.renderNewMessagesByIDs([details.messageID], true);
|
this.renderNewMessagesByIDs([details.messageID], true);
|
||||||
}
|
}
|
||||||
@ -393,9 +393,7 @@ export class AppImManager {
|
|||||||
}).sort((a, b) => a - b);
|
}).sort((a, b) => a - b);
|
||||||
|
|
||||||
ids.forEach(id => {
|
ids.forEach(id => {
|
||||||
let bubble = this.bubbles[id];
|
let elements = this.bubbles[id].querySelectorAll('.album-item img, .album-item video, .preview img, .preview video, .bubble__media-container') as NodeListOf<HTMLElement>;
|
||||||
|
|
||||||
let elements = this.bubbles[id].querySelectorAll('.attachment img, .preview img, video, .bubble__media-container') as NodeListOf<HTMLElement>;
|
|
||||||
Array.from(elements).forEach((element: HTMLElement) => {
|
Array.from(elements).forEach((element: HTMLElement) => {
|
||||||
let albumItem = findUpClassName(element, 'album-item');
|
let albumItem = findUpClassName(element, 'album-item');
|
||||||
targets.push({
|
targets.push({
|
||||||
@ -424,7 +422,7 @@ export class AppImManager {
|
|||||||
let peerID = +splitted[0];
|
let peerID = +splitted[0];
|
||||||
let msgID = +splitted[1];
|
let msgID = +splitted[1];
|
||||||
////this.log('savedFrom', peerID, msgID);
|
////this.log('savedFrom', peerID, msgID);
|
||||||
this.setPeer(peerID, msgID/* , true */);
|
this.setPeer(peerID, msgID);
|
||||||
return;
|
return;
|
||||||
} else if(target.tagName == "AVATAR-ELEMENT" || target.classList.contains('name')) {
|
} else if(target.tagName == "AVATAR-ELEMENT" || target.classList.contains('name')) {
|
||||||
let peerID = +target.dataset.peerID;
|
let peerID = +target.dataset.peerID;
|
||||||
@ -650,25 +648,15 @@ export class AppImManager {
|
|||||||
this.setScroll();
|
this.setScroll();
|
||||||
//apiUpdatesManager.attach();
|
//apiUpdatesManager.attach();
|
||||||
|
|
||||||
this.datesIntersectionObserver = new IntersectionObserver((entries) => {
|
this.stickyIntersector = new StickyIntersector(this.scrollable.container, (stuck, target) => {
|
||||||
//this.log('intersection', entries);
|
|
||||||
|
|
||||||
let entry = entries.filter(entry => entry.boundingClientRect.top < 0).sort((a, b) => b.boundingClientRect.top - a.boundingClientRect.top)[0];
|
|
||||||
if(!entry) return;
|
|
||||||
let container = entry.isIntersecting ? entry.target : entry.target.nextElementSibling;
|
|
||||||
for(let timestamp in this.dateMessages) {
|
for(let timestamp in this.dateMessages) {
|
||||||
let dateMessage = this.dateMessages[timestamp];
|
let dateMessage = this.dateMessages[timestamp];
|
||||||
if(dateMessage.container == container) {
|
if(dateMessage.container == target) {
|
||||||
if(this.lastDateMessageDiv) {
|
dateMessage.div.classList.toggle('is-sticky', stuck);
|
||||||
this.lastDateMessageDiv.classList.remove('is-sticky');
|
|
||||||
}
|
|
||||||
|
|
||||||
dateMessage.div.classList.add('is-sticky');
|
|
||||||
this.lastDateMessageDiv = dateMessage.div;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}/* , {root: this.chatInner} */);
|
});
|
||||||
|
|
||||||
this.unreadedObserver = new IntersectionObserver((entries) => {
|
this.unreadedObserver = new IntersectionObserver((entries) => {
|
||||||
let readed: number[] = [];
|
let readed: number[] = [];
|
||||||
@ -679,22 +667,32 @@ export class AppImManager {
|
|||||||
let mid = +target.dataset.mid;
|
let mid = +target.dataset.mid;
|
||||||
readed.push(mid);
|
readed.push(mid);
|
||||||
this.unreadedObserver.unobserve(target);
|
this.unreadedObserver.unobserve(target);
|
||||||
|
this.unreaded.findAndSplice(id => id == mid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(readed.length) {
|
if(readed.length) {
|
||||||
let max = Math.max(...readed);
|
let max = Math.max(...readed);
|
||||||
let min = Math.min(...readed);
|
|
||||||
|
|
||||||
if(this.peerID < 0) {
|
let length = readed.length;
|
||||||
max = appMessagesIDsManager.getMessageIDInfo(max)[0];
|
for(let i = this.unreaded.length - 1; i >= 0; --i) {
|
||||||
min = appMessagesIDsManager.getMessageIDInfo(min)[0];
|
let mid = this.unreaded[i];
|
||||||
|
if(mid < max) {
|
||||||
|
length++;
|
||||||
|
this.unreaded.splice(i, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.log('will readHistory by ids:', max, length);
|
||||||
|
|
||||||
|
/* if(this.peerID < 0) {
|
||||||
|
max = appMessagesIDsManager.getMessageIDInfo(max)[0];
|
||||||
|
} */
|
||||||
|
|
||||||
//appMessagesManager.readMessages(readed);
|
//appMessagesManager.readMessages(readed);
|
||||||
false && appMessagesManager.readHistory(this.peerID, max, min).catch((err: any) => {
|
/* false && */appMessagesManager.readHistory(this.peerID, max, length).catch((err: any) => {
|
||||||
this.log.error('readHistory err:', err);
|
this.log.error('readHistory err:', err);
|
||||||
appMessagesManager.readHistory(this.peerID, max, min);
|
appMessagesManager.readHistory(this.peerID, max, length);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -788,7 +786,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
if(this.isScrollingTimeout) {
|
if(this.isScrollingTimeout) {
|
||||||
clearTimeout(this.isScrollingTimeout);
|
clearTimeout(this.isScrollingTimeout);
|
||||||
} else if(this.chatInner.classList.contains('is-scrolling')) {
|
} else if(!this.chatInner.classList.contains('is-scrolling')) {
|
||||||
this.chatInner.classList.add('is-scrolling');
|
this.chatInner.classList.add('is-scrolling');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,19 +925,19 @@ export class AppImManager {
|
|||||||
|
|
||||||
this.getHistoryTopPromise = this.getHistoryBottomPromise = undefined;
|
this.getHistoryTopPromise = this.getHistoryBottomPromise = undefined;
|
||||||
|
|
||||||
this.datesIntersectionObserver.disconnect();
|
this.stickyIntersector.disconnect();
|
||||||
this.lastDateMessageDiv = null;
|
|
||||||
|
|
||||||
this.unreadedObserver.disconnect();
|
this.unreadedObserver.disconnect();
|
||||||
|
this.unreaded.length = 0;
|
||||||
|
|
||||||
this.loadedTopTimes = this.loadedBottomTimes = 0;
|
this.loadedTopTimes = this.loadedBottomTimes = 0;
|
||||||
|
|
||||||
////console.timeEnd('appImManager cleanup');
|
////console.timeEnd('appImManager cleanup');
|
||||||
}
|
}
|
||||||
|
|
||||||
public setPeer(peerID: number, lastMsgID = 0) {
|
public setPeer(peerID: number, lastMsgID?: number) {
|
||||||
console.time('appImManager setPeer');
|
//console.time('appImManager setPeer');
|
||||||
console.time('appImManager setPeer pre promise');
|
//console.time('appImManager setPeer pre promise');
|
||||||
////console.time('appImManager: pre render start');
|
////console.time('appImManager: pre render start');
|
||||||
if(peerID == 0) {
|
if(peerID == 0) {
|
||||||
appSidebarRight.toggleSidebar(false);
|
appSidebarRight.toggleSidebar(false);
|
||||||
@ -950,7 +948,7 @@ export class AppImManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let samePeer = this.peerID == peerID;
|
const samePeer = this.peerID == peerID;
|
||||||
|
|
||||||
if(this.setPeerPromise && samePeer) return this.setPeerPromise;
|
if(this.setPeerPromise && samePeer) return this.setPeerPromise;
|
||||||
|
|
||||||
@ -958,15 +956,19 @@ export class AppImManager {
|
|||||||
appMessagesManager.readHistory(peerID, lastMsgID); // lol
|
appMessagesManager.readHistory(peerID, lastMsgID); // lol
|
||||||
} */
|
} */
|
||||||
|
|
||||||
if(samePeer) {
|
const dialog = appMessagesManager.getDialogByPeerID(peerID)[0] || null;
|
||||||
if(!testScroll && !lastMsgID) {
|
const topMessage = lastMsgID <= 0 ? lastMsgID : dialog?.top_message ?? 0;
|
||||||
return true;
|
if(lastMsgID === undefined && dialog) {
|
||||||
|
if(dialog.unread_count) {
|
||||||
|
lastMsgID = dialog.read_inbox_max_id;
|
||||||
|
} else {
|
||||||
|
lastMsgID = dialog.top_message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(samePeer) {
|
||||||
if(this.bubbles[lastMsgID]) {
|
if(this.bubbles[lastMsgID]) {
|
||||||
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
|
if(dialog && lastMsgID == topMessage) {
|
||||||
|
|
||||||
if(dialog && lastMsgID == dialog.top_message) {
|
|
||||||
this.log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);
|
this.log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);
|
||||||
this.scroll.scrollTop = this.scroll.scrollHeight;
|
this.scroll.scrollTop = this.scroll.scrollHeight;
|
||||||
} else {
|
} else {
|
||||||
@ -983,19 +985,12 @@ export class AppImManager {
|
|||||||
// set new
|
// set new
|
||||||
this.peerID = $rootScope.selectedPeerID = peerID;
|
this.peerID = $rootScope.selectedPeerID = peerID;
|
||||||
|
|
||||||
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null;
|
|
||||||
if(!lastMsgID && dialog) {
|
|
||||||
if(dialog.unread_count) {
|
|
||||||
lastMsgID = dialog.read_inbox_max_id;
|
|
||||||
} else {
|
|
||||||
lastMsgID = dialog.top_message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//////this.log('setPeer peerID:', this.peerID, dialog, lastMsgID);
|
|
||||||
|
|
||||||
const isJump = lastMsgID != dialog?.top_message;
|
this.log('setPeer peerID:', this.peerID, dialog, lastMsgID, topMessage);
|
||||||
|
|
||||||
|
const isJump = lastMsgID != topMessage;
|
||||||
// add last message, bc in getHistory will load < max_id
|
// add last message, bc in getHistory will load < max_id
|
||||||
const additionMsgID = isJump ? 0 : dialog.top_message;
|
const additionMsgID = isJump ? 0 : topMessage;
|
||||||
|
|
||||||
/* this.setPeerPromise = null;
|
/* this.setPeerPromise = null;
|
||||||
this.preloader.detach();
|
this.preloader.detach();
|
||||||
@ -1005,28 +1000,33 @@ export class AppImManager {
|
|||||||
|
|
||||||
const maxBubbleID = samePeer && Math.max(...Object.keys(this.bubbles).map(mid => +mid));
|
const maxBubbleID = samePeer && Math.max(...Object.keys(this.bubbles).map(mid => +mid));
|
||||||
|
|
||||||
//let oldChatInner = this.chatInner;
|
const oldChatInner = this.chatInner;
|
||||||
this.cleanup();
|
this.cleanup();
|
||||||
this.chatInner = document.createElement('div');
|
this.chatInner = document.createElement('div');
|
||||||
this.chatInner.id = 'bubbles-inner';
|
this.chatInner.id = 'bubbles-inner';
|
||||||
this.scrollable.appendTo = this.chatInner;
|
this.scrollable.appendTo = this.chatInner;
|
||||||
|
this.chatInner.className = oldChatInner.className;
|
||||||
this.chatInner.classList.add('disable-hover', 'is-scrolling');
|
this.chatInner.classList.add('disable-hover', 'is-scrolling');
|
||||||
|
|
||||||
this.lazyLoadQueue.lock();
|
this.lazyLoadQueue.lock();
|
||||||
|
|
||||||
let {promise, cached} = this.getHistory(lastMsgID, true, isJump, additionMsgID);
|
const {promise, cached} = this.getHistory(lastMsgID, true, isJump, additionMsgID);
|
||||||
|
|
||||||
|
if(!samePeer) {
|
||||||
appSidebarRight.setPeer(this.peerID);
|
appSidebarRight.setPeer(this.peerID);
|
||||||
|
} else {
|
||||||
|
this.peerChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
// clear
|
// clear
|
||||||
if(!cached) {
|
if(!cached) {
|
||||||
this.scrollable.container.innerHTML = '';
|
this.scrollable.container.innerHTML = '';
|
||||||
//oldChatInner.remove();
|
//oldChatInner.remove();
|
||||||
this.finishPeerChange();
|
!samePeer && this.finishPeerChange();
|
||||||
this.preloader.attach(this.bubblesContainer);
|
this.preloader.attach(this.bubblesContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.timeEnd('appImManager setPeer pre promise');
|
//console.timeEnd('appImManager setPeer pre promise');
|
||||||
|
|
||||||
this.setPeerPromise = Promise.all([
|
this.setPeerPromise = Promise.all([
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
@ -1035,7 +1035,7 @@ export class AppImManager {
|
|||||||
if(cached) {
|
if(cached) {
|
||||||
this.scrollable.container.innerHTML = '';
|
this.scrollable.container.innerHTML = '';
|
||||||
//oldChatInner.remove();
|
//oldChatInner.remove();
|
||||||
this.finishPeerChange();
|
!samePeer && this.finishPeerChange();
|
||||||
} else {
|
} else {
|
||||||
this.preloader.detach();
|
this.preloader.detach();
|
||||||
}
|
}
|
||||||
@ -1046,19 +1046,19 @@ export class AppImManager {
|
|||||||
|
|
||||||
this.lazyLoadQueue.unlock();
|
this.lazyLoadQueue.unlock();
|
||||||
|
|
||||||
if(dialog && lastMsgID && lastMsgID != dialog.top_message && (this.bubbles[lastMsgID] || this.firstUnreadBubble)) {
|
if(dialog && lastMsgID && lastMsgID != topMessage && (this.bubbles[lastMsgID] || this.firstUnreadBubble)) {
|
||||||
if(this.scrollable.scrollLocked) {
|
if(this.scrollable.scrollLocked) {
|
||||||
clearTimeout(this.scrollable.scrollLocked);
|
clearTimeout(this.scrollable.scrollLocked);
|
||||||
this.scrollable.scrollLocked = 0;
|
this.scrollable.scrollLocked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fromUp = maxBubbleID > 0 && maxBubbleID < lastMsgID;
|
const fromUp = maxBubbleID > 0 && (maxBubbleID < lastMsgID || lastMsgID < 0);
|
||||||
if(!fromUp && samePeer) {
|
if(!fromUp && samePeer) {
|
||||||
this.scrollable.scrollTop = this.scrollable.scrollHeight;
|
this.scrollable.scrollTop = this.scrollable.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
let forwardingUnread = dialog.read_inbox_max_id == lastMsgID;
|
const forwardingUnread = dialog.read_inbox_max_id == lastMsgID;
|
||||||
let bubble = forwardingUnread ? (this.firstUnreadBubble || this.bubbles[lastMsgID]) : this.bubbles[lastMsgID];
|
const bubble = forwardingUnread ? (this.firstUnreadBubble || this.bubbles[lastMsgID]) : this.bubbles[lastMsgID];
|
||||||
|
|
||||||
this.scrollable.scrollIntoView(bubble, samePeer/* , fromUp */);
|
this.scrollable.scrollIntoView(bubble, samePeer/* , fromUp */);
|
||||||
if(!forwardingUnread) {
|
if(!forwardingUnread) {
|
||||||
@ -1069,13 +1069,13 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// warning
|
// warning
|
||||||
if(!lastMsgID || (dialog && (this.bubbles[dialog.top_message] || lastMsgID == dialog.top_message))) {
|
if(!lastMsgID || this.bubbles[topMessage] || lastMsgID == topMessage) {
|
||||||
this.scrolledAllDown = true;
|
this.scrolledAllDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log('scrolledAllDown:', this.scrolledAllDown);
|
this.log('scrolledAllDown:', this.scrolledAllDown);
|
||||||
|
|
||||||
console.timeEnd('appImManager setPeer');
|
//console.timeEnd('appImManager setPeer');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
@ -1115,17 +1115,14 @@ export class AppImManager {
|
|||||||
|
|
||||||
const isChannel = appPeersManager.isChannel(peerID);
|
const isChannel = appPeersManager.isChannel(peerID);
|
||||||
const hasRights = isChannel && appChatsManager.hasRights(-peerID, 'send');
|
const hasRights = isChannel && appChatsManager.hasRights(-peerID, 'send');
|
||||||
if(hasRights) this.chatInner.classList.add('has-rights');
|
this.chatInner.classList.toggle('has-rights', hasRights);
|
||||||
else this.chatInner.classList.remove('has-rights');
|
|
||||||
|
|
||||||
this.chatInput.style.display = !isChannel || hasRights ? '' : 'none';
|
this.chatInput.style.display = !isChannel || hasRights ? '' : 'none';
|
||||||
|
|
||||||
this.topbar.style.display = '';
|
this.topbar.style.display = '';
|
||||||
|
|
||||||
if(appPeersManager.isAnyGroup(peerID) || peerID == this.myID) this.chatInner.classList.add('is-chat');
|
this.chatInner.classList.toggle('is-chat', appPeersManager.isAnyGroup(peerID) || peerID == this.myID);
|
||||||
else this.chatInner.classList.remove('is-chat');
|
this.chatInner.classList.toggle('is-channel', isChannel);
|
||||||
if(isChannel) this.chatInner.classList.add('is-channel');
|
|
||||||
else this.chatInner.classList.remove('is-channel');
|
|
||||||
|
|
||||||
this.pinnedMessageContainer.style.display = 'none';
|
this.pinnedMessageContainer.style.display = 'none';
|
||||||
|
|
||||||
@ -1159,7 +1156,7 @@ export class AppImManager {
|
|||||||
}) as Promise<boolean>;
|
}) as Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateUnreadByDialog(dialog: any) {
|
public updateUnreadByDialog(dialog: Dialog) {
|
||||||
let maxID = this.peerID == this.myID ? dialog.read_inbox_max_id : dialog.read_outbox_max_id;
|
let maxID = this.peerID == this.myID ? dialog.read_inbox_max_id : dialog.read_outbox_max_id;
|
||||||
|
|
||||||
///////this.log('updateUnreadByDialog', maxID, dialog, this.unreadOut);
|
///////this.log('updateUnreadByDialog', maxID, dialog, this.unreadOut);
|
||||||
@ -1190,6 +1187,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
this.bubbleGroups.removeBubble(bubble, id);
|
this.bubbleGroups.removeBubble(bubble, id);
|
||||||
this.unreadedObserver.unobserve(bubble);
|
this.unreadedObserver.unobserve(bubble);
|
||||||
|
//this.unreaded.findAndSplice(mid => mid == id);
|
||||||
this.scrollable.removeElement(bubble);
|
this.scrollable.removeElement(bubble);
|
||||||
//bubble.remove();
|
//bubble.remove();
|
||||||
});
|
});
|
||||||
@ -1290,7 +1288,7 @@ export class AppImManager {
|
|||||||
this.scrollable.append(container, false);
|
this.scrollable.append(container, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.datesIntersectionObserver.observe(container);
|
this.stickyIntersector.observeStickyHeaderChanges(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.dateMessages[dateTimestamp];
|
return this.dateMessages[dateTimestamp];
|
||||||
@ -1423,9 +1421,13 @@ export class AppImManager {
|
|||||||
bubble.dataset.mid = message.mid;
|
bubble.dataset.mid = message.mid;
|
||||||
|
|
||||||
if(message._ == 'messageService') {
|
if(message._ == 'messageService') {
|
||||||
bubble.className = 'bubble service';
|
|
||||||
|
|
||||||
let action = message.action;
|
let action = message.action;
|
||||||
|
let _ = action._;
|
||||||
|
if(IGNOREACTIONS.indexOf(_) !== -1) {
|
||||||
|
return bubble;
|
||||||
|
}
|
||||||
|
|
||||||
|
bubble.className = 'bubble service';
|
||||||
|
|
||||||
let title = appPeersManager.getPeerTitle(message.fromID);
|
let title = appPeersManager.getPeerTitle(message.fromID);
|
||||||
let name = document.createElement('div');
|
let name = document.createElement('div');
|
||||||
@ -1433,7 +1435,10 @@ export class AppImManager {
|
|||||||
name.dataset.peerID = message.fromID;
|
name.dataset.peerID = message.fromID;
|
||||||
name.innerHTML = title;
|
name.innerHTML = title;
|
||||||
|
|
||||||
let _ = action._;
|
let str = '';
|
||||||
|
if(action.message) {
|
||||||
|
str = RichTextProcessor.wrapRichText(action.message, {noLinebreaks: true});
|
||||||
|
} else {
|
||||||
if(_ == "messageActionPhoneCall") {
|
if(_ == "messageActionPhoneCall") {
|
||||||
_ += '.' + action.type;
|
_ += '.' + action.type;
|
||||||
}
|
}
|
||||||
@ -1444,7 +1449,9 @@ export class AppImManager {
|
|||||||
l = '[' + _ + ']';
|
l = '[' + _ + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
let str = l[0].toUpperCase() == l[0] ? l : (name.innerText ? name.outerHTML + ' ' : '') + l;
|
str = l[0].toUpperCase() == l[0] ? l : (name.innerText ? name.outerHTML + ' ' : '') + l;
|
||||||
|
}
|
||||||
|
|
||||||
bubbleContainer.innerHTML = `<div class="service-msg">${str}</div>`;
|
bubbleContainer.innerHTML = `<div class="service-msg">${str}</div>`;
|
||||||
|
|
||||||
if(updatePosition) {
|
if(updatePosition) {
|
||||||
@ -1630,6 +1637,9 @@ export class AppImManager {
|
|||||||
//this.log('not our message', message, message.pFlags.unread);
|
//this.log('not our message', message, message.pFlags.unread);
|
||||||
if(message.pFlags.unread) {
|
if(message.pFlags.unread) {
|
||||||
this.unreadedObserver.observe(bubble);
|
this.unreadedObserver.observe(bubble);
|
||||||
|
if(!this.unreaded.indexOf(message.mid)) {
|
||||||
|
this.unreaded.push(message.mid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1845,19 +1855,28 @@ export class AppImManager {
|
|||||||
bubble.classList.add('sticker-animated');
|
bubble.classList.add('sticker-animated');
|
||||||
}
|
}
|
||||||
|
|
||||||
appPhotosManager.setAttachmentSize(doc, attachmentDiv, undefined, undefined, true);
|
let size = bubble.classList.contains('emoji-big') ? 140 : 200;
|
||||||
|
appPhotosManager.setAttachmentSize(doc, attachmentDiv, size, size, true);
|
||||||
//let preloader = new ProgressivePreloader(attachmentDiv, false);
|
//let preloader = new ProgressivePreloader(attachmentDiv, false);
|
||||||
bubbleContainer.style.height = attachmentDiv.style.height;
|
bubbleContainer.style.height = attachmentDiv.style.height;
|
||||||
bubbleContainer.style.width = attachmentDiv.style.width;
|
bubbleContainer.style.width = attachmentDiv.style.width;
|
||||||
//appPhotosManager.setAttachmentSize(doc, bubble);
|
//appPhotosManager.setAttachmentSize(doc, bubble);
|
||||||
wrapSticker(doc, attachmentDiv, () => {
|
wrapSticker({
|
||||||
|
doc,
|
||||||
|
div: attachmentDiv,
|
||||||
|
middleware: () => {
|
||||||
if(this.peerID != peerID) {
|
if(this.peerID != peerID) {
|
||||||
this.log.warn('peer changed, canceling sticker attach');
|
this.log.warn('peer changed, canceling sticker attach');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}, this.lazyLoadQueue, 'chat', false, !!message.pending || !multipleRender);
|
},
|
||||||
|
lazyLoadQueue: this.lazyLoadQueue,
|
||||||
|
group: 'chat',
|
||||||
|
play: !!message.pending || !multipleRender,
|
||||||
|
emoji: bubble.classList.contains('emoji-big') ? messageMessage : undefined
|
||||||
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else if(doc.type == 'video' || doc.type == 'gif' || doc.type == 'round'/* && doc.size <= 20e6 */) {
|
} else if(doc.type == 'video' || doc.type == 'gif' || doc.type == 'round'/* && doc.size <= 20e6 */) {
|
||||||
@ -2215,6 +2234,7 @@ export class AppImManager {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
this.log('getHistory result by maxID:', maxID, reverse, isBackLimit, result);
|
||||||
cached = true;
|
cached = true;
|
||||||
promise = this.performHistoryResult(result.history || [], reverse, isBackLimit, additionMsgID);
|
promise = this.performHistoryResult(result.history || [], reverse, isBackLimit, additionMsgID);
|
||||||
//return (reverse ? this.getHistoryTopPromise = promise : this.getHistoryBottomPromise = promise);
|
//return (reverse ? this.getHistoryTopPromise = promise : this.getHistoryBottomPromise = promise);
|
||||||
@ -2295,7 +2315,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
if(dateMessage.container.childElementCount == 1) { // only date div
|
if(dateMessage.container.childElementCount == 1) { // only date div
|
||||||
dateMessage.container.remove();
|
dateMessage.container.remove();
|
||||||
this.datesIntersectionObserver.unobserve(dateMessage.container);
|
this.stickyIntersector.unobserve(dateMessage.container, dateMessage.div);
|
||||||
delete this.dateMessages[i];
|
delete this.dateMessages[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,10 +582,10 @@ export class AppMediaViewer {
|
|||||||
public openMedia(message: any, target?: HTMLElement, reverse = false, targetContainer?: HTMLElement,
|
public openMedia(message: any, target?: HTMLElement, reverse = false, targetContainer?: HTMLElement,
|
||||||
prevTargets: AppMediaViewer['prevTargets'] = [], nextTargets: AppMediaViewer['prevTargets'] = [], needLoadMore = true) {
|
prevTargets: AppMediaViewer['prevTargets'] = [], nextTargets: AppMediaViewer['prevTargets'] = [], needLoadMore = true) {
|
||||||
////////this.log('openMedia doc:', message, prevTarget, nextTarget);
|
////////this.log('openMedia doc:', message, prevTarget, nextTarget);
|
||||||
let media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo;
|
const media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo;
|
||||||
|
|
||||||
let isVideo = media.mime_type == 'video/mp4';
|
const isVideo = media.mime_type == 'video/mp4';
|
||||||
let isFirstOpen = !this.peerID;
|
const isFirstOpen = !this.peerID;
|
||||||
|
|
||||||
if(isFirstOpen) {
|
if(isFirstOpen) {
|
||||||
this.peerID = $rootScope.selectedPeerID;
|
this.peerID = $rootScope.selectedPeerID;
|
||||||
@ -614,8 +614,8 @@ export class AppMediaViewer {
|
|||||||
this.buttons.prev.style.display = this.prevTargets.length ? '' : 'none';
|
this.buttons.prev.style.display = this.prevTargets.length ? '' : 'none';
|
||||||
this.buttons.next.style.display = this.nextTargets.length ? '' : 'none';
|
this.buttons.next.style.display = this.nextTargets.length ? '' : 'none';
|
||||||
|
|
||||||
let container = this.content.container;
|
const container = this.content.container;
|
||||||
let useContainerAsTarget = !target;
|
const useContainerAsTarget = !target;
|
||||||
if(useContainerAsTarget) target = container;
|
if(useContainerAsTarget) target = container;
|
||||||
|
|
||||||
this.currentMessageID = message.mid;
|
this.currentMessageID = message.mid;
|
||||||
@ -635,13 +635,13 @@ export class AppMediaViewer {
|
|||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
let date = new Date(media.date * 1000);
|
const date = new Date(media.date * 1000);
|
||||||
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||||
|
|
||||||
let dateStr = months[date.getMonth()] + ' ' + date.getDate() + ' at '+ date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
|
const dateStr = months[date.getMonth()] + ' ' + date.getDate() + ' at '+ date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
|
||||||
this.author.date.innerText = dateStr;
|
this.author.date.innerText = dateStr;
|
||||||
|
|
||||||
let name = appPeersManager.getPeerTitle(message.fromID);
|
const name = appPeersManager.getPeerTitle(message.fromID);
|
||||||
this.author.nameEl.innerHTML = name;
|
this.author.nameEl.innerHTML = name;
|
||||||
|
|
||||||
if(message.message) {
|
if(message.message) {
|
||||||
@ -656,7 +656,7 @@ export class AppMediaViewer {
|
|||||||
|
|
||||||
// ok set
|
// ok set
|
||||||
|
|
||||||
let wasActive = fromRight !== 0;
|
const wasActive = fromRight !== 0;
|
||||||
if(wasActive) {
|
if(wasActive) {
|
||||||
this.moveTheMover(this.content.mover, fromRight === 1);
|
this.moveTheMover(this.content.mover, fromRight === 1);
|
||||||
this.setNewMover();
|
this.setNewMover();
|
||||||
@ -667,18 +667,19 @@ export class AppMediaViewer {
|
|||||||
|
|
||||||
////////this.log('wasActive:', wasActive);
|
////////this.log('wasActive:', wasActive);
|
||||||
|
|
||||||
|
const mover = this.content.mover;
|
||||||
|
|
||||||
|
//const maxWidth = appPhotosManager.windowW - 16;
|
||||||
|
const maxWidth = this.pageEl.scrollWidth - 16;
|
||||||
|
const maxHeight = appPhotosManager.windowH - 100;
|
||||||
|
const size = appPhotosManager.setAttachmentSize(isVideo ? media : media.id, container, maxWidth, maxHeight);
|
||||||
|
|
||||||
|
// need after setAttachmentSize
|
||||||
if(useContainerAsTarget) {
|
if(useContainerAsTarget) {
|
||||||
target = target.querySelector('img, video') || target;
|
target = target.querySelector('img, video') || target;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mover = this.content.mover;
|
|
||||||
|
|
||||||
//let maxWidth = appPhotosManager.windowW - 16;
|
|
||||||
let maxWidth = this.pageEl.scrollWidth - 16;
|
|
||||||
let maxHeight = appPhotosManager.windowH - 100;
|
|
||||||
if(isVideo) {
|
if(isVideo) {
|
||||||
appPhotosManager.setAttachmentSize(media, container, maxWidth, maxHeight);
|
|
||||||
|
|
||||||
////////this.log('will wrap video', media, size);
|
////////this.log('will wrap video', media, size);
|
||||||
|
|
||||||
let afterTimeout = this.setMoverToTarget(target, false, fromRight);
|
let afterTimeout = this.setMoverToTarget(target, false, fromRight);
|
||||||
@ -721,10 +722,10 @@ export class AppMediaViewer {
|
|||||||
this.updateMediaSource(mover, url, 'source');
|
this.updateMediaSource(mover, url, 'source');
|
||||||
this.updateMediaSource(target, url, 'source');
|
this.updateMediaSource(target, url, 'source');
|
||||||
} else {
|
} else {
|
||||||
let aspecter = mover.firstElementChild;
|
let div = mover.firstElementChild.classList.contains('media-viewer-aspecter') ? mover.firstElementChild : mover;
|
||||||
let img = aspecter.firstElementChild;
|
let image = div.firstElementChild as HTMLImageElement;
|
||||||
if(img instanceof HTMLImageElement) {
|
if(image instanceof HTMLImageElement) {
|
||||||
img.remove();
|
image.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderImageFromUrl(source, url);
|
renderImageFromUrl(source, url);
|
||||||
@ -735,11 +736,7 @@ export class AppMediaViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!video.parentElement) {
|
if(!video.parentElement) {
|
||||||
if(aspecter.classList.contains('media-viewer-aspecter')) {
|
div.prepend(video);
|
||||||
aspecter.prepend(video);
|
|
||||||
} else {
|
|
||||||
mover.prepend(video);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,8 +745,6 @@ export class AppMediaViewer {
|
|||||||
} else createPlayer();
|
} else createPlayer();
|
||||||
}, 0);
|
}, 0);
|
||||||
} else {
|
} else {
|
||||||
let size = appPhotosManager.setAttachmentSize(media.id, container, maxWidth, maxHeight);
|
|
||||||
|
|
||||||
let afterTimeout = this.setMoverToTarget(target, false, fromRight);
|
let afterTimeout = this.setMoverToTarget(target, false, fromRight);
|
||||||
//return; // set and don't move
|
//return; // set and don't move
|
||||||
//if(wasActive) return;
|
//if(wasActive) return;
|
||||||
@ -772,14 +767,17 @@ export class AppMediaViewer {
|
|||||||
this.updateMediaSource(target, url, 'img');
|
this.updateMediaSource(target, url, 'img');
|
||||||
this.updateMediaSource(mover, url, 'img');
|
this.updateMediaSource(mover, url, 'img');
|
||||||
} else {
|
} else {
|
||||||
let aspecter = mover.firstElementChild;
|
let div = mover.firstElementChild.classList.contains('media-viewer-aspecter') ? mover.firstElementChild : mover;
|
||||||
let image = aspecter.firstElementChild as HTMLImageElement;
|
let image = div.firstElementChild as HTMLImageElement;
|
||||||
if(!image) {
|
if(!image || image.tagName != 'IMG') {
|
||||||
image = new Image();
|
image = new Image();
|
||||||
aspecter.append(image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderImageFromUrl(image, url);
|
//this.log('will renderImageFromUrl:', image, div, target);
|
||||||
|
|
||||||
|
renderImageFromUrl(image, url).then(() => {
|
||||||
|
div.append(image);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.preloader.detach();
|
this.preloader.detach();
|
||||||
|
@ -30,7 +30,7 @@ export type HistoryStorage = {
|
|||||||
history: number[],
|
history: number[],
|
||||||
pending: number[],
|
pending: number[],
|
||||||
|
|
||||||
readPromise?: any,
|
readPromise?: Promise<boolean>,
|
||||||
maxOutID?: number,
|
maxOutID?: number,
|
||||||
reply_markup?: any
|
reply_markup?: any
|
||||||
};
|
};
|
||||||
@ -1425,18 +1425,19 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public generateIndexForDialog(dialog: Dialog) {
|
public generateIndexForDialog(dialog: Dialog) {
|
||||||
let channelID = appPeersManager.isChannel(dialog.peerID) ? -dialog.peerID : 0;
|
const channelID = appPeersManager.isChannel(dialog.peerID) ? -dialog.peerID : 0;
|
||||||
let mid = appMessagesIDsManager.getFullMessageID(dialog.top_message, channelID);
|
const mid = appMessagesIDsManager.getFullMessageID(dialog.top_message, channelID);
|
||||||
let message = this.getMessage(mid);
|
const message = this.getMessage(mid);
|
||||||
|
|
||||||
let topDate = message.date;
|
let topDate = message.date;
|
||||||
if(channelID) {
|
if(channelID) {
|
||||||
let channel = appChatsManager.getChat(channelID);
|
const channel = appChatsManager.getChat(channelID);
|
||||||
if(!topDate || channel.date && channel.date > topDate) {
|
if(!topDate || channel.date && channel.date > topDate) {
|
||||||
topDate = channel.date;
|
topDate = channel.date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let savedDraft: any = {};// DraftsManager.saveDraft(peerID, dialog.draft); // warning
|
|
||||||
|
const savedDraft: any = {};// DraftsManager.saveDraft(peerID, dialog.draft); // warning
|
||||||
if(savedDraft && savedDraft.date > topDate) {
|
if(savedDraft && savedDraft.date > topDate) {
|
||||||
topDate = savedDraft.date;
|
topDate = savedDraft.date;
|
||||||
}
|
}
|
||||||
@ -1619,20 +1620,20 @@ export class AppMessagesManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var peerID = this.getMessagePeer(apiMessage);
|
const peerID = this.getMessagePeer(apiMessage);
|
||||||
var isChannel = apiMessage.to_id._ == 'peerChannel';
|
const isChannel = apiMessage.to_id._ == 'peerChannel';
|
||||||
var channelID = isChannel ? -peerID : 0;
|
const channelID = isChannel ? -peerID : 0;
|
||||||
var isBroadcast = isChannel && appChatsManager.isBroadcast(channelID);
|
const isBroadcast = isChannel && appChatsManager.isBroadcast(channelID);
|
||||||
|
|
||||||
var mid = appMessagesIDsManager.getFullMessageID(apiMessage.id, channelID);
|
const mid = appMessagesIDsManager.getFullMessageID(apiMessage.id, channelID);
|
||||||
apiMessage.mid = mid;
|
apiMessage.mid = mid;
|
||||||
|
|
||||||
if(apiMessage.grouped_id) {
|
if(apiMessage.grouped_id) {
|
||||||
let storage = this.groupedMessagesStorage[apiMessage.grouped_id] ?? (this.groupedMessagesStorage[apiMessage.grouped_id] = {});
|
const storage = this.groupedMessagesStorage[apiMessage.grouped_id] ?? (this.groupedMessagesStorage[apiMessage.grouped_id] = {});
|
||||||
storage[mid] = apiMessage;
|
storage[mid] = apiMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dialog = this.getDialogByPeerID(peerID)[0];
|
const dialog = this.getDialogByPeerID(peerID)[0];
|
||||||
if(dialog && mid > 0) {
|
if(dialog && mid > 0) {
|
||||||
apiMessage.pFlags.unread = mid > dialog[apiMessage.pFlags.out
|
apiMessage.pFlags.unread = mid > dialog[apiMessage.pFlags.out
|
||||||
? 'read_outbox_max_id'
|
? 'read_outbox_max_id'
|
||||||
@ -1651,12 +1652,12 @@ export class AppMessagesManager {
|
|||||||
apiMessage.peerID = peerID;
|
apiMessage.peerID = peerID;
|
||||||
apiMessage.fromID = apiMessage.pFlags.post ? peerID : apiMessage.from_id;
|
apiMessage.fromID = apiMessage.pFlags.post ? peerID : apiMessage.from_id;
|
||||||
|
|
||||||
var fwdHeader = apiMessage.fwd_from;
|
const fwdHeader = apiMessage.fwd_from;
|
||||||
if(fwdHeader) {
|
if(fwdHeader) {
|
||||||
if(peerID == appUsersManager.getSelf().id) {
|
if(peerID == appUsersManager.getSelf().id) {
|
||||||
if(fwdHeader.saved_from_peer && fwdHeader.saved_from_msg_id) {
|
if(fwdHeader.saved_from_peer && fwdHeader.saved_from_msg_id) {
|
||||||
var savedFromPeerID = appPeersManager.getPeerID(fwdHeader.saved_from_peer);
|
const savedFromPeerID = appPeersManager.getPeerID(fwdHeader.saved_from_peer);
|
||||||
var savedFromMid = appMessagesIDsManager.getFullMessageID(fwdHeader.saved_from_msg_id,
|
const savedFromMid = appMessagesIDsManager.getFullMessageID(fwdHeader.saved_from_msg_id,
|
||||||
appPeersManager.isChannel(savedFromPeerID) ? -savedFromPeerID : 0);
|
appPeersManager.isChannel(savedFromPeerID) ? -savedFromPeerID : 0);
|
||||||
apiMessage.savedFrom = savedFromPeerID + '_' + savedFromMid;
|
apiMessage.savedFrom = savedFromPeerID + '_' + savedFromMid;
|
||||||
}
|
}
|
||||||
@ -1675,7 +1676,7 @@ export class AppMessagesManager {
|
|||||||
apiMessage.viaBotID = apiMessage.via_bot_id;
|
apiMessage.viaBotID = apiMessage.via_bot_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaContext = {
|
const mediaContext = {
|
||||||
user_id: apiMessage.fromID,
|
user_id: apiMessage.fromID,
|
||||||
date: apiMessage.date
|
date: apiMessage.date
|
||||||
};
|
};
|
||||||
@ -1725,8 +1726,8 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(apiMessage.action) {
|
if(apiMessage.action) {
|
||||||
var migrateFrom;
|
let migrateFrom;
|
||||||
var migrateTo;
|
let migrateTo;
|
||||||
switch(apiMessage.action._) {
|
switch(apiMessage.action._) {
|
||||||
case 'messageActionChatEditPhoto':
|
case 'messageActionChatEditPhoto':
|
||||||
apiMessage.action.photo = appPhotosManager.savePhoto(apiMessage.action.photo, mediaContext);
|
apiMessage.action.photo = appPhotosManager.savePhoto(apiMessage.action.photo, mediaContext);
|
||||||
@ -1810,8 +1811,8 @@ export class AppMessagesManager {
|
|||||||
apiMessage.rReply = this.getRichReplyText(apiMessage);
|
apiMessage.rReply = this.getRichReplyText(apiMessage);
|
||||||
|
|
||||||
if(apiMessage.message && apiMessage.message.length) {
|
if(apiMessage.message && apiMessage.message.length) {
|
||||||
var myEntities = RichTextProcessor.parseEntities(apiMessage.message);
|
const myEntities = RichTextProcessor.parseEntities(apiMessage.message);
|
||||||
var apiEntities = apiMessage.entities || [];
|
const apiEntities = apiMessage.entities || [];
|
||||||
apiMessage.totalEntities = RichTextProcessor.mergeEntities(myEntities, apiEntities, !apiMessage.pending);
|
apiMessage.totalEntities = RichTextProcessor.mergeEntities(myEntities, apiEntities, !apiMessage.pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2037,22 +2038,24 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public canEditMessage(messageID: number) {
|
public canEditMessage(messageID: number) {
|
||||||
if (!this.messagesStorage[messageID]) {
|
if(!this.messagesStorage[messageID]) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
var message = this.messagesStorage[messageID]
|
|
||||||
if (!message ||
|
const message = this.messagesStorage[messageID];
|
||||||
!message.canBeEdited) {
|
if(!message || !message.canBeEdited) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
if (this.getMessagePeer(message) == appUsersManager.getSelf().id) {
|
|
||||||
return true
|
if(this.getMessagePeer(message) == appUsersManager.getSelf().id) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (message.date < tsNow(true) - 2 * 86400 ||
|
|
||||||
!message.pFlags.out) {
|
if(message.date < tsNow(true) - 2 * 86400 || !message.pFlags.out) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public applyConversations(dialogsResult: any) {
|
public applyConversations(dialogsResult: any) {
|
||||||
@ -2062,12 +2065,12 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
//console.log('applyConversation', dialogsResult);
|
//console.log('applyConversation', dialogsResult);
|
||||||
|
|
||||||
var updatedDialogs: {[peerID: number]: Dialog} = {};
|
const updatedDialogs: {[peerID: number]: Dialog} = {};
|
||||||
var hasUpdated = false;
|
let hasUpdated = false;
|
||||||
dialogsResult.dialogs.forEach((dialog: any) => {
|
dialogsResult.dialogs.forEach((dialog: any) => {
|
||||||
var peerID = appPeersManager.getPeerID(dialog.peer);
|
const peerID = appPeersManager.getPeerID(dialog.peer);
|
||||||
var topMessage = dialog.top_message;
|
let topMessage = dialog.top_message;
|
||||||
var topPendingMesage = this.pendingTopMsgs[peerID];
|
const topPendingMesage = this.pendingTopMsgs[peerID];
|
||||||
if(topPendingMesage) {
|
if(topPendingMesage) {
|
||||||
if(!topMessage || this.getMessage(topPendingMesage).date > this.getMessage(topMessage).date) {
|
if(!topMessage || this.getMessage(topPendingMesage).date > this.getMessage(topMessage).date) {
|
||||||
dialog.top_message = topMessage = topPendingMesage;
|
dialog.top_message = topMessage = topPendingMesage;
|
||||||
@ -2075,7 +2078,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(topMessage) {
|
if(topMessage) {
|
||||||
let wasDialogBefore = this.getDialogByPeerID(peerID)[0];
|
const wasDialogBefore = this.getDialogByPeerID(peerID)[0];
|
||||||
|
|
||||||
// here need to just replace, not FULL replace dialog! WARNING
|
// here need to just replace, not FULL replace dialog! WARNING
|
||||||
if(wasDialogBefore && wasDialogBefore.pFlags && wasDialogBefore.pFlags.pinned) {
|
if(wasDialogBefore && wasDialogBefore.pFlags && wasDialogBefore.pFlags.pinned) {
|
||||||
@ -2093,7 +2096,7 @@ export class AppMessagesManager {
|
|||||||
hasUpdated = true;
|
hasUpdated = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var foundDialog = this.getDialogByPeerID(peerID);
|
const foundDialog = this.getDialogByPeerID(peerID);
|
||||||
if(foundDialog.length) {
|
if(foundDialog.length) {
|
||||||
this.dialogsStorage[foundDialog[0].folder_id].splice(foundDialog[1], 1);
|
this.dialogsStorage[foundDialog[0].folder_id].splice(foundDialog[1], 1);
|
||||||
$rootScope.$broadcast('dialog_drop', {peerID: peerID, dialog: foundDialog[0]});
|
$rootScope.$broadcast('dialog_drop', {peerID: peerID, dialog: foundDialog[0]});
|
||||||
@ -2101,8 +2104,8 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(this.newUpdatesAfterReloadToHandle[peerID] !== undefined) {
|
if(this.newUpdatesAfterReloadToHandle[peerID] !== undefined) {
|
||||||
for(let i in this.newUpdatesAfterReloadToHandle[peerID]) {
|
for(const i in this.newUpdatesAfterReloadToHandle[peerID]) {
|
||||||
let update = this.newUpdatesAfterReloadToHandle[peerID][i];
|
const update = this.newUpdatesAfterReloadToHandle[peerID][i];
|
||||||
this.handleUpdate(update);
|
this.handleUpdate(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2534,27 +2537,21 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public readHistory(peerID: number, maxID = 0, minID = 0): Promise<boolean> {
|
public readHistory(peerID: number, maxID = 0, readLength = 0): Promise<boolean> {
|
||||||
// console.trace('start read')
|
// console.trace('start read')
|
||||||
var isChannel = appPeersManager.isChannel(peerID);
|
const isChannel = appPeersManager.isChannel(peerID);
|
||||||
var historyStorage = this.historiesStorage[peerID];
|
const historyStorage = this.historiesStorage[peerID];
|
||||||
var foundDialog = this.getDialogByPeerID(peerID)[0];
|
const foundDialog = this.getDialogByPeerID(peerID)[0];
|
||||||
|
|
||||||
if(!foundDialog || !foundDialog.unread_count) {
|
if(!foundDialog || !foundDialog.unread_count) {
|
||||||
if(!historyStorage || !historyStorage.history.length) {
|
if(!historyStorage || !historyStorage.history.length) {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let messageID, message;
|
let foundUnread = !!historyStorage.history.find(messageID => {
|
||||||
let foundUnread = false;
|
const message = this.messagesStorage[messageID];
|
||||||
for(let i = historyStorage.history.length; i >= 0; i--) {
|
return message && !message.pFlags.out && message.pFlags.unread;
|
||||||
messageID = historyStorage.history[i];
|
});
|
||||||
message = this.messagesStorage[messageID];
|
|
||||||
if(message && !message.pFlags.out && message.pFlags.unread) {
|
|
||||||
foundUnread = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!foundUnread) {
|
if(!foundUnread) {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
@ -2562,10 +2559,10 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(historyStorage.readPromise) {
|
if(historyStorage.readPromise) {
|
||||||
return historyStorage.readPromise as Promise<boolean>;
|
return historyStorage.readPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiPromise: any;
|
let apiPromise: any;
|
||||||
if(isChannel) {
|
if(isChannel) {
|
||||||
apiPromise = apiManager.invokeApi('channels.readHistory', {
|
apiPromise = apiManager.invokeApi('channels.readHistory', {
|
||||||
channel: appChatsManager.getChannelInput(-peerID),
|
channel: appChatsManager.getChannelInput(-peerID),
|
||||||
@ -2588,22 +2585,46 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
historyStorage.readPromise = apiPromise.then(() => {
|
historyStorage.readPromise = apiPromise.then(() => {
|
||||||
|
let index = -1;
|
||||||
|
if(maxID != 0 && historyStorage.history.length) {
|
||||||
|
index = historyStorage.history.indexOf(maxID);
|
||||||
|
}
|
||||||
|
|
||||||
|
let readedLength = 0;
|
||||||
|
|
||||||
|
if(historyStorage.history.length && maxID) {
|
||||||
|
for(let i = index == -1 ? 0 : index, length = historyStorage.history.length; i < length; i++) {
|
||||||
|
const messageID = historyStorage.history[i];
|
||||||
|
|
||||||
|
if(messageID > maxID) continue;
|
||||||
|
|
||||||
|
const message = this.messagesStorage[messageID];
|
||||||
|
if(message && !message.pFlags.out) {
|
||||||
|
message.pFlags.unread = false;
|
||||||
|
readedLength++;
|
||||||
|
//NotificationsManager.cancel('msg' + messageID); // warning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(foundDialog) {
|
if(foundDialog) {
|
||||||
// console.log('done read history', peerID)
|
// console.log('done read history', peerID)
|
||||||
|
|
||||||
let index = -1;
|
if(historyStorage.history.length) {
|
||||||
if(maxID != 0 && historyStorage && historyStorage.history.length) {
|
////////console.warn('readPromise:', index, historyStorage.history[index != -1 ? index : 0]);
|
||||||
index = historyStorage.history.findIndex((mid: number) => mid == maxID);
|
foundDialog.read_inbox_max_id = maxID;
|
||||||
}
|
}
|
||||||
|
|
||||||
foundDialog.unread_count = index == -1 ? 0 : index;
|
if(foundDialog.read_inbox_max_id == foundDialog.top_message || foundDialog.read_inbox_max_id == foundDialog.read_outbox_max_id) {
|
||||||
////////console.log('readHistory set unread_count to:', foundDialog.unread_count, foundDialog);
|
foundDialog.unread_count = 0;
|
||||||
|
} else {
|
||||||
|
foundDialog.unread_count = Math.max(foundDialog.unread_count - (readLength || readedLength), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log('readHistory set unread_count to:', foundDialog.unread_count, foundDialog);
|
||||||
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: foundDialog.unread_count});
|
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: foundDialog.unread_count});
|
||||||
$rootScope.$broadcast('messages_read');
|
$rootScope.$broadcast('messages_read');
|
||||||
if(historyStorage && historyStorage.history.length) {
|
|
||||||
////////console.warn('readPromise:', index, historyStorage.history[index != -1 ? index : 0]);
|
|
||||||
foundDialog.read_inbox_max_id = historyStorage.history[index != -1 ? index : 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2613,23 +2634,6 @@ export class AppMessagesManager {
|
|||||||
delete historyStorage.readPromise;
|
delete historyStorage.readPromise;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(historyStorage && historyStorage.history.length) {
|
|
||||||
let messageID: number;
|
|
||||||
let message, i;
|
|
||||||
for(i = 0; i < historyStorage.history.length; i++) {
|
|
||||||
messageID = historyStorage.history[i];
|
|
||||||
|
|
||||||
message = this.messagesStorage[messageID];
|
|
||||||
if(message && !message.pFlags.out) {
|
|
||||||
message.pFlags.unread = false;
|
|
||||||
|
|
||||||
//NotificationsManager.cancel('msg' + messageID); // warning
|
|
||||||
}
|
|
||||||
|
|
||||||
if(messageID == minID) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotificationsManager.soundReset(appPeersManager.getPeerString(peerID)) // warning
|
// NotificationsManager.soundReset(appPeersManager.getPeerString(peerID)) // warning
|
||||||
|
|
||||||
return historyStorage.readPromise;
|
return historyStorage.readPromise;
|
||||||
@ -3346,14 +3350,16 @@ export class AppMessagesManager {
|
|||||||
if(this.migratedFromTo[peerID]) {
|
if(this.migratedFromTo[peerID]) {
|
||||||
peerID = this.migratedFromTo[peerID];
|
peerID = this.migratedFromTo[peerID];
|
||||||
}
|
}
|
||||||
var historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {count: null, history: [], pending: []});
|
|
||||||
var offset = 0;
|
|
||||||
var offsetNotFound = false;
|
|
||||||
var unreadOffset = 0;
|
|
||||||
var unreadSkip = false;
|
|
||||||
|
|
||||||
var isMigrated = false;
|
const historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {count: null, history: [], pending: []});
|
||||||
var reqPeerID = peerID;
|
const unreadOffset = 0;
|
||||||
|
const unreadSkip = false;
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
let offsetNotFound = false;
|
||||||
|
|
||||||
|
let isMigrated = false;
|
||||||
|
let reqPeerID = peerID;
|
||||||
if(this.migratedToFrom[peerID]) {
|
if(this.migratedToFrom[peerID]) {
|
||||||
isMigrated = true;
|
isMigrated = true;
|
||||||
if(maxID && maxID < appMessagesIDsManager.fullMsgIDModulus) {
|
if(maxID && maxID < appMessagesIDsManager.fullMsgIDModulus) {
|
||||||
@ -3363,7 +3369,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
if(maxID > 0) {
|
if(maxID > 0) {
|
||||||
offsetNotFound = true;
|
offsetNotFound = true;
|
||||||
for(offset = 0; offset < historyStorage.history.length; offset++) {
|
for(; offset < historyStorage.history.length; offset++) {
|
||||||
if(maxID > historyStorage.history[offset]) {
|
if(maxID > historyStorage.history[offset]) {
|
||||||
offsetNotFound = false;
|
offsetNotFound = false;
|
||||||
break;
|
break;
|
||||||
@ -3383,7 +3389,7 @@ export class AppMessagesManager {
|
|||||||
limit = limit;
|
limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var history = historyStorage.history.slice(offset, offset + limit);
|
let history = historyStorage.history.slice(offset, offset + limit);
|
||||||
if(!maxID && historyStorage.pending.length) {
|
if(!maxID && historyStorage.pending.length) {
|
||||||
history = historyStorage.pending.slice().concat(history);
|
history = historyStorage.pending.slice().concat(history);
|
||||||
}
|
}
|
||||||
@ -3411,10 +3417,10 @@ export class AppMessagesManager {
|
|||||||
historyStorage.count++;
|
historyStorage.count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var history: number[] = [];
|
let history: number[] = [];
|
||||||
historyResult.messages.forEach((message: any) => {
|
historyResult.messages.forEach((message: any) => {
|
||||||
history.push(message.mid);
|
history.push(message.mid);
|
||||||
})
|
});
|
||||||
|
|
||||||
if(!maxID && historyStorage.pending.length) {
|
if(!maxID && historyStorage.pending.length) {
|
||||||
history = historyStorage.pending.slice().concat(history);
|
history = historyStorage.pending.slice().concat(history);
|
||||||
@ -3455,25 +3461,26 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
public fillHistoryStorage(peerID: number, maxID: number, fullLimit: number, historyStorage: HistoryStorage): Promise<boolean> {
|
public fillHistoryStorage(peerID: number, maxID: number, fullLimit: number, historyStorage: HistoryStorage): Promise<boolean> {
|
||||||
// console.log('fill history storage', peerID, maxID, fullLimit, angular.copy(historyStorage))
|
// console.log('fill history storage', peerID, maxID, fullLimit, angular.copy(historyStorage))
|
||||||
var offset = (this.migratedFromTo[peerID] && !maxID) ? 1 : 0;
|
const offset = (this.migratedFromTo[peerID] && !maxID) ? 1 : 0;
|
||||||
return this.requestHistory(peerID, maxID, fullLimit, offset).then((historyResult: any) => {
|
return this.requestHistory(peerID, maxID, fullLimit, offset).then((historyResult: any) => {
|
||||||
historyStorage.count = historyResult.count || historyResult.messages.length;
|
historyStorage.count = historyResult.count || historyResult.messages.length;
|
||||||
|
|
||||||
var offset = 0;
|
|
||||||
if(!maxID && historyResult.messages.length) {
|
if(!maxID && historyResult.messages.length) {
|
||||||
maxID = historyResult.messages[0].mid + 1;
|
maxID = historyResult.messages[0].mid + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
if(maxID > 0) {
|
if(maxID > 0) {
|
||||||
for(offset = 0; offset < historyStorage.history.length; offset++) {
|
for(; offset < historyStorage.history.length; offset++) {
|
||||||
if(maxID > historyStorage.history[offset]) {
|
if(maxID > historyStorage.history[offset]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var wasTotalCount = historyStorage.history.length;
|
const wasTotalCount = historyStorage.history.length;
|
||||||
|
|
||||||
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: peerID});
|
||||||
@ -3482,12 +3489,12 @@ export class AppMessagesManager {
|
|||||||
historyStorage.history.push(message.mid);
|
historyStorage.history.push(message.mid);
|
||||||
});
|
});
|
||||||
|
|
||||||
var totalCount = historyStorage.history.length;
|
const totalCount = historyStorage.history.length;
|
||||||
fullLimit -= (totalCount - wasTotalCount);
|
fullLimit -= (totalCount - wasTotalCount);
|
||||||
|
|
||||||
var migratedNextPeer = this.migratedFromTo[peerID];
|
const migratedNextPeer = this.migratedFromTo[peerID];
|
||||||
var migratedPrevPeer = this.migratedToFrom[peerID]
|
const migratedPrevPeer = this.migratedToFrom[peerID]
|
||||||
var isMigrated = migratedNextPeer !== undefined || migratedPrevPeer !== undefined;
|
const isMigrated = migratedNextPeer !== undefined || migratedPrevPeer !== undefined;
|
||||||
|
|
||||||
if(isMigrated) {
|
if(isMigrated) {
|
||||||
historyStorage.count = Math.max(historyStorage.count, totalCount) + 1;
|
historyStorage.count = Math.max(historyStorage.count, totalCount) + 1;
|
||||||
@ -3517,12 +3524,9 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public wrapHistoryResult(result: HistoryResult) {
|
public wrapHistoryResult(result: HistoryResult) {
|
||||||
var unreadOffset = result.unreadOffset;
|
if(result.unreadOffset) {
|
||||||
if(unreadOffset) {
|
for(let i = result.history.length - 1; i >= 0; i--) {
|
||||||
var i;
|
const message = this.messagesStorage[result.history[i]];
|
||||||
var message;
|
|
||||||
for(i = result.history.length - 1; i >= 0; i--) {
|
|
||||||
message = this.messagesStorage[result.history[i]];
|
|
||||||
if(message && !message.pFlags.out && message.pFlags.unread) {
|
if(message && !message.pFlags.out && message.pFlags.unread) {
|
||||||
result.unreadOffset = i + 1;
|
result.unreadOffset = i + 1;
|
||||||
break;
|
break;
|
||||||
@ -3533,7 +3537,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public requestHistory(peerID: number, maxID: number, limit: number, offset = 0): Promise<any> {
|
public requestHistory(peerID: number, maxID: number, limit: number, offset = 0): Promise<any> {
|
||||||
var isChannel = appPeersManager.isChannel(peerID);
|
const isChannel = appPeersManager.isChannel(peerID);
|
||||||
|
|
||||||
//console.trace('requestHistory', peerID, maxID, limit, offset);
|
//console.trace('requestHistory', peerID, maxID, limit, offset);
|
||||||
|
|
||||||
@ -3562,7 +3566,7 @@ export class AppMessagesManager {
|
|||||||
apiUpdatesManager.addChannelState(-peerID, historyResult.pts);
|
apiUpdatesManager.addChannelState(-peerID, historyResult.pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
var length = historyResult.messages.length;
|
let length = historyResult.messages.length;
|
||||||
if(length && historyResult.messages[length - 1].deleted) {
|
if(length && historyResult.messages[length - 1].deleted) {
|
||||||
historyResult.messages.splice(length - 1, 1);
|
historyResult.messages.splice(length - 1, 1);
|
||||||
length--;
|
length--;
|
||||||
@ -3570,7 +3574,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// will load more history if last message is album grouped (because it can be not last item)
|
// will load more history if last message is album grouped (because it can be not last item)
|
||||||
let historyStorage = this.historiesStorage[peerID];
|
const historyStorage = this.historiesStorage[peerID];
|
||||||
// historyResult.messages: desc sorted
|
// historyResult.messages: desc sorted
|
||||||
if(length && historyResult.messages[length - 1].grouped_id && (historyStorage.history.length + historyResult.messages.length) < historyResult.count) {
|
if(length && historyResult.messages[length - 1].grouped_id && (historyStorage.history.length + historyResult.messages.length) < historyResult.count) {
|
||||||
return this.requestHistory(peerID, historyResult.messages[length - 1].mid, 10, 0).then((_historyResult: any) => {
|
return this.requestHistory(peerID, historyResult.messages[length - 1].mid, 10, 0).then((_historyResult: any) => {
|
||||||
@ -3614,7 +3618,7 @@ export class AppMessagesManager {
|
|||||||
}, (error) => {
|
}, (error) => {
|
||||||
switch (error.type) {
|
switch (error.type) {
|
||||||
case 'CHANNEL_PRIVATE':
|
case 'CHANNEL_PRIVATE':
|
||||||
var channel = appChatsManager.getChat(-peerID);
|
let channel = appChatsManager.getChat(-peerID);
|
||||||
channel = {_: 'channelForbidden', access_hash: channel.access_hash, title: channel.title};
|
channel = {_: 'channelForbidden', access_hash: channel.access_hash, title: channel.title};
|
||||||
apiUpdatesManager.processUpdateMessage({
|
apiUpdatesManager.processUpdateMessage({
|
||||||
_: 'updates',
|
_: 'updates',
|
||||||
@ -3628,7 +3632,7 @@ export class AppMessagesManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(error);
|
throw error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,12 +219,7 @@ class AppSidebarRight {
|
|||||||
if(!willChange) return Promise.resolve();
|
if(!willChange) return Promise.resolve();
|
||||||
|
|
||||||
let set = () => {
|
let set = () => {
|
||||||
if(enable !== undefined) {
|
this.sidebarEl.classList.toggle('active', enable);
|
||||||
if(enable) this.sidebarEl.classList.add('active');
|
|
||||||
else this.sidebarEl.classList.remove('active');
|
|
||||||
} else {
|
|
||||||
this.sidebarEl.classList.toggle('active');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -138,7 +138,7 @@ class AppStickersManager {
|
|||||||
public getAnimatedEmojiSticker(emoji: string) {
|
public getAnimatedEmojiSticker(emoji: string) {
|
||||||
let stickerSet = this.stickerSets.emoji;
|
let stickerSet = this.stickerSets.emoji;
|
||||||
|
|
||||||
emoji = emoji.replace(/\ufe0f/g, '');
|
emoji = emoji.replace(/\ufe0f/g, '').replace(/🏻|🏼|🏽|🏾|🏿/g, '');
|
||||||
return stickerSet.documents.find(doc => doc.stickerEmojiRaw == emoji);
|
return stickerSet.documents.find(doc => doc.stickerEmojiRaw == emoji);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,6 +1,10 @@
|
|||||||
import { isInDOM } from "./utils";
|
import { isInDOM } from "./utils";
|
||||||
import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie.d";
|
import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie.d";
|
||||||
|
|
||||||
|
let convert = (value: number) => {
|
||||||
|
return Math.round(Math.min(Math.max(value, 0), 1) * 255);
|
||||||
|
};
|
||||||
|
|
||||||
class LottieLoader {
|
class LottieLoader {
|
||||||
public lottie: /* any */ typeof LottiePlayer = null;
|
public lottie: /* any */ typeof LottiePlayer = null;
|
||||||
private animations: {
|
private animations: {
|
||||||
@ -16,6 +20,35 @@ class LottieLoader {
|
|||||||
public loaded: Promise<void>;
|
public loaded: Promise<void>;
|
||||||
private lastTimeLoad = 0;
|
private lastTimeLoad = 0;
|
||||||
private waitingTimeouts = 0;
|
private waitingTimeouts = 0;
|
||||||
|
private static COLORREPLACEMENTS = [
|
||||||
|
[
|
||||||
|
[0xf77e41, 0xca907a],
|
||||||
|
[0xffb139, 0xedc5a5],
|
||||||
|
[0xffd140, 0xf7e3c3],
|
||||||
|
[0xffdf79, 0xfbefd6],
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
[0xf77e41, 0xaa7c60],
|
||||||
|
[0xffb139, 0xc8a987],
|
||||||
|
[0xffd140, 0xddc89f],
|
||||||
|
[0xffdf79, 0xe6d6b2],
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
[0xf77e41, 0x8c6148],
|
||||||
|
[0xffb139, 0xad8562],
|
||||||
|
[0xffd140, 0xc49e76],
|
||||||
|
[0xffdf79, 0xd4b188],
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
[0xf77e41, 0x6e3c2c],
|
||||||
|
[0xffb139, 0x925a34],
|
||||||
|
[0xffd140, 0xa16e46],
|
||||||
|
[0xffdf79, 0xac7a52],
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
public loadLottie() {
|
public loadLottie() {
|
||||||
if(this.loaded) return this.loaded;
|
if(this.loaded) return this.loaded;
|
||||||
@ -89,13 +122,54 @@ class LottieLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadAnimation(params: /* any */AnimationConfigWithPath | AnimationConfigWithData, group = '') {
|
private applyReplacements(object: any, toneIndex: number) {
|
||||||
|
const replacements = LottieLoader.COLORREPLACEMENTS[toneIndex - 2];
|
||||||
|
|
||||||
|
const iterateIt = (it: any) => {
|
||||||
|
for(let smth of it) {
|
||||||
|
switch(smth.ty) {
|
||||||
|
case 'st':
|
||||||
|
case 'fl':
|
||||||
|
let k = smth.c.k;
|
||||||
|
let color = convert(k[2]) | (convert(k[1]) << 8) | (convert(k[0]) << 16);
|
||||||
|
|
||||||
|
let foundReplacement = replacements.find(p => p[0] == color);
|
||||||
|
if(foundReplacement) {
|
||||||
|
k[0] = ((foundReplacement[1] >> 16) & 255) / 255;
|
||||||
|
k[1] = ((foundReplacement[1] >> 8) & 255) / 255;
|
||||||
|
k[2] = (foundReplacement[1] & 255) / 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('foundReplacement!', foundReplacement, color.toString(16), k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(smth.hasOwnProperty('it')) {
|
||||||
|
iterateIt(smth.it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for(let layer of object.layers) {
|
||||||
|
if(!layer.shapes) continue;
|
||||||
|
|
||||||
|
for(let shape of layer.shapes) {
|
||||||
|
iterateIt(shape.it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async loadAnimation(params: /* any */AnimationConfigWithPath & AnimationConfigWithData, group = '', toneIndex = -1) {
|
||||||
//params.autoplay = false;
|
//params.autoplay = false;
|
||||||
//if(group != 'auth') {
|
//if(group != 'auth') {
|
||||||
//params.renderer = 'canvas';
|
//params.renderer = 'canvas';
|
||||||
params.renderer = 'svg';
|
params.renderer = 'svg';
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
if(toneIndex >= 1 && toneIndex <= 5) {
|
||||||
|
this.applyReplacements(params.animationData, toneIndex);
|
||||||
|
}
|
||||||
|
|
||||||
let rendererSettings = {
|
let rendererSettings = {
|
||||||
//context: context, // the canvas context
|
//context: context, // the canvas context
|
||||||
//preserveAspectRatio: 'xMinYMin slice', // Supports the same options as the svg element's preserveAspectRatio property
|
//preserveAspectRatio: 'xMinYMin slice', // Supports the same options as the svg element's preserveAspectRatio property
|
||||||
|
@ -641,7 +641,7 @@ emojiUnicode.raw = function(input) {
|
|||||||
+ (input.charCodeAt(i + 1) - 0xdc00) + 0x10000
|
+ (input.charCodeAt(i + 1) - 0xdc00) + 0x10000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (input.charCodeAt(i) < 0xd800 || input.charCodeAt(i) > 0xdfff) {
|
} else if(input.charCodeAt(i) < 0xd800 || input.charCodeAt(i) > 0xdfff) {
|
||||||
// modifiers and joiners
|
// modifiers and joiners
|
||||||
pairs.push(input.charCodeAt(i))
|
pairs.push(input.charCodeAt(i))
|
||||||
}
|
}
|
||||||
@ -653,6 +653,11 @@ emojiUnicode.raw = function(input) {
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getEmojiToneIndex(input) {
|
||||||
|
let match = input.match(/[\uDFFB-\uDFFF]/);
|
||||||
|
return match ? 5 - (57343 - match[0].charCodeAt(0)) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
//var badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<\s]+/g,
|
//var badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<\s]+/g,
|
||||||
var badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<]+/g,
|
var badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<]+/g,
|
||||||
trimRe = /^\s+|\s$/g
|
trimRe = /^\s+|\s$/g
|
||||||
|
@ -12,6 +12,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bubbles-date-group {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
/* .sticky_sentinel {
|
||||||
|
visibility: visible;
|
||||||
|
background: #000;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.sticky_sentinel--top {
|
||||||
|
/* Adjust the height and top values based on your on your sticky top position.
|
||||||
|
e.g. make the height bigger and adjust the top so observeHeaders()'s
|
||||||
|
IntersectionObserver fires as soon as the bottom of the sentinel crosses the
|
||||||
|
top of the intersection container. */
|
||||||
|
height: 5px;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .sticky_sentinel--bottom {
|
||||||
|
// /* Height should match the top of the header when it's at the bottom of the
|
||||||
|
// intersection container. */
|
||||||
|
// height: 1px;
|
||||||
|
// bottom: 0;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
.bubble {
|
.bubble {
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
max-width: $chat-max-width;
|
max-width: $chat-max-width;
|
||||||
@ -249,8 +274,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.sticker .bubble__container {
|
&.sticker .bubble__container {
|
||||||
max-width: 140px;
|
max-width: 140px !important;
|
||||||
max-height: 140px;
|
max-height: 140px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,15 +344,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bubble__container {
|
.bubble__container {
|
||||||
max-width: 200px;
|
max-width: 200px !important;
|
||||||
max-height: 200px;
|
max-height: 200px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.round {
|
&.round {
|
||||||
.attachment {
|
.attachment {
|
||||||
max-width: 200px;
|
max-width: 200px !important;
|
||||||
max-height: 200px;
|
max-height: 200px !important;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -378,7 +403,9 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.download, .preloader-container {
|
||||||
& ~ .video-play {
|
& ~ .video-play {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -930,6 +957,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -1313,7 +1341,6 @@ poll-element {
|
|||||||
|
|
||||||
&-answer {
|
&-answer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
padding-left: 34px;
|
padding-left: 34px;
|
||||||
@ -1339,7 +1366,7 @@ poll-element {
|
|||||||
|
|
||||||
&-selected {
|
&-selected {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 33px;
|
bottom: 3px;
|
||||||
left: 26px;
|
left: 26px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: #50a2e9;
|
background: #50a2e9;
|
||||||
@ -1379,7 +1406,7 @@ poll-element {
|
|||||||
height: 35px;
|
height: 35px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 17.5px;
|
left: 17.5px;
|
||||||
top: 11px;
|
bottom: 2px;
|
||||||
transition: stroke-dashoffset .34s linear, stroke-dasharray .34s linear;
|
transition: stroke-dashoffset .34s linear, stroke-dasharray .34s linear;
|
||||||
stroke-dashoffset: 0;
|
stroke-dashoffset: 0;
|
||||||
stroke-dasharray: 0, 485.9;
|
stroke-dasharray: 0, 485.9;
|
||||||
|
@ -1376,6 +1376,14 @@ img.emoji {
|
|||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sticky_sentinel {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0; /* needs dimensions */
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.page-chats {
|
.page-chats {
|
||||||
/* display: grid; */
|
/* display: grid; */
|
||||||
/* grid-template-columns: 25% 50%; */
|
/* grid-template-columns: 25% 50%; */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user