Browse Source

channel views & groups online & fix message images

master
Eduard Kuzmenko 5 years ago
parent
commit
52db4564b7
  1. 24
      src/components/misc.ts
  2. 4
      src/lib/appManagers/appDialogsManager.ts
  3. 142
      src/lib/appManagers/appImManager.ts
  4. 14
      src/lib/appManagers/appMediaViewer.ts
  5. 5
      src/lib/appManagers/appPeersManager.ts
  6. 20
      src/lib/appManagers/appPhotosManager.ts
  7. 9
      src/lib/richtextprocessor.js
  8. 20
      src/lib/utils.js
  9. 128
      src/scss/partials/_chat.scss
  10. 6
      src/scss/partials/_chatlist.scss
  11. 5
      src/scss/partials/_sidebar.scss
  12. 6
      src/scss/style.scss

24
src/components/misc.ts

@ -222,9 +222,9 @@ export class LazyLoadQueue {
} }
export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, message: any, justLoader = true, preloader?: ProgressivePreloader, controls = true) { export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, message: any, justLoader = true, preloader?: ProgressivePreloader, controls = true) {
//if(!container.firstElementChild || container.firstElementChild.tagName != 'IMG') { if(!container.firstElementChild || container.firstElementChild.tagName != 'IMG') {
let size = appPhotosManager.setAttachmentSize(doc, container); let size = appPhotosManager.setAttachmentSize(doc, container);
//} }
let peerID = this.peerID ? this.peerID : this.currentMessageID; let peerID = this.peerID ? this.peerID : this.currentMessageID;
@ -240,7 +240,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
//return Promise.resolve(); //return Promise.resolve();
if(!preloader) { if(!preloader) {
preloader = new ProgressivePreloader(container, true); preloader = new ProgressivePreloader(container, false);
} }
let loadVideo = () => { let loadVideo = () => {
@ -283,11 +283,14 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
video.append(source); video.append(source);
container.append(video); container.append(video);
//container.style.width = '';
//container.style.height = '';
preloader.detach(); preloader.detach();
}); });
}; };
if(doc.type == 'gif') { if(doc.type == 'gif' || true) { // extra fix
return this.peerID ? this.loadMediaQueuePush(loadVideo) : loadVideo(); return this.peerID ? this.loadMediaQueuePush(loadVideo) : loadVideo();
} else { // if video } else { // if video
let load = () => appPhotosManager.preloadPhoto(doc).then((blob) => { let load = () => appPhotosManager.preloadPhoto(doc).then((blob) => {
@ -301,7 +304,10 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
/* image.style.height = doc.h + 'px'; /* image.style.height = doc.h + 'px';
image.style.width = doc.w + 'px'; */ image.style.width = doc.w + 'px'; */
/* if(justLoader) { // extra fix
justLoader = false;
controls = false;
} */
if(!justLoader) { if(!justLoader) {
return loadVideo(); return loadVideo();
@ -555,10 +561,10 @@ export function wrapPhoto(this: AppImManager, photo: any, message: any, containe
preloader.detach(); preloader.detach();
image.style.width = ''; //image.style.width = '';
image.style.height = ''; //image.style.height = '';
container.style.width = ''; //container.style.width = '';
container.style.height = ''; //container.style.height = '';
}); });
console.log('wrapPhoto', load, container, image); console.log('wrapPhoto', load, container, image);

4
src/lib/appManagers/appDialogsManager.ts

@ -101,7 +101,7 @@ export class AppDialogsManager {
div.classList.remove('tgico-savedmessages'); div.classList.remove('tgico-savedmessages');
div.style.fontSize = ''; div.style.fontSize = '';
let abbrSplitted = (typeof(peerID) != 'string' ? appPeersManager.getPeerTitle(peerID) : peerID).split(' '); let abbrSplitted = (typeof(peerID) != 'string' ? appPeersManager.getPeerTitle(peerID, true) : peerID).split(' ');
let abbr = (abbrSplitted.length == 2 ? let abbr = (abbrSplitted.length == 2 ?
abbrSplitted[0][0] + abbrSplitted[1][0] : abbrSplitted[0][0] + abbrSplitted[1][0] :
abbrSplitted[0][0]).toUpperCase(); abbrSplitted[0][0]).toUpperCase();
@ -413,7 +413,7 @@ export class AppDialogsManager {
//console.log('trying to load photo for:', title); //console.log('trying to load photo for:', title);
this.loadDialogPhoto(avatarDiv, dialog.peerID, true); this.loadDialogPhoto(avatarDiv, dialog.peerID, true);
titleSpan.innerText = title; titleSpan.innerHTML = title;
//p.classList.add('') //p.classList.add('')
let span = document.createElement('span'); let span = document.createElement('span');

142
src/lib/appManagers/appImManager.ts

@ -1,5 +1,5 @@
import apiManager from '../mtproto/apiManager'; import apiManager from '../mtproto/apiManager';
import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName } from "../utils"; import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName, formatNumber } from "../utils";
import appUsersManager from "./appUsersManager"; import appUsersManager from "./appUsersManager";
import appMessagesManager from "./appMessagesManager"; import appMessagesManager from "./appMessagesManager";
import appPeersManager from "./appPeersManager"; import appPeersManager from "./appPeersManager";
@ -138,8 +138,8 @@ class ChatInput {
if(this.lastUrl != url) return; if(this.lastUrl != url) return;
console.log(webpage); console.log(webpage);
appImManager.replyElements.titleEl.innerText = webpage.site_name || webpage.title || ''; appImManager.replyElements.titleEl.innerHTML = RichTextProcessor.wrapEmojiText(webpage.site_name || webpage.title || '');
appImManager.replyElements.subtitleEl.innerText = webpage.description || webpage.url || ''; appImManager.replyElements.subtitleEl.innerHTML = RichTextProcessor.wrapEmojiText(webpage.description || webpage.url || '');
appImManager.replyElements.container.classList.add('active'); appImManager.replyElements.container.classList.add('active');
appImManager.replyToMsgID = 0; appImManager.replyToMsgID = 0;
appImManager.noWebPage = false; appImManager.noWebPage = false;
@ -195,9 +195,7 @@ class ChatInput {
// console.log('messageInput paste', text); // console.log('messageInput paste', text);
let entities = RichTextProcessor.parseEntities(text); let entities = RichTextProcessor.parseEntities(text);
text = RichTextProcessor.wrapRichText(text, { text = RichTextProcessor.wrapEmojiText(text);
entities: entities.filter(e => e._ == 'messageEntityEmoji')
});
// console.log('messageInput paste after', text); // console.log('messageInput paste after', text);
@ -340,6 +338,7 @@ export class AppImManager {
public loadMediaQueue: Array<() => Promise<void>> = []; public loadMediaQueue: Array<() => Promise<void>> = [];
private loadMediaQueuePromise: Promise<void[]> = null; private loadMediaQueuePromise: Promise<void[]> = null;
private loadingMedia = 0;
public scroll: HTMLDivElement = null; public scroll: HTMLDivElement = null;
public scrollPosition: ScrollPosition = null; public scrollPosition: ScrollPosition = null;
@ -445,7 +444,7 @@ export class AppImManager {
this.log('setting pinned message', message); this.log('setting pinned message', message);
this.pinnedMessageContainer.setAttribute('data-mid', mid); this.pinnedMessageContainer.setAttribute('data-mid', mid);
this.pinnedMessageContainer.style.display = ''; this.pinnedMessageContainer.style.display = '';
this.pinnedMessageContent.innerHTML = RichTextProcessor.wrapPlainText(message.message); this.pinnedMessageContent.innerHTML = RichTextProcessor.wrapEmojiText(message.message);
} }
}); });
@ -482,7 +481,9 @@ export class AppImManager {
bubble = findUpClassName(e.target, 'bubble'); bubble = findUpClassName(e.target, 'bubble');
} catch(err) {} } catch(err) {}
if(target.tagName == 'VIDEO' && bubble && bubble.classList.contains('round')) { if(!bubble) return;
if(target.tagName == 'VIDEO' && bubble.classList.contains('round')) {
let video = target as HTMLVideoElement; let video = target as HTMLVideoElement;
video.currentTime = 0; video.currentTime = 0;
if(video.paused) { if(video.paused) {
@ -506,13 +507,17 @@ export class AppImManager {
appMediaViewer.openMedia(message, true); appMediaViewer.openMedia(message, true);
} else if(target.tagName == 'DIV') { } else if(target.tagName == 'DIV') {
if(bubble) { let isReplyClick = false;
if(bubble.classList.contains('is-reply')/* || bubble.classList.contains('forwarded') */) {
try {
isReplyClick = !!findUpClassName(e.target, 'box');
} catch(err) {}
if(isReplyClick && bubble.classList.contains('is-reply')/* || bubble.classList.contains('forwarded') */) {
let originalMessageID = +bubble.getAttribute('data-original-mid'); let originalMessageID = +bubble.getAttribute('data-original-mid');
this.setPeer(this.peerID, originalMessageID); this.setPeer(this.peerID, originalMessageID);
} }
} }
}
//console.log('chatInner click', e); //console.log('chatInner click', e);
}); });
@ -614,7 +619,7 @@ export class AppImManager {
if(this.peerID > 0) { if(this.peerID > 0) {
let title = appPeersManager.getPeerTitle(this.peerID); let title = appPeersManager.getPeerTitle(this.peerID);
this.popupDeleteMessage.deleteBothBtn.innerText = 'DELETE FOR ME AND ' + title.split(' ')[0]; this.popupDeleteMessage.deleteBothBtn.innerHTML = 'DELETE FOR ME AND ' + title;
} else { } else {
this.popupDeleteMessage.deleteBothBtn.innerText = 'DELETE FOR ALL'; this.popupDeleteMessage.deleteBothBtn.innerText = 'DELETE FOR ALL';
} }
@ -625,9 +630,9 @@ export class AppImManager {
this.contextMenu.querySelector('.menu-reply').addEventListener('click', () => { this.contextMenu.querySelector('.menu-reply').addEventListener('click', () => {
let message = appMessagesManager.getMessage(this.contextMenuMsgID); let message = appMessagesManager.getMessage(this.contextMenuMsgID);
let title = appPeersManager.getPeerTitle(message.fromID).split(' ')[0]; let title = appPeersManager.getPeerTitle(message.fromID);
this.replyElements.titleEl.innerText = title; this.replyElements.titleEl.innerHTML = title;
this.replyElements.subtitleEl.innerText = message.message || ''; this.replyElements.subtitleEl.innerHTML = message.message ? RichTextProcessor.wrapEmojiText(message.message) : '';
this.replyElements.container.classList.add('active'); this.replyElements.container.classList.add('active');
this.replyToMsgID = this.contextMenuMsgID; this.replyToMsgID = this.contextMenuMsgID;
}); });
@ -701,14 +706,24 @@ export class AppImManager {
this.loadMediaQueueProcess(); this.loadMediaQueueProcess();
} }
public async loadMediaQueueProcess(): Promise<void[]> { public async loadMediaQueueProcessOld(): Promise<void[]> {
if(this.loadMediaQueuePromise/* || 1 == 1 */) return this.loadMediaQueuePromise; if(this.loadMediaQueuePromise /* || 1 == 1 */) return this.loadMediaQueuePromise;
let woo = this.loadMediaQueue.splice(-5, 5).reverse().map(f => f()); let woo = this.loadMediaQueue.splice(-5, 5).reverse().map(f => f());
if(woo.length) { if(woo.length) {
this.log('Will load more media:', woo.length); this.log('Will load more media:', woo.length);
woo.forEach(async(promise) => {
try {
await promise;
} catch(err) {
this.log.error('loadMediaQueue error:', err);
}
this.loadingMedia--;
});
try { try {
this.loadMediaQueuePromise = Promise.all(woo); this.loadMediaQueuePromise = Promise.all(woo);
await this.loadMediaQueuePromise; await this.loadMediaQueuePromise;
@ -723,6 +738,26 @@ export class AppImManager {
return this.loadMediaQueuePromise; return this.loadMediaQueuePromise;
} }
public async loadMediaQueueProcess(): Promise<void[]> {
if(this.loadingMedia >= 5) return;
let item = this.loadMediaQueue.pop();
if(item) {
this.loadingMedia++;
let promise = item();
try {
await promise;
} catch(err) {
this.log.error('loadMediaQueue error:', err);
}
this.loadingMedia--;
}
if(this.loadMediaQueue.length) return this.loadMediaQueueProcess();
}
public updateStatus() { public updateStatus() {
if(!this.myID) return Promise.resolve(); if(!this.myID) return Promise.resolve();
@ -771,7 +806,7 @@ export class AppImManager {
} }
// load more history // load more history
if(!this.getHistoryPromise && !this.getHistoryTimeout /* && false */) { if(!this.getHistoryPromise && !this.getHistoryTimeout && !testScroll) {
this.getHistoryTimeout = setTimeout(() => { // must be this.getHistoryTimeout = setTimeout(() => { // must be
let history = Object.keys(this.bubbles).map(id => +id).sort(); let history = Object.keys(this.bubbles).map(id => +id).sort();
@ -853,18 +888,32 @@ export class AppImManager {
let isChannel = appPeersManager.isChannel(this.peerID) && !appPeersManager.isMegagroup(this.peerID); let isChannel = appPeersManager.isChannel(this.peerID) && !appPeersManager.isMegagroup(this.peerID);
this.log('setPeerStatus', chat); this.log('setPeerStatus', chat);
Promise.all([
appPeersManager.isMegagroup(this.peerID) ? apiManager.invokeApi('messages.getOnlines', {
peer: appPeersManager.getInputPeerByID(this.peerID)
}) as Promise<any> : Promise.resolve(),
// will redirect if wrong // will redirect if wrong
appProfileManager.getChatFull(chat.id).then((res: any) => { appProfileManager.getChatFull(chat.id)
this.log('chatInfo res:', res); ]).then(results => {
let [chatOnlines, chatInfo] = results;
let onlines = chatOnlines ? chatOnlines.onlines : 1;
this.log('chatInfo res:', chatInfo);
if(res.pinned_msg_id) { // request pinned message if(chatInfo.pinned_msg_id) { // request pinned message
this.pinnedMsgID = res.pinned_msg_id; this.pinnedMsgID = chatInfo.pinned_msg_id;
appMessagesManager.wrapSingleMessage(res.pinned_msg_id); appMessagesManager.wrapSingleMessage(chatInfo.pinned_msg_id);
} }
let participants_count = res.participants_count || res.participants.participants.length; let participants_count = chatInfo.participants_count || chatInfo.participants.participants.length;
let subtitle = numberWithCommas(participants_count) + ' ' + (isChannel ? 'subscribers' : 'members'); let subtitle = numberWithCommas(participants_count) + ' ' + (isChannel ? 'subscribers' : 'members');
if(onlines > 1) {
subtitle += ', ' + numberWithCommas(onlines) + ' online';
}
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = subtitle; this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = subtitle;
}); });
} else if(!appUsersManager.isBot(this.peerID)) { // user } else if(!appUsersManager.isBot(this.peerID)) { // user
@ -1012,7 +1061,7 @@ export class AppImManager {
this.setPeerStatus(); this.setPeerStatus();
this.titleEl.innerText = appSidebarRight.profileElements.name.innerText = dom.titleSpan.innerText; this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = dom.titleSpan.innerHTML;
this.topbar.style.display = ''; this.topbar.style.display = '';
appSidebarRight.toggleSidebar(true); appSidebarRight.toggleSidebar(true);
@ -1028,6 +1077,8 @@ export class AppImManager {
if(lastMsgID != dialog.top_message) { if(lastMsgID != dialog.top_message) {
this.bubbles[lastMsgID].scrollIntoView(); this.bubbles[lastMsgID].scrollIntoView();
} else {
this.scroll.scrollTop = this.scroll.scrollHeight;
} }
} else if(dialog.top_message) { // add last message, bc in getHistory will load < max_id } else if(dialog.top_message) { // add last message, bc in getHistory will load < max_id
this.renderMessage(appMessagesManager.getMessage(dialog.top_message)); this.renderMessage(appMessagesManager.getMessage(dialog.top_message));
@ -1127,24 +1178,29 @@ export class AppImManager {
//messageDiv.innerText = message.message; //messageDiv.innerText = message.message;
// bubble
let bubble = document.createElement('div');
bubble.classList.add('bubble');
this.bubbles[+message.mid] = bubble;
// time section // time section
let date = new Date(message.date * 1000); let date = new Date(message.date * 1000);
let time = ('0' + date.getHours()).slice(-2) + let time = ('0' + date.getHours()).slice(-2) +
':' + ('0' + date.getMinutes()).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;
}
let timeSpan = document.createElement('span'); let timeSpan = document.createElement('span');
timeSpan.classList.add('time'); timeSpan.classList.add('time');
let timeInner = document.createElement('div'); let timeInner = document.createElement('div');
timeInner.classList.add('inner', 'tgico'); timeInner.classList.add('inner', 'tgico');
timeInner.innerText = time; timeInner.innerHTML = time;
// bubble
let bubble = document.createElement('div');
bubble.classList.add('bubble');
this.bubbles[+message.mid] = bubble;
let richText = RichTextProcessor.wrapRichText(message.message, { let richText = RichTextProcessor.wrapRichText(message.message, {
entities: message.totalEntities entities: message.totalEntities
@ -1182,6 +1238,7 @@ export class AppImManager {
timeSpan.appendChild(timeInner); timeSpan.appendChild(timeInner);
messageDiv.append(timeSpan); messageDiv.append(timeSpan);
bubble.prepend(messageDiv); bubble.prepend(messageDiv);
//bubble.prepend(timeSpan, messageDiv); // that's bad
if(our) { if(our) {
if(message.pFlags.unread) this.unreadOut.push(message.mid); if(message.pFlags.unread) this.unreadOut.push(message.mid);
@ -1287,8 +1344,10 @@ export class AppImManager {
doc = webpage.document; doc = webpage.document;
if(doc.type == 'gif' || doc.type == 'video') { if(doc.type == 'gif' || doc.type == 'video') {
//if(doc.size <= 20e6) {
bubble.classList.add('video'); bubble.classList.add('video');
wrapVideo.call(this, doc, preview, message); wrapVideo.call(this, doc, preview, message);
//}
} else { } else {
doc = null; doc = null;
} }
@ -1307,7 +1366,7 @@ export class AppImManager {
nameEl.setAttribute('target', '_blank'); nameEl.setAttribute('target', '_blank');
nameEl.href = webpage.url || '#'; nameEl.href = webpage.url || '#';
nameEl.innerText = webpage.site_name || ''; nameEl.innerHTML = webpage.site_name ? RichTextProcessor.wrapEmojiText(webpage.site_name) : '';
if(webpage.description) { if(webpage.description) {
textDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.description); textDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.description);
@ -1318,7 +1377,8 @@ export class AppImManager {
quote.append(nameEl, titleDiv, textDiv); quote.append(nameEl, titleDiv, textDiv);
box.append(quote); box.append(quote);
bubble.prepend(box); //bubble.prepend(box);
bubble.prepend(timeSpan, box);
//this.log('night running', bubble.scrollHeight); //this.log('night running', bubble.scrollHeight);
@ -1361,7 +1421,7 @@ export class AppImManager {
this.loadMediaQueuePush(load); this.loadMediaQueuePush(load);
break; break;
} else if(doc.mime_type == 'video/mp4') { } else if(doc.mime_type == 'video/mp4' && doc.size <= 20e6) {
this.log('never get free 2', doc); this.log('never get free 2', doc);
if(doc.type == 'round') { if(doc.type == 'round') {
@ -1414,7 +1474,7 @@ export class AppImManager {
if(!bubble.classList.contains('sticker')) { if(!bubble.classList.contains('sticker')) {
let nameDiv = document.createElement('div'); let nameDiv = document.createElement('div');
nameDiv.classList.add('name'); nameDiv.classList.add('name');
nameDiv.innerText = 'Forwarded from ' + title; nameDiv.innerHTML = 'Forwarded from ' + title;
bubble.append(nameDiv); bubble.append(nameDiv);
} }
} else { } else {
@ -1455,7 +1515,7 @@ export class AppImManager {
} }
} }
nameEl.innerText = originalPeerTitle; nameEl.innerHTML = originalPeerTitle;
textDiv.innerHTML = originalText; textDiv.innerHTML = originalText;
quote.append(nameEl, textDiv); quote.append(nameEl, textDiv);
@ -1484,7 +1544,7 @@ export class AppImManager {
if(!bubble.classList.contains('sticker') && (peerID < 0 && peerID != message.fromID)) { if(!bubble.classList.contains('sticker') && (peerID < 0 && peerID != message.fromID)) {
let nameDiv = document.createElement('div'); let nameDiv = document.createElement('div');
nameDiv.classList.add('name'); nameDiv.classList.add('name');
nameDiv.innerText = title; nameDiv.innerHTML = title;
bubble.append(nameDiv); bubble.append(nameDiv);
} else if(!message.reply_to_mid) { } else if(!message.reply_to_mid) {
bubble.classList.add('hide-name'); bubble.classList.add('hide-name');
@ -1615,6 +1675,12 @@ export class AppImManager {
20 : 20 :
(this.chatInner.parentElement.parentElement.scrollHeight) / 30 * 1.25 | 0; (this.chatInner.parentElement.parentElement.scrollHeight) / 30 * 1.25 | 0;
if(testScroll) {
loadCount = 1;
//if(Object.keys(this.bubbles).length > 0)
return Promise.resolve(true);
}
console.time('render getHistory'); console.time('render getHistory');
console.time('render history total'); console.time('render history total');

14
src/lib/appManagers/appMediaViewer.ts

@ -133,7 +133,7 @@ export class AppMediaViewer {
public openMedia(message: any, reverse = false) { public openMedia(message: any, reverse = false) {
this.log('openMedia doc:', message); this.log('openMedia doc:', message);
let media = message.media.photo || message.media.document || message.media.webpage.photo || message.media.webpage.document; let media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo;
let isVideo = media.mime_type == 'video/mp4'; let isVideo = media.mime_type == 'video/mp4';
@ -153,7 +153,7 @@ export class AppMediaViewer {
this.author.date.innerText = dateStr; this.author.date.innerText = dateStr;
let name = appPeersManager.getPeerTitle(message.fromID); let name = appPeersManager.getPeerTitle(message.fromID);
this.author.nameEl.innerText = name; this.author.nameEl.innerHTML = name;
if(message.message) { if(message.message) {
this.content.caption.innerHTML = RichTextProcessor.wrapRichText(message.message, { this.content.caption.innerHTML = RichTextProcessor.wrapRichText(message.message, {
@ -175,8 +175,16 @@ export class AppMediaViewer {
this.log('will wrap video'); this.log('will wrap video');
appPhotosManager.setAttachmentSize(media, container, appPhotosManager.windowW, appPhotosManager.windowH);
wrapVideo.call(this, media, container, message, false, this.preloader).then(() => { wrapVideo.call(this, media, container, message, false, this.preloader).then(() => {
if(this.currentMessageID != message.mid) {
this.log.warn('media viewer changed video');
return;
}
container.classList.remove('loading'); container.classList.remove('loading');
container.style.width = '';
container.style.height = '';
}); });
} else { } else {
let size = appPhotosManager.setAttachmentSize(media.id, container, appPhotosManager.windowW, appPhotosManager.windowH); let size = appPhotosManager.setAttachmentSize(media.id, container, appPhotosManager.windowW, appPhotosManager.windowH);
@ -206,6 +214,8 @@ export class AppMediaViewer {
container.style.height = ''; container.style.height = '';
this.preloader.detach(); this.preloader.detach();
}).catch(err => {
this.log.error(err);
}); });
} }

5
src/lib/appManagers/appPeersManager.ts

@ -1,6 +1,7 @@
import appUsersManager from "./appUsersManager"; import appUsersManager from "./appUsersManager";
import appChatsManager from "./appChatsManager"; import appChatsManager from "./appChatsManager";
import { isObject } from "../utils"; import { isObject } from "../utils";
import { RichTextProcessor } from "../richtextprocessor";
const AppPeersManager = { const AppPeersManager = {
getPeerPhoto: (peerID: number) => { getPeerPhoto: (peerID: number) => {
@ -20,7 +21,7 @@ const AppPeersManager = {
return false; return false;
}, },
getPeerTitle: (peerID: number | any) => { getPeerTitle: (peerID: number | any, plainText = false) => {
let peer: any = {}; let peer: any = {};
if(!isObject(peerID)) { if(!isObject(peerID)) {
peer = AppPeersManager.getPeer(peerID); peer = AppPeersManager.getPeer(peerID);
@ -37,7 +38,7 @@ const AppPeersManager = {
title = peer.title; title = peer.title;
} }
return title; return plainText ? title : RichTextProcessor.wrapEmojiText(title);
}, },
getOutputPeer: (peerID: number) => { getOutputPeer: (peerID: number) => {

20
src/lib/appManagers/appPhotosManager.ts

@ -159,7 +159,7 @@ export class AppPhotosManager {
} }
} }
public setAttachmentSize(photoID: any, div: HTMLDivElement, w = 380, h = 380, isSticker = false) { public setAttachmentSize(photoID: any, div: HTMLDivElement, boxWidth = 380, boxHeight = 380, isSticker = false) {
let photo: /* MTDocument | MTPhoto */any = null; let photo: /* MTDocument | MTPhoto */any = null;
if(typeof(photoID) === 'string') { if(typeof(photoID) === 'string') {
@ -169,7 +169,7 @@ export class AppPhotosManager {
photo = photoID; photo = photoID;
} }
let photoSize = this.choosePhotoSize(photo, w, h); let photoSize = this.choosePhotoSize(photo, boxWidth, boxHeight);
//console.log('setAttachmentSize', photo, photo.sizes[0].bytes, div); //console.log('setAttachmentSize', photo, photo.sizes[0].bytes, div);
let sizes = photo.sizes || photo.thumbs; let sizes = photo.sizes || photo.thumbs;
@ -177,16 +177,14 @@ export class AppPhotosManager {
this.setAttachmentPreview(sizes[0].bytes, div, isSticker); this.setAttachmentPreview(sizes[0].bytes, div, isSticker);
} }
if(photo._ == 'document' /* && photo.type != 'video' */ && photo.type != 'gif') { if(photo._ == 'document' /* && photo.type != 'video' *//* && photo.type != 'gif' */) {
div.style.width = (photo.w || 512) + 'px'; let {w, h} = calcImageInBox(photo.w || 512, photo.h || 512, boxWidth, boxHeight);
div.style.height = (photo.h || 512) + 'px'; div.style.width = w + 'px';
div.style.height = h + 'px';
/* if(div.lastElementChild) {
div.lastElementChild.width
} */
} else { } else {
div.style.width = (photoSize.w || 100) + 'px'; let {w, h} = calcImageInBox(photoSize.w || 100, photoSize.h || 100, boxWidth, boxHeight);
div.style.height = (photoSize.h || 100) + 'px'; div.style.width = w + 'px';
div.style.height = h + 'px';
} }
return photoSize; return photoSize;

9
src/lib/richtextprocessor.js

@ -8,7 +8,7 @@ var EmojiHelper = {
var emojiData = Config.Emoji; var emojiData = Config.Emoji;
var emojiIconSize = emojiData.img_size; var emojiIconSize = emojiData.img_size;
var emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS|Android/i) != -1/* && false */, var emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS|Android/i) != -1 /* && false */,
emojiCode; emojiCode;
//var emojiRegExp = '\\u0023\\u20E3|\\u00a9|\\u00ae|\\u203c|\\u2049|\\u2139|[\\u2194-\\u2199]|\\u21a9|\\u21aa|\\u231a|\\u231b|\\u23e9|[\\u23ea-\\u23ec]|\\u23f0|\\u24c2|\\u25aa|\\u25ab|\\u25b6|\\u2611|\\u2614|\\u26fd|\\u2705|\\u2709|[\\u2795-\\u2797]|\\u27a1|\\u27b0|\\u27bf|\\u2934|\\u2935|[\\u2b05-\\u2b07]|\\u2b1b|\\u2b1c|\\u2b50|\\u2b55|\\u3030|\\u303d|\\u3297|\\u3299|[\\uE000-\\uF8FF\\u270A-\\u2764\\u2122\\u25C0\\u25FB-\\u25FE\\u2615\\u263a\\u2648-\\u2653\\u2660-\\u2668\\u267B\\u267F\\u2693\\u261d\\u26A0-\\u26FA\\u2708\\u2702\\u2601\\u260E]|[\\u2600\\u26C4\\u26BE\\u23F3\\u2764]|\\uD83D[\\uDC00-\\uDFFF]|\\uD83C[\\uDDE8-\\uDDFA\uDDEC]\\uD83C[\\uDDEA-\\uDDFA\uDDE7]|[0-9]\\u20e3|\\uD83C[\\uDC00-\\uDFFF]'; //var emojiRegExp = '\\u0023\\u20E3|\\u00a9|\\u00ae|\\u203c|\\u2049|\\u2139|[\\u2194-\\u2199]|\\u21a9|\\u21aa|\\u231a|\\u231b|\\u23e9|[\\u23ea-\\u23ec]|\\u23f0|\\u24c2|\\u25aa|\\u25ab|\\u25b6|\\u2611|\\u2614|\\u26fd|\\u2705|\\u2709|[\\u2795-\\u2797]|\\u27a1|\\u27b0|\\u27bf|\\u2934|\\u2935|[\\u2b05-\\u2b07]|\\u2b1b|\\u2b1c|\\u2b50|\\u2b55|\\u3030|\\u303d|\\u3297|\\u3299|[\\uE000-\\uF8FF\\u270A-\\u2764\\u2122\\u25C0\\u25FB-\\u25FE\\u2615\\u263a\\u2648-\\u2653\\u2660-\\u2668\\u267B\\u267F\\u2693\\u261d\\u26A0-\\u26FA\\u2708\\u2702\\u2601\\u260E]|[\\u2600\\u26C4\\u26BE\\u23F3\\u2764]|\\uD83D[\\uDC00-\\uDFFF]|\\uD83C[\\uDDE8-\\uDDFA\uDDEC]\\uD83C[\\uDDEA-\\uDDFA\uDDE7]|[0-9]\\u20e3|\\uD83C[\\uDC00-\\uDFFF]';
//var emojiRegExp = '\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff]'; //var emojiRegExp = '\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff]';
@ -718,6 +718,12 @@ function wrapPlainText(text, options = {}) {
text.push(raw); text.push(raw);
return text.join(''); return text.join('');
} }
function wrapEmojiText(text) {
if(!text) return '';
let entities = parseEntities(text).filter(e => e._ == 'messageEntityEmoji');
return wrapRichText(text, {entities});
}
function wrapUrl (url, unsafe) { function wrapUrl (url, unsafe) {
if (!url.match(/^https?:\/\//i)) { if (!url.match(/^https?:\/\//i)) {
url = 'http://' + url url = 'http://' + url
@ -773,6 +779,7 @@ let RichTextProcessor = {
wrapPlainText: wrapPlainText, wrapPlainText: wrapPlainText,
wrapDraftText: wrapDraftText, wrapDraftText: wrapDraftText,
wrapUrl: wrapUrl, wrapUrl: wrapUrl,
wrapEmojiText: wrapEmojiText,
parseEntities: parseEntities, parseEntities: parseEntities,
parseMarkdown: parseMarkdown, parseMarkdown: parseMarkdown,
parseEmojis: parseEmojis, parseEmojis: parseEmojis,

20
src/lib/utils.js

@ -472,6 +472,18 @@ export function formatBytes(bytes, decimals = 2) {
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
} }
export function formatNumber(bytes, decimals = 2) {
if(bytes === 0) return '0';
const k = 1000;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['', 'K', 'M', 'B', 'T'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i];
}
export function deepEqual(x, y) { export function deepEqual(x, y) {
const ok = Object.keys, tx = typeof x, ty = typeof y; const ok = Object.keys, tx = typeof x, ty = typeof y;
return x && y && tx === 'object' && tx === ty ? ( return x && y && tx === 'object' && tx === ty ? (
@ -551,11 +563,11 @@ export function calcImageInBox (imageW, imageH, boxW, boxH, noZooom) {
var boxedImageW = boxW var boxedImageW = boxW
var boxedImageH = boxH var boxedImageH = boxH
if ((imageW / imageH) > (boxW / boxH)) { if((imageW / imageH) > (boxW / boxH)) {
boxedImageH = parseInt(imageH * boxW / imageW) boxedImageH = parseInt(imageH * boxW / imageW)
}else { } else {
boxedImageW = parseInt(imageW * boxH / imageH) boxedImageW = parseInt(imageW * boxH / imageH)
if (boxedImageW > boxW) { if(boxedImageW > boxW) {
boxedImageH = parseInt(boxedImageH * boxW / boxedImageW) boxedImageH = parseInt(boxedImageH * boxW / boxedImageW)
boxedImageW = boxW boxedImageW = boxW
} }
@ -566,7 +578,7 @@ export function calcImageInBox (imageW, imageH, boxW, boxH, noZooom) {
// imageH = Math.floor(imageH / 2) // imageH = Math.floor(imageH / 2)
// } // }
if (noZooom && boxedImageW >= imageW && boxedImageH >= imageH) { if(noZooom && boxedImageW >= imageW && boxedImageH >= imageH) {
boxedImageW = imageW boxedImageW = imageW
boxedImageH = imageH boxedImageH = imageH
} }

128
src/scss/partials/_chat.scss

@ -13,6 +13,10 @@
#im-title { #im-title {
cursor: pointer; cursor: pointer;
span.emoji {
vertical-align: inherit;
}
} }
/* .chat-background, #chat-closed { /* .chat-background, #chat-closed {
@ -196,6 +200,8 @@
.attachment { .attachment {
padding-top: .5rem; padding-top: .5rem;
padding-bottom: 1.5rem; padding-bottom: 1.5rem;
max-width: fit-content!important;
max-height: fit-content!important;
span.emoji { span.emoji {
height: auto; height: auto;
@ -300,21 +306,23 @@
} }
img, video { img, video {
object-fit: contain; /* object-fit: contain; */
/* object-fit: cover; */ object-fit: cover;
width: 100%;
height: 100%;
} }
} }
&.video { //&.video {
.attachment { //.attachment {
//max-height: fit-content; //max-height: fit-content;
img { /*img {
/* width: 100%; */ width: 100%;
/* height: 100%; */ height: 100%;
} }*/
} //}
} //}
&.round.video { &.round.video {
.attachment { .attachment {
@ -454,6 +462,13 @@
bottom: 0; bottom: 0;
right: 0; right: 0;
font-size: .75rem; font-size: .75rem;
display: flex;
i {
font-size: 1.15rem;
margin-right: .4rem;
margin-left: .1rem;
}
} }
} }
@ -562,6 +577,10 @@
} }
} }
.bubble.channel-post .time {
width: 5rem;
}
.bubble { .bubble {
background-color: #ffffff; background-color: #ffffff;
border-radius: 6px 12px 12px 6px; border-radius: 6px 12px 12px 6px;
@ -693,6 +712,47 @@
flex: 0 0 auto; /* Forces side columns to stay same width */ flex: 0 0 auto; /* Forces side columns to stay same width */
position: relative; position: relative;
#input-message {
background: none;
border: none;
width: 100%;
padding: .5rem .5rem;
font-size: .95rem;
/* height: 100%; */
max-height: 30rem;
overflow-y: none;
resize: none;
border: none;
outline: none;
cursor: text;
}
[contenteditable=true]:empty:before {
content: attr(data-placeholder);
color: #9e9e9e;
display: block; /* For Firefox By Ariel Flesler */
}
.btn-circle {
flex: 0 0 auto;
font-size: 1.5rem;
line-height: 1.5rem;
height: 3.25rem;
width: 3.25rem;
color: #9e9e9e;
background-color: #fff;
align-self: flex-end;
&.tgico-send {
color: $blue;
}
}
.os-scrollbar-handle {
background: rgba(0, 0, 0, 0.2);
}
}
.input-message { .input-message {
display: flex; display: flex;
align-items: center; align-items: center;
@ -788,47 +848,6 @@
} }
} }
#input-message {
background: none;
border: none;
width: 100%;
padding: .5rem .5rem;
font-size: .95rem;
/* height: 100%; */
max-height: 30rem;
overflow-y: none;
resize: none;
border: none;
outline: none;
cursor: text;
}
[contenteditable=true]:empty:before {
content: attr(data-placeholder);
color: #9e9e9e;
display: block; /* For Firefox By Ariel Flesler */
}
.btn-circle {
flex: 0 0 auto;
font-size: 1.5rem;
line-height: 1.5rem;
height: 3.25rem;
width: 3.25rem;
color: #9e9e9e;
background-color: #fff;
align-self: flex-end;
&.tgico-send {
color: $blue;
}
}
.os-scrollbar-handle {
background: rgba(0, 0, 0, 0.2);
}
}
.pinned-message, .reply { .pinned-message, .reply {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
@ -876,6 +895,13 @@
white-space: nowrap; white-space: nowrap;
color: #111; color: #111;
} }
.emoji {
font-size: 16px;
height: 16px;
width: 16px;
vertical-align: top;
}
} }
/* #chat-closed { /* #chat-closed {

6
src/scss/partials/_chatlist.scss

@ -132,6 +132,12 @@
.user-title { .user-title {
max-width: 80%; max-width: 80%;
.emoji {
vertical-align: top;
width: 18px;
height: 18px;
}
} }
.user-last-message { .user-last-message {

5
src/scss/partials/_sidebar.scss

@ -36,6 +36,11 @@
font-size: 23px; font-size: 23px;
font-weight: 500; font-weight: 500;
margin: 3px 0; margin: 3px 0;
span.emoji {
vertical-align: inherit;
min-width: min-content;
}
} }
.profile-subtitle { .profile-subtitle {

6
src/scss/style.scss

@ -925,8 +925,10 @@ $width: 100px;
.emoji { .emoji {
display: inline-block; display: inline-block;
width: 100%; /* width: 100%;
height: 100%; height: 100%; */
width: 18px;
height: 18px;
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 100%;
vertical-align: middle; vertical-align: middle;

Loading…
Cancel
Save