Browse Source

fix reply unknown messages & reply sticker background & minor css fixes

master
Eduard Kuzmenko 5 years ago
parent
commit
b2ddf3dd0a
  1. 4
      src/components/wrappers.ts
  2. 7
      src/lib/appManagers/appDialogsManager.ts
  3. 89
      src/lib/appManagers/appImManager.ts
  4. 4
      src/lib/appManagers/appMessagesIDsManager.ts
  5. 37
      src/lib/appManagers/appMessagesManager.ts
  6. 2
      src/lib/utils.js
  7. 88
      src/scss/partials/_chat.scss
  8. 4
      src/scss/style.scss
  9. 2
      tsconfig.json

4
src/components/wrappers.ts

@ -54,7 +54,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
//container.classList.add('video'); //container.classList.add('video');
let img = container.firstElementChild as HTMLImageElement || new Image(); let img = container.firstElementChild as HTMLImageElement || new Image();
img.setAttribute('message-id', '' + message.id); img.setAttribute('message-id', '' + message.mid);
if(!container.contains(img)) { if(!container.contains(img)) {
container.append(img); container.append(img);
@ -93,7 +93,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
video.volume = 0; video.volume = 0;
} */ } */
video.setAttribute('message-id', '' + message.id); video.setAttribute('message-id', '' + message.mid);
let source = document.createElement('source'); let source = document.createElement('source');
//source.src = doc.url; //source.src = doc.url;

7
src/lib/appManagers/appDialogsManager.ts

@ -1,6 +1,6 @@
import apiManager from "../mtproto/apiManager"; import apiManager from "../mtproto/apiManager";
import apiFileManager from '../mtproto/apiFileManager'; import apiFileManager from '../mtproto/apiFileManager';
import { $rootScope, findUpTag, isElementInViewport } from "../utils"; import { $rootScope, findUpTag, isElementInViewport, langPack } from "../utils";
import appImManager from "./appImManager"; import appImManager from "./appImManager";
import appPeersManager from './appPeersManager'; import appPeersManager from './appPeersManager';
import appMessagesManager from "./appMessagesManager"; import appMessagesManager from "./appMessagesManager";
@ -315,6 +315,11 @@ export class AppDialogsManager {
} }
} }
if(lastMessage.action) {
// @ts-ignore
lastMessageText = langPack[lastMessage.action._];
}
dom.lastMessageSpan.innerHTML = lastMessageText + dom.lastMessageSpan.innerHTML = lastMessageText +
(lastMessage.message ? RichTextProcessor.wrapRichText(lastMessage.message.replace(/\n/g, ' '), {noLinebreakers: true}) : ''); (lastMessage.message ? RichTextProcessor.wrapRichText(lastMessage.message.replace(/\n/g, ' '), {noLinebreakers: true}) : '');

89
src/lib/appManagers/appImManager.ts

@ -1,5 +1,5 @@
import apiManager from '../mtproto/apiManager'; import apiManager from '../mtproto/apiManager';
import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, calcImageInBox, findUpTag, getRichValue, getRichValueWithCaret, getSelectedText } from "../utils"; import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, calcImageInBox, findUpTag, getRichValue, getRichValueWithCaret, getSelectedText, langPack } 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";
@ -259,6 +259,7 @@ class ChatInput {
this.attachMediaPopUp.mediaContainer.innerHTML = ''; this.attachMediaPopUp.mediaContainer.innerHTML = '';
this.attachMediaPopUp.mediaContainer.style.width = ''; this.attachMediaPopUp.mediaContainer.style.width = '';
this.attachMediaPopUp.mediaContainer.style.height = ''; this.attachMediaPopUp.mediaContainer.style.height = '';
this.attachMediaPopUp.mediaContainer.classList.remove('is-document');
switch(willAttach) { switch(willAttach) {
case 'media': { case 'media': {
@ -295,6 +296,7 @@ class ChatInput {
this.attachMediaPopUp.titleEl.innerText = 'Send File'; this.attachMediaPopUp.titleEl.innerText = 'Send File';
this.attachMediaPopUp.mediaContainer.append(docDiv); this.attachMediaPopUp.mediaContainer.append(docDiv);
this.attachMediaPopUp.mediaContainer.classList.add('is-document');
this.attachMediaPopUp.container.classList.add('active'); this.attachMediaPopUp.container.classList.add('active');
break; break;
} }
@ -465,6 +467,7 @@ export class AppImManager {
public dateMessages: {[timestamp: number]: { div: HTMLDivElement, firstTimestamp: number }} = {}; public dateMessages: {[timestamp: number]: { div: HTMLDivElement, firstTimestamp: number }} = {};
public unreaded: number[] = []; public unreaded: number[] = [];
public unreadOut: number[] = []; public unreadOut: number[] = [];
public needUpdate: {replyMid: number, mid: number}[] = []; // if need wrapSingleMessage
public offline = false; public offline = false;
public updateStatusInterval = 0; public updateStatusInterval = 0;
@ -628,19 +631,37 @@ export class AppImManager {
if(!bubble) return; if(!bubble) return;
let message = appMessagesManager.getMessage(mid); let message = appMessagesManager.getMessage(mid);
this.renderMessage(message, false, false, bubble); this.renderMessage(message, false, false, bubble, false);
}); });
$rootScope.$on('messages_downloaded', (e: CustomEvent) => { $rootScope.$on('messages_downloaded', (e: CustomEvent) => {
let mid = e.detail; let mids: number[] = e.detail;
mids.forEach(mid => {
if(this.pinnedMsgID == mid) { if(this.pinnedMsgID == mid) {
let message = appMessagesManager.getMessage(mid); let message = appMessagesManager.getMessage(mid);
this.log('setting pinned message', message); this.log('setting pinned message', message);
this.pinnedMessageContainer.setAttribute('data-mid', mid); this.pinnedMessageContainer.dataset.mid = '' + mid;
this.pinnedMessageContainer.style.display = ''; this.pinnedMessageContainer.style.display = '';
this.pinnedMessageContent.innerHTML = RichTextProcessor.wrapEmojiText(message.message); this.pinnedMessageContent.innerHTML = RichTextProcessor.wrapEmojiText(message.message);
} }
let idx = this.needUpdate.findIndex(v => v.replyMid == mid);
if(idx !== -1) {
let {mid, replyMid} = this.needUpdate.splice(idx, 1)[0];
let bubble = this.bubbles[mid];
if(!bubble) return;
let message = appMessagesManager.getMessage(mid);
let repliedMessage = appMessagesManager.getMessage(replyMid);
if(repliedMessage.deleted) { // чтобы не пыталось бесконечно загрузить удалённое сообщение
delete message.reply_to_mid; // WARNING!
}
this.renderMessage(message, false, false, bubble, false);
}
});
}); });
$rootScope.$on('apiUpdate', (e: CustomEvent) => { $rootScope.$on('apiUpdate', (e: CustomEvent) => {
@ -1285,6 +1306,7 @@ export class AppImManager {
this.unreadOut = []; this.unreadOut = [];
this.loadMediaQueue = []; this.loadMediaQueue = [];
this.loadingMedia = 0; this.loadingMedia = 0;
this.needUpdate.length = 0;
lottieLoader.checkAnimations(false, 'chat', true); lottieLoader.checkAnimations(false, 'chat', true);
@ -1344,7 +1366,7 @@ export class AppImManager {
this.log('setPeer peerID:', this.peerID, dialog, lastMsgID); this.log('setPeer peerID:', this.peerID, dialog, lastMsgID);
appDialogsManager.loadDialogPhoto(this.avatarEl, this.peerID); appDialogsManager.loadDialogPhoto(this.avatarEl, this.peerID);
appDialogsManager.loadDialogPhoto(appSidebarRight.profileElements.avatar, this.peerID); appDialogsManager.loadDialogPhoto(appSidebarRight.profileElements.avatar, this.peerID);
if(appDialogsManager.lastActiveListElement) { if(!samePeer && appDialogsManager.lastActiveListElement) {
appDialogsManager.lastActiveListElement.classList.remove('active'); appDialogsManager.lastActiveListElement.classList.remove('active');
} }
@ -1483,7 +1505,7 @@ export class AppImManager {
}); });
} }
public renderMessage(message: any, reverse = false, multipleRender?: boolean, bubble: HTMLDivElement = null) { public renderMessage(message: any, reverse = false, multipleRender?: boolean, bubble: HTMLDivElement = null, updatePosition = true) {
this.log('message to render:', message); this.log('message to render:', message);
if(message.deleted) return; if(message.deleted) return;
@ -1844,6 +1866,16 @@ export class AppImManager {
this.log('message to render reply', originalMessage, originalPeerTitle, bubble, message); this.log('message to render reply', originalMessage, originalPeerTitle, bubble, message);
// need to download separately
if(originalMessage._ == 'messageEmpty') {
this.log('message to render reply empty, need download');
if(appMessagesManager.wrapSingleMessage(message.reply_to_mid).loading) {
this.needUpdate.push({replyMid: message.reply_to_mid, mid: message.mid});
}
originalPeerTitle = 'Loading...';
}
let originalText = ''; let originalText = '';
if(originalMessage.message) { if(originalMessage.message) {
originalText = RichTextProcessor.wrapRichText(originalMessage.message, { originalText = RichTextProcessor.wrapRichText(originalMessage.message, {
@ -1871,6 +1903,8 @@ export class AppImManager {
if(originalMessage.mid) { if(originalMessage.mid) {
bubble.setAttribute('data-original-mid', originalMessage.mid); bubble.setAttribute('data-original-mid', originalMessage.mid);
} else {
bubble.setAttribute('data-original-mid', message.reply_to_mid);
} }
bubble.append(box); bubble.append(box);
@ -1928,8 +1962,28 @@ export class AppImManager {
} }
} }
let type = our ? 'out' : 'in'; if(message._ == 'messageService') {
bubble.className = '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;
// @ts-ignore
let str = name.outerHTML + ' ' + langPack[action._];
bubble.innerHTML = `<div class="service-msg">${str}</div>`;
}
if(!multipleRender) {
this.scrollPosition.prepareFor(reverse ? 'up' : 'down'); // лагает из-за этого
}
if(updatePosition) {
let type = our ? 'out' : 'in';
let containerDiv = reverse ? this.firstContainerDiv : this.lastContainerDiv; let containerDiv = reverse ? this.firstContainerDiv : this.lastContainerDiv;
if(!containerDiv || !containerDiv.classList.contains(type)) { if(!containerDiv || !containerDiv.classList.contains(type)) {
/* if(containerDiv) { /* if(containerDiv) {
@ -1947,27 +2001,21 @@ export class AppImManager {
} }
if(reverse) { if(reverse) {
if(!multipleRender) { /* if(!multipleRender) {
this.scrollPosition.prepareFor('up'); // лагает из-за этого this.scrollPosition.prepareFor('up'); // лагает из-за этого
} } */
containerDiv.prepend(bubble); containerDiv.prepend(bubble);
this.chatInner.prepend(containerDiv); this.chatInner.prepend(containerDiv);
} else { } else {
if(!multipleRender) { /* if(!multipleRender) {
this.scrollPosition.prepareFor('down'); // лагает из-за этого this.scrollPosition.prepareFor('down'); // лагает из-за этого
} } */
containerDiv.append(bubble); containerDiv.append(bubble);
this.chatInner.append(containerDiv); this.chatInner.append(containerDiv);
} }
/* if(bubble.classList.contains('webpage')) {
this.log('night running', bubble, bubble.scrollHeight);
} */
//return //this.scrollPosition.restore();
let justDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); let justDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
let dateTimestamp = justDate.getTime(); let dateTimestamp = justDate.getTime();
if(!(dateTimestamp in this.dateMessages)) { if(!(dateTimestamp in this.dateMessages)) {
@ -2007,6 +2055,13 @@ export class AppImManager {
containerDiv.insertBefore(dateMessage.div, bubble); containerDiv.insertBefore(dateMessage.div, bubble);
} }
} }
}
/* if(bubble.classList.contains('webpage')) {
this.log('night running', bubble, bubble.scrollHeight);
} */
//return //this.scrollPosition.restore();
if(!multipleRender) { if(!multipleRender) {
this.scrollPosition.restore(); // лагает из-за этого this.scrollPosition.restore(); // лагает из-за этого

4
src/lib/appManagers/appMessagesIDsManager.ts

@ -37,8 +37,8 @@ export class AppMessagesIDsManager {
} }
public splitMessageIDsByChannels (mids: any[]) { public splitMessageIDsByChannels (mids: any[]) {
var msgIDsByChannels: any = {}; var msgIDsByChannels: {[channelID: number]: number[]} = {};
var midsByChannels: any = {}; var midsByChannels: {[channelID: number]: number[]} = {};
var i; var i;
var mid, msgChannel; var mid, msgChannel;
var channelID; var channelID;

37
src/lib/appManagers/appMessagesManager.ts

@ -3206,7 +3206,7 @@ export class AppMessagesManager {
}); });
} }
public wrapForDialog(msgID: number, dialog?: any) { /* public wrapForDialog(msgID: number, dialog?: any) {
var useCache = msgID && dialog !== undefined; var useCache = msgID && dialog !== undefined;
var unreadCount = dialog && dialog.unread_count; var unreadCount = dialog && dialog.unread_count;
@ -3255,7 +3255,7 @@ export class AppMessagesManager {
} }
return message; return message;
} } */
public fetchSingleMessages() { public fetchSingleMessages() {
if(this.fetchSingleMessagesPromise) { if(this.fetchSingleMessagesPromise) {
@ -3263,20 +3263,21 @@ export class AppMessagesManager {
} }
var mids = this.needSingleMessages.slice(); var mids = this.needSingleMessages.slice();
this.needSingleMessages = []; this.needSingleMessages.length = 0;
var splitted = appMessagesIDsManager.splitMessageIDsByChannels(mids); var splitted = appMessagesIDsManager.splitMessageIDsByChannels(mids);
let promises: Promise<void>[] = []; let promises: Promise<void>[] = [];
Object.keys(splitted.msgIDs).forEach((channelID: number | string) => { Object.keys(splitted.msgIDs).forEach((channelID: number | string) => {
let msgIDs = splitted.msgIDs[channelID].map((mid: number) => { channelID = +channelID;
let msgIDs = splitted.msgIDs[channelID].map((msgID: number) => {
return { return {
_: 'inputMessageID', _: 'inputMessageID',
id: mid id: msgID
}; };
}); });
var promise; var promise;
channelID = +channelID;
if(channelID > 0) { if(channelID > 0) {
promise = apiManager.invokeApi('channels.getMessages', { promise = apiManager.invokeApi('channels.getMessages', {
channel: appChatsManager.getChannelInput(channelID), channel: appChatsManager.getChannelInput(channelID),
@ -3293,43 +3294,39 @@ export class AppMessagesManager {
appChatsManager.saveApiChats(getMessagesResult.chats); appChatsManager.saveApiChats(getMessagesResult.chats);
this.saveMessages(getMessagesResult.messages); this.saveMessages(getMessagesResult.messages);
$rootScope.$broadcast('messages_downloaded', splitted.mids[channelID]) $rootScope.$broadcast('messages_downloaded', splitted.mids[+channelID]);
})); }));
}); });
return this.fetchSingleMessagesPromise = Promise.all(promises).then(() => { return this.fetchSingleMessagesPromise = Promise.all(promises).then(() => {
this.fetchSingleMessagesTimeout = 0;
this.fetchSingleMessagesPromise = null; this.fetchSingleMessagesPromise = null;
if(this.needSingleMessages.length) this.fetchSingleMessages(); if(this.needSingleMessages.length) this.fetchSingleMessages();
}).catch(() => { }).catch(() => {
this.fetchSingleMessagesTimeout = 0;
this.fetchSingleMessagesPromise = null; this.fetchSingleMessagesPromise = null;
if(this.needSingleMessages.length) this.fetchSingleMessages(); if(this.needSingleMessages.length) this.fetchSingleMessages();
}); });
} }
/* public wrapSingleMessage(msgID: number) { public wrapSingleMessage(msgID: number) {
if(this.messagesStorage[msgID]) { if(this.messagesStorage[msgID]) {
return this.wrapForDialog(msgID); //let ret = this.wrapForDialog(msgID); // hm
$rootScope.$broadcast('messages_downloaded', [msgID]);
//return ret;
return {mid: msgID, loading: false};
} }
if(this.needSingleMessages.indexOf(msgID) == -1) { if(this.needSingleMessages.indexOf(msgID) == -1) {
this.needSingleMessages.push(msgID); this.needSingleMessages.push(msgID);
if(this.fetchSingleMessagesTimeout == 0) { if(this.fetchSingleMessagesTimeout == 0) {
this.fetchSingleMessagesTimeout = window.setTimeout(this.fetchSingleMessages.bind(this), 100); this.fetchSingleMessagesTimeout = window.setTimeout(this.fetchSingleMessages.bind(this), 25);
}
} }
return {mid: msgID, loading: true}; return {mid: msgID, loading: true};
} */
public wrapSingleMessage(msgID: number) {
if(this.messagesStorage[msgID]) {
$rootScope.$broadcast('messages_downloaded', msgID);
return;
} }
if(this.needSingleMessages.indexOf(msgID) == -1) { return {mid: msgID, loading: false};
this.needSingleMessages.push(msgID);
this.fetchSingleMessages();
}
} }
} }

2
src/lib/utils.js

@ -324,11 +324,11 @@ export const langPack = {
"messageActionChatLeave": "left group", "messageActionChatLeave": "left group",
"messageActionChatDeleteUser": "removed user", "messageActionChatDeleteUser": "removed user",
"messageActionChatJoinedByLink": "joined the group", "messageActionChatJoinedByLink": "joined the group",
"messageActionPinMessage": "pinned message",
"messageActionChannelCreate": "Channel created", "messageActionChannelCreate": "Channel created",
"messageActionChannelEditTitle": "Channel renamed", "messageActionChannelEditTitle": "Channel renamed",
"messageActionChannelEditPhoto": "Channel photo updated", "messageActionChannelEditPhoto": "Channel photo updated",
"messageActionChannelDeletePhoto": "Channel photo removed", "messageActionChannelDeletePhoto": "Channel photo removed",
"messageActionPinMessage": "pinned message",
"messageActionPhoneCall.in_ok": "Incoming Call", "messageActionPhoneCall.in_ok": "Incoming Call",
"messageActionPhoneCall.out_ok": "Outgoing Call", "messageActionPhoneCall.out_ok": "Outgoing Call",

88
src/scss/partials/_chat.scss

@ -178,9 +178,8 @@
} }
.service { .service {
justify-content: center;
align-self: center;
margin: 1rem 0; margin: 1rem 0;
align-self: center;
.service-msg { .service-msg {
color: #fff; color: #fff;
@ -190,6 +189,14 @@
font-size: 15px; font-size: 15px;
border-radius: 12px; border-radius: 12px;
user-select: none; user-select: none;
display: flex;
align-items: center;
justify-content: center;
.name {
cursor: pointer;
margin-right: 5px;
}
} }
} }
@ -488,6 +495,20 @@
} }
} }
&.is-reply {
&.emoji-big, &.sticker {
.box {
padding: 10px;
border-radius: 12px;
border: 1px solid #ccc;
max-width: 300px;
white-space: nowrap;
position: absolute;
top: 0;
}
}
}
.message { .message {
font-size: 16px; font-size: 16px;
//padding: 0 .6rem .2675rem .6rem; //padding: 0 .6rem .2675rem .6rem;
@ -542,7 +563,7 @@
position: absolute; position: absolute;
bottom: 0; bottom: 0;
right: 0; right: 0;
font-size: .75rem; font-size: 12px;
display: flex; display: flex;
align-items: center; align-items: center;
line-height: 1; line-height: 1;
@ -572,6 +593,20 @@
width: 90px; width: 90px;
} }
.message.message-empty .time {
padding: 0;
display: flex;
align-items: center;
width: auto;
.inner {
margin-bottom: 0;
position: relative;
padding: 0 2.5px;
bottom: 0;
}
}
.user-avatar { .user-avatar {
position: absolute; position: absolute;
left: -3rem; left: -3rem;
@ -659,6 +694,15 @@
background-color: $light; background-color: $light;
} }
.bubble.is-reply {
&.emoji-big, &.sticker {
.box {
left: calc(100% + 10px);
background-color: #fff;
}
}
}
.quote { .quote {
border-left: 2px $darkblue solid; border-left: 2px $darkblue solid;
@ -673,11 +717,11 @@
} }
.time { .time {
color: rgba($darkgrey, 0.6); color: #a3adb6;
width: 2rem; width: 36px;
.inner { .inner {
padding: 0 .35rem; padding: 0 7px 0 5px;
margin-bottom: 4px; margin-bottom: 4px;
} }
} }
@ -705,8 +749,8 @@
} }
&.forwarded .attachment, &.forwarded .attachment,
&.is-reply .attachment, &.is-reply .attachment/* ,
&:not(.hide-name):not(.sticker) .attachment { &:not(.hide-name):not(.sticker) .attachment */ {
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
} }
@ -724,6 +768,16 @@
background-color: rgba($green, 0.12); background-color: rgba($green, 0.12);
} }
.bubble.is-reply {
&.emoji-big, &.sticker {
.box {
background-color: #eeffde;
right: calc(100% + 10px);
border-color: rgba($green, .12);
}
}
}
.quote { .quote {
border-left: 2px $darkgreen solid; border-left: 2px $darkgreen solid;
@ -734,20 +788,20 @@
.time { .time {
color: $darkgreen; color: $darkgreen;
width: 48px; width: 50px;
display: inline-block; display: inline-block;
.inner { .inner {
padding: 0 .25rem; padding: 0 4px 0 4px;
bottom: 1px; bottom: 1px;
} }
} }
.bubble { .bubble {
.time .tgico:after { .time .tgico:after {
font-size: 1.1rem; font-size: 19px;
vertical-align: middle; vertical-align: middle;
margin-left: .1rem; margin-left: 1px;
} }
} }
@ -902,6 +956,12 @@
transform: scaleX(-1); transform: scaleX(-1);
} }
#attach-file {
&.menu-open {
color: $blue;
}
}
> div { > div {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -950,7 +1010,7 @@
color: $placeholder-color; color: $placeholder-color;
font-size: 1.5rem; font-size: 1.5rem;
line-height: 1.5rem; line-height: 1.5rem;
transition: .2s color;
flex: 0 0 auto; flex: 0 0 auto;
&.active { &.active {
@ -1307,8 +1367,6 @@
.popup { .popup {
&.popup-delete-message { &.popup-delete-message {
.popup-header { .popup-header {
margin-bottom: 1rem; margin-bottom: 1rem;
} }

4
src/scss/style.scss

@ -1385,6 +1385,10 @@ div.scrollable::-webkit-scrollbar-thumb {
margin: 0 auto; margin: 0 auto;
/* align-items: center; */ /* align-items: center; */
&.is-document {
margin-left: 0;
}
.document { .document {
max-width: 100%; max-width: 100%;
overflow: hidden; overflow: hidden;

2
tsconfig.json

@ -65,8 +65,8 @@
"node_modules", "node_modules",
"public", "public",
"coverage", "coverage",
"./src/lib/StackBlur.js",
"./src/lib/*.js", "./src/lib/*.js",
"src/lib/StackBlur.js",
"./src/*.js", "./src/*.js",
"*.js", "*.js",
] ]

Loading…
Cancel
Save