Browse Source

GIF sending & fix blink after message send

master
morethanwords 5 years ago
parent
commit
2a5ad412f1
  1. 56
      src/components/chatInput.ts
  2. 37
      src/components/emoticonsDropdown.ts
  3. 16
      src/components/wrappers.ts
  4. 22
      src/lib/appManagers/appDocsManager.ts
  5. 35
      src/lib/appManagers/appImManager.ts
  6. 2
      src/lib/appManagers/appMediaViewer.ts
  7. 228
      src/lib/appManagers/appMessagesManager.ts
  8. 129
      src/lib/appManagers/appPhotosManager.ts
  9. 9
      src/lib/appManagers/appSidebarRight.ts
  10. 2
      src/lib/appManagers/appStickersManager.ts
  11. 16
      src/lib/appManagers/appWebPagesManager.ts
  12. 2
      src/pages/pageIm.ts
  13. 4
      src/scss/partials/_chat.scss
  14. 2
      src/scss/partials/_emojiDropdown.scss
  15. 1
      tsconfig.json

56
src/components/chatInput.ts

@ -189,6 +189,7 @@ export class ChatInput { @@ -189,6 +189,7 @@ export class ChatInput {
console.log('selected file:', file, typeof(file));
willAttachFile = file;
willAttachObjectURL = '';
this.fileInput.value = '';
@ -207,7 +208,7 @@ export class ChatInput { @@ -207,7 +208,7 @@ export class ChatInput {
switch(willAttach) {
case 'media': {
let img = new Image();
img.src = URL.createObjectURL(file);
img.src = willAttachObjectURL = URL.createObjectURL(file);
img.onload = () => {
willAttachWidth = img.naturalWidth;
willAttachHeight = img.naturalHeight;
@ -248,6 +249,7 @@ export class ChatInput { @@ -248,6 +249,7 @@ export class ChatInput {
let willAttach = '';
let willAttachFile: File = null;
let willAttachObjectURL = '';
let willAttachWidth = 0, willAttachHeight = 0;
this.fileInput.addEventListener('change', (e) => {
var file = (e.target as HTMLInputElement & EventTarget).files[0];
@ -302,14 +304,11 @@ export class ChatInput { @@ -302,14 +304,11 @@ export class ChatInput {
isMedia: true,
caption,
width: willAttachWidth,
height: willAttachHeight
height: willAttachHeight,
objectURL: willAttachObjectURL
});
appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight;
let dialog = appMessagesManager.getDialogByPeerID(appImManager.peerID)[0];
if(dialog && dialog.top_message) {
appMessagesManager.readHistory(appImManager.peerID, dialog.top_message); // lol
}
this.onMessageSent();
});
this.btnSend.addEventListener('click', () => {
@ -384,6 +383,29 @@ export class ChatInput { @@ -384,6 +383,29 @@ export class ChatInput {
}, '');
};
public onMessageSent(scrollDown = true, clearInput = true) {
if(scrollDown) {
appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight;
}
let dialog = appMessagesManager.getDialogByPeerID(appImManager.peerID)[0];
if(dialog && dialog.top_message) {
appMessagesManager.readHistory(appImManager.peerID, dialog.top_message); // lol
}
if(clearInput) {
this.lastUrl = '';
this.editMsgID = 0;
this.replyToMsgID = 0;
this.noWebPage = false;
this.replyElements.container.classList.remove('active');
this.willSendWebPage = null;
this.messageInput.innerText = '';
this.btnSend.classList.remove('tgico-send');
this.btnSend.classList.add('tgico-microphone2');
}
}
public sendMessage() {
//let str = this.serializeNodes(Array.from(this.messageInput.childNodes));
let str = getRichValue(this.messageInput);
@ -391,7 +413,6 @@ export class ChatInput { @@ -391,7 +413,6 @@ export class ChatInput {
//console.log('childnode str after:', str/* , getRichValue(this.messageInput) */);
//return;
this.lastUrl = '';
if(this.editMsgID) {
appMessagesManager.editMessage(this.editMsgID, str, {
@ -403,24 +424,9 @@ export class ChatInput { @@ -403,24 +424,9 @@ export class ChatInput {
noWebPage: this.noWebPage,
webPage: this.willSendWebPage
});
appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight;
}
let dialog = appMessagesManager.getDialogByPeerID(appImManager.peerID)[0];
if(dialog && dialog.top_message) {
appMessagesManager.readHistory(appImManager.peerID, dialog.top_message); // lol
}
this.editMsgID = 0;
this.replyToMsgID = 0;
this.noWebPage = false;
this.replyElements.container.classList.remove('active');
this.willSendWebPage = null;
this.messageInput.innerText = '';
this.btnSend.classList.remove('tgico-send');
this.btnSend.classList.add('tgico-microphone2');
this.onMessageSent(!this.editMsgID);
};
public setTopInfo(title: string, subtitle: string, input?: string, media?: any) {

37
src/components/emoticonsDropdown.ts

@ -206,6 +206,22 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement, @@ -206,6 +206,22 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
emoticonsMenuOnClick(menu, heights, emojiScroll);
}
let onMediaClick = (e: MouseEvent) => {
let target = e.target as HTMLDivElement;
target = findUpTag(target, 'DIV');
let fileID = target.dataset.docID;
let document = appDocsManager.getDoc(fileID);
if(document._ != 'documentEmpty') {
appMessagesManager.sendFile(appImManager.peerID, document, {isMedia: true});
appImManager.chatInputC.onMessageSent(true, false);
dropdown.classList.remove('active');
toggleEl.classList.remove('active');
} else {
console.warn('got no doc by id:', fileID);
}
};
let stickersInit = () => {
let contentStickersDiv = document.getElementById('content-stickers') as HTMLDivElement;
//let stickersDiv = contentStickersDiv.querySelector('.os-content') as HTMLDivElement;
@ -236,22 +252,7 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement, @@ -236,22 +252,7 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
}
});
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);
}
});
stickersDiv.addEventListener('click', onMediaClick);
let heights: number[] = [];
@ -403,6 +404,8 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement, @@ -403,6 +404,8 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
let contentDiv = document.getElementById('content-gifs') as HTMLDivElement;
let masonry = contentDiv.firstElementChild as HTMLDivElement;
masonry.addEventListener('click', onMediaClick);
let scroll = new Scrollable(contentDiv, 'y', 500, 'GIFS', null);
scroll.container.addEventListener('scroll', (e) => {
@ -459,7 +462,7 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement, @@ -459,7 +462,7 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
let div = document.createElement('div');
div.style.width = w + 'px';
//div.style.height = h + 'px';
div.dataset.documentID = gif.id;
div.dataset.docID = gif.id;
masonry.append(div);

16
src/components/wrappers.ts

@ -596,7 +596,7 @@ function wrapMediaWithTail(photo: any, message: {mid: number, message: string}, @@ -596,7 +596,7 @@ function wrapMediaWithTail(photo: any, message: {mid: number, message: string},
return image;
}
export async function wrapPhoto(photoID: string, message: any, container: HTMLDivElement, boxWidth = 380, boxHeight = 380, withTail = true, isOut = false, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean) {
export function wrapPhoto(photoID: string, message: any, container: HTMLDivElement, boxWidth = 380, boxHeight = 380, withTail = true, isOut = false, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean) {
let photo = appPhotosManager.getPhoto(photoID);
let size: MTPhotoSize;
@ -615,6 +615,12 @@ export async function wrapPhoto(photoID: string, message: any, container: HTMLDi @@ -615,6 +615,12 @@ export async function wrapPhoto(photoID: string, message: any, container: HTMLDi
console.log('wrapPhoto downloaded:', photo, photo.downloaded, container);
// так нельзя делать, потому что может быть загружен неправильный размер картинки
/* if(photo.downloaded && photo.url) {
renderImageFromUrl(image, photo.url);
return;
} */
let preloader: ProgressivePreloader;
if(!photo.downloaded) preloader = new ProgressivePreloader(container, false);
let load = () => {
@ -625,7 +631,7 @@ export async function wrapPhoto(photoID: string, message: any, container: HTMLDi @@ -625,7 +631,7 @@ export async function wrapPhoto(photoID: string, message: any, container: HTMLDi
}
return promise.then(() => {
if(!middleware()) return;
if(middleware && !middleware()) return;
renderImageFromUrl(image, photo.url);
});
@ -680,7 +686,7 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: ( @@ -680,7 +686,7 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: (
div.append(img);
div.setAttribute('file-id', doc.id);
div.dataset.docID = doc.id;
appStickersManager.saveSticker(doc);
});
@ -778,7 +784,7 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: ( @@ -778,7 +784,7 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: (
div.append(img);
}
div.setAttribute('file-id', doc.id);
div.dataset.docID = doc.id;
appStickersManager.saveSticker(doc);
});
@ -827,7 +833,7 @@ export function wrapReply(title: string, subtitle: string, media?: any) { @@ -827,7 +833,7 @@ export function wrapReply(title: string, subtitle: string, media?: any) {
appPhotosManager.preloadPhoto(photo, appPhotosManager.choosePhotoSize(photo, 32, 32))
.then(blob => {
renderImageFromUrl(replyMedia, photo.url || URL.createObjectURL(blob));
renderImageFromUrl(replyMedia, photo._ == 'photo' ? photo.url : URL.createObjectURL(blob));
});
replyContent.append(replyMedia);

22
src/lib/appManagers/appDocsManager.ts

@ -5,19 +5,31 @@ import { CancellablePromise } from '../polyfill'; @@ -5,19 +5,31 @@ import { CancellablePromise } from '../polyfill';
import { MTDocument } from '../../components/wrappers';
class AppDocsManager {
private docs: any = {};
private docs: {[docID: string]: MTDocument} = {};
public saveDoc(apiDoc: MTDocument/* any */, context?: any) {
console.log('saveDoc', apiDoc, this.docs[apiDoc.id]);
if(this.docs[apiDoc.id]) return this.docs[apiDoc.id];
if(this.docs[apiDoc.id]) {
let d = this.docs[apiDoc.id];
this.docs[apiDoc.id] = apiDoc;
if(apiDoc.thumbs) {
if(!d.thumbs) d.thumbs = apiDoc.thumbs;
else if(apiDoc.thumbs[0].bytes && !d.thumbs[0].bytes) {
d.thumbs.unshift(apiDoc.thumbs[0]);
}
}
return context ? Object.assign(d, context) : d;
}
/* if(context) {
if(context) {
Object.assign(apiDoc, context);
} */
}
this.docs[apiDoc.id] = apiDoc;
if(apiDoc.thumb && apiDoc.thumb._ == 'photoCachedSize') {
console.warn('this will happen!!!');
apiFileManager.saveSmallFile(apiDoc.thumb.location, apiDoc.thumb.bytes);
// Memory

35
src/lib/appManagers/appImManager.ts

@ -44,7 +44,7 @@ export class AppImManager { @@ -44,7 +44,7 @@ export class AppImManager {
private getHistoryTopPromise: Promise<boolean>;
private getHistoryBottomPromise: Promise<boolean>;
private chatInputC: ChatInput = null;
public chatInputC: ChatInput = null;
public myID = 0;
public peerID = 0;
@ -158,7 +158,12 @@ export class AppImManager { @@ -158,7 +158,12 @@ export class AppImManager {
let message = appMessagesManager.getMessage(mid);
//this.log('history_update', this.bubbles[mid], mid, message);
this.renderMessage(message, false, false, bubble);
let dateMessage = this.getDateContainerByMessage(message, false);
dateMessage.container.append(bubble);
this.bubbleGroups.addBubble(bubble, message, false);
//this.renderMessage(message, false, false, bubble);
}
});
@ -191,9 +196,21 @@ export class AppImManager { @@ -191,9 +196,21 @@ export class AppImManager {
this.bubbles[mid] = bubble;
/////this.log('message_sent', bubble);
// set cached url to media
let message = appMessagesManager.getMessage(mid);
if(message.media && message.media.photo) {
let photo = appPhotosManager.getPhoto(tempID);
if(photo) {
let newPhoto = message.media.photo;
newPhoto.downloaded = photo.downloaded;
newPhoto.url = photo.url;
}
}
bubble.classList.remove('is-sending');
bubble.classList.add('is-sent');
bubble.dataset.mid = mid;
this.bubbleGroups.removeBubble(bubble, tempID);
@ -1163,7 +1180,7 @@ export class AppImManager { @@ -1163,7 +1180,7 @@ export class AppImManager {
// reverse means top
public renderMessage(message: any, reverse = false, multipleRender = false, bubble: HTMLDivElement = null, updatePosition = true) {
/////this.log('message to render:', message);
this.log('message to render:', message);
if(message.deleted) return;
let peerID = this.peerID;
@ -1323,15 +1340,9 @@ export class AppImManager { @@ -1323,15 +1340,9 @@ export class AppImManager {
switch(pending.type) {
case 'photo': {
if(pending.size < 5e6) {
let img = new Image();
img.src = URL.createObjectURL(pending.file);
let {w, h} = calcImageInBox(pending.w, pending.h, 380, 380);
attachmentDiv.style.width = w + 'px';
attachmentDiv.style.height = h + 'px';
attachmentDiv.append(img);
this.log('will wrap pending photo:', pending, message, appPhotosManager.getPhoto(message.id));
wrapPhoto(message.id, message, attachmentDiv, undefined, undefined, true, true, this.lazyLoadQueue, null);
preloader.attach(attachmentDiv, false);
bubble.classList.add('hide-name', 'photo');

2
src/lib/appManagers/appMediaViewer.ts

@ -693,7 +693,7 @@ export class AppMediaViewer { @@ -693,7 +693,7 @@ export class AppMediaViewer {
this.preloader.attach(mover);
let cancellablePromise = appPhotosManager.preloadPhoto(media.id, size);
cancellablePromise.then((blob) => {
cancellablePromise.then(() => {
if(this.currentMessageID != message.mid) {
this.log.warn('media viewer changed photo');
return;

228
src/lib/appManagers/appMessagesManager.ts

@ -14,7 +14,7 @@ import ServerTimeManager from "../mtproto/serverTimeManager"; @@ -14,7 +14,7 @@ import ServerTimeManager from "../mtproto/serverTimeManager";
import apiFileManager from "../mtproto/apiFileManager";
import appDocsManager from "./appDocsManager";
import appImManager from "./appImManager";
import { MTDocument } from "../../components/wrappers";
import { MTDocument, MTPhotoSize } from "../../components/wrappers";
import ProgressivePreloader from "../../components/preloader";
import serverTimeManager from "../mtproto/serverTimeManager";
import apiManager from "../mtproto/apiManager";
@ -37,7 +37,6 @@ export type HistoryResult = { @@ -37,7 +37,6 @@ export type HistoryResult = {
export class AppMessagesManager {
public messagesStorage: any = {};
public messagesForHistory: any = {};
public messagesForDialogs: any = {};
public historiesStorage: {
[peerID: string]: HistoryStorage
@ -107,20 +106,14 @@ export class AppMessagesManager { @@ -107,20 +106,14 @@ export class AppMessagesManager {
$rootScope.$on('webpage_updated', (e: CustomEvent) => {
let eventData = e.detail;
eventData.msgs.forEach((msgID: number) => {
var historyMessage = this.messagesForHistory[msgID];
if(historyMessage) {
historyMessage.media = {
_: 'messageMediaWebPage',
webpage: appWebPagesManager.wrapForHistory(eventData.id)
};
$rootScope.$broadcast('message_edit', {
peerID: this.getMessagePeer(historyMessage),
id: historyMessage.id,
mid: msgID,
justMedia: true
});
}
let message = this.getMessage(msgID);
message.webpage = appWebPagesManager.getWebPage(eventData.id); // warning
$rootScope.$broadcast('message_edit', {
peerID: this.getMessagePeer(message),
id: message.id,
mid: msgID,
justMedia: true
});
});
});
@ -327,17 +320,10 @@ export class AppMessagesManager { @@ -327,17 +320,10 @@ export class AppMessagesManager {
}
var toggleError = (on: any) => {
var historyMessage = this.messagesForHistory[messageID];
if(on) {
message.error = true;
if(historyMessage) {
historyMessage.error = true;
}
} else {
delete message.error;
if(historyMessage) {
delete historyMessage.error;
}
}
$rootScope.$broadcast('messages_pending');
}
@ -467,7 +453,8 @@ export class AppMessagesManager { @@ -467,7 +453,8 @@ export class AppMessagesManager {
caption?: string,
entities?: any[],
width?: number,
height?: number
height?: number,
objectURL?: string
} = {}) {
peerID = AppPeersManager.getPeerMigratedTo(peerID) || peerID;
var messageID = this.tempID--;
@ -487,6 +474,8 @@ export class AppMessagesManager { @@ -487,6 +474,8 @@ export class AppMessagesManager {
let isDocument = !(file instanceof File) && !(file instanceof Blob);
let caption = options.caption || '';
let date = tsNow(true) + ServerTimeManager.serverTimeOffset;
if(caption) {
let entities = options.entities || [];
caption = RichTextProcessor.parseMarkdown(caption, entities);
@ -497,13 +486,31 @@ export class AppMessagesManager { @@ -497,13 +486,31 @@ export class AppMessagesManager {
attachType = 'document';
apiFileName = 'document.' + fileType.split('/')[1];
actionName = 'sendMessageUploadDocumentAction';
} else if(isDocument) { // maybe it's a sticker
} else if(isDocument) { // maybe it's a sticker or gif
attachType = 'document';
apiFileName = '';
} else if(['image/jpeg', 'image/png', 'image/bmp'].indexOf(fileType) >= 0) {
attachType = 'photo';
apiFileName = 'photo.' + fileType.split('/')[1];
actionName = 'sendMessageUploadPhotoAction';
let photo: any = {
_: 'photo',
id: '' + messageID,
sizes: [{
_: 'photoSize',
w: options.width,
h: options.height,
type: 'm',
size: file.size
} as MTPhotoSize],
w: options.width,
h: options.height,
downloaded: file.size,
url: options.objectURL || ''
};
appPhotosManager.savePhoto(photo);
} else if(fileType.substr(0, 6) == 'audio/' || ['video/ogg'].indexOf(fileType) >= 0) {
attachType = 'audio';
apiFileName = 'audio.' + (fileType.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
@ -559,6 +566,7 @@ export class AppMessagesManager { @@ -559,6 +566,7 @@ export class AppMessagesManager {
preloader: preloader,
w: options.width,
h: options.height,
url: options.objectURL,
progress: {
percent: 1,
total: file.size,
@ -580,7 +588,7 @@ export class AppMessagesManager { @@ -580,7 +588,7 @@ export class AppMessagesManager {
to_id: AppPeersManager.getOutputPeer(peerID),
flags: flags,
pFlags: pFlags,
date: tsNow(true) + ServerTimeManager.serverTimeOffset,
date: date,
message: caption,
media: isDocument ? {
_: 'messageMediaDocument',
@ -595,19 +603,10 @@ export class AppMessagesManager { @@ -595,19 +603,10 @@ export class AppMessagesManager {
};
var toggleError = (on: boolean) => {
var historyMessage = this.messagesForHistory[messageID];
if(on) {
message.error = true;
if(historyMessage) {
historyMessage.error = true;
}
} else {
delete message.error;
if(historyMessage) {
delete historyMessage.error;
}
}
$rootScope.$broadcast('messages_pending');
@ -677,6 +676,8 @@ export class AppMessagesManager { @@ -677,6 +676,8 @@ export class AppMessagesManager {
}
uploadPromise && uploadPromise.then((inputFile) => {
console.log('appMessagesManager: sendFile uploaded:', inputFile);
inputFile.name = apiFileName;
uploaded = true;
var inputMedia;
@ -767,7 +768,6 @@ export class AppMessagesManager { @@ -767,7 +768,6 @@ export class AppMessagesManager {
historyStorage.pending.splice(pos, 1);
}
delete this.messagesForHistory[tempID];
delete this.messagesStorage[tempID];
return true;
@ -2177,10 +2177,6 @@ export class AppMessagesManager { @@ -2177,10 +2177,6 @@ export class AppMessagesManager {
if(message && !message.pFlags.out) {
message.pFlags.unread = false;
if(this.messagesForHistory[messageID]) {
this.messagesForHistory[messageID].pFlags.unread = false;
}
if(this.messagesForDialogs[messageID]) {
this.messagesForDialogs[messageID].pFlags.unread = false;
}
@ -2235,7 +2231,7 @@ export class AppMessagesManager { @@ -2235,7 +2231,7 @@ export class AppMessagesManager {
}
public handleUpdate(update: any) {
//console.log('AMM: handleUpdate:', update._);
console.log('AMM: handleUpdate:', update._);
switch(update._) {
case 'updateMessageID': {
var randomID = update.random_id;
@ -2252,14 +2248,8 @@ export class AppMessagesManager { @@ -2252,14 +2248,8 @@ export class AppMessagesManager {
if(pos != -1) {
historyStorage.pending.splice(pos, 1);
}
delete this.messagesForHistory[tempID];
delete this.messagesStorage[tempID];
var msgs: any = {}
msgs[tempID] = true;
//$rootScope.$broadcast('history_delete', {peerID: peerID, msgs: msgs}); // commented 11.02.2020
this.finalizePendingMessageCallbacks(tempID, mid);
} else {
this.pendingByMessageID[mid] = randomID;
@ -2489,23 +2479,11 @@ export class AppMessagesManager { @@ -2489,23 +2479,11 @@ export class AppMessagesManager {
this.saveMessages([message], {isEdited: true});
safeReplaceObject(this.messagesStorage[mid], message);
var wasForHistory = this.messagesForHistory[mid];
if(wasForHistory !== undefined) {
delete this.messagesForHistory[mid];
var newForHistory = this.wrapForHistory(mid);
safeReplaceObject(wasForHistory, newForHistory);
this.messagesForHistory[mid] = wasForHistory;
}
var dialog = this.getDialogByPeerID(peerID)[0];
var isTopMessage = dialog && dialog.top_message == mid;
if(message.clear_history) { // that's will never happen
if(isTopMessage) {
$rootScope.$broadcast('dialog_flush', {peerID: peerID});
} else {
var msgs: any = {};
msgs[mid] = true;
/////////$rootScope.$broadcast('history_delete', {peerID: peerID, msgs: msgs}); // commented 11.02.2020
}
} else {
$rootScope.$broadcast('message_edit', {
@ -2562,11 +2540,8 @@ export class AppMessagesManager { @@ -2562,11 +2540,8 @@ export class AppMessagesManager {
// console.warn('read', messageID, message.pFlags.unread, message)
if(message && message.pFlags.unread) {
message.pFlags.unread = false
if(this.messagesForHistory[messageID]) {
this.messagesForHistory[messageID].pFlags.unread = false;
if(!foundAffected) {
foundAffected = true;
}
if(!foundAffected) {
foundAffected = true;
}
if(this.messagesForDialogs[messageID]) {
this.messagesForDialogs[messageID].pFlags.unread = false;
@ -2614,15 +2589,11 @@ export class AppMessagesManager { @@ -2614,15 +2589,11 @@ export class AppMessagesManager {
var len = messages.length;
var i;
var messageID: number, message;
var historyMessage;
for(i = 0; i < len; i++) {
messageID = messages[i];
if(message = this.messagesStorage[messageID]) {
delete message.pFlags.media_unread;
}
if(historyMessage = this.messagesForHistory[messageID]) {
delete historyMessage.pFlags.media_unread;
}
}
break;
}
@ -2668,10 +2639,6 @@ export class AppMessagesManager { @@ -2668,10 +2639,6 @@ export class AppMessagesManager {
history.count++;
history.msgs[messageID] = true;
if(this.messagesForHistory[messageID]) {
this.messagesForHistory[messageID].deleted = true;
delete this.messagesForHistory[messageID];
}
if(this.messagesForDialogs[messageID]) {
this.messagesForDialogs[messageID].deleted = true;
delete this.messagesForDialogs[messageID];
@ -2842,7 +2809,6 @@ export class AppMessagesManager { @@ -2842,7 +2809,6 @@ export class AppMessagesManager {
});
}
if(update.pFlags.popup && update.message) {
var historyMessage = this.wrapForHistory(messageID);
//ErrorService.show({error: {code: 400, type: 'UPDATE_SERVICE_NOTIFICATION'}, historyMessage: historyMessage}); // warning
}
break;
@ -2850,106 +2816,6 @@ export class AppMessagesManager { @@ -2850,106 +2816,6 @@ export class AppMessagesManager {
}
}
public wrapForHistory(msgID: number) {
if(this.messagesForHistory[msgID] !== undefined) {
return this.messagesForHistory[msgID];
}
var message = copy(this.messagesStorage[msgID]) || {id: msgID};
if(message.media && message.media.progress !== undefined) {
message.media.progress = this.messagesStorage[msgID].media.progress;
}
var fromUser = message.from_id && appUsersManager.getUser(message.from_id);
var fromBot = fromUser && fromUser.pFlags.bot && fromUser.username || false;
var withBot = (fromBot ||
message.to_id && (
message.to_id.chat_id ||
message.to_id.user_id && appUsersManager.isBot(message.to_id.user_id)
)
)
if(message.media) {
if(message.media.caption &&
message.media.caption.length) {
message.media.rCaption = RichTextProcessor.wrapRichText(message.media.caption, {
noCommands: !withBot,
fromBot: fromBot
})
}
switch (message.media._) {
case 'messageMediaPhoto':
message.media.photo = appPhotosManager.wrapForHistory(message.media.photo.id)
break
/* case 'messageMediaDocument':
message.media.document = appDocsManager.wrapForHistory(message.media.document.id)
break */
case 'messageMediaGeo':
var mapUrl = 'https://maps.google.com/?q=' + message.media.geo['lat'] + ',' + message.media.geo['long']
message.media.mapUrl = mapUrl;//$sce.trustAsResourceUrl(mapUrl) // warning
break
case 'messageMediaVenue':
var mapUrl: string;
if(message.media.provider == 'foursquare' &&
message.media.venue_id) {
mapUrl = 'https://foursquare.com/v/' + encodeURIComponent(message.media.venue_id)
} else {
mapUrl = 'https://maps.google.com/?q=' + message.media.geo['lat'] + ',' + message.media.geo['long']
}
message.media.mapUrl = mapUrl;//$sce.trustAsResourceUrl(mapUrl) // warning
break
case 'messageMediaContact':
message.media.rFullName = RichTextProcessor.wrapRichText(
message.media.first_name + ' ' + (message.media.last_name || ''),
{noLinks: true, noLinebreaks: true}
)
break
case 'messageMediaWebPage':
if(!message.media.webpage ||
message.media.webpage._ == 'webPageEmpty') {
delete message.media
break
}
message.media.webpage = appWebPagesManager.wrapForHistory(message.media.webpage.id)
break
/*case 'messageMediaGame':
message.media.game = AppGamesManager.wrapForHistory(message.media.game.id)
break */
}
} else if(message.action) {
switch (message.action._) {
case 'messageActionChatEditPhoto':
case 'messageActionChannelEditPhoto':
message.action.photo = appPhotosManager.wrapForHistory(message.action.photo.id);
break
case 'messageActionChatCreate':
case 'messageActionChatEditTitle':
case 'messageActionChannelCreate':
case 'messageActionChannelEditTitle':
message.action.rTitle = RichTextProcessor.wrapRichText(message.action.title, {noLinebreaks: true}) || 'chat_title_deleted';
break
case 'messageActionBotIntro':
message.action.rDescription = RichTextProcessor.wrapRichText(message.action.description, {
noCommands: !withBot,
fromBot: fromBot
});
break;
}
}
return this.messagesForHistory[msgID] = message;
}
public finalizePendingMessage(randomID: number, finalMessage: any) {
var pendingData = this.pendingByRandomID[randomID];
// console.log('pdata', randomID, pendingData)
@ -2958,8 +2824,7 @@ export class AppMessagesManager { @@ -2958,8 +2824,7 @@ export class AppMessagesManager {
var peerID = pendingData[0];
var tempID = pendingData[1];
var historyStorage = this.historiesStorage[peerID],
message,
historyMessage;
message;
// console.log('pending', randomID, historyStorage.pending)
var pos = historyStorage.pending.indexOf(tempID);
@ -2972,19 +2837,10 @@ export class AppMessagesManager { @@ -2972,19 +2837,10 @@ export class AppMessagesManager {
delete message.error;
delete message.random_id;
delete message.send;
}
if(historyMessage = this.messagesForHistory[tempID]) {
this.messagesForHistory[finalMessage.mid] = Object.assign(historyMessage, this.wrapForHistory(finalMessage.mid));
delete historyMessage.pending;
delete historyMessage.error;
delete historyMessage.random_id;
delete historyMessage.send;
$rootScope.$broadcast('messages_pending');
}
delete this.messagesForHistory[tempID];
delete this.messagesStorage[tempID];
this.finalizePendingMessageCallbacks(tempID, finalMessage.mid);
@ -2995,10 +2851,6 @@ export class AppMessagesManager { @@ -2995,10 +2851,6 @@ export class AppMessagesManager {
return false
}
/* public finalizePendingMessageCallbacks(tempID: number, mid: number) {
$rootScope.$broadcast('message_sent', {tempID, mid});
} */
public finalizePendingMessageCallbacks(tempID: number, mid: number) {
var callbacks = this.tempFinalizeCallbacks[tempID];
console.warn(dT(), callbacks, tempID);

129
src/lib/appManagers/appPhotosManager.ts

@ -1,12 +1,12 @@ @@ -1,12 +1,12 @@
import appUsersManager from "./appUsersManager";
import { copy, calcImageInBox } from "../utils";
import { calcImageInBox, isObject } from "../utils";
import fileManager from '../filemanager';
import { bytesFromHex } from "../bin_utils";
import { MTPhotoSize, MTDocument } from "../../components/wrappers";
import { MTPhotoSize } from "../../components/wrappers";
import apiFileManager from "../mtproto/apiFileManager";
import apiManager from "../mtproto/apiManager";
type MTPhoto = {
export type MTPhoto = {
_: 'photo' | 'photoEmpty' | string,
pFlags: any,
flags: number,
@ -51,7 +51,7 @@ export class AppPhotosManager { @@ -51,7 +51,7 @@ export class AppPhotosManager {
if(!photo.id) {
console.warn('no apiPhoto.id', photo);
} else this.photos[photo.id] = photo;
} else this.photos[photo.id] = photo as any;
/* if(!('sizes' in photo)) return;
@ -241,98 +241,61 @@ export class AppPhotosManager { @@ -241,98 +241,61 @@ export class AppPhotosManager {
return photoSize;
}
public preloadPhoto(photoID: any, photoSize?: MTPhotoSize): Promise<Blob | string> {
let photo: MTPhoto = null;
if(typeof(photoID) === 'string') {
photo = this.photos[photoID];
if(!photo) return Promise.reject();
} else {
photo = photoID;
}
public preloadPhoto(photoID: any, photoSize?: MTPhotoSize): Promise<Blob | void> {
let photo = this.getPhoto(photoID);
if(!photoSize) {
let fullWidth = this.windowW/* - (Config.Mobile ? 20 : 32) */;
let fullHeight = this.windowH/* - (Config.Mobile ? 150 : 116) */;
let fullWidth = this.windowW;
let fullHeight = this.windowH;
photoSize = this.choosePhotoSize(photo, fullWidth, fullHeight);
}
if(photoSize && photoSize._ != 'photoSizeEmpty') {
// maybe it's a thumb
let isPhoto = photoSize.size && photo.access_hash && photo.file_reference;
let location = isPhoto ? {
_: photo._ == 'document' ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation',
id: photo.id,
access_hash: photo.access_hash,
file_reference: photo.file_reference,
thumb_size: photoSize.type
} : photoSize.location;
let promise: Promise<Blob>;
if(photo.downloaded >= photoSize.size && photo.url) {
return Promise.resolve();
}
/* if(photo.downloaded == photoSize.size && photo.url) {
return Promise.resolve(photo.url);
} */
if(!photoSize || photoSize._ == 'photoSizeEmpty') {
console.error('no photoSize by photo:', photo);
return Promise.reject('no photoSize');
}
// maybe it's a thumb
let isPhoto = photoSize.size && photo.access_hash && photo.file_reference;
let location = isPhoto ? {
_: photo._ == 'document' ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation',
id: photo.id,
access_hash: photo.access_hash,
file_reference: photo.file_reference,
thumb_size: photoSize.type
} : photoSize.location;
if(isPhoto/* && photoSize.size >= 1e6 */) {
//console.log('Photos downloadFile exec', photo);
promise = apiFileManager.downloadFile(photo.dc_id, location, photoSize.size);
} else {
//console.log('Photos downloadSmallFile exec', photo, location);
promise = apiFileManager.downloadSmallFile(location);
}
let promise: Promise<Blob>;
if(isPhoto/* && photoSize.size >= 1e6 */) {
//console.log('Photos downloadFile exec', photo);
promise = apiFileManager.downloadFile(photo.dc_id, location, photoSize.size);
} else {
//console.log('Photos downloadSmallFile exec', photo, location);
promise = apiFileManager.downloadSmallFile(location);
}
if(typeof(photoID) === 'string') {
let photo = this.photos[photoID];
promise.then(blob => {
if(!photo.downloaded || photo.downloaded < blob.size) {
photo.downloaded = blob.size;
photo.url = URL.createObjectURL(blob);
if(typeof(photoID) === 'string') {
let photo = this.photos[photoID];
promise.then(blob => {
if(!photo.downloaded || photo.downloaded < blob.size) {
photo.downloaded = blob.size;
photo.url = URL.createObjectURL(blob);
console.log('wrote photo:', photo, photoSize, blob);
}
});
}
console.log('wrote photo:', photo, photoSize, blob);
}
});
}
return promise;
} else return Promise.reject('no photoSize');
}
public getPhoto(photoID: string) {
return this.photos[photoID] || {_: 'photoEmpty'} as unknown as Partial<MTPhoto>;
return promise;
}
public wrapForHistory(photoID: string, options: any = {}) {
var photo = copy(this.photos[photoID]) || {_: 'photoEmpty'};
var width = options.website ? 64 : Math.min(this.windowW - 80, Config.Mobile ? 210 : 260);
var height = options.website ? 64 : Math.min(this.windowH - 100, Config.Mobile ? 210 : 260);
var thumbPhotoSize = this.choosePhotoSize(photo, width, height);
var thumb: any = {
width: width,
height: height
};
if(options.website && Config.Mobile) {
width = 50;
height = 50;
}
// console.log('chosen photo size', photoID, thumbPhotoSize)
if(thumbPhotoSize && thumbPhotoSize._ != 'photoSizeEmpty') {
var dim = calcImageInBox(thumbPhotoSize.w, thumbPhotoSize.h, width, height);
thumb.width = dim.w;
thumb.height = dim.h;
thumb.location = thumbPhotoSize.location;
thumb.size = thumbPhotoSize.size;
} else {
thumb.width = 100;
thumb.height = 100;
}
photo.thumb = thumb;
return photo;
public getPhoto(photoID: any): MTPhoto {
return isObject(photoID) ? photoID : this.photos[photoID];
}
public downloadPhoto(photoID: string) {

9
src/lib/appManagers/appSidebarRight.ts

@ -348,19 +348,14 @@ class AppSidebarRight { @@ -348,19 +348,14 @@ class AppSidebarRight {
//this.log('wrapping webpage', webpage);
if(webpage.photo) {
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 380, 0))
.then((blob) => {
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 60, 60))
.then(() => {
if($rootScope.selectedPeerID != peerID) {
this.log.warn('peer changed');
return;
}
renderImageFromUrl(previewDiv, webpage.photo.url);
/* let url = URL.createObjectURL(blob);
this.urlsToRevoke.push(url);
previewDiv.style.backgroundImage = 'url(' + url + ')'; */
});
this.lazyLoadQueueSidebar.push({div: previewDiv, load});

2
src/lib/appManagers/appStickersManager.ts

@ -81,7 +81,7 @@ class appStickersManager { @@ -81,7 +81,7 @@ class appStickersManager {
doc.file_reference = Array.from(doc.file_reference);
appDocsManager.saveDoc(doc);
doc = appDocsManager.saveDoc(doc);
this.documents[doc.id] = doc;
return doc;

16
src/lib/appManagers/appWebPagesManager.ts

@ -19,7 +19,7 @@ class AppWebPagesManager { @@ -19,7 +19,7 @@ class AppWebPagesManager {
});
}
saveWebPage(apiWebPage: any, messageID?: number, mediaContext?: any) {
public saveWebPage(apiWebPage: any, messageID?: number, mediaContext?: any) {
if(apiWebPage.photo && apiWebPage.photo._ === 'photo') {
//appPhotosManager.savePhoto(apiWebPage.photo, mediaContext);
apiWebPage.photo = appPhotosManager.savePhoto(apiWebPage.photo, mediaContext);
@ -102,19 +102,9 @@ class AppWebPagesManager { @@ -102,19 +102,9 @@ class AppWebPagesManager {
});
}
}
wrapForHistory(webPageID: number) {
var webPage = copy(this.webpages[webPageID]) || {_: 'webPageEmpty'};
if(webPage.photo && webPage.photo.id) {
webPage.photo = appPhotosManager.wrapForHistory(webPage.photo.id, {website: webPage.type != 'photo' && webPage.type != 'video'});
}
/* if (webPage.document && webPage.document.id) {
webPage.document = appDocsManager.wrapForHistory(webPage.document.id)
} */ // warning
return webPage;
public getWebPage(id: string) {
return this.webpages[id];
}
}

2
src/pages/pageIm.ts

@ -42,6 +42,8 @@ let onFirstMount = () => import('../lib/appManagers/appImManager').then(() => {/ @@ -42,6 +42,8 @@ let onFirstMount = () => import('../lib/appManagers/appImManager').then(() => {/
toggleEmoticons.classList.toggle('active');
}; */
import('../lib/services');
(Array.from(document.getElementsByClassName('rp')) as HTMLElement[]).forEach(el => ripple(el));
Array.from(document.getElementsByClassName('btn-menu-toggle')).forEach((el) => {

4
src/scss/partials/_chat.scss

@ -476,6 +476,10 @@ $chat-max-width: 696px; @@ -476,6 +476,10 @@ $chat-max-width: 696px;
.attachment {
max-width: 200px;
max-height: 200px;
img {
border-radius: 50%;
}
}
}

2
src/scss/partials/_emojiDropdown.scss

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
overflow: hidden;
transition: all 0.2s ease-out;
//transform: scale(0);
transform: scale(0);
transform-origin: 0 100%;
&.active {

1
tsconfig.json

@ -66,6 +66,7 @@ @@ -66,6 +66,7 @@
"public",
"coverage",
"./src/lib/ckin.js",
"./src/lib/config.js",
"./src/lib/StackBlur.js",
"./src/lib/*.js",
"./src/*.js",

Loading…
Cancel
Save