tweb/src/lib/appManagers/appImManager.ts

2300 lines
80 KiB
TypeScript
Raw Normal View History

2020-04-26 14:19:17 +02:00
//import apiManager from '../mtproto/apiManager';
import apiManager from '../mtproto/mtprotoworker';
2020-04-30 15:43:26 +02:00
import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, findUpTag, langPack } from "../utils";
2020-02-06 16:43:07 +01:00
import appUsersManager from "./appUsersManager";
import appMessagesManager from "./appMessagesManager";
2020-02-06 16:43:07 +01:00
import appPeersManager from "./appPeersManager";
import appProfileManager from "./appProfileManager";
import appDialogsManager from "./appDialogsManager";
import { RichTextProcessor } from "../richtextprocessor";
import appPhotosManager from "./appPhotosManager";
import appSidebarRight from './appSidebarRight';
import { logger } from "../polyfill";
import lottieLoader from "../lottieLoader";
import appMediaViewer from "./appMediaViewer";
import appSidebarLeft from "./appSidebarLeft";
import appChatsManager from "./appChatsManager";
import appMessagesIDsManager from "./appMessagesIDsManager";
import apiUpdatesManager from './apiUpdatesManager';
2020-05-01 23:28:40 +02:00
import { wrapDocument, wrapPhoto, wrapVideo, wrapSticker, wrapReply, wrapAlbum } from '../../components/wrappers';
import ProgressivePreloader from '../../components/preloader';
2020-05-01 23:28:40 +02:00
import { openBtnMenu, formatPhoneNumber } from '../../components/misc';
2020-02-20 09:13:15 +01:00
import { ChatInput } from '../../components/chatInput';
//import Scrollable from '../../components/scrollable';
import Scrollable from '../../components/scrollable_new';
2020-04-14 17:46:31 +02:00
import BubbleGroups from '../../components/bubbleGroups';
import LazyLoadQueue from '../../components/lazyLoadQueue';
import appDocsManager from './appDocsManager';
import appForward from '../../components/appForward';
2020-02-06 16:43:07 +01:00
console.log('appImManager included!');
appSidebarLeft; // just to include
2020-02-06 16:43:07 +01:00
let testScroll = false;
export class AppImManager {
public pageEl = document.querySelector('.page-chats') as HTMLDivElement;
public btnMute = this.pageEl.querySelector('.tool-mute') as HTMLButtonElement;
public btnMenuMute = this.pageEl.querySelector('.menu-mute') as HTMLButtonElement;
2020-02-06 16:43:07 +01:00
public avatarEl = document.getElementById('im-avatar') as HTMLDivElement;
public titleEl = document.getElementById('im-title') as HTMLDivElement;
public subtitleEl = document.getElementById('im-subtitle') as HTMLDivElement;
2020-02-20 09:13:15 +01:00
public bubblesContainer = document.getElementById('bubbles') as HTMLDivElement;
2020-02-06 16:43:07 +01:00
public chatInner = document.getElementById('bubbles-inner') as HTMLDivElement;
public searchBtn = this.pageEl.querySelector('.chat-search-button') as HTMLButtonElement;
public goDownBtn = this.pageEl.querySelector('#bubbles-go-down') as HTMLButtonElement;
2020-04-08 17:46:43 +02:00
private getHistoryTopPromise: Promise<boolean>;
private getHistoryBottomPromise: Promise<boolean>;
2020-03-01 18:26:25 +01:00
public chatInputC: ChatInput = null;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
public myID = 0;
public peerID = 0;
public muted = false;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
public bubbles: {[mid: number]: HTMLDivElement} = {};
2020-04-08 17:46:43 +02:00
public dateMessages: {[timestamp: number]: {
div: HTMLDivElement,
firstTimestamp: number,
2020-04-22 21:10:09 +02:00
container: HTMLDivElement,
2020-04-08 17:46:43 +02:00
timeout?: number
}} = {};
public unreadOut = new Set<number>();
public needUpdate: {replyMid: number, mid: number}[] = []; // if need wrapSingleMessage
2020-02-06 16:43:07 +01:00
public offline = false;
public updateStatusInterval = 0;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
public pinnedMsgID = 0;
private pinnedMessageContainer = this.pageEl.querySelector('.pinned-message') as HTMLDivElement;
private pinnedMessageContent = this.pinnedMessageContainer.querySelector('.pinned-message-subtitle') as HTMLDivElement;
private firstTopMsgID = 0;
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
public lazyLoadQueue = new LazyLoadQueue();
2020-02-06 16:43:07 +01:00
public scroll: HTMLDivElement = null;
2020-02-20 09:13:15 +01:00
public scrollable: Scrollable = null;
2020-04-16 02:48:41 +02:00
2020-02-07 07:38:55 +01:00
public log: ReturnType<typeof logger>;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
private preloader: ProgressivePreloader = null;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
private typingTimeouts: {[peerID: number]: number} = {};
private typingUsers: {[userID: number]: number} = {} // to peerID
2020-03-01 18:26:25 +01:00
private topbar = document.getElementById('topbar') as HTMLDivElement;
private chatInput = document.getElementById('chat-input') as HTMLDivElement;
private scrolledAll: boolean;
private scrolledAllDown: boolean;
2020-03-01 18:26:25 +01:00
public contextMenu = document.getElementById('bubble-contextmenu') as HTMLDivElement;
private contextMenuPin = this.contextMenu.querySelector('.menu-pin') as HTMLDivElement;
2020-02-10 17:40:33 +01:00
private contextMenuEdit = this.contextMenu.querySelector('.menu-edit') as HTMLDivElement;
private contextMenuMsgID: number;
2020-03-01 18:26:25 +01:00
private popupDeleteMessage: {
popupEl?: HTMLDivElement,
deleteBothBtn?: HTMLButtonElement,
deleteMeBtn?: HTMLButtonElement,
cancelBtn?: HTMLButtonElement
} = {};
2020-03-01 18:26:25 +01:00
private setPeerPromise: Promise<boolean> = null;
2020-03-01 18:26:25 +01:00
public bubbleGroups = new BubbleGroups();
2020-04-16 02:48:41 +02:00
private scrolledDown = true;
2020-04-22 21:10:09 +02:00
private onScrollRAF = 0;
private isScrollingTimeout = 0;
private datesIntersectionObserver: IntersectionObserver = null;
private lastDateMessageDiv: HTMLDivElement = null;
private unreadedObserver: IntersectionObserver = null;
private loadedTopTimes = 0;
private loadedBottomTimes = 0;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
constructor() {
2020-04-14 17:46:31 +02:00
/* if(!lottieLoader.loaded) {
lottieLoader.loadLottie();
} */
2020-02-06 16:43:07 +01:00
this.log = logger('IM');
2020-03-01 18:26:25 +01:00
2020-02-10 08:56:15 +01:00
this.chatInputC = new ChatInput();
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.preloader = new ProgressivePreloader(null, false);
2020-03-01 18:26:25 +01:00
this.popupDeleteMessage.popupEl = this.pageEl.querySelector('.popup-delete-message') as HTMLDivElement;
this.popupDeleteMessage.deleteBothBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-delete-both') as HTMLButtonElement;
this.popupDeleteMessage.deleteMeBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-delete-me') as HTMLButtonElement;
this.popupDeleteMessage.cancelBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-close') as HTMLButtonElement;
2020-03-01 18:26:25 +01:00
apiManager.getUserID().then((id) => {
this.myID = $rootScope.myID = id;
2020-02-06 16:43:07 +01:00
});
2020-02-06 16:43:07 +01:00
$rootScope.$on('user_auth', (e: CustomEvent) => {
let userAuth = e.detail;
this.myID = $rootScope.myID = userAuth ? userAuth.id : 0;
2020-02-06 16:43:07 +01:00
});
2020-03-01 18:26:25 +01:00
// will call when message is sent (only 1)
2020-02-06 16:43:07 +01:00
$rootScope.$on('history_append', (e: CustomEvent) => {
let details = e.detail;
2020-03-01 18:26:25 +01:00
2020-04-16 02:48:41 +02:00
this.renderNewMessagesByIDs([details.messageID]);
2020-02-06 16:43:07 +01:00
});
2020-03-01 18:26:25 +01:00
// will call when sent for update pos
$rootScope.$on('history_update', (e: CustomEvent) => {
let details = e.detail;
2020-03-01 18:26:25 +01:00
if(details.mid && details.peerID == this.peerID) {
let mid = details.mid;
2020-03-01 18:26:25 +01:00
let bubble = this.bubbles[mid];
if(!bubble) return;
2020-03-01 18:26:25 +01:00
let message = appMessagesManager.getMessage(mid);
//this.log('history_update', this.bubbles[mid], mid, message);
let dateMessage = this.getDateContainerByMessage(message, false);
dateMessage.container.append(bubble);
this.bubbleGroups.addBubble(bubble, message, false);
//this.renderMessage(message, false, false, bubble);
}
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
$rootScope.$on('history_multiappend', (e: CustomEvent) => {
let msgIDsByPeer = e.detail;
if(!(this.peerID in msgIDsByPeer)) return;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let msgIDs = msgIDsByPeer[this.peerID];
2020-03-01 18:26:25 +01:00
2020-04-16 02:48:41 +02:00
this.renderNewMessagesByIDs(msgIDs);
});
2020-03-01 18:26:25 +01:00
$rootScope.$on('history_delete', (e: CustomEvent) => {
let detail: {
peerID: string,
msgs: {[x: number]: boolean}
} = e.detail;
2020-03-01 18:26:25 +01:00
this.deleteMessagesByIDs(Object.keys(detail.msgs).map(s => +s));
2020-02-06 16:43:07 +01:00
});
2020-03-01 18:26:25 +01:00
// Calls when message successfully sent and we have an ID
2020-02-06 16:43:07 +01:00
$rootScope.$on('message_sent', (e: CustomEvent) => {
let {tempID, mid} = e.detail;
2020-03-01 18:26:25 +01:00
2020-05-01 23:28:40 +02:00
this.log('message_sent', e.detail);
// set cached url to media
let message = appMessagesManager.getMessage(mid);
if(message.media) {
if(message.media.photo) {
let photo = appPhotosManager.getPhoto(tempID);
if(photo) {
let newPhoto = message.media.photo;
newPhoto.downloaded = photo.downloaded;
newPhoto.url = photo.url;
}
} else if(message.media.document) {
let doc = appDocsManager.getDoc(tempID);
if(doc && doc.type && doc.type != 'sticker') {
let newDoc = message.media.document;
newDoc.downloaded = doc.downloaded;
newDoc.url = doc.url;
}
}
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let bubble = this.bubbles[tempID];
if(bubble) {
this.bubbles[mid] = bubble;
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
/////this.log('message_sent', bubble);
2020-05-01 23:28:40 +02:00
// set new mids to album items for mediaViewer
if(message.grouped_id) {
let items = bubble.querySelectorAll('.album-item');
let groupIDs = Object.keys(appMessagesManager.groupedMessagesStorage[message.grouped_id]).map(i => +i).sort((a, b) => a - b);
(Array.from(items) as HTMLElement[]).forEach((item, idx) => {
item.dataset.mid = '' + groupIDs[idx];
});
}
2020-05-01 23:28:40 +02:00
bubble.classList.remove('is-sending');
bubble.classList.add('is-sent');
bubble.dataset.mid = mid;
2020-03-01 18:26:25 +01:00
this.bubbleGroups.removeBubble(bubble, tempID);
2020-02-06 16:43:07 +01:00
delete this.bubbles[tempID];
} else {
this.log.warn('message_sent there is no bubble', e.detail);
2020-02-06 16:43:07 +01:00
}
if(this.unreadOut.has(tempID)) {
this.unreadOut.delete(tempID);
this.unreadOut.add(mid);
2020-02-06 16:43:07 +01:00
}
});
2020-03-01 18:26:25 +01:00
$rootScope.$on('message_edit', (e: CustomEvent) => {
let {peerID, mid, id, justMedia} = e.detail;
2020-03-01 18:26:25 +01:00
if(peerID != this.peerID) return;
2020-05-01 23:28:40 +02:00
let message = appMessagesManager.getMessage(mid);
2020-03-01 18:26:25 +01:00
let bubble = this.bubbles[mid];
2020-05-01 23:28:40 +02:00
if(!bubble && message.grouped_id) {
let a = this.getAlbumBubble(message.grouped_id);
bubble = a.bubble;
message = a.message;
}
if(!bubble) return;
2020-03-01 18:26:25 +01:00
2020-04-08 17:46:43 +02:00
this.renderMessage(message, true, false, bubble, false);
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
$rootScope.$on('messages_downloaded', (e: CustomEvent) => {
let mids: number[] = e.detail;
2020-02-06 16:43:07 +01:00
mids.forEach(mid => {
if(this.pinnedMsgID == mid) {
let message = appMessagesManager.getMessage(mid);
2020-02-17 13:18:06 +01:00
/////this.log('setting pinned message', message);
this.pinnedMessageContainer.dataset.mid = '' + mid;
this.pinnedMessageContainer.style.display = '';
this.pinnedMessageContent.innerHTML = RichTextProcessor.wrapEmojiText(message.message);
}
2020-03-01 18:26:25 +01:00
2020-02-22 17:00:17 +01:00
this.needUpdate.forEachReverse((obj, idx) => {
if(obj.replyMid == mid) {
let {mid, replyMid} = this.needUpdate.splice(idx, 1)[0];
2020-03-01 18:26:25 +01:00
2020-02-14 14:10:10 +01:00
//this.log('messages_downloaded', mid, replyMid, i, this.needUpdate, this.needUpdate.length, mids, this.bubbles[mid]);
let bubble = this.bubbles[mid];
if(!bubble) return;
2020-03-01 18:26:25 +01:00
2020-02-14 14:10:10 +01:00
let message = appMessagesManager.getMessage(mid);
2020-03-01 18:26:25 +01:00
2020-02-14 14:10:10 +01:00
let repliedMessage = appMessagesManager.getMessage(replyMid);
if(repliedMessage.deleted) { // чтобы не пыталось бесконечно загрузить удалённое сообщение
delete message.reply_to_mid; // WARNING!
}
2020-03-01 18:26:25 +01:00
2020-04-08 17:46:43 +02:00
this.renderMessage(message, true, false, bubble, false);
//this.renderMessage(message, true, true, bubble, false);
}
2020-02-22 17:00:17 +01:00
});
});
2020-02-06 16:43:07 +01:00
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
$rootScope.$on('apiUpdate', (e: CustomEvent) => {
let update = e.detail;
2020-03-01 18:26:25 +01:00
this.handleUpdate(update);
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
window.addEventListener('blur', () => {
lottieLoader.checkAnimations(true);
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.offline = true;
this.updateStatus();
clearInterval(this.updateStatusInterval);
window.addEventListener('focus', () => {
lottieLoader.checkAnimations(false);
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.offline = false;
this.updateStatus();
this.updateStatusInterval = window.setInterval(() => this.updateStatus(), 50e3);
}, {once: true});
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
(this.pageEl.querySelector('.person') as HTMLDivElement).addEventListener('click', (e) => {
appSidebarRight.toggleSidebar(true);
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.chatInner.addEventListener('click', (e) => {
let target = e.target as HTMLElement;
let bubble: HTMLDivElement = null;
try {
bubble = findUpClassName(e.target, 'bubble');
} catch(err) {}
2020-03-01 18:26:25 +01:00
if(!bubble) return;
2020-05-01 23:28:40 +02:00
//this.log('chatInner click:', target);
if(target.tagName == 'SPAN') {
(target.parentElement.querySelector('video') as HTMLElement).click(); // hot-fix for time and play button
return;
}
2020-05-01 23:28:40 +02:00
if((target.tagName == 'IMG' && !target.classList.contains('emoji') && !target.parentElement.classList.contains('user-avatar'))
|| target.tagName == 'image'
|| target.classList.contains('album-item')
|| (target.tagName == 'VIDEO' && !bubble.classList.contains('round'))) {
let messageID = +findUpClassName(target, 'album-item')?.dataset.mid || +bubble.dataset.mid;
let message = appMessagesManager.getMessage(messageID);
if(!message) {
this.log.warn('no message by messageID:', messageID);
return;
}
let targets: {element: HTMLElement, mid: number}[] = [];
let ids = Object.keys(this.bubbles).map(k => +k).filter(id => {
//if(!this.scrollable.visibleElements.find(e => e.element == this.bubbles[id])) return false;
let message = appMessagesManager.getMessage(id);
return message.media && (message.media.photo || (message.media.document && (message.media.document.type == 'video' || message.media.document.type == 'gif')) || (message.media.webpage && (message.media.webpage.document || message.media.webpage.photo)));
}).sort((a, b) => a - b);
ids.forEach(id => {
let bubble = this.bubbles[id];
let elements = this.bubbles[id].querySelectorAll('.attachment img, .preview img, video, .bubble__media-container') as NodeListOf<HTMLElement>;
Array.from(elements).forEach((element: HTMLElement) => {
let albumItem = findUpClassName(element, 'album-item');
targets.push({
element,
mid: +albumItem?.dataset.mid || id
});
});
});
let idx = targets.findIndex(t => t.mid == messageID);
this.log('open mediaViewer single with ids:', ids, idx, targets);
appMediaViewer.openMedia(message, targets[idx].element, true,
this.scroll.parentElement, targets.slice(0, idx), targets.slice(idx + 1)/* , !message.grouped_id */);
//appMediaViewer.openMedia(message, target as HTMLImageElement);
}
2020-03-01 18:26:25 +01:00
2020-05-01 23:28:40 +02:00
if(['IMG', 'DIV'].indexOf(target.tagName) === -1) target = findUpTag(target, 'DIV');
2020-03-01 18:26:25 +01:00
if(target.tagName == 'DIV') {
if(target.classList.contains('forward')) {
let savedFrom = bubble.dataset.savedFrom;
let splitted = savedFrom.split('_');
let peerID = +splitted[0];
let msgID = +splitted[1];
2020-02-17 13:18:06 +01:00
////this.log('savedFrom', peerID, msgID);
this.setPeer(peerID, msgID, true);
return;
} else if(target.classList.contains('user-avatar') || target.classList.contains('name')) {
let peerID = +target.dataset.peerID;
if(!isNaN(peerID)) {
this.setPeer(peerID);
}
2020-03-01 18:26:25 +01:00
return;
}
2020-03-01 18:26:25 +01:00
let isReplyClick = false;
2020-03-01 18:26:25 +01:00
try {
2020-02-15 19:08:26 +01:00
isReplyClick = !!findUpClassName(e.target, 'reply');
} catch(err) {}
2020-03-01 18:26:25 +01:00
if(isReplyClick && bubble.classList.contains('is-reply')/* || bubble.classList.contains('forwarded') */) {
let originalMessageID = +bubble.getAttribute('data-original-mid');
this.setPeer(this.peerID, originalMessageID);
2020-02-10 08:56:15 +01:00
}
} else if(target.tagName == 'IMG' && target.parentElement.classList.contains('user-avatar')) {
let peerID = +target.parentElement.dataset.peerID;
2020-03-01 18:26:25 +01:00
if(!isNaN(peerID)) {
this.setPeer(peerID);
}
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
//console.log('chatInner click', e);
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.searchBtn.addEventListener('click', (e) => {
if(this.peerID) {
appSidebarRight.beginSearch();
//appSidebarLeft.archivedCount;
//appSidebarLeft.beginSearch(this.peerID);
2020-02-06 16:43:07 +01:00
}
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.pinnedMessageContainer.addEventListener('click', (e) => {
e.preventDefault();
e.cancelBubble = true;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let mid = +this.pinnedMessageContainer.getAttribute('data-mid');
this.setPeer(this.peerID, mid);
});
2020-03-01 18:26:25 +01:00
this.btnMenuMute.addEventListener('click', () => this.mutePeer());
this.btnMute.addEventListener('click', () => this.mutePeer());
2020-03-01 18:26:25 +01:00
let onKeyDown = (e: KeyboardEvent) => {
let target = e.target as HTMLElement;
2020-03-01 18:26:25 +01:00
//if(target.tagName == 'INPUT') return;
2020-03-01 18:26:25 +01:00
//this.log('onkeydown', e);
2020-03-01 18:26:25 +01:00
if(this.chatInputC.attachMediaPopUp.container.classList.contains('active')) {
if(target.tagName != 'INPUT') {
this.chatInputC.attachMediaPopUp.captionInput.focus();
}
2020-03-01 18:26:25 +01:00
if(e.key == 'Enter') {
this.chatInputC.attachMediaPopUp.sendBtn.click();
} else if(e.key == 'Escape') {
this.chatInputC.attachMediaPopUp.container.classList.remove('active');
}
2020-03-01 18:26:25 +01:00
return;
}
2020-03-01 18:26:25 +01:00
if(e.key == 'Escape' && this.peerID != 0) { // hide current dialog
this.setPeer(0);
} else if(e.key == 'Meta' || e.key == 'Control') {
2020-02-13 16:42:39 +01:00
return;
} else if(e.key == 'c' && (e.ctrlKey || e.metaKey) && target.tagName != 'INPUT') {
return;
}
2020-03-01 18:26:25 +01:00
if(e.target != this.chatInputC.messageInput && target.tagName != 'INPUT') {
this.chatInputC.messageInput.focus();
placeCaretAtEnd(this.chatInputC.messageInput);
}
};
2020-03-01 18:26:25 +01:00
document.body.addEventListener('keydown', onKeyDown);
2020-03-01 18:26:25 +01:00
this.chatInner.addEventListener('contextmenu', e => {
2020-02-10 08:56:15 +01:00
let bubble: HTMLDivElement = null;
2020-03-01 18:26:25 +01:00
2020-02-10 08:56:15 +01:00
try {
2020-04-08 17:46:43 +02:00
bubble = findUpClassName(e.target, 'bubble__container');
2020-02-10 08:56:15 +01:00
} catch(e) {}
2020-03-01 18:26:25 +01:00
if(bubble) {
2020-04-08 17:46:43 +02:00
bubble = bubble.parentElement as HTMLDivElement; // bc container
e.preventDefault();
e.cancelBubble = true;
let msgID = 0;
for(let id in this.bubbles) {
if(this.bubbles[id] === bubble) {
msgID = +id;
break;
}
}
2020-03-01 18:26:25 +01:00
if(!msgID) return;
2020-03-01 18:26:25 +01:00
if(this.myID == this.peerID || (this.peerID < 0 && !appPeersManager.isChannel(this.peerID) && !appPeersManager.isMegagroup(this.peerID))) {
this.contextMenuPin.style.display = '';
} else this.contextMenuPin.style.display = 'none';
2020-03-01 18:26:25 +01:00
this.contextMenuMsgID = msgID;
2020-03-01 18:26:25 +01:00
2020-04-08 17:46:43 +02:00
let side = bubble.classList.contains('is-in') ? 'left' : 'right';
2020-03-01 18:26:25 +01:00
2020-02-10 17:40:33 +01:00
this.contextMenuEdit.style.display = side == 'right' ? '' : 'none';
2020-03-01 18:26:25 +01:00
this.contextMenu.classList.remove('bottom-left', 'bottom-right');
this.contextMenu.classList.add(side == 'left' ? 'bottom-right' : 'bottom-left');
2020-03-01 18:26:25 +01:00
let {clientX, clientY} = e;
2020-03-01 18:26:25 +01:00
this.contextMenu.style.left = (side == 'right' ? clientX - this.contextMenu.scrollWidth : clientX) + 'px';
if((clientY + this.contextMenu.scrollHeight) > window.innerHeight) {
this.contextMenu.style.top = (window.innerHeight - this.contextMenu.scrollHeight) + 'px';
} else {
this.contextMenu.style.top = clientY + 'px';
}
2020-03-01 18:26:25 +01:00
//this.contextMenu.classList.add('active');
openBtnMenu(this.contextMenu);
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
/////this.log('contextmenu', e, bubble, msgID, side);
}
});
2020-03-01 18:26:25 +01:00
this.contextMenu.querySelector('.menu-copy').addEventListener('click', () => {
let message = appMessagesManager.getMessage(this.contextMenuMsgID);
2020-03-01 18:26:25 +01:00
let str = message ? message.message : '';
2020-03-01 18:26:25 +01:00
var textArea = document.createElement("textarea");
textArea.value = str;
textArea.style.position = "fixed"; //avoid scrolling to bottom
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
2020-03-01 18:26:25 +01:00
try {
document.execCommand('copy');
} catch (err) {
console.error('Oops, unable to copy', err);
}
2020-03-01 18:26:25 +01:00
document.body.removeChild(textArea);
});
2020-03-01 18:26:25 +01:00
this.contextMenu.querySelector('.menu-delete').addEventListener('click', () => {
if(this.peerID == this.myID) {
this.popupDeleteMessage.deleteBothBtn.style.display = 'none';
this.popupDeleteMessage.deleteMeBtn.innerText = 'DELETE';
} else {
this.popupDeleteMessage.deleteBothBtn.style.display = '';
this.popupDeleteMessage.deleteMeBtn.innerText = 'DELETE JUST FOR ME';
2020-03-01 18:26:25 +01:00
if(this.peerID > 0) {
let title = appPeersManager.getPeerTitle(this.peerID);
this.popupDeleteMessage.deleteBothBtn.innerHTML = 'DELETE FOR ME AND ' + title;
} else {
this.popupDeleteMessage.deleteBothBtn.innerText = 'DELETE FOR ALL';
}
}
2020-03-01 18:26:25 +01:00
this.popupDeleteMessage.popupEl.classList.add('active');
});
this.contextMenu.querySelector('.menu-reply').addEventListener('click', () => {
let message = appMessagesManager.getMessage(this.contextMenuMsgID);
this.chatInputC.setTopInfo(appPeersManager.getPeerTitle(message.fromID, true), message.message, undefined, message);
this.chatInputC.replyToMsgID = this.contextMenuMsgID;
this.chatInputC.editMsgID = 0;
});
this.contextMenu.querySelector('.menu-forward').addEventListener('click', () => {
appForward.init([this.contextMenuMsgID]);
});
2020-03-01 18:26:25 +01:00
this.contextMenuEdit.addEventListener('click', () => {
let message = appMessagesManager.getMessage(this.contextMenuMsgID);
this.chatInputC.setTopInfo('Editing', message.message, message.message, message);
this.chatInputC.replyToMsgID = 0;
this.chatInputC.editMsgID = this.contextMenuMsgID;
});
2020-03-01 18:26:25 +01:00
this.contextMenuPin.addEventListener('click', () => {
apiManager.invokeApi('messages.updatePinnedMessage', {
flags: 0,
peer: appPeersManager.getInputPeerByID(this.peerID),
id: this.contextMenuMsgID
}).then(updates => {
2020-02-17 13:18:06 +01:00
/////this.log('pinned updates:', updates);
apiUpdatesManager.processUpdateMessage(updates);
});
});
2020-03-01 18:26:25 +01:00
this.popupDeleteMessage.deleteBothBtn.addEventListener('click', () => {
this.deleteMessages(true);
this.popupDeleteMessage.cancelBtn.click();
});
2020-03-01 18:26:25 +01:00
this.popupDeleteMessage.deleteMeBtn.addEventListener('click', () => {
this.deleteMessages(false);
this.popupDeleteMessage.cancelBtn.click();
});
this.goDownBtn.addEventListener('click', () => {
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0];
2020-03-01 18:26:25 +01:00
if(dialog) {
this.setPeer(this.peerID, dialog.top_message);
} else {
2020-03-02 18:15:11 +01:00
this.log('will scroll down 3');
this.scroll.scrollTop = this.scroll.scrollHeight;
}
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.updateStatusInterval = window.setInterval(() => this.updateStatus(), 50e3);
this.updateStatus();
setInterval(() => this.setPeerStatus(), 60e3);
2020-03-01 18:26:25 +01:00
2020-02-20 09:13:15 +01:00
this.setScroll();
apiUpdatesManager.attach();
2020-04-22 21:10:09 +02:00
this.datesIntersectionObserver = new IntersectionObserver((entries) => {
//this.log('intersection', entries);
2020-04-22 21:10:09 +02:00
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) {
let dateMessage = this.dateMessages[timestamp];
if(dateMessage.container == container) {
if(this.lastDateMessageDiv) {
this.lastDateMessageDiv.classList.remove('is-sticky');
}
dateMessage.div.classList.add('is-sticky');
this.lastDateMessageDiv = dateMessage.div;
break;
}
}
}/* , {root: this.chatInner} */);
this.unreadedObserver = new IntersectionObserver((entries) => {
let readed: number[] = [];
entries.forEach(entry => {
if(entry.isIntersecting) {
let target = entry.target as HTMLElement;
let mid = +target.dataset.mid;
readed.push(mid);
this.unreadedObserver.unobserve(target);
}
});
if(readed.length) {
let max = Math.max(...readed);
let min = Math.min(...readed);
if(this.peerID < 0) {
max = appMessagesIDsManager.getMessageIDInfo(max)[0];
min = appMessagesIDsManager.getMessageIDInfo(min)[0];
}
//appMessagesManager.readMessages(readed);
appMessagesManager.readHistory(this.peerID, max, min).catch((err: any) => {
this.log.error('readHistory err:', err);
appMessagesManager.readHistory(this.peerID, max, min);
});
}
});
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
public deleteMessages(revoke = false) {
let flags = revoke ? 1 : 0;
let ids = [this.contextMenuMsgID];
2020-03-01 18:26:25 +01:00
apiManager.invokeApi('messages.deleteMessages', {
flags: flags,
revoke: revoke,
id: ids
}).then((affectedMessages: any) => {
2020-02-17 13:18:06 +01:00
/////this.log('deleted messages:', affectedMessages);
2020-03-01 18:26:25 +01:00
apiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updatePts',
pts: affectedMessages.pts,
pts_count: affectedMessages.pts_count
}
});
2020-03-01 18:26:25 +01:00
apiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updateDeleteMessages',
messages: ids
}
});
});
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
public updateStatus() {
if(!this.myID) return Promise.resolve();
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
appUsersManager.setUserStatus(this.myID, this.offline);
2020-02-22 17:00:17 +01:00
return apiManager.invokeApi('account.updateStatus', {offline: this.offline});
2020-02-06 16:43:07 +01:00
}
2020-05-01 23:28:40 +02:00
public getAlbumBubble(groupID: string) {
let group = appMessagesManager.groupedMessagesStorage[groupID];
for(let i in group) {
let mid = +i;
if(this.bubbles[mid]) return {
bubble: this.bubbles[mid],
message: appMessagesManager.getMessage(mid)
};
}
return null;
}
2020-03-01 18:26:25 +01:00
public loadMoreHistory(top: boolean) {
2020-04-08 17:46:43 +02:00
this.log('loadMoreHistory', top);
2020-04-14 17:46:31 +02:00
if(!this.peerID || testScroll || this.setPeerPromise || (top && this.getHistoryTopPromise) || (!top && this.getHistoryBottomPromise)) return;
2020-04-08 17:46:43 +02:00
let history = Object.keys(this.bubbles).map(id => +id).sort((a, b) => a - b);
2020-04-08 17:46:43 +02:00
if(!history.length) return;
/* let history = appMessagesManager.historiesStorage[this.peerID].history;
let length = history.length; */
// filter negative ids
let lastBadIndex = -1;
for(let i = 0; i < history.length; ++i) {
if(history[i] <= 0) lastBadIndex = i;
else break;
}
if(lastBadIndex != -1) {
history = history.slice(lastBadIndex + 1);
}
if(top && !this.scrolledAll) {
this.log('Will load more (up) history by id:', history[0], 'maxID:', history[history.length - 1], history);
2020-04-14 17:46:31 +02:00
/* false && */this.getHistory(history[0], true);
2020-04-08 17:46:43 +02:00
}
if(this.scrolledAllDown) return;
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0];
/* if(!dialog) {
this.log.warn('no dialog for load history');
return;
} */
// if scroll down after search
if(!top && (!dialog || history.indexOf(dialog.top_message) === -1)) {
this.log('Will load more (down) history by maxID:', history[history.length - 1], history);
2020-04-14 17:46:31 +02:00
/* false && */this.getHistory(history[history.length - 1], false, true);
2020-03-01 18:26:25 +01:00
}
}
2020-02-06 16:43:07 +01:00
public onScroll() {
2020-04-22 21:10:09 +02:00
if(this.onScrollRAF) window.cancelAnimationFrame(this.onScrollRAF);
this.onScrollRAF = window.requestAnimationFrame(() => {
lottieLoader.checkAnimations(false, 'chat');
if(this.isScrollingTimeout) {
clearTimeout(this.isScrollingTimeout);
} else {
this.chatInner.classList.add('is-scrolling');
}
2020-04-22 21:10:09 +02:00
this.isScrollingTimeout = setTimeout(() => {
this.chatInner.classList.remove('is-scrolling');
this.isScrollingTimeout = 0;
}, 300);
2020-03-01 18:26:25 +01:00
2020-04-22 21:10:09 +02:00
if(this.scroll.scrollHeight - (this.scroll.scrollTop + this.scroll.offsetHeight) == 0/* <= 5 */) {
this.scroll.parentElement.classList.add('scrolled-down');
this.scrolledDown = true;
} else if(this.scroll.parentElement.classList.contains('scrolled-down')) {
this.scroll.parentElement.classList.remove('scrolled-down');
this.scrolledDown = false;
}
this.onScrollRAF = 0;
});
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-20 09:13:15 +01:00
public setScroll() {
2020-04-08 17:46:43 +02:00
this.scrollable = new Scrollable(this.bubblesContainer, 'y', 750, 'IM', this.chatInner/* 1500 */, 300);
2020-02-20 09:13:15 +01:00
this.scroll = this.scrollable.container;
2020-03-02 18:15:11 +01:00
this.bubblesContainer.append(this.goDownBtn);
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
//this.scrollable.setVirtualContainer(this.chatInner);
2020-03-01 18:26:25 +01:00
this.scrollable.onScrolledTop = () => this.loadMoreHistory(true);
this.scrollable.onScrolledBottom = () => this.loadMoreHistory(false);
2020-04-16 02:48:41 +02:00
this.scroll.addEventListener('scroll', this.onScroll.bind(this));
this.scroll.parentElement.classList.add('scrolled-down');
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
public setPeerStatus(needClear = false) {
2020-02-06 16:43:07 +01:00
if(!this.myID) return;
2020-04-14 17:46:31 +02:00
2020-02-06 16:43:07 +01:00
if(this.peerID < 0) { // not human
let chat = appPeersManager.getPeer(this.peerID);
let isChannel = appPeersManager.isChannel(this.peerID) && !appPeersManager.isMegagroup(this.peerID);
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
this.subtitleEl.classList.remove('online');
appSidebarRight.profileElements.subtitle.classList.remove('online');
2020-02-17 13:18:06 +01:00
///////this.log('setPeerStatus', chat);
2020-04-14 17:46:31 +02:00
if(needClear) {
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = '';
}
Promise.all([
appPeersManager.isMegagroup(this.peerID) ? apiManager.invokeApi('messages.getOnlines', {
peer: appPeersManager.getInputPeerByID(this.peerID)
}) as Promise<any> : Promise.resolve(),
// will redirect if wrong
appProfileManager.getChatFull(chat.id)
]).then(results => {
let [chatOnlines, chatInfo] = results;
2020-03-01 18:26:25 +01:00
let onlines = chatOnlines ? chatOnlines.onlines : 1;
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
///////////this.log('chatInfo res:', chatInfo);
2020-03-01 18:26:25 +01:00
if(chatInfo.pinned_msg_id) { // request pinned message
this.pinnedMsgID = chatInfo.pinned_msg_id;
appMessagesManager.wrapSingleMessage(chatInfo.pinned_msg_id);
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
let participants_count = chatInfo.participants_count || chatInfo.participants.participants.length;
2020-02-06 16:43:07 +01:00
let subtitle = numberWithCommas(participants_count) + ' ' + (isChannel ? 'subscribers' : 'members');
2020-03-01 18:26:25 +01:00
if(onlines > 1) {
subtitle += ', ' + numberWithCommas(onlines) + ' online';
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = subtitle;
});
} else if(!appUsersManager.isBot(this.peerID)) { // user
let user = appUsersManager.getUser(this.peerID);
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
if(this.myID == this.peerID) {
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = '';
} else if(user && user.status) {
let subtitle = appUsersManager.getUserStatusString(user.id);
2020-04-14 17:46:31 +02:00
if(subtitle == 'online') {
this.subtitleEl.classList.add('online');
appSidebarRight.profileElements.subtitle.classList.add('online');
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
appSidebarRight.profileElements.subtitle.innerText = subtitle;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(this.typingUsers[this.peerID] == this.peerID) {
this.subtitleEl.innerText = 'typing...';
this.subtitleEl.classList.add('online');
2020-04-14 17:46:31 +02:00
} else {
this.subtitleEl.innerText = subtitle;
if(subtitle != 'online') {
this.subtitleEl.classList.remove('online');
appSidebarRight.profileElements.subtitle.classList.remove('online');
}
}
2020-02-06 16:43:07 +01:00
}
}
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
public cleanup() {
2020-04-14 17:46:31 +02:00
////console.time('appImManager cleanup');
2020-02-06 16:43:07 +01:00
this.peerID = $rootScope.selectedPeerID = 0;
2020-02-08 12:58:22 +01:00
this.scrolledAll = false;
this.scrolledAllDown = false;
this.muted = false;
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
/* for(let i in this.bubbles) {
2020-02-06 16:43:07 +01:00
let bubble = this.bubbles[i];
bubble.remove();
2020-04-14 17:46:31 +02:00
} */
2020-02-06 16:43:07 +01:00
this.bubbles = {};
this.dateMessages = {};
2020-03-01 18:26:25 +01:00
this.bubbleGroups.cleanup();
this.unreadOut.clear();
this.needUpdate.length = 0;
2020-04-14 17:46:31 +02:00
this.lazyLoadQueue.clear();
2020-03-01 18:26:25 +01:00
2020-02-10 08:56:15 +01:00
// clear input
this.chatInputC.messageInput.innerHTML = '';
this.chatInputC.replyElements.cancelBtn.click();
2020-03-01 18:26:25 +01:00
2020-02-10 08:56:15 +01:00
// clear messages
2020-02-06 16:43:07 +01:00
this.chatInner.innerHTML = '';
2020-04-14 17:46:31 +02:00
lottieLoader.checkAnimations(false, 'chat', true);
this.getHistoryTopPromise = this.getHistoryBottomPromise = undefined;
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
//this.scrollable.setVirtualContainer(this.chatInner);
2020-04-16 02:48:41 +02:00
this.scrollable.setVirtualContainer(null);
2020-04-14 17:46:31 +02:00
2020-04-22 21:10:09 +02:00
this.datesIntersectionObserver.disconnect();
this.lastDateMessageDiv = null;
this.unreadedObserver.disconnect();
this.loadedTopTimes = this.loadedBottomTimes = 0;
2020-04-22 21:10:09 +02:00
2020-04-14 17:46:31 +02:00
////console.timeEnd('appImManager cleanup');
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
public setPeer(peerID: number, lastMsgID = 0, forwarding = false, fromClick = false) {
console.time('appImManager setPeer');
console.time('appImManager setPeer pre promise');
2020-04-14 17:46:31 +02:00
////console.time('appImManager: pre render start');
if(peerID == 0) {
appSidebarRight.toggleSidebar(false);
this.topbar.style.display = this.chatInput.style.display = this.goDownBtn.style.display = 'none';
this.cleanup();
if(appDialogsManager.lastActiveListElement) {
appDialogsManager.lastActiveListElement.classList.remove('active');
appDialogsManager.lastActiveListElement = null;
}
2020-04-14 17:46:31 +02:00
return false;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let samePeer = this.peerID == peerID;
2020-03-01 18:26:25 +01:00
if(this.setPeerPromise && samePeer) return this.setPeerPromise;
2020-03-01 18:26:25 +01:00
if(lastMsgID) {
appMessagesManager.readHistory(peerID, lastMsgID); // lol
}
2020-03-01 18:26:25 +01:00
2020-02-10 08:56:15 +01:00
if(samePeer) {
if(!testScroll && !lastMsgID) {
2020-04-14 17:46:31 +02:00
return true;
2020-02-10 08:56:15 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(this.bubbles[lastMsgID]) {
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
2020-03-01 18:26:25 +01:00
if(dialog && lastMsgID == dialog.top_message) {
2020-03-02 18:15:11 +01:00
this.log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);
2020-02-10 08:56:15 +01:00
this.scroll.scrollTop = this.scroll.scrollHeight;
} else {
2020-03-01 18:26:25 +01:00
//this.bubbles[lastMsgID].scrollIntoView();
this.scrollable.scrollIntoView(this.bubbles[lastMsgID]);
2020-02-10 08:56:15 +01:00
}
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
return true;
2020-02-06 16:43:07 +01:00
}
} else {
appSidebarRight.searchCloseBtn.click();
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
// clear
this.cleanup();
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
// set new
this.peerID = $rootScope.selectedPeerID = peerID;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
// no dialog
/* if(!appMessagesManager.getDialogByPeerID(this.peerID).length) {
2020-02-06 16:43:07 +01:00
this.log.error('No dialog by peerID:', this.peerID);
return Promise.reject();
} */
2020-03-01 18:26:25 +01:00
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null;
2020-02-17 13:18:06 +01:00
//////this.log('setPeer peerID:', this.peerID, dialog, lastMsgID);
appProfileManager.putPhoto(this.avatarEl, this.peerID);
appProfileManager.putPhoto(appSidebarRight.profileElements.avatar, this.peerID);
2020-04-08 17:46:43 +02:00
this.firstTopMsgID = dialog ? dialog.top_message : 0;
2020-03-01 18:26:25 +01:00
this.chatInner.style.visibility = 'hidden';
this.chatInput.style.display = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID) ? 'none' : '';
this.topbar.style.display = '';
2020-04-16 02:48:41 +02:00
if(appPeersManager.isAnyGroup(peerID)) this.chatInner.classList.add('is-chat');
else this.chatInner.classList.remove('is-chat');
if(appPeersManager.isChannel(peerID)) this.chatInner.classList.add('is-channel');
else this.chatInner.classList.remove('is-channel');
this.pinnedMessageContainer.style.display = 'none';
2020-04-14 17:46:31 +02:00
window.requestAnimationFrame(() => {
//this.chatInner.style.visibility = 'hidden';
2020-04-14 17:46:31 +02:00
let title = '';
if(this.peerID == this.myID) title = 'Saved Messages';
else title = appPeersManager.getPeerTitle(this.peerID);
//this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = dom.titleSpan.innerHTML;
this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = title;
this.goDownBtn.style.display = '';
//this.topbar.style.display = this.goDownBtn.style.display = '';
//this.chatInput.style.display = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID) ? 'none' : '';
2020-04-14 17:46:31 +02:00
//appSidebarRight.toggleSidebar(true);
2020-04-16 02:48:41 +02:00
//if(appPeersManager.isAnyGroup(peerID)) this.chatInner.classList.add('is-chat');
//else this.chatInner.classList.remove('is-chat');
2020-04-14 17:46:31 +02:00
if(!fromClick) {
if(!samePeer && appDialogsManager.lastActiveListElement) {
appDialogsManager.lastActiveListElement.classList.remove('active');
}
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
let dom = appDialogsManager.getDialogDom(this.peerID);
if(dom) {
appDialogsManager.lastActiveListElement = dom.listEl;
dom.listEl.classList.add('active');
}
}
2020-04-14 17:46:31 +02:00
this.setPeerStatus(true);
});
// add last message, bc in getHistory will load < max_id
let additionMsgID = 0;
if(lastMsgID && !forwarding) additionMsgID = lastMsgID;
else if(dialog && dialog.top_message) additionMsgID = dialog.top_message;
/* this.setPeerPromise = null;
this.preloader.detach();
return true; */
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
//////appSidebarRight.toggleSidebar(true);
console.timeEnd('appImManager setPeer pre promise');
2020-04-14 17:46:31 +02:00
this.preloader.attach(this.bubblesContainer);
return this.setPeerPromise = Promise.all([
2020-04-14 17:46:31 +02:00
this.getHistory(forwarding ? lastMsgID + 1 : lastMsgID, true, false, additionMsgID).then(() => {
2020-02-17 13:18:06 +01:00
////this.log('setPeer removing preloader');
2020-02-06 16:43:07 +01:00
if(lastMsgID) {
if(!dialog || lastMsgID != dialog.top_message) {
let bubble = this.bubbles[lastMsgID];
if(bubble) this.bubbles[lastMsgID].scrollIntoView();
else this.log.warn('no bubble by lastMsgID:', lastMsgID);
} else {
2020-03-02 18:15:11 +01:00
this.log('will scroll down 2');
this.scroll.scrollTop = this.scroll.scrollHeight;
2020-02-06 16:43:07 +01:00
}
}
2020-04-14 17:46:31 +02:00
/* this.onScroll();
this.scrollable.onScroll();*/
2020-02-06 16:43:07 +01:00
this.preloader.detach();
2020-04-14 17:46:31 +02:00
this.chatInner.style.visibility = '';
console.timeEnd('appImManager setPeer');
2020-03-01 18:26:25 +01:00
//setTimeout(() => {
2020-03-01 18:26:25 +01:00
//appSidebarRight.fillProfileElements();
2020-04-14 17:46:31 +02:00
//appSidebarRight.loadSidebarMedia(true);
//}, 500);
2020-02-06 16:43:07 +01:00
return true;
})/* .catch(err => {
this.log.error(err);
}) *//* ,
2020-03-01 18:26:25 +01:00
appSidebarRight.fillProfileElements() *//* ,
2020-04-14 17:46:31 +02:00
appSidebarRight.loadSidebarMedia(true) */
]).catch(err => {
2020-02-08 12:58:22 +01:00
this.log.error('setPeer promises error:', err);
2020-03-02 18:15:11 +01:00
this.preloader.detach();
return false;
2020-04-14 17:46:31 +02:00
}).then(res => {
if(this.peerID == peerID) {
this.setPeerPromise = null;
}
return !!res;
2020-02-06 16:43:07 +01:00
});
}
2020-03-01 18:26:25 +01:00
public setTyping(action: any): Promise<boolean> {
if(!this.peerID) return Promise.resolve(false);
2020-03-01 18:26:25 +01:00
if(typeof(action) == 'string') {
action = {_: action};
}
2020-03-01 18:26:25 +01:00
let input = appPeersManager.getInputPeerByID(this.peerID);
return apiManager.invokeApi('messages.setTyping', {
peer: input,
action: action
}) as Promise<boolean>;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
public updateUnreadByDialog(dialog: any) {
let maxID = this.peerID == this.myID ? dialog.read_inbox_max_id : dialog.read_outbox_max_id;
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
///////this.log('updateUnreadByDialog', maxID, dialog, this.unreadOut);
2020-03-01 18:26:25 +01:00
for(let msgID of this.unreadOut) {
if(msgID > 0 && msgID <= maxID) {
2020-02-06 16:43:07 +01:00
let bubble = this.bubbles[msgID];
if(bubble) {
bubble.classList.remove('is-sent');
bubble.classList.add('is-read');
}
this.unreadOut.delete(msgID);
2020-02-06 16:43:07 +01:00
}
}
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
public deleteMessagesByIDs(msgIDs: number[], forever = true) {
2020-02-06 16:43:07 +01:00
msgIDs.forEach(id => {
if(this.firstTopMsgID == id && forever) {
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0];
2020-03-01 18:26:25 +01:00
if(dialog) {
2020-02-17 13:18:06 +01:00
///////this.log('setting firstTopMsgID after delete:', id, dialog.top_message, dialog);
this.firstTopMsgID = dialog.top_message;
}
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(!(id in this.bubbles)) return;
let bubble = this.bubbles[id];
delete this.bubbles[id];
this.bubbleGroups.removeBubble(bubble, id);
this.unreadedObserver.unobserve(bubble);
2020-03-01 18:26:25 +01:00
this.scrollable.removeElement(bubble);
//bubble.remove();
2020-02-06 16:43:07 +01:00
});
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
lottieLoader.checkAnimations();
this.deleteEmptyDateGroups();
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-04-16 02:48:41 +02:00
public renderNewMessagesByIDs(msgIDs: number[]) {
if(!this.bubbles[this.firstTopMsgID] && Object.keys(this.bubbles).length) { // seems search active
2020-02-17 13:18:06 +01:00
//////this.log('seems search is active, skipping render:', msgIDs);
2020-02-06 16:43:07 +01:00
return;
}
2020-03-01 18:26:25 +01:00
2020-04-16 02:48:41 +02:00
let scrolledDown = this.scrolledDown;
2020-02-06 16:43:07 +01:00
msgIDs.forEach((msgID: number) => {
let message = appMessagesManager.getMessage(msgID);
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
/////////this.log('got new message to append:', message);
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
//this.unreaded.push(msgID);
this.renderMessage(message);
});
2020-04-16 02:48:41 +02:00
if(scrolledDown) this.scrollable.scrollTop = this.scrollable.scrollHeight;
2020-02-06 16:43:07 +01:00
}
2020-04-22 21:10:09 +02:00
public getDateContainerByMessage(message: any, reverse: boolean) {
let date = new Date(message.date * 1000);
let justDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
let dateTimestamp = justDate.getTime();
if(!(dateTimestamp in this.dateMessages)) {
let str = '';
let today = new Date();
today.setHours(0);
today.setMinutes(0);
today.setSeconds(0);
if(today < date) {
str = 'Today';
} else {
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
str = justDate.getFullYear() == new Date().getFullYear() ?
months[justDate.getMonth()] + ' ' + justDate.getDate() :
justDate.toISOString().split('T')[0].split('-').reverse().join('.');
}
let div = document.createElement('div');
div.className = 'bubble service is-date';
div.innerHTML = `<div class="bubble__container"><div class="service-msg">${str}</div></div>`;
////////this.log('need to render date message', dateTimestamp, str);
let container = document.createElement('div');
container.className = 'bubbles-date-group';
this.dateMessages[dateTimestamp] = {
div,
container,
firstTimestamp: date.getTime()
};
container.append(div);
//this.scrollable.prepareElement(div, false);
2020-04-22 21:10:09 +02:00
if(reverse) {
//let scrollTopPrevious = this.scrollable.scrollTop;
this.scrollable.prepend(container, false);
2020-04-22 21:10:09 +02:00
/* if(!scrollTopPrevious) {
2020-04-22 21:10:09 +02:00
this.scrollable.scrollTop += container.scrollHeight;
} */
2020-04-22 21:10:09 +02:00
} else {
this.scrollable.append(container, false);
2020-04-22 21:10:09 +02:00
}
this.datesIntersectionObserver.observe(container);
}
return this.dateMessages[dateTimestamp];
}
2020-03-01 18:26:25 +01:00
2020-04-16 02:48:41 +02:00
// reverse means top
public renderMessage(message: any, reverse = false, multipleRender = false, bubble: HTMLDivElement = null, updatePosition = true) {
//this.log('message to render:', message);
if(message.deleted) return;
2020-04-29 21:35:27 +02:00
else if(message.grouped_id) { // will render only last album's message
let storage = appMessagesManager.groupedMessagesStorage[message.grouped_id];
let maxID = Math.max(...Object.keys(storage).map(i => +i));
if(message.mid < maxID) {
return;
}
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let peerID = this.peerID;
let our = message.fromID == this.myID;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let messageDiv = document.createElement('div');
messageDiv.classList.add('message');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
//messageDiv.innerText = message.message;
2020-04-16 02:48:41 +02:00
2020-02-26 18:52:59 +01:00
let bubbleContainer: HTMLDivElement;
2020-03-01 18:26:25 +01:00
// bubble
if(!bubble) {
2020-02-26 18:52:59 +01:00
bubbleContainer = document.createElement('div');
bubbleContainer.classList.add('bubble__container');
2020-03-01 18:26:25 +01:00
bubble = document.createElement('div');
bubble.classList.add('bubble');
2020-02-26 18:52:59 +01:00
bubble.appendChild(bubbleContainer);
this.bubbles[+message.mid] = bubble;
} else {
bubble.className = 'bubble';
2020-02-26 18:52:59 +01:00
bubbleContainer = bubble.firstElementChild as HTMLDivElement;
bubbleContainer.innerHTML = '';
//bubble.innerHTML = '';
}
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
bubble.dataset.mid = message.mid;
2020-03-01 18:26:25 +01:00
if(message._ == 'messageService') {
bubble.className = 'bubble service';
let action = message.action;
let title = appPeersManager.getPeerTitle(message.fromID);
let name = document.createElement('div');
name.classList.add('name');
name.dataset.peerID = message.fromID;
name.innerHTML = title;
let _ = action._;
if(_ == "messageActionPhoneCall") {
_ += '.' + action.type;
}
// @ts-ignore
let str = (name.innerText ? name.outerHTML + ' ' : '') + langPack[_];
bubbleContainer.innerHTML = `<div class="service-msg">${str}</div>`;
2020-04-14 17:46:31 +02:00
/* if(!updatePosition) {
if(!multipleRender) {
this.scrollPosition.restore(); // лагает из-за этого
}
} else if(reverse) {
this.scrollable.prepend(bubble);
} else {
this.scrollable.append(bubble);
} */
2020-03-01 18:26:25 +01:00
2020-04-22 21:10:09 +02:00
let dateContainer = this.getDateContainerByMessage(message, reverse);
if(!updatePosition) {
} else if(reverse) {
dateContainer.container.insertBefore(bubble, dateContainer.div.nextSibling);
//this.scrollable.prepareElement(bubble, false);
2020-04-22 21:10:09 +02:00
} else {
dateContainer.container.append(bubble);
//this.scrollable.prepareElement(bubble, true);
2020-04-22 21:10:09 +02:00
}
2020-04-14 17:46:31 +02:00
return bubble;
2020-03-01 18:26:25 +01:00
}
2020-02-06 16:43:07 +01:00
// time section
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let date = new Date(message.date * 1000);
2020-03-01 18:26:25 +01:00
let time = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
if(message.views) {
bubble.classList.add('channel-post');
time = formatNumber(message.views, 1) + ' <i class="tgico-channelviews"></i> ' + time;
}
2020-03-01 18:26:25 +01:00
if(message.edit_date) {
bubble.classList.add('is-edited');
time = '<i class="edited">edited</i> ' + time;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let timeSpan = document.createElement('span');
timeSpan.classList.add('time');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let timeInner = document.createElement('div');
timeInner.classList.add('inner', 'tgico');
timeInner.innerHTML = time;
2020-05-01 23:28:40 +02:00
let messageMessage: string, totalEntities: any[];
if(message.grouped_id) {
let group = appMessagesManager.groupedMessagesStorage[message.grouped_id];
let foundMessages = 0;
for(let i in group) {
let m = group[i];
if(m.message) {
if(++foundMessages > 1) break;
messageMessage = m.message;
totalEntities = m.totalEntities;
}
}
if(foundMessages > 1) {
messageMessage = undefined;
totalEntities = undefined;
}
}
2020-03-01 18:26:25 +01:00
2020-05-01 23:28:40 +02:00
if(!messageMessage && !totalEntities) {
messageMessage = message.message;
totalEntities = message.totalEntities;
}
let richText = RichTextProcessor.wrapRichText(messageMessage, {
entities: totalEntities
2020-02-06 16:43:07 +01:00
});
2020-03-01 18:26:25 +01:00
2020-05-01 23:28:40 +02:00
if(totalEntities) {
let emojiEntities = totalEntities.filter((e: any) => e._ == 'messageEntityEmoji');
let strLength = messageMessage.length;
2020-02-06 16:43:07 +01:00
let emojiStrLength = emojiEntities.reduce((acc: number, curr: any) => acc + curr.length, 0);
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(emojiStrLength == strLength && emojiEntities.length <= 3) {
let attachmentDiv = document.createElement('div');
attachmentDiv.classList.add('attachment');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
attachmentDiv.innerHTML = richText;
2020-03-01 18:26:25 +01:00
2020-04-08 17:46:43 +02:00
bubble.classList.add('is-message-empty', 'emoji-' + emojiEntities.length + 'x', 'emoji-big');
2020-03-01 18:26:25 +01:00
2020-02-26 18:52:59 +01:00
bubbleContainer.append(attachmentDiv);
2020-02-06 16:43:07 +01:00
} else {
messageDiv.innerHTML = richText;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
/* if(strLength == emojiStrLength) {
messageDiv.classList.add('emoji-only');
messageDiv.classList.add('message-empty');
} */
} else {
messageDiv.innerHTML = richText;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
timeSpan.appendChild(timeInner);
messageDiv.append(timeSpan);
2020-02-26 18:52:59 +01:00
bubbleContainer.prepend(messageDiv);
//bubble.prepend(timeSpan, messageDiv); // that's bad
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(our) {
if(message.pFlags.unread || message.mid < 0) this.unreadOut.add(message.mid); // message.mid < 0 added 11.02.2020
let status = '';
if(message.mid < 0) status = 'is-sending';
else status = message.pFlags.unread ? 'is-sent' : 'is-read';
2020-02-06 16:43:07 +01:00
bubble.classList.add(status);
} else {
2020-02-07 08:39:00 +01:00
//this.log('not our message', message, message.pFlags.unread);
2020-04-14 17:46:31 +02:00
if(message.pFlags.unread) {
this.unreadedObserver.observe(bubble);
2020-04-14 17:46:31 +02:00
}
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
// media
if(message.media) {
let attachmentDiv = document.createElement('div');
attachmentDiv.classList.add('attachment');
2020-03-01 18:26:25 +01:00
2020-05-01 23:28:40 +02:00
if(!messageMessage) {
2020-04-08 17:46:43 +02:00
bubble.classList.add('is-message-empty');
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let processingWebPage = false;
2020-05-01 23:28:40 +02:00
2020-02-06 16:43:07 +01:00
switch(message.media._) {
case 'messageMediaPending': {
let pending = message.media;
let preloader = pending.preloader as ProgressivePreloader;
2020-03-01 18:26:25 +01:00
switch(pending.type) {
2020-05-01 23:28:40 +02:00
case 'album': {
this.log('will wrap pending album');
bubble.classList.add('hide-name', 'photo', 'is-album');
wrapAlbum({
groupID: '' + message.id,
attachmentDiv,
uploading: true,
isOut: true
});
break;
}
case 'photo': {
//if(pending.size < 5e6) {
this.log('will wrap pending photo:', pending, message, appPhotosManager.getPhoto(message.id));
wrapPhoto(message.id, message, attachmentDiv, undefined, undefined, true, true, this.lazyLoadQueue, null);
bubble.classList.add('hide-name', 'photo');
//}
break;
}
case 'video': {
//if(pending.size < 5e6) {
let doc = appDocsManager.getDoc(message.id);
this.log('will wrap pending video:', pending, message, doc);
wrapVideo({
doc,
container: attachmentDiv,
message,
boxWidth: 380,
boxHeight: 380,
withTail: doc.type != 'round',
isOut: our,
lazyLoadQueue: this.lazyLoadQueue,
middleware: null
});
preloader.attach(attachmentDiv, false);
bubble.classList.add('hide-name', 'video');
//}
break;
}
2020-03-01 18:26:25 +01:00
case 'audio':
case 'document': {
2020-02-15 20:03:27 +01:00
let docDiv = wrapDocument(pending, false, true);
2020-03-01 18:26:25 +01:00
let icoDiv = docDiv.querySelector('.document-ico');
preloader.attach(icoDiv, false);
2020-03-01 18:26:25 +01:00
2020-04-08 17:46:43 +02:00
bubble.classList.remove('is-message-empty');
2020-05-01 23:28:40 +02:00
messageDiv.classList.add((pending.type || 'document') + '-message');
messageDiv.append(docDiv);
processingWebPage = true;
break;
}
2020-03-01 18:26:25 +01:00
}
2020-03-01 18:26:25 +01:00
break;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
case 'messageMediaPhoto': {
let photo = message.media.photo;
2020-02-17 13:18:06 +01:00
////////this.log('messageMediaPhoto', photo);
2020-03-01 18:26:25 +01:00
2020-02-07 07:38:55 +01:00
bubble.classList.add('hide-name', 'photo');
2020-04-29 21:35:27 +02:00
if(message.grouped_id) {
bubble.classList.add('is-album');
2020-05-01 23:28:40 +02:00
wrapAlbum({
groupID: message.grouped_id,
attachmentDiv,
middleware: () => {
return this.peerID == peerID;
},
isOut: our,
lazyLoadQueue: this.lazyLoadQueue
});
2020-04-29 21:35:27 +02:00
} else {
wrapPhoto(photo.id, message, attachmentDiv, undefined, undefined, true, our, this.lazyLoadQueue, () => {
return this.peerID == peerID;
});
}
2020-02-06 16:43:07 +01:00
break;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
case 'messageMediaWebPage': {
processingWebPage = true;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let webpage = message.media.webpage;
2020-02-17 13:18:06 +01:00
////////this.log('messageMediaWebPage', webpage);
2020-02-06 16:43:07 +01:00
if(webpage._ == 'webPageEmpty') {
break;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
bubble.classList.add('webpage');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let box = document.createElement('div');
box.classList.add('box', 'web');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let quote = document.createElement('div');
quote.classList.add('quote');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let nameEl = document.createElement('a');
nameEl.classList.add('name');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let titleDiv = document.createElement('div');
titleDiv.classList.add('title');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let textDiv = document.createElement('div');
textDiv.classList.add('text');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let preview: HTMLDivElement = null;
if(webpage.photo || webpage.document) {
preview = document.createElement('div');
preview.classList.add('preview');
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let doc: any = null;
if(webpage.document) {
doc = webpage.document;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(doc.type == 'gif' || doc.type == 'video') {
//if(doc.size <= 20e6) {
2020-03-01 18:26:25 +01:00
bubble.classList.add('video');
wrapVideo({
doc,
container: preview,
message,
boxWidth: 380,
boxHeight: 300,
lazyLoadQueue: this.lazyLoadQueue,
middleware: () => {
return this.peerID == peerID;
}
});
//}
2020-02-06 16:43:07 +01:00
} else {
doc = null;
}
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(webpage.photo && !doc) {
bubble.classList.add('photo');
2020-04-16 02:48:41 +02:00
wrapPhoto(webpage.photo.id, message, preview, 380, 300, false, null, this.lazyLoadQueue, () => {
return this.peerID == peerID;
});
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(preview) {
quote.append(preview);
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
nameEl.setAttribute('target', '_blank');
nameEl.href = webpage.url || '#';
nameEl.innerHTML = webpage.site_name ? RichTextProcessor.wrapEmojiText(webpage.site_name) : '';
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(webpage.description) {
textDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.description);
}
2020-03-01 18:26:25 +01:00
if(webpage.title) {
titleDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.title);
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
quote.append(nameEl, titleDiv, textDiv);
box.append(quote);
2020-03-01 18:26:25 +01:00
//bubble.prepend(box);
2020-02-26 18:52:59 +01:00
bubbleContainer.prepend(timeSpan, box);
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
//this.log('night running', bubble.scrollHeight);
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
break;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
case 'messageMediaDocument': {
let doc = message.media.document;
2020-04-16 02:48:41 +02:00
//this.log('messageMediaDocument', doc, bubble);
2020-03-01 18:26:25 +01:00
if(doc.sticker/* && doc.size <= 1e6 */) {
2020-02-06 16:43:07 +01:00
bubble.classList.add('sticker');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(doc.animated) {
bubble.classList.add('sticker-animated');
}
2020-03-01 18:26:25 +01:00
appPhotosManager.setAttachmentSize(doc, attachmentDiv, undefined, undefined, true);
2020-04-14 17:46:31 +02:00
//let preloader = new ProgressivePreloader(attachmentDiv, false);
2020-02-26 18:52:59 +01:00
bubbleContainer.style.height = attachmentDiv.style.height;
bubbleContainer.style.width = attachmentDiv.style.width;
2020-02-06 16:43:07 +01:00
//appPhotosManager.setAttachmentSize(doc, bubble);
wrapSticker(doc, attachmentDiv, () => {
2020-02-06 16:43:07 +01:00
if(this.peerID != peerID) {
this.log.warn('peer changed, canceling sticker attach');
return false;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
return true;
}, this.lazyLoadQueue, 'chat', false, !!message.pending || !multipleRender);
2020-02-06 16:43:07 +01:00
break;
} else if(doc.type == 'video' || doc.type == 'gif' || doc.type == 'round'/* && doc.size <= 20e6 */) {
//this.log('never get free 2', doc);
2020-03-01 18:26:25 +01:00
if(doc.type == 'round') {
bubble.classList.add('round');
}
2020-03-01 18:26:25 +01:00
2020-04-08 17:46:43 +02:00
bubble.classList.add('hide-name', 'video');
2020-05-01 23:28:40 +02:00
if(message.grouped_id) {
bubble.classList.add('is-album');
wrapAlbum({
groupID: message.grouped_id,
attachmentDiv,
middleware: () => {
return this.peerID == peerID;
},
isOut: our,
lazyLoadQueue: this.lazyLoadQueue
});
} else {
wrapVideo({
doc,
container: attachmentDiv,
message,
boxWidth: 380,
boxHeight: 380,
withTail: doc.type != 'round',
isOut: our,
lazyLoadQueue: this.lazyLoadQueue,
middleware: () => {
return this.peerID == peerID;
}
});
}
2020-03-01 18:26:25 +01:00
break;
} else if(doc.mime_type == 'audio/ogg') {
let docDiv = wrapDocument(doc);
2020-04-08 17:46:43 +02:00
bubble.classList.remove('is-message-empty');
2020-03-01 18:26:25 +01:00
bubble.classList.add('bubble-audio');
messageDiv.append(docDiv);
processingWebPage = true;
2020-02-06 16:43:07 +01:00
break;
} else {
let docDiv = wrapDocument(doc);
2020-03-01 18:26:25 +01:00
2020-04-08 17:46:43 +02:00
bubble.classList.remove('is-message-empty');
2020-02-06 16:43:07 +01:00
messageDiv.append(docDiv);
2020-04-30 15:43:26 +02:00
messageDiv.classList.add((doc.type || 'document') + '-message');
2020-02-06 16:43:07 +01:00
processingWebPage = true;
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
break;
}
2020-04-30 15:43:26 +02:00
break;
}
case 'messageMediaContact': {
//this.log('wrapping contact', message);
2020-04-30 15:43:26 +02:00
let contactDiv = document.createElement('div');
contactDiv.classList.add('contact');
messageDiv.classList.add('contact-message');
processingWebPage = true;
let texts = [];
if(message.media.first_name) texts.push(RichTextProcessor.wrapEmojiText(message.media.first_name));
if(message.media.last_name) texts.push(RichTextProcessor.wrapEmojiText(message.media.last_name));
contactDiv.innerHTML = `
<div class="contact-avatar user-avatar"><img src="blob:https://192.168.0.105:9000/803514b4-4a46-4125-984f-ca8f86405ef2"></div>
<div class="contact-details">
<div class="contact-name">${texts.join(' ')}</div>
<div class="contact-number">${message.media.phone_number ? '+' + formatPhoneNumber(message.media.phone_number).formatted : 'Unknown phone number'}</div>
</div>`;
bubble.classList.remove('is-message-empty');
messageDiv.append(contactDiv);
break;
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
default:
2020-04-08 17:46:43 +02:00
bubble.classList.remove('is-message-empty');
2020-03-01 18:26:25 +01:00
messageDiv.innerHTML = 'unrecognized media type: ' + message.media._;
messageDiv.append(timeSpan);
this.log.warn('unrecognized media type:', message.media._, message);
break;
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(!processingWebPage) {
2020-02-26 18:52:59 +01:00
bubbleContainer.append(attachmentDiv);
2020-02-06 16:43:07 +01:00
}
}
2020-03-01 18:26:25 +01:00
if((this.peerID < 0 && !our) || message.fwd_from || message.reply_to_mid) { // chat
2020-02-06 16:43:07 +01:00
let title = appPeersManager.getPeerTitle(message.fwdFromID || message.fromID);
2020-03-01 18:26:25 +01:00
let isHidden = message.fwd_from && !message.fwd_from.from_id && !message.fwd_from.channel_id;
2020-02-10 08:56:15 +01:00
if(isHidden) {
2020-02-17 13:18:06 +01:00
///////this.log('message to render hidden', message);
2020-02-10 08:56:15 +01:00
title = message.fwd_from.from_name;
bubble.classList.add('hidden-profile');
}
2020-02-06 16:43:07 +01:00
//this.log(title);
2020-03-01 18:26:25 +01:00
2020-02-10 08:56:15 +01:00
if(message.fwdFromID || message.fwd_from) {
2020-02-06 16:43:07 +01:00
bubble.classList.add('forwarded');
2020-03-01 18:26:25 +01:00
if(message.savedFrom) {
let fwd = document.createElement('div');
fwd.classList.add('forward'/* , 'tgico-forward' */);
2020-03-01 18:26:25 +01:00
fwd.innerHTML = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<defs><path d="M13.55 3.24L13.64 3.25L13.73 3.27L13.81 3.29L13.9 3.32L13.98 3.35L14.06 3.39L14.14 3.43L14.22 3.48L14.29 3.53L14.36 3.59L14.43 3.64L22.23 10.85L22.36 10.99L22.48 11.15L22.57 11.31L22.64 11.48L22.69 11.66L22.72 11.85L22.73 12.04L22.71 12.22L22.67 12.41L22.61 12.59L22.53 12.76L22.42 12.93L22.29 13.09L22.23 13.15L14.43 20.36L14.28 20.48L14.12 20.58L13.95 20.66L13.77 20.72L13.58 20.76L13.4 20.77L13.22 20.76L13.03 20.73L12.85 20.68L12.68 20.61L12.52 20.52L12.36 20.4L12.22 20.27L12.16 20.2L12.1 20.13L12.05 20.05L12.01 19.98L11.96 19.9L11.93 19.82L11.89 19.73L11.87 19.65L11.84 19.56L11.83 19.47L11.81 19.39L11.81 19.3L11.8 19.2L11.8 16.42L11 16.49L10.23 16.58L9.51 16.71L8.82 16.88L8.18 17.09L7.57 17.33L7.01 17.6L6.48 17.91L5.99 18.26L5.55 18.64L5.14 19.05L4.77 19.51L4.43 19.99L4.29 20.23L4.21 20.35L4.11 20.47L4 20.57L3.88 20.65L3.75 20.72L3.62 20.78L3.48 20.82L3.33 20.84L3.19 20.84L3.04 20.83L2.9 20.79L2.75 20.74L2.62 20.68L2.53 20.62L2.45 20.56L2.38 20.5L2.31 20.43L2.25 20.36L2.2 20.28L2.15 20.19L2.11 20.11L2.07 20.02L2.04 19.92L2.02 19.83L2.01 19.73L2 19.63L2.04 17.99L2.19 16.46L2.46 15.05L2.85 13.75L3.35 12.58L3.97 11.53L4.7 10.6L5.55 9.8L6.51 9.12L7.59 8.56L8.77 8.13L10.07 7.83L11.48 7.65L11.8 7.63L11.8 4.8L11.91 4.56L12.02 4.35L12.14 4.16L12.25 3.98L12.37 3.82L12.48 3.68L12.61 3.56L12.73 3.46L12.85 3.38L12.98 3.31L13.11 3.27L13.24 3.24L13.37 3.23L13.46 3.23L13.55 3.24Z" id="b13RmHDQtl"></path></defs><use xlink:href="#b13RmHDQtl" opacity="1" fill="#fff" fill-opacity="1"></use></svg>`;
2020-02-26 18:52:59 +01:00
bubbleContainer.append(fwd);
bubble.dataset.savedFrom = message.savedFrom;
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
if(!bubble.classList.contains('sticker')) {
let nameDiv = document.createElement('div');
nameDiv.classList.add('name');
nameDiv.innerHTML = 'Forwarded from ' + title;
nameDiv.dataset.peerID = message.fwdFromID;
//nameDiv.style.color = appPeersManager.getPeerColorByID(message.fromID, false);
2020-02-26 18:52:59 +01:00
bubbleContainer.append(nameDiv);
2020-02-06 16:43:07 +01:00
}
} else {
if(message.reply_to_mid) {
let originalMessage = appMessagesManager.getMessage(message.reply_to_mid);
2020-02-15 19:08:26 +01:00
let originalPeerTitle = appPeersManager.getPeerTitle(originalMessage.fromID, true) || '';
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
/////////this.log('message to render reply', originalMessage, originalPeerTitle, bubble, message);
2020-03-01 18:26:25 +01:00
// need to download separately
if(originalMessage._ == 'messageEmpty') {
2020-02-17 13:18:06 +01:00
//////////this.log('message to render reply empty, need download', message, message.reply_to_mid);
2020-02-14 14:10:10 +01:00
appMessagesManager.wrapSingleMessage(message.reply_to_mid);
this.needUpdate.push({replyMid: message.reply_to_mid, mid: message.mid});
2020-03-01 18:26:25 +01:00
originalPeerTitle = 'Loading...';
}
2020-03-01 18:26:25 +01:00
2020-02-10 08:56:15 +01:00
if(originalMessage.mid) {
bubble.setAttribute('data-original-mid', originalMessage.mid);
} else {
bubble.setAttribute('data-original-mid', message.reply_to_mid);
}
2020-03-01 18:26:25 +01:00
bubbleContainer.append(wrapReply(originalPeerTitle, originalMessage.message || '', originalMessage));
2020-02-10 08:56:15 +01:00
bubble.classList.add('is-reply');
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
if(!bubble.classList.contains('sticker') && (peerID < 0 && peerID != message.fromID)) {
2020-02-06 16:43:07 +01:00
let nameDiv = document.createElement('div');
nameDiv.classList.add('name');
nameDiv.innerHTML = title;
nameDiv.style.color = appPeersManager.getPeerColorByID(message.fromID, false);
nameDiv.dataset.peerID = message.fromID;
2020-02-26 18:52:59 +01:00
bubbleContainer.append(nameDiv);
} else /* if(!message.reply_to_mid) */ {
bubble.classList.add('hide-name');
2020-02-06 16:43:07 +01:00
}
}
2020-03-01 18:26:25 +01:00
if(!our && this.peerID < 0 && (!appPeersManager.isChannel(this.peerID) || appPeersManager.isMegagroup(this.peerID))) {
2020-02-07 07:38:55 +01:00
let avatarDiv = document.createElement('div');
avatarDiv.classList.add('user-avatar');
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
/////////this.log('exec loadDialogPhoto', message);
2020-02-07 07:38:55 +01:00
if(message.fromID) { // if no - user hidden
appProfileManager.putPhoto(avatarDiv, message.fromID);
2020-02-07 07:38:55 +01:00
} else if(!title && message.fwd_from && message.fwd_from.from_name) {
title = message.fwd_from.from_name;
2020-03-01 18:26:25 +01:00
appProfileManager.putPhoto(avatarDiv, 0, false, title);
2020-02-07 07:38:55 +01:00
}
2020-03-01 18:26:25 +01:00
avatarDiv.dataset.peerID = message.fromID;
2020-03-01 18:26:25 +01:00
2020-02-26 18:52:59 +01:00
bubbleContainer.append(avatarDiv);
2020-02-06 16:43:07 +01:00
}
} else {
bubble.classList.add('hide-name');
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-26 18:52:59 +01:00
bubble.classList.add(our ? 'is-out' : 'is-in');
if(updatePosition) {
2020-04-08 17:46:43 +02:00
this.bubbleGroups.addBubble(bubble, message, reverse);
2020-04-14 17:46:31 +02:00
//window.requestAnimationFrame(() => {
/* if(reverse) {
this.scrollable.prependByBatch(bubble);
} else {
this.scrollable.appendByBatch(bubble);
} */
2020-04-22 21:10:09 +02:00
// раскомментировать ////// если рендер должен быть в другой функции (если хочешь сделать через requestAnimationFrame)
//////if(!multipleRender) {
/* if(reverse) {
2020-04-16 02:48:41 +02:00
this.scrollable.prepend(bubble);
} else {
this.scrollable.append(bubble);
2020-04-22 21:10:09 +02:00
} */
//////}
2020-04-14 17:46:31 +02:00
//});
2020-03-01 18:26:25 +01:00
2020-04-22 21:10:09 +02:00
let dateMessage = this.getDateContainerByMessage(message, reverse);
if(reverse) {
dateMessage.container.insertBefore(bubble, dateMessage.div.nextSibling);
//this.scrollable.prepareElement(bubble, false);
} else {
2020-04-22 21:10:09 +02:00
dateMessage.container.append(bubble);
//this.scrollable.prepareElement(bubble, true);
2020-04-08 17:46:43 +02:00
}
2020-03-01 18:26:25 +01:00
} else {
this.bubbleGroups.updateGroupByMessageID(message.mid);
}
2020-03-01 18:26:25 +01:00
/* if(bubble.classList.contains('webpage')) {
this.log('night running', bubble, bubble.scrollHeight);
} */
2020-04-14 17:46:31 +02:00
return bubble;
}
public performHistoryResult(history: number[], reverse: boolean, isBackLimit: boolean, additionMsgID: number, resetPromises = false) {
// commented bot getProfile in getHistory!
if(!history/* .filter((id: number) => id > 0) */.length) {
if(!isBackLimit) {
this.scrolledAll = true;
} else {
this.scrolledAllDown = true;
}
}
//history = history.slice(); // need
2020-04-14 17:46:31 +02:00
if(additionMsgID) {
history.unshift(additionMsgID);
}
if(testScroll && additionMsgID) {
for(let i = 0; i < 3; ++i) {
let _history = history.slice();
setTimeout(() => {
this.performHistoryResult(_history, reverse, isBackLimit, 0, resetPromises);
}, (i + 1) * 2500);
}
}
console.time('appImManager render history');
2020-04-14 17:46:31 +02:00
let firstLoad = !!this.setPeerPromise && false;
2020-04-14 17:46:31 +02:00
let peerID = this.peerID;
return new Promise<boolean>((resolve, reject) => {
let resolved = false;
/* let bubbles: HTMLDivElement[] = [];
method((msgID) => {
let message = appMessagesManager.getMessage(msgID);
let bubble = this.renderMessage(message, reverse, true);
bubbles.push(bubble);
}); */
//let leftHeightToScroll = this.scrollable.innerHeight;
2020-04-14 17:46:31 +02:00
//console.timeEnd('appImManager: pre render start');
//this.log('start performHistoryResult, scrollTop:', this.scrollable.scrollTop, this.scrollable.scrollHeight, this.scrollable.innerHeight);
let method = (reverse ? history.shift : history.pop).bind(history);
let renderedFirstScreen = !!this.scrollable.scrollTop;
2020-04-14 17:46:31 +02:00
let r = () => {
//let bubble = bubbles.shift();
//if(!bubble && !resolved) return resolve();
//if(!history.length) return resolve(true);
/* let msgID = result.history.shift();
if(!msgID && !resolved) return resolve();
let message = appMessagesManager.getMessage(msgID); */
if(this.peerID != peerID) {
return reject('peer changed');
}
//let startTime = Date.now();
//let elapsedTime = 0;
//do {
//let msgID = history.shift();
let msgID = method();
2020-04-14 17:46:31 +02:00
if(!msgID) {
if(resetPromises) {
(reverse ? this.getHistoryTopPromise = undefined : this.getHistoryBottomPromise = undefined);
}
if(!resolved) {
resolve(true);
}
return;
}
let message = appMessagesManager.getMessage(msgID);
let bubble = this.renderMessage(message, reverse, true);
if(bubble) {
if(reverse) {
2020-04-22 21:10:09 +02:00
////////this.scrollable.prepend(bubble);
2020-04-14 17:46:31 +02:00
//this.log('performHistoryResult scrollTop', this.scrollable.scrollTop, bubble.scrollHeight);
2020-04-14 17:46:31 +02:00
/* if(innerHeight >= 0) {
let height = bubble.scrollHeight;
innerHeight -= height;
this.scrollable.scrollTop += height;
} */
if(!renderedFirstScreen) {
if(!this.scrollable.scrollTop) {
let height = bubble.scrollHeight;
//let height = Math.ceil(bubble.getBoundingClientRect().height);
this.scrollable.scrollTop += height;
//innerHeight -= height;
2020-04-16 02:48:41 +02:00
}
/* if(leftHeightToScroll >= 0) {
let height = bubble.scrollHeight;
leftHeightToScroll -= height;
this.scrollable.scrollTop += height;
} */ else {
2020-04-14 17:46:31 +02:00
renderedFirstScreen = true;
resolve();
resolved = true;
}
}
} else {
2020-04-22 21:10:09 +02:00
////////this.scrollable.append(bubble);
2020-04-14 17:46:31 +02:00
}
}
//} while(cached && !this.scrollable.scrollTop);
//} while((elapsedTime = Date.now() - startTime) < 3);
/* let bubble = this.renderMessage(message, reverse, true);
if(!bubble) return r();
if(reverse) {
this.scrollable.prepend(bubble);
if(!this.scrollable.scrollTop) {
let height = bubble.scrollHeight;
this.scrollable.scrollTop += height;
//innerHeight -= height;
} else if(!resolved) {
resolve();
resolved = true;
}
} else {
this.scrollable.append(bubble);
} */
firstLoad ? window.requestAnimationFrame(r) : r();
2020-04-14 17:46:31 +02:00
};
firstLoad ? window.requestAnimationFrame(r) : r();
2020-04-14 17:46:31 +02:00
//r();
/* method((msgID) => {
let message = appMessagesManager.getMessage(msgID);
window.requestAnimationFrame(() => {
this.renderMessage(message, reverse, true);
});
}); */
}).then(() => {
console.timeEnd('appImManager render history');
2020-04-14 17:46:31 +02:00
return true;
});
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
// reverse means scroll up
2020-04-14 17:46:31 +02:00
public getHistory(maxID = 0, reverse = false, isBackLimit = false, additionMsgID = 0) {
2020-02-06 16:43:07 +01:00
let peerID = this.peerID;
2020-04-14 17:46:31 +02:00
//console.time('appImManager call getHistory');
2020-03-01 18:26:25 +01:00
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
if(!maxID && dialog && dialog.top_message) {
maxID = dialog.top_message/* + 1 */;
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
let pageCount = this.bubblesContainer.clientHeight / 38/* * 1.25 */ | 0;
//let loadCount = Object.keys(this.bubbles).length > 0 ? 50 : pageCount;
let realLoadCount = Object.keys(this.bubbles).length > 0 ? 40 : pageCount;//let realLoadCount = 50;
let loadCount = realLoadCount;
2020-03-01 18:26:25 +01:00
if(testScroll) {
//loadCount = 1;
2020-02-20 09:13:15 +01:00
if(Object.keys(this.bubbles).length > 0)
return Promise.resolve(true);
}
2020-03-01 18:26:25 +01:00
2020-04-14 17:46:31 +02:00
////console.time('render history total');
2020-03-01 18:26:25 +01:00
2020-02-06 16:43:07 +01:00
let backLimit = 0;
if(isBackLimit) {
backLimit = loadCount;
loadCount = 0;
maxID += 1;
}
2020-04-08 17:46:43 +02:00
2020-04-14 17:46:31 +02:00
let result = appMessagesManager.getHistory(this.peerID, maxID, loadCount, backLimit);
/* if(!(result instanceof Promise)) {
let _result = result;
$rootScope.$broadcast('history_request'); // for ripple
result = new Promise((resolve, reject) => setTimeout(() => resolve(_result), 150));
} */
let promise: Promise<boolean>;
2020-04-14 17:46:31 +02:00
if(result instanceof Promise) {
promise = result.then((result) => {
2020-04-14 17:46:31 +02:00
this.log('getHistory result by maxID:', maxID, reverse, isBackLimit, result);
//console.timeEnd('appImManager call getHistory');
if(this.peerID != peerID) {
this.log.warn('peer changed');
////console.timeEnd('render history total');
return Promise.reject();
}
2020-04-14 17:46:31 +02:00
////console.timeEnd('render history total');
return this.performHistoryResult(result.history || [], reverse, isBackLimit, additionMsgID, true);
}, (err) => {
this.log.error('getHistory error:', err);
(reverse ? this.getHistoryTopPromise = undefined : this.getHistoryBottomPromise = undefined);
return false;
});
(reverse ? this.getHistoryTopPromise = promise : this.getHistoryBottomPromise = promise);
2020-04-14 17:46:31 +02:00
} else {
promise = this.performHistoryResult(result.history || [], reverse, isBackLimit, additionMsgID, true);
2020-04-16 02:48:41 +02:00
//return (reverse ? this.getHistoryTopPromise = promise : this.getHistoryBottomPromise = promise);
//return this.performHistoryResult(result.history || [], reverse, isBackLimit, additionMsgID, true);
2020-04-14 17:46:31 +02:00
}
/* false && */promise.then(() => {
if(reverse) {
this.loadedTopTimes++;
this.loadedBottomTimes = Math.max(0, --this.loadedBottomTimes);
} else {
this.loadedBottomTimes++;
this.loadedTopTimes = Math.max(0, --this.loadedTopTimes);
}
let ids: number[];
if((reverse && this.loadedTopTimes > 2) || (!reverse && this.loadedBottomTimes > 2)) {
ids = Object.keys(this.bubbles).map(i => +i).sort((a, b) => a - b);
}
this.log('getHistory: slice loadedTimes:', reverse, pageCount, this.loadedTopTimes, this.loadedBottomTimes, ids && ids.length);
let removeCount = loadCount / 2;
let safeCount = realLoadCount * 2;
if(ids && ids.length > safeCount) {
if(reverse) {
//ids = ids.slice(-removeCount);
//ids = ids.slice(removeCount * 2);
ids = ids.slice(safeCount);
this.scrolledAllDown = false;
} else {
//ids = ids.slice(0, removeCount);
//ids = ids.slice(0, ids.length - (removeCount * 2));
ids = ids.slice(0, ids.length - safeCount);
this.scrolledAll = false;
this.log('getHistory: slice bottom: to:', ids.length, loadCount);
}
this.log('getHistory: will slice ids:', ids, reverse);
this.deleteMessagesByIDs(ids, false);
/* ids.forEach(id => {
this.bubbles[id].remove();
delete this.bubbles[id];
});
this.deleteEmptyDateGroups(); */
}
});
return promise;
}
public deleteEmptyDateGroups() {
for(let i in this.dateMessages) {
let dateMessage = this.dateMessages[i];
if(dateMessage.container.childElementCount == 1) { // only date div
dateMessage.container.remove();
this.datesIntersectionObserver.unobserve(dateMessage.container);
delete this.dateMessages[i];
}
}
2020-02-06 16:43:07 +01:00
}
2020-03-01 18:26:25 +01:00
public setMutedState(muted = false) {
appSidebarRight.profileElements.notificationsCheckbox.checked = !muted;
appSidebarRight.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
2020-03-01 18:26:25 +01:00
let peerID = this.peerID;
2020-03-01 18:26:25 +01:00
this.muted = muted;
if(peerID < 0) { // not human
let isChannel = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID);
if(isChannel) {
this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
this.btnMute.classList.add(muted ? 'tgico-unmute' : 'tgico-mute');
this.btnMute.style.display = '';
} else {
this.btnMute.style.display = 'none';
}
} else {
this.btnMute.style.display = 'none';
}
2020-03-01 18:26:25 +01:00
this.btnMenuMute.classList.remove('tgico-mute', 'tgico-unmute');
this.btnMenuMute.classList.add(muted ? 'tgico-unmute' : 'tgico-mute');
let rp = this.btnMenuMute.firstElementChild;
this.btnMenuMute.innerText = muted ? 'Unmute' : 'Mute';
this.btnMenuMute.appendChild(rp);
}
2020-03-01 18:26:25 +01:00
public mutePeer() {
let inputPeer = appPeersManager.getInputPeerByID(this.peerID);
let inputNotifyPeer = {
_: 'inputNotifyPeer',
peer: inputPeer
};
2020-03-01 18:26:25 +01:00
let settings = {
_: 'inputPeerNotifySettings',
flags: 0,
mute_until: 0
};
2020-03-01 18:26:25 +01:00
if(!this.muted) {
settings.flags |= 1 << 2;
settings.mute_until = 2147483646;
} else {
settings.flags |= 2;
}
2020-03-01 18:26:25 +01:00
apiManager.invokeApi('account.updateNotifySettings', {
peer: inputNotifyPeer,
settings: settings
}).then(res => {
this.handleUpdate({_: 'updateNotifySettings', peer: inputNotifyPeer, notify_settings: settings});
});
2020-03-01 18:26:25 +01:00
/* return apiManager.invokeApi('account.getNotifySettings', {
peer: inputNotifyPeer
}).then((settings: any) => {
settings.flags |= 2 << 1;
settings.mute_until = 2000000000; // 2147483646
2020-03-01 18:26:25 +01:00
return apiManager.invokeApi('account.updateNotifySettings', {
peer: inputNotifyPeer,
settings: Object.assign(settings, {
_: 'inputPeerNotifySettings'
})
}).then(res => {
this.log('mute result:', res);
});
}); */
}
2020-03-01 18:26:25 +01:00
public handleUpdate(update: any) {
switch(update._) {
case 'updateUserTyping':
case 'updateChatUserTyping':
2020-03-01 18:26:25 +01:00
if(this.myID == update.user_id) {
return;
}
var peerID = update._ == 'updateUserTyping' ? update.user_id : -update.chat_id;
this.typingUsers[update.user_id] = peerID;
if(!appUsersManager.hasUser(update.user_id)) {
if(update.chat_id && appChatsManager.hasChat(update.chat_id) && !appChatsManager.isChannel(update.chat_id)) {
appProfileManager.getChatFull(update.chat_id);
}
2020-03-01 18:26:25 +01:00
//return;
}
appUsersManager.forceUserOnline(update.user_id);
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
let currentPeer = this.peerID == peerID;
if(this.typingTimeouts[peerID]) clearTimeout(this.typingTimeouts[peerID]);
else if(dialog) {
appDialogsManager.setTyping(dialog, appUsersManager.getUser(update.user_id));
if(currentPeer) { // user
this.setPeerStatus();
}
2020-03-01 18:26:25 +01:00
}
this.typingTimeouts[peerID] = setTimeout(() => {
this.typingTimeouts[peerID] = 0;
delete this.typingUsers[update.user_id];
if(dialog) {
appDialogsManager.unsetTyping(dialog);
}
2020-03-01 18:26:25 +01:00
// лень просчитывать случаи
this.setPeerStatus();
}, 6000);
break;
case 'updateNotifySettings': {
let {peer, notify_settings} = update;
2020-03-01 18:26:25 +01:00
// peer was NotifyPeer
peer = peer.peer;
2020-03-01 18:26:25 +01:00
let peerID = appPeersManager.getPeerID(peer);
2020-03-01 18:26:25 +01:00
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
if(dialog) {
dialog.notify_settings = notify_settings;
}
2020-03-01 18:26:25 +01:00
if(peerID == this.peerID) {
let muted = notify_settings.mute_until ? new Date(notify_settings.mute_until * 1000) > new Date() : false;
this.setMutedState(muted);
}
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
/////this.log('updateNotifySettings', peerID, notify_settings);
break;
}
2020-03-01 18:26:25 +01:00
case 'updateChatPinnedMessage':
case 'updateUserPinnedMessage': {
let {id} = update;
2020-03-01 18:26:25 +01:00
2020-02-17 13:18:06 +01:00
/////this.log('updateUserPinnedMessage', update);
2020-03-01 18:26:25 +01:00
this.pinnedMsgID = id;
// hz nado li tut appMessagesIDsManager.getFullMessageID(update.max_id, channelID);
let peerID = update.user_id || -update.chat_id || -update.channel_id;
if(peerID == this.peerID) {
appMessagesManager.wrapSingleMessage(id);
}
2020-03-01 18:26:25 +01:00
break;
}
}
}
2020-02-06 16:43:07 +01:00
}
2020-02-10 08:56:15 +01:00
const appImManager = new AppImManager();
(window as any).appImManager = appImManager;
2020-02-10 08:56:15 +01:00
export default appImManager;