759 lines
24 KiB
TypeScript
759 lines
24 KiB
TypeScript
//import { appImManager, appMessagesManager, appDialogsManager, apiUpdatesManager, appUsersManager } from "../lib/services";
|
|
import { putPreloader, horizontalMenu, wrapSticker, MTDocument, LazyLoadQueue, scrollable } from "./misc";
|
|
|
|
import { isElementInViewport, whichChild, findUpTag } from "../lib/utils";
|
|
import {stackBlurImage} from '../lib/StackBlur';
|
|
import * as Config from '../lib/config';
|
|
import { RichTextProcessor } from "../lib/richtextprocessor";
|
|
import { MTProto } from "../lib/mtproto/mtproto";
|
|
import lottieLoader from "../lib/lottieLoader";
|
|
import CryptoWorker from '../lib/crypto/cryptoworker';
|
|
|
|
import appStickersManager, { MTStickerSet } from "../lib/appManagers/appStickersManager";
|
|
import { AppImManager } from "../lib/appManagers/appImManager";
|
|
import { AppMessagesManager } from "../lib/appManagers/appMessagesManager";
|
|
import appSidebarRight from "../lib/appManagers/appSidebarRight";
|
|
|
|
const EMOTICONSSTICKERGROUP = 'emoticons-dropdown';
|
|
|
|
let initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|
appImManager: AppImManager, appMessagesManager: AppMessagesManager,
|
|
messageInput: HTMLDivElement, toggleEl: HTMLButtonElement, btnSend: HTMLButtonElement) => {
|
|
let dropdown = pageEl.querySelector('.emoji-dropdown') as HTMLDivElement;
|
|
dropdown.classList.add('active'); // need
|
|
|
|
let lazyLoadQueue = new LazyLoadQueue();
|
|
|
|
let container = pageEl.querySelector('.emoji-container .tabs-container') as HTMLDivElement;
|
|
let tabs = pageEl.querySelector('.emoji-dropdown .emoji-tabs') as HTMLUListElement;
|
|
horizontalMenu(tabs, container, (id) => {
|
|
lottieLoader.checkAnimations(true, EMOTICONSSTICKERGROUP);
|
|
|
|
if(id == 1 && stickersInit) {
|
|
stickersInit();
|
|
}
|
|
}, () => {
|
|
lottieLoader.checkAnimations(false, EMOTICONSSTICKERGROUP);
|
|
lazyLoadQueue.check(); // for stickers
|
|
});
|
|
(tabs.children[0] as HTMLLIElement).click(); // set media
|
|
|
|
let emoticonsMenuOnClick = (menu: HTMLUListElement, heights: number[], scroll: HTMLDivElement) => {
|
|
menu.addEventListener('click', function(e) {
|
|
let target = e.target as HTMLLIElement;
|
|
target = findUpTag(target, 'LI');
|
|
|
|
let index = whichChild(target);
|
|
let y = heights[index - 1/* 2 */] || 0; // 10 == padding .scrollable
|
|
|
|
//console.log(target, index, heights, y, scroll);
|
|
|
|
//scroll.scroll({y: y + 'px'});
|
|
scroll.scrollTop = y;
|
|
});
|
|
};
|
|
|
|
let emoticonsContentOnScroll = (menu: HTMLUListElement, heights: number[], prevCategoryIndex: number, scroll: HTMLDivElement) => {
|
|
let pos = scroll.scroll();
|
|
let y = scroll.scrollTop;
|
|
|
|
//console.log(heights, y);
|
|
|
|
for(let i = 0; i < heights.length; ++i) {
|
|
let height = heights[i];
|
|
if(y < height) {
|
|
menu.children[prevCategoryIndex].classList.remove('active');
|
|
prevCategoryIndex = i/* + 1 */;
|
|
menu.children[prevCategoryIndex].classList.add('active');
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return prevCategoryIndex;
|
|
};
|
|
|
|
{
|
|
let categories = ["Smileys & Emotion", "Animals & Nature", "Food & Drink", "Travel & Places", "Activities", "Objects", "Symbols", "Flags", "Skin Tones"];
|
|
let divs: {
|
|
[category: string]: HTMLDivElement
|
|
} = {};
|
|
|
|
let keyCategory = Config.Emoji.keyCategory;
|
|
let sorted: {
|
|
[category: string]: any[]
|
|
} = {};
|
|
|
|
for(let unified in Config.Emoji.emoji) {
|
|
// @ts-ignore
|
|
let details = Config.Emoji.emoji[unified];
|
|
let category = details[keyCategory];
|
|
|
|
details.unified = unified;
|
|
|
|
if(!sorted[category]) sorted[category] = [];
|
|
sorted[category][details.sort_order] = details;
|
|
}
|
|
|
|
Object.keys(sorted).forEach(c => sorted[c].sort());
|
|
|
|
categories.pop();
|
|
delete sorted["Skin Tones"];
|
|
|
|
console.time('emojiParse');
|
|
for(let category in sorted) {
|
|
let div = document.createElement('div');
|
|
div.classList.add('emoji-category');
|
|
|
|
let emojis = sorted[category];
|
|
emojis.forEach(details => {
|
|
let emoji = details.unified;
|
|
//let emoji = (details.unified as string).split('-')
|
|
//.reduce((prev, curr) => prev + String.fromCodePoint(parseInt(curr, 16)), '');
|
|
|
|
let spanEmoji = document.createElement('span');
|
|
let kek = RichTextProcessor.wrapRichText(emoji);
|
|
|
|
if(!kek.includes('emoji')) {
|
|
console.log(details, emoji, kek, spanEmoji, emoji.length, new TextEncoder().encode(emoji));
|
|
return;
|
|
}
|
|
|
|
//console.log(kek);
|
|
|
|
spanEmoji.innerHTML = kek;
|
|
|
|
//spanEmoji = spanEmoji.firstElementChild as HTMLSpanElement;
|
|
//spanEmoji.setAttribute('emoji', emoji);
|
|
div.appendChild(spanEmoji);
|
|
});
|
|
|
|
divs[category] = div;
|
|
}
|
|
console.timeEnd('emojiParse');
|
|
|
|
let heights: number[] = [0];
|
|
|
|
let contentEmojiDiv = document.getElementById('content-emoji') as HTMLDivElement;
|
|
categories.forEach(category => {
|
|
let div = divs[category];
|
|
|
|
if(!div) {
|
|
console.error('no div by category:', category);
|
|
}
|
|
|
|
contentEmojiDiv.append(div);
|
|
heights.push((heights[heights.length - 1] || 0) + div.scrollHeight);
|
|
|
|
//console.log(div, div.scrollHeight);
|
|
});
|
|
|
|
contentEmojiDiv.addEventListener('click', function(e) {
|
|
let target = e.target as any;
|
|
//if(target.tagName != 'SPAN') return;
|
|
|
|
if(target.tagName == 'SPAN' && !target.classList.contains('emoji')) {
|
|
target = target.firstElementChild;
|
|
} else if(target.tagName == 'DIV') return;
|
|
|
|
//console.log('contentEmoji div', target);
|
|
|
|
/* if(!target.classList.contains('emoji')) {
|
|
target = target.parentElement as HTMLSpanElement;
|
|
|
|
if(!target.classList.contains('emoji')) {
|
|
return;
|
|
}
|
|
} */
|
|
|
|
//messageInput.innerHTML += target.innerHTML;
|
|
messageInput.innerHTML += target.outerHTML;
|
|
|
|
btnSend.classList.add('tgico-send');
|
|
btnSend.classList.remove('tgico-microphone2');
|
|
});
|
|
|
|
let prevCategoryIndex = 1;
|
|
let menu = contentEmojiDiv.nextElementSibling as HTMLUListElement;
|
|
let emojiScroll = scrollable(contentEmojiDiv);
|
|
emojiScroll.onscroll = (e) => {
|
|
prevCategoryIndex = emoticonsContentOnScroll(menu, heights, prevCategoryIndex, emojiScroll);
|
|
};
|
|
|
|
emoticonsMenuOnClick(menu, heights, emojiScroll);
|
|
}
|
|
|
|
let stickersInit = () => {
|
|
let contentStickersDiv = document.getElementById('content-stickers') as HTMLDivElement;
|
|
//let stickersDiv = contentStickersDiv.querySelector('.os-content') as HTMLDivElement;
|
|
|
|
let menuWrapper = contentStickersDiv.nextElementSibling as HTMLDivElement;
|
|
let menu = menuWrapper.firstElementChild as HTMLUListElement;
|
|
|
|
let menuScroll = scrollable(menuWrapper, true, false);
|
|
|
|
let stickersDiv = document.createElement('div');
|
|
stickersDiv.classList.add('stickers-categories');
|
|
contentStickersDiv.append(stickersDiv);
|
|
|
|
stickersDiv.addEventListener('mouseover', (e) => {
|
|
let target = e.target as HTMLElement;
|
|
|
|
if(target.tagName == 'CANVAS') { // turn on sticker
|
|
let animation = lottieLoader.getAnimation(target.parentElement, EMOTICONSSTICKERGROUP);
|
|
|
|
if(animation) {
|
|
// @ts-ignore
|
|
if(animation.currentFrame == animation.totalFrames - 1) {
|
|
animation.goToAndPlay(0, true);
|
|
} else {
|
|
animation.play();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
stickersDiv.addEventListener('click', (e) => {
|
|
let target = e.target as HTMLDivElement;
|
|
target = findUpTag(target, 'DIV');
|
|
|
|
let fileID = target.getAttribute('file-id');
|
|
let document = appStickersManager.getSticker(fileID);
|
|
|
|
if(document) {
|
|
appMessagesManager.sendFile(appImManager.peerID, document, {isMedia: true});
|
|
appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight;
|
|
dropdown.classList.remove('active');
|
|
toggleEl.classList.remove('active');
|
|
} else {
|
|
console.warn('got no sticker by id:', fileID);
|
|
}
|
|
});
|
|
|
|
let heights: number[] = [];
|
|
|
|
let categoryPush = (categoryDiv: HTMLDivElement, docs: MTDocument[], prepend?: boolean) => {
|
|
//if((docs.length % 5) != 0) categoryDiv.classList.add('not-full');
|
|
|
|
docs.forEach(doc => {
|
|
let div = document.createElement('div');
|
|
wrapSticker(doc, div, undefined, lazyLoadQueue, EMOTICONSSTICKERGROUP, true);
|
|
|
|
categoryDiv.append(div);
|
|
});
|
|
|
|
/* if(prepend) {
|
|
stickersDiv.prepend(categoryDiv);
|
|
} else {
|
|
stickersDiv.append(categoryDiv);
|
|
} */
|
|
|
|
setTimeout(() => lazyLoadQueue.check(), 0);
|
|
|
|
/* let scrollHeight = categoryDiv.scrollHeight;
|
|
let prevHeight = heights[heights.length - 1] || 0;
|
|
//console.log('scrollHeight', scrollHeight, categoryDiv, stickersDiv.childElementCount);
|
|
if(prepend && heights.length) {// all stickers loaded faster than recent
|
|
heights.forEach((h, i) => heights[i] += scrollHeight);
|
|
|
|
return heights.unshift(scrollHeight) - 1;
|
|
} */
|
|
|
|
heights.length = 0;
|
|
Array.from(stickersDiv.children).forEach((div, i) => {
|
|
heights[i] = (heights[i - 1] || 0) + div.scrollHeight;
|
|
});
|
|
|
|
//return heights.push(prevHeight + scrollHeight) - 1;
|
|
};
|
|
|
|
MTProto.apiManager.invokeApi('messages.getRecentStickers', {flags: 0, hash: 0}).then((res) => {
|
|
let stickers: {
|
|
_: string,
|
|
hash: number,
|
|
packs: any[],
|
|
stickers: MTDocument[],
|
|
dates: number[]
|
|
} = res as any;
|
|
|
|
let categoryDiv = document.createElement('div');
|
|
categoryDiv.classList.add('sticker-category');
|
|
|
|
stickersDiv.prepend(categoryDiv);
|
|
|
|
categoryPush(categoryDiv, stickers.stickers, true);
|
|
});
|
|
|
|
MTProto.apiManager.invokeApi('messages.getAllStickers', {hash: 0}).then((res) => {
|
|
let stickers: {
|
|
_: 'messages.allStickers',
|
|
hash: number,
|
|
sets: Array<MTStickerSet>
|
|
} = res as any;
|
|
|
|
stickers.sets/* .slice(0, 10) */.forEach(async(set) => {
|
|
let categoryDiv = document.createElement('div');
|
|
categoryDiv.classList.add('sticker-category');
|
|
|
|
let li = document.createElement('li');
|
|
li.classList.add('btn-icon');
|
|
|
|
menu.append(li);
|
|
|
|
stickersDiv.append(categoryDiv);
|
|
|
|
let stickerSet = await appStickersManager.getStickerSet(set);
|
|
|
|
if(stickerSet.set.thumb) {
|
|
let thumb = stickerSet.set.thumb;
|
|
|
|
appStickersManager.getStickerSetThumb(stickerSet.set).then(async(blob) => {
|
|
if(thumb.w == 1 && thumb.h == 1) {
|
|
const reader = new FileReader();
|
|
|
|
reader.addEventListener('loadend', async(e) => {
|
|
// @ts-ignore
|
|
const text = e.srcElement.result;
|
|
let json = await CryptoWorker.gzipUncompress<string>(text, true);
|
|
|
|
let animation = await lottieLoader.loadAnimation({
|
|
container: li,
|
|
loop: true,
|
|
autoplay: false,
|
|
animationData: JSON.parse(json)
|
|
}, EMOTICONSSTICKERGROUP);
|
|
});
|
|
|
|
reader.readAsArrayBuffer(blob);
|
|
} else {
|
|
let image = new Image();
|
|
image.src = URL.createObjectURL(blob);
|
|
|
|
li.append(image);
|
|
}
|
|
});
|
|
} else { // as thumb will be used first sticker
|
|
wrapSticker(stickerSet.documents[0], li as any, undefined, undefined, EMOTICONSSTICKERGROUP); // kostil
|
|
}
|
|
|
|
categoryPush(categoryDiv, stickerSet.documents);
|
|
});
|
|
});
|
|
|
|
let prevCategoryIndex = 0;
|
|
let stickersScroll = scrollable(contentStickersDiv);
|
|
stickersScroll.onscroll = (e) => {
|
|
lazyLoadQueue.check();
|
|
lottieLoader.checkAnimations();
|
|
|
|
prevCategoryIndex = emoticonsContentOnScroll(menu, heights, prevCategoryIndex, stickersScroll);
|
|
};
|
|
|
|
emoticonsMenuOnClick(menu, heights, stickersScroll);
|
|
|
|
stickersInit = null;
|
|
};
|
|
|
|
return {dropdown, lazyLoadQueue};
|
|
};
|
|
|
|
export default () => import('../lib/services').then(services => {
|
|
console.log('included services', services);
|
|
|
|
let {appImManager, appMessagesManager, appDialogsManager, apiUpdatesManager, appUsersManager} = services;
|
|
//export default () => {
|
|
let chatsContainer = document.getElementById('chats-container') as HTMLDivElement;
|
|
let d = document.createElement('div');
|
|
d.classList.add('preloader');
|
|
putPreloader(d);
|
|
chatsContainer.append(d);
|
|
|
|
let pageEl = document.body.getElementsByClassName('page-chats')[0] as HTMLDivElement;
|
|
pageEl.style.display = '';
|
|
|
|
const loadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
|
|
|
|
let chatsScroll = scrollable(chatsContainer as HTMLDivElement);
|
|
let sidebarScroll = scrollable(document.body.querySelector('.profile-container'));
|
|
let chatScroll = scrollable(document.getElementById('bubbles') as HTMLDivElement);
|
|
|
|
apiUpdatesManager.attach();
|
|
|
|
let offsetIndex = 0;
|
|
let loadDialogsPromise: Promise<any>;
|
|
let loadDialogs = async() => {
|
|
if(loadDialogsPromise) return loadDialogsPromise;
|
|
|
|
chatsContainer.append(d);
|
|
|
|
//let offset = appMessagesManager.generateDialogIndex();/* appMessagesManager.dialogsNum */;
|
|
|
|
try {
|
|
loadDialogsPromise = appMessagesManager.getConversations('', offsetIndex, loadCount);
|
|
|
|
let result = await loadDialogsPromise;
|
|
|
|
console.log('loaded ' + loadCount + ' dialogs by offset:', offsetIndex, result);
|
|
|
|
if(result && result.dialogs && result.dialogs.length) {
|
|
offsetIndex = result.dialogs[result.dialogs.length - 1].index;
|
|
result.dialogs.forEach((dialog: any) => {
|
|
appDialogsManager.addDialog(dialog);
|
|
});
|
|
}
|
|
} catch(err) {
|
|
console.error(err);
|
|
}
|
|
|
|
d.remove();
|
|
loadDialogsPromise = undefined;
|
|
};
|
|
|
|
let onScroll = () => {
|
|
if(!loadDialogsPromise) {
|
|
let d = Array.from(appDialogsManager.chatList.childNodes).slice(-5);
|
|
for(let node of d) {
|
|
if(isElementInViewport(node)) {
|
|
loadDialogs();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//console.log('last 5 dialogs:', d);
|
|
}
|
|
};
|
|
|
|
chatsScroll.onscroll = onScroll;
|
|
window.addEventListener('resize', () => {
|
|
setTimeout(onScroll, 0);
|
|
});
|
|
|
|
// @ts-ignore
|
|
document.addEventListener('user_update', (e: CustomEvent) => {
|
|
let userID = e.detail;
|
|
|
|
let user = appUsersManager.getUser(userID);
|
|
|
|
let dialog = appMessagesManager.getDialogByPeerID(user.id)[0];
|
|
//console.log('updating user:', user, dialog);
|
|
|
|
if(dialog && !appUsersManager.isBot(dialog.peerID) && dialog.peerID != appImManager.myID) {
|
|
let online = user.status._ == 'userStatusOnline';
|
|
let dom = appDialogsManager.getDialogDom(dialog.peerID);
|
|
|
|
if(dom) {
|
|
if(online) {
|
|
dom.avatarDiv.classList.add('is-online');
|
|
} else {
|
|
dom.avatarDiv.classList.remove('is-online');
|
|
}
|
|
}
|
|
}
|
|
|
|
if(appImManager.peerID == user.id) {
|
|
appImManager.setPeerStatus();
|
|
}
|
|
});
|
|
|
|
// @ts-ignore
|
|
document.addEventListener('history_multiappend', (e: CustomEvent) => {
|
|
//let msgIDsByPeer = e.detail;
|
|
|
|
appDialogsManager.sortDom();
|
|
});
|
|
|
|
// @ts-ignore
|
|
document.addEventListener('dialog_top', (e: CustomEvent) => {
|
|
let dialog: any = e.detail;
|
|
|
|
appDialogsManager.setLastMessage(dialog);
|
|
appDialogsManager.sortDom();
|
|
});
|
|
|
|
// @ts-ignore
|
|
document.addEventListener('history_delete', (e: CustomEvent) => {
|
|
let detail: {
|
|
peerID: string,
|
|
msgs: {[x: number]: boolean}
|
|
} = e.detail;
|
|
|
|
appImManager.deleteMessagesByIDs(Object.keys(detail.msgs).map(s => +s));
|
|
});
|
|
|
|
// @ts-ignore
|
|
document.addEventListener('dialogs_multiupdate', (e: CustomEvent) => {
|
|
let dialogs = e.detail;
|
|
|
|
for(let id in dialogs) {
|
|
let dialog = dialogs[id];
|
|
|
|
console.log('updating dialog:', dialog);
|
|
|
|
if(!(dialog.peerID in appDialogsManager.doms)) {
|
|
appDialogsManager.addDialog(dialog);
|
|
continue;
|
|
}
|
|
|
|
appDialogsManager.setLastMessage(dialog);
|
|
}
|
|
|
|
appDialogsManager.sortDom();
|
|
});
|
|
|
|
// @ts-ignore
|
|
document.addEventListener('dialog_unread', (e: CustomEvent) => {
|
|
let info: {
|
|
peerID: number,
|
|
count: number
|
|
} = e.detail;
|
|
|
|
let dialog = appMessagesManager.getDialogByPeerID(info.peerID)[0];
|
|
if(dialog) {
|
|
appDialogsManager.setUnreadMessages(dialog);
|
|
|
|
if(dialog.peerID == appImManager.peerID) {
|
|
appImManager.updateUnreadByDialog(dialog);
|
|
}
|
|
}
|
|
});
|
|
/*
|
|
loadDialogs().then(result => {
|
|
//appImManager.setScroll(chatScroll);
|
|
});
|
|
return;
|
|
*/
|
|
let messageInput = document.getElementById('input-message') as HTMLDivElement/* HTMLInputElement */;
|
|
messageInput.addEventListener('keydown', function(this: typeof messageInput, e: KeyboardEvent) {
|
|
if(e.key == 'Enter') {
|
|
if(e.shiftKey) {
|
|
return;
|
|
}
|
|
|
|
sendMessage();
|
|
}
|
|
});
|
|
|
|
messageInput.addEventListener('input', function(this: typeof messageInput, e) {
|
|
//console.log('messageInput input', this.innerText, serializeNodes(Array.from(messageInput.childNodes)));
|
|
if(!this.innerText.trim() && !serializeNodes(Array.from(messageInput.childNodes)).trim()) {
|
|
this.innerHTML = '';
|
|
btnSend.classList.remove('tgico-send');
|
|
btnSend.classList.add('tgico-microphone2');
|
|
} else if(!btnSend.classList.contains('tgico-send')) {
|
|
btnSend.classList.add('tgico-send');
|
|
btnSend.classList.remove('tgico-microphone2');
|
|
}
|
|
});
|
|
|
|
let serializeNodes = (nodes: Node[]): string => {
|
|
return nodes.reduce((str, child: any) => {
|
|
//console.log('childNode', str, child, typeof(child), typeof(child) === 'string', child.innerText);
|
|
|
|
if(typeof(child) === 'object' && child.textContent) return str += child.textContent;
|
|
if(child.innerText) return str += child.innerText;
|
|
if(child.tagName == 'IMG' && child.classList && child.classList.contains('emoji')) return str += child.getAttribute('emoji');
|
|
|
|
return str;
|
|
}, '');
|
|
};
|
|
|
|
messageInput.addEventListener('copy', function(e) {
|
|
const selection = document.getSelection();
|
|
|
|
let range = selection.getRangeAt(0);
|
|
let ancestorContainer = range.commonAncestorContainer;
|
|
|
|
let str = '';
|
|
|
|
let selectedNodes = Array.from(ancestorContainer.childNodes).slice(range.startOffset, range.endOffset);
|
|
if(selectedNodes.length) {
|
|
str = serializeNodes(selectedNodes);
|
|
} else {
|
|
str = selection.toString();
|
|
}
|
|
|
|
console.log('messageInput copy', str, ancestorContainer.childNodes, range);
|
|
|
|
// @ts-ignore
|
|
event.clipboardData.setData('text/plain', str);
|
|
event.preventDefault();
|
|
});
|
|
|
|
messageInput.addEventListener('paste', function(this: typeof messageInput, e) {
|
|
e.preventDefault();
|
|
// @ts-ignore
|
|
let text = (e.originalEvent || e).clipboardData.getData('text/plain');
|
|
|
|
// console.log('messageInput paste', text);
|
|
|
|
text = RichTextProcessor.wrapRichText(text);
|
|
|
|
// console.log('messageInput paste after', text);
|
|
|
|
// @ts-ignore
|
|
//let html = (e.originalEvent || e).clipboardData.getData('text/html');
|
|
|
|
// @ts-ignore
|
|
//console.log('paste text', text, );
|
|
window.document.execCommand('insertHTML', false, text);
|
|
});
|
|
|
|
let fileInput = document.getElementById('input-file') as HTMLInputElement;
|
|
|
|
fileInput.addEventListener('change', (e) => {
|
|
var file = (e.target as HTMLInputElement & EventTarget).files[0];
|
|
if(!file) {
|
|
return;
|
|
}
|
|
|
|
console.log('selected file:', file, typeof(file));
|
|
|
|
fileInput.value = '';
|
|
|
|
appMessagesManager.sendFile(appImManager.peerID, file, {isMedia: true});
|
|
appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight;
|
|
|
|
/* MTProto.apiFileManager.uploadFile(file).then((inputFile) => {
|
|
console.log('uploaded smthn', inputFile);
|
|
}); */
|
|
}, false);
|
|
|
|
pageEl.querySelector('#attach-file').addEventListener('click', () => {
|
|
fileInput.click();
|
|
});
|
|
|
|
let inputMessageContainer = document.getElementsByClassName('input-message-container')[0] as HTMLDivElement;
|
|
|
|
let inputScroll = scrollable(inputMessageContainer);
|
|
|
|
let sendMessage = () => {
|
|
let str = serializeNodes(Array.from(messageInput.childNodes));
|
|
|
|
//console.log('childnode str after:', str);
|
|
|
|
appMessagesManager.sendText(appImManager.peerID, str);
|
|
appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight;
|
|
messageInput.innerText = '';
|
|
|
|
btnSend.classList.remove('tgico-send');
|
|
btnSend.classList.add('tgico-microphone2');
|
|
};
|
|
|
|
let btnSend = document.getElementById('btn-send') as HTMLButtonElement;
|
|
btnSend.addEventListener('click', () => {
|
|
if(btnSend.classList.contains('tgico-send')) {
|
|
sendMessage();
|
|
}
|
|
});
|
|
|
|
/* function placeCaretAfterNode(node: HTMLElement) {
|
|
if (typeof window.getSelection != "undefined") {
|
|
var range = document.createRange();
|
|
range.setStartAfter(node);
|
|
range.collapse(true);
|
|
var selection = window.getSelection();
|
|
selection.removeAllRanges();
|
|
selection.addRange(range);
|
|
}
|
|
}
|
|
|
|
messageInput.onclick = (e) => {
|
|
let target = e.target as HTMLElement;
|
|
if(target.classList.contains('emoji-inner')) {
|
|
placeCaretAfterNode(target.parentElement);
|
|
} else if(target.classList.contains('emoji-sizer')) {
|
|
placeCaretAfterNode(target);
|
|
}
|
|
console.log('lol', target);
|
|
}; */
|
|
|
|
/* window.addEventListener('click', function(this, e) {
|
|
// @ts-ignore
|
|
let isInput = e.target.tagName == 'INPUT';
|
|
if(!isInput && !window.getSelection().toString()) {
|
|
console.log('click');
|
|
messageInput.focus();
|
|
}
|
|
}); */
|
|
|
|
fetch('assets/img/camomile.jpg')
|
|
.then(res => res.blob())
|
|
.then(blob => {
|
|
let img = new Image();
|
|
let url = URL.createObjectURL(blob);
|
|
img.src = url;
|
|
img.onload = () => {
|
|
let id = 'chat-background-canvas';
|
|
var canvas = document.getElementById(id) as HTMLCanvasElement;
|
|
URL.revokeObjectURL(url);
|
|
|
|
stackBlurImage(img, id, 15, 0);
|
|
|
|
canvas.toBlob(blob => {
|
|
//let dataUrl = canvas.toDataURL('image/jpeg', 1);
|
|
let dataUrl = URL.createObjectURL(blob);
|
|
|
|
[/* '.chat-background', '#chat-closed' */'.chat-container'].forEach(selector => {
|
|
let bg = document.querySelector(selector) as HTMLDivElement;
|
|
bg.style.backgroundImage = 'url(' + dataUrl + ')';
|
|
});
|
|
}, 'image/jpeg', 1);
|
|
};
|
|
});
|
|
|
|
let emoticonsDropdown: HTMLDivElement = null;
|
|
let emoticonsTimeout: number = 0;
|
|
let toggleEmoticons = pageEl.querySelector('.toggle-emoticons') as HTMLButtonElement;
|
|
let emoticonsLazyLoadQueue: LazyLoadQueue = null;
|
|
toggleEmoticons.onmouseover = (e) => {
|
|
clearTimeout(emoticonsTimeout);
|
|
emoticonsTimeout = setTimeout(() => {
|
|
if(!emoticonsDropdown) {
|
|
let res = initEmoticonsDropdown(pageEl, appImManager,
|
|
appMessagesManager, messageInput, toggleEmoticons, btnSend);
|
|
|
|
emoticonsDropdown = res.dropdown;
|
|
emoticonsLazyLoadQueue = res.lazyLoadQueue;
|
|
|
|
toggleEmoticons.onmouseout = emoticonsDropdown.onmouseout = (e) => {
|
|
clearTimeout(emoticonsTimeout);
|
|
emoticonsTimeout = setTimeout(() => {
|
|
emoticonsDropdown.classList.remove('active');
|
|
toggleEmoticons.classList.remove('active');
|
|
lottieLoader.checkAnimations(true, EMOTICONSSTICKERGROUP);
|
|
}, 200);
|
|
};
|
|
|
|
emoticonsDropdown.onmouseover = (e) => {
|
|
clearTimeout(emoticonsTimeout);
|
|
};
|
|
} else {
|
|
emoticonsDropdown.classList.add('active');
|
|
emoticonsLazyLoadQueue.check();
|
|
}
|
|
|
|
toggleEmoticons.classList.add('active');
|
|
|
|
lottieLoader.checkAnimations(false, EMOTICONSSTICKERGROUP);
|
|
}, 0/* 200 */);
|
|
};
|
|
|
|
/* toggleEmoticons.onclick = (e) => {
|
|
if(!emoticonsDropdown) {
|
|
emoticonsDropdown = initEmoticonsDropdown(pageEl, appImManager,
|
|
appMessagesManager, messageInput, toggleEmoticons);
|
|
} else {
|
|
emoticonsDropdown.classList.toggle('active');
|
|
}
|
|
|
|
toggleEmoticons.classList.toggle('active');
|
|
}; */
|
|
|
|
|
|
loadDialogs().then(result => {
|
|
onScroll();
|
|
appImManager.setScroll(chatScroll);
|
|
appSidebarRight.setScroll(sidebarScroll);
|
|
});
|
|
});
|