webp detect & new message paddings & forward forwarded & down button & avatar click

This commit is contained in:
Eduard Kuzmenko 2020-02-13 18:59:55 +07:00
parent 03c6b98445
commit 9f695bc863
11 changed files with 227 additions and 49 deletions

View File

@ -106,7 +106,7 @@ export default class LazyLoadQueue {
let {div} = this.lazyLoadMedia[i];
if(isElementInViewport(div)) {
console.log('will load div:', div);
//console.log('will load div:', div);
this.lazyLoadMedia[i].wasSeen = true;
this.processQueue(i);
//this.lazyLoadMedia.splice(i, 1);

View File

@ -70,18 +70,20 @@ export default () => import('../lib/services').then(services => {
console.log('updating dialog:', dialog);
++performed;
if(!(dialog.peerID in appDialogsManager.doms)) {
appDialogsManager.addDialog(dialog);
continue;
}
appDialogsManager.setLastMessage(dialog);
++performed;
}
if(performed) {
console.log('will sortDom');
appDialogsManager.sortDom();
appDialogsManager.sortDom(true);
}
});

View File

@ -108,10 +108,17 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
container.append(video);
if(!justLoader) {
if(!justLoader || round) {
video.dataset.ckin = round ? 'circle' : 'default';
video.dataset.overlay = '1';
wrapPlayer(video);
let wrapper = wrapPlayer(video);
if(!round) {
(wrapper.querySelector('.toggle') as HTMLButtonElement).click();
}
} else if(doc.type == 'gif') {
video.autoplay = true;
video.loop = true;
}
//container.style.width = '';

View File

@ -61,9 +61,9 @@ export class AppDialogsManager {
return;
}
if(this.lastActiveListElement) {
/* if(this.lastActiveListElement) {
this.lastActiveListElement.classList.remove('active');
}
} */
if(elem) {
/* if(chatClosedDiv) {

View File

@ -1,5 +1,5 @@
import apiManager from '../mtproto/apiManager';
import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, calcImageInBox } from "../utils";
import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, calcImageInBox, findUpTag } from "../utils";
import appUsersManager from "./appUsersManager";
import appMessagesManager from "./appMessagesManager";
import appPeersManager from "./appPeersManager";
@ -435,6 +435,7 @@ export class AppImManager {
public subtitleEl = document.getElementById('im-subtitle') as HTMLDivElement;
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;
public firstContainerDiv: HTMLDivElement;
public lastContainerDiv: HTMLDivElement;
private getHistoryPromise: Promise<boolean>;
@ -664,6 +665,8 @@ export class AppImManager {
if(!bubble) return;
if(['IMG', 'VIDEO', 'SVG', 'DIV'].indexOf(target.tagName) === -1) target = findUpTag(target, 'DIV');
/* if(target.tagName == 'VIDEO' && bubble.classList.contains('round')) {
let video = target as HTMLVideoElement;
video.currentTime = 0;
@ -678,6 +681,24 @@ export class AppImManager {
} */
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];
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);
}
return;
}
let isReplyClick = false;
try {
@ -690,6 +711,12 @@ export class AppImManager {
}
} else if(bubble.classList.contains('round')) {
} else if(target.tagName == 'IMG' && target.parentElement.classList.contains('user-avatar')) {
let peerID = +target.parentElement.dataset.peerID;
if(!isNaN(peerID)) {
this.setPeer(peerID);
}
} else if((target.tagName == 'IMG' && !target.classList.contains('emoji')) || target.tagName == 'VIDEO') {
let messageID = +target.getAttribute('message-id');
let message = appMessagesManager.getMessage(messageID);
@ -888,6 +915,14 @@ export class AppImManager {
this.deleteMessages(false);
this.popupDeleteMessage.cancelBtn.click();
});
this.goDownBtn.addEventListener('click', () => {
if(this.lastDialog) {
this.setPeer(this.peerID, this.lastDialog.top_message);
} else {
this.scroll.scrollTop = this.scroll.scrollHeight;
}
});
this.updateStatusInterval = window.setInterval(() => this.updateStatus(), 50e3);
this.updateStatus();
@ -1056,7 +1091,8 @@ export class AppImManager {
let willLoad = false;
if(!this.scrolledAll) {
for(let i = 0; i < 10; ++i) {
let length = history.length < 10 ? history.length : 10;
for(let i = 0; i < length; ++i) {
let msgID = history[i];
let bubble = this.bubbles[msgID];
@ -1117,6 +1153,7 @@ export class AppImManager {
this.scroll = scroll;
this.scrollPosition = new ScrollPosition(this.chatInner);
this.scroll.addEventListener('scroll', this.onScroll.bind(this));
this.scroll.parentElement.classList.add('scrolled-down');
}
public setPeerStatus() {
@ -1242,10 +1279,10 @@ export class AppImManager {
//appSidebarRight.minMediaID = {};
}
public setPeer(peerID: number, lastMsgID = 0) {
public setPeer(peerID: number, lastMsgID = 0, forwarding = false) {
if(peerID == 0) {
appSidebarRight.toggleSidebar(false);
this.topbar.style.display = this.chatInput.style.display = 'none';
this.topbar.style.display = this.chatInput.style.display = this.goDownBtn.style.display = 'none';
this.cleanup();
return Promise.resolve(false);
}
@ -1285,9 +1322,12 @@ export class AppImManager {
this.preloader.attach(this.chatInner);
let dialog = this.lastDialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null;
this.log('setPeer peerID:', this.peerID, dialog);
this.log('setPeer peerID:', this.peerID, dialog, lastMsgID);
appDialogsManager.loadDialogPhoto(this.avatarEl, this.peerID);
appDialogsManager.loadDialogPhoto(appSidebarRight.profileElements.avatar, this.peerID);
if(appDialogsManager.lastActiveListElement) {
appDialogsManager.lastActiveListElement.classList.remove('active');
}
this.firstTopMsgID = dialog ? dialog.top_message : 0;
@ -1305,7 +1345,7 @@ export class AppImManager {
//this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = dom.titleSpan.innerHTML;
this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = appPeersManager.getPeerTitle(this.peerID);
this.topbar.style.display = '';
this.topbar.style.display = this.goDownBtn.style.display = '';
appSidebarRight.toggleSidebar(true);
this.chatInput.style.display = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID) ? 'none' : '';
@ -1317,14 +1357,21 @@ export class AppImManager {
}
return Promise.all([
this.getHistory(lastMsgID).then(() => {
this.getHistory(forwarding ? lastMsgID + 1 : lastMsgID).then(() => {
this.log('setPeer removing preloader');
if(lastMsgID) {
this.renderMessage(appMessagesManager.getMessage(lastMsgID));
if(!forwarding) {
let message = appMessagesManager.getMessage(lastMsgID);
this.log('setPeer render last message:', message, lastMsgID);
this.renderMessage(message);
}
if(!dialog || lastMsgID != dialog.top_message) {
this.bubbles[lastMsgID].scrollIntoView();
let bubble = this.bubbles[lastMsgID];
if(bubble) this.bubbles[lastMsgID].scrollIntoView();
else this.log.warn('no bubble by lastMsgID:', lastMsgID);
} else {
this.scroll.scrollTop = this.scroll.scrollHeight;
}
@ -1418,6 +1465,8 @@ export class AppImManager {
}
public renderMessage(message: any, reverse = false, multipleRender?: boolean, bubble: HTMLDivElement = null) {
if(message.deleted) return;
let peerID = this.peerID;
let our = message.fromID == this.myID;
@ -1694,7 +1743,7 @@ export class AppImManager {
}
bubble.classList.add('video');
wrapVideo.call(this, doc, attachmentDiv, message, doc.type != 'round', null, false, doc.type == 'round');
wrapVideo.call(this, doc, attachmentDiv, message, true, null, false, doc.type == 'round');
break;
} else {
@ -1736,10 +1785,25 @@ export class AppImManager {
if(message.fwdFromID || message.fwd_from) {
bubble.classList.add('forwarded');
if(message.savedFrom) {
let fwd = document.createElement('div');
fwd.classList.add('forward'/* , 'tgico-forward' */);
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>`;
bubble.append(fwd);
bubble.dataset.savedFrom = message.savedFrom;
}
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);
bubble.append(nameDiv);
}
@ -1789,7 +1853,7 @@ export class AppImManager {
if(originalMessage.mid) {
bubble.setAttribute('data-original-mid', originalMessage.mid);
}
}
bubble.append(box);
bubble.classList.add('is-reply');
@ -1812,6 +1876,7 @@ export class AppImManager {
nameDiv.classList.add('name');
nameDiv.innerHTML = title;
nameDiv.style.color = appPeersManager.getPeerColorByID(message.fromID, false);
nameDiv.dataset.peerID = message.fromID;
bubble.append(nameDiv);
} else if(!message.reply_to_mid) {
bubble.classList.add('hide-name');
@ -1838,6 +1903,8 @@ export class AppImManager {
appDialogsManager.loadDialogPhoto(avatarDiv, title);
}
avatarDiv.dataset.peerID = message.fromID;
bubble.append(avatarDiv);
}

View File

@ -225,7 +225,9 @@ export class AppMediaViewer {
let index = history.findIndex(m => m == message.mid);
let comparer = (mid: number) => {
let _message = appMessagesManager.getMessage(mid);
if(_message.media && _message.media.photo) return true;
let media = _message.media;
if(media && (media.photo || (media.document && ['video', 'gif'].indexOf(media.document.type) !== -1))) return true;
return false;
};

View File

@ -1034,10 +1034,11 @@ export class AppMessagesManager {
apiMessage.fromID = fwdHeader.channel_id ? -fwdHeader.channel_id : fwdHeader.from_id;
} else {
apiMessage.fwdFromID = fwdHeader.channel_id ? -fwdHeader.channel_id : fwdHeader.from_id;
apiMessage.fwdPostID = fwdHeader.channel_post;
}
apiMessage.fwdFromID = fwdHeader.channel_id ? -fwdHeader.channel_id : fwdHeader.from_id;
fwdHeader.date -= serverTimeManager.serverTimeOffset;
}

View File

@ -7,6 +7,7 @@ class AppWebpManager {
public busyPromise: Promise<string>;
public queue: {bytes: Uint8Array, img: HTMLImageElement}[] = [];
//public worker: any;
public webpSupport: Promise<boolean> = null;
constructor() {
//let canvas = document.createElement('canvas');
@ -16,21 +17,25 @@ class AppWebpManager {
console.log('got message from worker:', e, canvas.toDataURL());
}); */
this.loaded = new Promise((resolve, reject) => {
(window as any).webpLoaded = () => {
console.log('webpHero loaded');
this.webpMachine = new (window as any).WebpMachine();
resolve();
};
let sc = document.createElement('script');
sc.src = 'webp.bundle.js';
sc.async = true;
sc.onload = (window as any).webpLoaded;
document.body.appendChild(sc);
resolve();
this.webpSupported().then(res => {
this.loaded = new Promise((resolve, reject) => {
if(!res) {
(window as any).webpLoaded = () => {
console.log('webpHero loaded');
this.webpMachine = new (window as any).WebpMachine();
resolve();
};
let sc = document.createElement('script');
sc.src = 'webp.bundle.js';
sc.async = true;
sc.onload = (window as any).webpLoaded;
document.body.appendChild(sc);
} else {
resolve();
}
});
});
}
@ -56,11 +61,23 @@ class AppWebpManager {
}
}
webpSupported() {
return this.webpSupport = new Promise((resolve, reject) => {
var webP = new Image();
webP.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMw' +
'AgSSNtse/cXjxyCCmrYNWPwmHRH9jwMA';
webP.onload = webP.onerror = () => {
resolve(webP.height === 2);
};
});
}
async polyfillImage(img: HTMLImageElement, blob: Blob) {
/* console.log('polyfillImage', this);
return this.webpMachine.polyfillImage(image); */
if(await this.webpMachine.webpSupport) {
//if(await this.webpMachine.webpSupport) {
if(await this.webpSupport) {
img.src = URL.createObjectURL(blob);
return;
}

View File

@ -173,6 +173,8 @@ export function wrapPlayer(video) {
wrapper.appendChild(video);
stylePlayer(wrapper, video);
return wrapper;
}
function buildControls(skin) {

View File

@ -110,10 +110,18 @@
flex: 1 1 auto; /* Lets middle column shrink/grow to available width */
overflow: hidden;
position: relative;
> .scrollable {
position: unset;
}
&:not(.scrolled-down) {
-webkit-mask-image: -webkit-linear-gradient(bottom, transparent, #000 20px);
mask-image: linear-gradient(0deg, transparent 0, #000 20px);
#bubbles-go-down {
opacity: 1;
}
}
.preloader {
@ -144,6 +152,30 @@
}
}
}
#bubbles-go-down {
position: absolute;
//opacity: 0;
background-color: #fff;
border-radius: 50%;
width: 3.25rem;
height: 3.25rem;
color: $placeholder-color;
font-size: 30px;
display: flex;
align-items: center;
justify-content: center;
right: 17.5px;
bottom: 17.5px;
cursor: pointer;
opacity: 0;
transition: .2s opacity;
user-select: none;
&:before {
margin-left: .75px;
}
}
.service {
justify-content: center;
@ -172,6 +204,37 @@
font-size: 0;
width: max-content;
height: fit-content;
&.forwarded {
.forward {
opacity: 0;
position: absolute;
right: -46px;
bottom: 0;
width: 38px;
height: 38px;
font-size: 1.5rem;
align-items: center;
display: flex;
justify-content: center;
color: #fff;
border-radius: 50%;
background: rgba(0, 0, 0, 0.16);
cursor: pointer;
transition: .2s opacity;
svg {
width: 20px;
height: 20px;
}
}
}
&:hover {
.forward {
opacity: 1;
}
}
&.photo, &.video {
width: min-content;
@ -426,12 +489,14 @@
}
.message {
font-size: 1rem;
padding: 0 .6rem .2675rem .6rem;
font-size: 16px;
//padding: 0 .6rem .2675rem .6rem;
padding: 0 .6rem 6px .6rem;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
color: #000;
line-height: 21px;
* {
overflow: hidden;
@ -439,7 +504,8 @@
}
&:last-child {
padding-top: .2675rem;
//padding-top: .2675rem;
padding-top: 6px;
}
&.message-empty {
@ -498,13 +564,13 @@
width: calc(5rem + 42px);
}
&.is-edited .time {
width: 90px;
}
&.channel-post .time {
width: 5rem;
}
&.is-edited .time {
width: 90px;
}
.user-avatar {
position: absolute;
@ -514,6 +580,7 @@
line-height: 40px;
bottom: 0;
font-size: 1rem;
cursor: pointer;
}
&:not(.forwarded).hide-name, &.emoji-big {
@ -543,17 +610,20 @@
&:not(.webpage) {
&.photo, &.video {
.name {
padding-bottom: .2675rem;
//padding-bottom: .2675rem;
padding-bottom: 6px;
}
.message:not(.message-empty) {
padding-top: .2675rem;
//padding-top: .2675rem;
padding-top: 6px;
}
}
}
&.hide-name .message:not(.message-empty) {
padding-top: .2675rem;
//padding-top: .2675rem;
padding-top: 6px;
}
&:not(.sticker):not(.emoji-big):not(.round):last-child:after {
@ -622,6 +692,7 @@
&:last-child {
border-radius: 6px 12px 12px 0px;
//border-radius: 12px 12px 12px 0px;
&:after {
left: -8.4px;
@ -707,6 +778,10 @@
.bubble.is-reply .name {
display: none;
}
.bubble.is-edited .time {
width: 85px;
}
.bubble {
background-color: #eeffde;

View File

@ -42,6 +42,11 @@
border-radius: 0 !important;
display: -ms-flexbox;
display: flex;
video {
max-height: none;
max-width: none;
}
}
.default {
@ -290,7 +295,7 @@ video::-webkit-media-controls-enclosure {
}
.bottom-controls {
padding: 3px 4px 5px 4px;
padding: 3px 4px 0px 4px;
//padding: 5px 4px 5px 4px;
display: flex;
justify-content: space-between;
@ -308,8 +313,8 @@ video::-webkit-media-controls-enclosure {
color: #fff;
font-size: 13px;
float: left;
margin-top: 1px;
}
//margin-top: 1px;
}
.circle .circle-time-left {
position: absolute;
top: 3px;