Refactor message ids
Refactor message storage Handle scheduled messages updates
This commit is contained in:
parent
bdefbcfa41
commit
8330fd2774
@ -34,7 +34,7 @@ class AppMediaPlaybackController {
|
||||
document.body.append(this.container);
|
||||
}
|
||||
|
||||
public addMedia(doc: MyDocument, mid: number, autoload = true): HTMLMediaElement {
|
||||
public addMedia(peerId: number, doc: MyDocument, mid: number, autoload = true): HTMLMediaElement {
|
||||
if(this.media[mid]) return this.media[mid];
|
||||
|
||||
const media = document.createElement(doc.type == 'round' ? 'video' : 'audio');
|
||||
@ -61,12 +61,12 @@ class AppMediaPlaybackController {
|
||||
}
|
||||
|
||||
this.playingMedia = media;
|
||||
this.loadSiblingsMedia(doc.type as MediaType, mid);
|
||||
this.loadSiblingsMedia(peerId, doc.type as MediaType, mid);
|
||||
}
|
||||
|
||||
// audio_pause не успеет сработать без таймаута
|
||||
setTimeout(() => {
|
||||
rootScope.broadcast('audio_play', {doc, mid});
|
||||
rootScope.broadcast('audio_play', {peerId, doc, mid});
|
||||
}, 0);
|
||||
});
|
||||
|
||||
@ -75,7 +75,7 @@ class AppMediaPlaybackController {
|
||||
|
||||
const onError = (e: Event) => {
|
||||
if(this.nextMid == mid) {
|
||||
this.loadSiblingsMedia(doc.type as MediaType, mid).then(() => {
|
||||
this.loadSiblingsMedia(peerId, doc.type as MediaType, mid).then(() => {
|
||||
if(this.nextMid && this.media[this.nextMid]) {
|
||||
this.media[this.nextMid].play();
|
||||
}
|
||||
@ -181,12 +181,11 @@ class AppMediaPlaybackController {
|
||||
}
|
||||
};
|
||||
|
||||
private loadSiblingsMedia(type: MediaType, mid: number) {
|
||||
private loadSiblingsMedia(peerId: number, type: MediaType, mid: number) {
|
||||
const media = this.playingMedia;
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
this.prevMid = this.nextMid = 0;
|
||||
|
||||
return appMessagesManager.getSearch(message.peerId, '', {
|
||||
return appMessagesManager.getSearch(peerId, '', {
|
||||
//_: type == 'audio' ? 'inputMessagesFilterMusic' : (type == 'round' ? 'inputMessagesFilterRoundVideo' : 'inputMessagesFilterVoice')
|
||||
_: type == 'audio' ? 'inputMessagesFilterMusic' : 'inputMessagesFilterRoundVoice'
|
||||
}, mid, 3, 0, 2).then(value => {
|
||||
@ -204,8 +203,8 @@ class AppMediaPlaybackController {
|
||||
}
|
||||
|
||||
[this.prevMid, this.nextMid].filter(Boolean).forEach(mid => {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
this.addMedia(message.media.document, mid, false);
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, mid);
|
||||
this.addMedia(peerId, message.media.document, mid, false);
|
||||
});
|
||||
|
||||
//console.log('loadSiblingsAudio', audio, type, mid, value, this.prevMid, this.nextMid);
|
||||
|
@ -1165,18 +1165,18 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
||||
|
||||
onPrevClick = (target: AppMediaViewerTargetType) => {
|
||||
this.nextTargets.unshift({element: this.lastTarget, mid: this.currentMessageId});
|
||||
this.openMedia(appMessagesManager.getMessage(target.mid), target.element);
|
||||
this.openMedia(appMessagesManager.getMessageByPeer(this.peerId, target.mid), target.element);
|
||||
};
|
||||
|
||||
onNextClick = (target: AppMediaViewerTargetType) => {
|
||||
this.prevTargets.push({element: this.lastTarget, mid: this.currentMessageId});
|
||||
this.openMedia(appMessagesManager.getMessage(target.mid), target.element);
|
||||
this.openMedia(appMessagesManager.getMessageByPeer(this.peerId, target.mid), target.element);
|
||||
};
|
||||
|
||||
onForwardClick = () => {
|
||||
if(this.currentMessageId) {
|
||||
//appSidebarRight.forwardTab.open([this.currentMessageId]);
|
||||
new PopupForward([this.currentMessageId], () => {
|
||||
new PopupForward(this.peerId, [this.currentMessageId], () => {
|
||||
return this.close();
|
||||
});
|
||||
}
|
||||
@ -1192,14 +1192,14 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
||||
appSidebarRight.sharedMediaTab.closeBtn.click();
|
||||
}
|
||||
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = appMessagesManager.getMessageByPeer(this.peerId, mid);
|
||||
appImManager.setPeer(message.peerId, mid);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onDownloadClick = () => {
|
||||
const message = appMessagesManager.getMessage(this.currentMessageId);
|
||||
const message = appMessagesManager.getMessageByPeer(this.peerId, this.currentMessageId);
|
||||
if(message.media.photo) {
|
||||
appPhotosManager.savePhotoFile(message.media.photo, appImManager.chat.bubbles.lazyLoadQueue.queueId);
|
||||
} else {
|
||||
@ -1262,7 +1262,7 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
||||
|
||||
const method = older ? value.history.forEach : value.history.forEachReverse;
|
||||
method.call(value.history, mid => {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = appMessagesManager.getMessageByPeer(this.peerId, mid);
|
||||
const media = this.getMediaFromMessage(message);
|
||||
|
||||
if(!media) return;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import appDialogsManager from "../lib/appManagers/appDialogsManager";
|
||||
import Scrollable from "./scrollable";
|
||||
import appMessagesIdsManager from "../lib/appManagers/appMessagesIdsManager";
|
||||
import appUsersManager from "../lib/appManagers/appUsersManager";
|
||||
import appPeersManager from '../lib/appManagers/appPeersManager';
|
||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||
@ -157,7 +156,7 @@ export default class AppSearch {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const maxId = appMessagesIdsManager.getMessageIdInfo(this.minMsgId)[0] || 0;
|
||||
const maxId = this.minMsgId || 0;
|
||||
|
||||
if(!this.peerId && !maxId && !this.loadedContacts) {
|
||||
const renderedPeerIds: Set<number> = new Set();
|
||||
@ -259,7 +258,7 @@ export default class AppSearch {
|
||||
const searchGroup = this.searchGroups.messages;
|
||||
|
||||
history.forEach((msgId: number) => {
|
||||
const message = appMessagesManager.getMessage(msgId);
|
||||
const message = appMessagesManager.getMessageByPeer(this.peerId, msgId);
|
||||
|
||||
const {dialog, dom} = appDialogsManager.addDialogNew({
|
||||
dialog: message.peerId,
|
||||
|
@ -14,10 +14,10 @@ import './middleEllipsis';
|
||||
import { attachClickEvent, cancelEvent, detachClickEvent } from "../helpers/dom";
|
||||
|
||||
rootScope.on('messages_media_read', e => {
|
||||
const mids = e.detail;
|
||||
const {mids, peerId} = e.detail;
|
||||
|
||||
mids.forEach(mid => {
|
||||
(Array.from(document.querySelectorAll('audio-element[message-id="' + mid + '"]')) as AudioElement[]).forEach(elem => {
|
||||
(Array.from(document.querySelectorAll('audio-element[message-id="' + mid + '"][peer-id="' + peerId + '"]')) as AudioElement[]).forEach(elem => {
|
||||
//console.log('updating avatar:', elem);
|
||||
elem.classList.remove('is-unread');
|
||||
});
|
||||
@ -61,10 +61,10 @@ export function decodeWaveform(waveform: Uint8Array | number[]) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function wrapVoiceMessage(doc: MyDocument, audioEl: AudioElement, mid: number) {
|
||||
function wrapVoiceMessage(peerId: number, doc: MyDocument, audioEl: AudioElement, mid: number) {
|
||||
audioEl.classList.add('is-voice');
|
||||
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, mid);
|
||||
const isOut = message.fromId == rootScope.myId && message.peerId != rootScope.myId;
|
||||
let isUnread = message && message.pFlags.media_unread;
|
||||
if(isUnread) {
|
||||
@ -171,7 +171,7 @@ function wrapVoiceMessage(doc: MyDocument, audioEl: AudioElement, mid: number) {
|
||||
audioEl.addAudioListener('playing', () => {
|
||||
if(isUnread && !isOut && audioEl.classList.contains('is-unread')) {
|
||||
audioEl.classList.remove('is-unread');
|
||||
appMessagesManager.readMessages([mid]);
|
||||
appMessagesManager.readMessages(peerId, [mid]);
|
||||
isUnread = false;
|
||||
}
|
||||
|
||||
@ -329,6 +329,7 @@ export default class AudioElement extends HTMLElement {
|
||||
|
||||
this.classList.add('audio');
|
||||
|
||||
const peerId = +this.getAttribute('peer-id');
|
||||
const mid = +this.getAttribute('message-id');
|
||||
const docId = this.getAttribute('doc-id');
|
||||
const doc = appDocsManager.getDoc(docId);
|
||||
@ -351,13 +352,13 @@ export default class AudioElement extends HTMLElement {
|
||||
this.append(downloadDiv);
|
||||
}
|
||||
|
||||
const onTypeLoad = doc.type == 'voice' ? wrapVoiceMessage(doc, this, mid) : wrapAudio(doc, this);
|
||||
const onTypeLoad = doc.type == 'voice' ? wrapVoiceMessage(peerId, doc, this, mid) : wrapAudio(doc, this);
|
||||
|
||||
const audioTimeDiv = this.querySelector('.audio-time') as HTMLDivElement;
|
||||
audioTimeDiv.innerHTML = durationStr;
|
||||
|
||||
const onLoad = (autoload = true) => {
|
||||
const audio = this.audio = appMediaPlaybackController.addMedia(doc, mid, autoload);
|
||||
const audio = this.audio = appMediaPlaybackController.addMedia(peerId, doc, mid, autoload);
|
||||
|
||||
this.onTypeDisconnect = onTypeLoad();
|
||||
|
||||
|
@ -57,7 +57,7 @@ export default class AvatarElement extends HTMLElement {
|
||||
|
||||
if(mid) {
|
||||
// ! гений в деле, костылируем (но это гениально)
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
let message = appMessagesManager.getMessageByPeer(peerId, mid);
|
||||
const messagePhoto = message.action.photo;
|
||||
if(messagePhoto.id != photo.id) {
|
||||
message = {
|
||||
@ -72,7 +72,7 @@ export default class AvatarElement extends HTMLElement {
|
||||
fromId: peerId
|
||||
};
|
||||
|
||||
appMessagesManager.messagesStorage[maxId] = message;
|
||||
appMessagesManager.getMessagesStorage(peerId)[maxId] = message;
|
||||
}
|
||||
|
||||
const good = Array.from(this.querySelectorAll('img')).find(img => !img.classList.contains('emoji'));
|
||||
|
@ -35,10 +35,10 @@ export default class ChatAudio extends PinnedContainer {
|
||||
this.wrapper.prepend(this.toggleEl);
|
||||
|
||||
this.topbar.listenerSetter.add(rootScope, 'audio_play', (e) => {
|
||||
const {doc, mid} = e.detail;
|
||||
const {doc, mid, peerId} = e.detail;
|
||||
|
||||
let title: string, subtitle: string;
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, mid);
|
||||
if(doc.type == 'voice' || doc.type == 'round') {
|
||||
title = appPeersManager.getPeerTitle(message.fromId, false, true);
|
||||
//subtitle = 'Voice message';
|
||||
|
@ -35,7 +35,6 @@ import LazyLoadQueue from "../lazyLoadQueue";
|
||||
import { AppChatsManager } from "../../lib/appManagers/appChatsManager";
|
||||
import Chat from "./chat";
|
||||
import ListenerSetter from "../../helpers/listenerSetter";
|
||||
import { pause } from "../../helpers/schedulers";
|
||||
|
||||
const IGNORE_ACTIONS = ['messageActionHistoryClear'];
|
||||
|
||||
@ -148,7 +147,7 @@ export default class ChatBubbles {
|
||||
let bubble = this.bubbles[mid];
|
||||
if(!bubble) return;
|
||||
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
let message = this.chat.getMessage(mid);
|
||||
//this.log('history_update', this.bubbles[mid], mid, message);
|
||||
|
||||
let dateMessage = this.getDateContainerByMessage(message, false);
|
||||
@ -196,7 +195,7 @@ export default class ChatBubbles {
|
||||
|
||||
this.log('message_sent', e.detail);
|
||||
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.chat.getMessage(mid);
|
||||
|
||||
appSidebarRight.sharedMediaTab.renderNewMessages(message.peerId, [mid]);
|
||||
|
||||
@ -282,7 +281,7 @@ export default class ChatBubbles {
|
||||
if(!this.bubbles[maxId]) return;
|
||||
|
||||
const renderMaxId = getObjectKeysAndSort(appMessagesManager.groupedMessagesStorage[groupId], 'asc').pop();
|
||||
this.renderMessage(appMessagesManager.getMessage(renderMaxId), true, false, this.bubbles[maxId], false);
|
||||
this.renderMessage(this.chat.getMessage(renderMaxId), true, false, this.bubbles[maxId], false);
|
||||
});
|
||||
|
||||
this.listenerSetter.add(rootScope, 'messages_downloaded', (e) => {
|
||||
@ -301,9 +300,9 @@ export default class ChatBubbles {
|
||||
const bubble = this.bubbles[mid];
|
||||
if(!bubble) return;
|
||||
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = this.chat.getMessage(mid);
|
||||
|
||||
const repliedMessage = appMessagesManager.getMessage(replyMid);
|
||||
const repliedMessage = this.chat.getMessage(replyMid);
|
||||
if(repliedMessage.deleted) { // чтобы не пыталось бесконечно загрузить удалённое сообщение
|
||||
delete message.reply_to_mid; // WARNING!
|
||||
}
|
||||
@ -321,10 +320,14 @@ export default class ChatBubbles {
|
||||
}
|
||||
});
|
||||
|
||||
this.listenerSetter.add(this.bubblesContainer, 'click', this.onBubblesClick/* , {capture: true, passive: false} */);
|
||||
}
|
||||
|
||||
public constructPeerHelpers() {
|
||||
this.listenerSetter.add(rootScope, 'dialog_unread', (e) => {
|
||||
const info = e.detail;
|
||||
|
||||
const dialog = appMessagesManager.getDialogByPeerId(info.peerId)[0];
|
||||
const dialog = this.appMessagesManager.getDialogByPeerId(info.peerId)[0];
|
||||
if(dialog?.peerId == this.peerId) {
|
||||
this.chat.input.setUnreadCount();
|
||||
this.updateUnreadByDialog(dialog);
|
||||
@ -347,8 +350,6 @@ export default class ChatBubbles {
|
||||
}
|
||||
});
|
||||
|
||||
this.listenerSetter.add(this.bubblesContainer, 'click', this.onBubblesClick/* , {capture: true, passive: false} */);
|
||||
|
||||
this.stickyIntersector = new StickyIntersector(this.scrollable.container, (stuck, target) => {
|
||||
for(const timestamp in this.dateMessages) {
|
||||
const dateMessage = this.dateMessages[timestamp];
|
||||
@ -395,9 +396,9 @@ export default class ChatBubbles {
|
||||
} */
|
||||
|
||||
//appMessagesManager.readMessages(readed);
|
||||
/* false && */ appMessagesManager.readHistory(this.peerId, max).catch((err: any) => {
|
||||
/* false && */ this.appMessagesManager.readHistory(this.peerId, max).catch((err: any) => {
|
||||
this.log.error('readHistory err:', err);
|
||||
appMessagesManager.readHistory(this.peerId, max);
|
||||
this.appMessagesManager.readHistory(this.peerId, max);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -406,7 +407,6 @@ export default class ChatBubbles {
|
||||
public constructPinnedHelpers() {
|
||||
this.listenerSetter.add(rootScope, 'peer_pinned_messages', (e) => {
|
||||
const {peerId, mids, pinned} = e.detail;
|
||||
|
||||
if(peerId !== this.peerId) return;
|
||||
|
||||
if(mids) {
|
||||
@ -417,6 +417,15 @@ export default class ChatBubbles {
|
||||
});
|
||||
}
|
||||
|
||||
public constructScheduledHelpers() {
|
||||
this.listenerSetter.add(rootScope, 'scheduled_delete', (e) => {
|
||||
const {peerId, mids} = e.detail;
|
||||
if(peerId !== this.peerId) return;
|
||||
|
||||
this.deleteMessagesByIds(mids);
|
||||
});
|
||||
}
|
||||
|
||||
public onBubblesClick = (e: Event) => {
|
||||
let target = e.target as HTMLElement;
|
||||
let bubble: HTMLElement = null;
|
||||
@ -479,7 +488,7 @@ export default class ChatBubbles {
|
||||
|
||||
if(bubble.classList.contains('sticker') && target.parentElement.classList.contains('attachment')) {
|
||||
const messageId = +bubble.dataset.mid;
|
||||
const message = this.appMessagesManager.getMessage(messageId);
|
||||
const message = this.chat.getMessage(messageId);
|
||||
|
||||
const doc = message.media?.document;
|
||||
|
||||
@ -495,7 +504,7 @@ export default class ChatBubbles {
|
||||
|| isVideoComponentElement
|
||||
|| (target.tagName == 'VIDEO' && !bubble.classList.contains('round'))) {
|
||||
let messageId = +findUpClassName(target, 'album-item')?.dataset.mid || +bubble.dataset.mid;
|
||||
let message = this.appMessagesManager.getMessage(messageId);
|
||||
let message = this.chat.getMessage(messageId);
|
||||
if(!message) {
|
||||
this.log.warn('no message by messageId:', messageId);
|
||||
return;
|
||||
@ -505,7 +514,7 @@ export default class ChatBubbles {
|
||||
let ids = Object.keys(this.bubbles).map(k => +k).filter(id => {
|
||||
//if(!this.scrollable.visibleElements.find(e => e.element == this.bubbles[id])) return false;
|
||||
|
||||
let message = this.appMessagesManager.getMessage(id);
|
||||
let message = this.chat.getMessage(id);
|
||||
|
||||
return message.media && (message.media.photo || (message.media.document && (message.media.document.type == 'video' || message.media.document.type == 'gif')) || (message.media.webpage && (message.media.webpage.document || message.media.webpage.photo)));
|
||||
}).sort((a, b) => a - b);
|
||||
@ -548,9 +557,9 @@ export default class ChatBubbles {
|
||||
return;
|
||||
}
|
||||
|
||||
if(['IMG', 'DIV', "AVATAR-ELEMENT", 'A'].indexOf(target.tagName) === -1) target = findUpTag(target, 'DIV');
|
||||
if(['IMG', 'DIV', "AVATAR-ELEMENT"/* , 'A' */].indexOf(target.tagName) === -1) target = findUpTag(target, 'DIV');
|
||||
|
||||
if(target.tagName == 'DIV' || target.tagName == "AVATAR-ELEMENT" || target.tagName == 'A') {
|
||||
if(target.tagName == 'DIV' || target.tagName == "AVATAR-ELEMENT"/* || target.tagName == 'A' */) {
|
||||
if(target.classList.contains('goto-original')) {
|
||||
const savedFrom = bubble.dataset.savedFrom;
|
||||
const splitted = savedFrom.split('_');
|
||||
@ -561,25 +570,10 @@ export default class ChatBubbles {
|
||||
return;
|
||||
} else if(target.classList.contains('forward')) {
|
||||
const mid = +bubble.dataset.mid;
|
||||
new PopupForward([mid]);
|
||||
new PopupForward(this.peerId, [mid]);
|
||||
//appSidebarRight.forwardTab.open([mid]);
|
||||
return;
|
||||
}/* else if(target.classList.contains('follow')) {
|
||||
cancelEvent(e);
|
||||
const savedFrom = target.dataset.follow;
|
||||
const splitted = savedFrom.split('_');
|
||||
this.chat.appImManager.setInnerPeer(+splitted[0], splitted.length > 1 ? +splitted[1] : undefined);
|
||||
|
||||
return;
|
||||
} else if(target.classList.contains('mention')) {
|
||||
cancelEvent(e);
|
||||
const username = target.innerText;
|
||||
this.appUsersManager.resolveUsername(username.slice(1)).then(peer => {
|
||||
this.chat.appImManager.setInnerPeer(peer._ == 'user' ? peer.id : -peer.id);
|
||||
});
|
||||
|
||||
return;
|
||||
} */ else if(target.classList.contains('name')) {
|
||||
} else if(target.classList.contains('name')) {
|
||||
const peerId = +target.dataset.peerId;
|
||||
|
||||
if(peerId) {
|
||||
@ -628,7 +622,7 @@ export default class ChatBubbles {
|
||||
const rect = bubble.getBoundingClientRect();
|
||||
bad = (this.appPhotosManager.windowH / 2) > rect.top;
|
||||
} else {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.chat.getMessage(mid);
|
||||
if(!message.deleted) {
|
||||
bad = false;
|
||||
}
|
||||
@ -661,7 +655,7 @@ export default class ChatBubbles {
|
||||
if(this.bubbles[mid]) {
|
||||
return {
|
||||
bubble: this.bubbles[mid],
|
||||
message: this.appMessagesManager.getMessage(+mid)
|
||||
message: this.chat.getMessage(+mid)
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -674,7 +668,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
public getMountedBubble(mid: number) {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.chat.getMessage(mid);
|
||||
|
||||
if(message.grouped_id && this.appMessagesManager.getMidsByAlbum(message.grouped_id).length > 1) {
|
||||
const a = this.getGroupedBubble(message.grouped_id);
|
||||
@ -837,7 +831,9 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
this.bubbleGroups.removeBubble(bubble, mid);
|
||||
this.unreadedObserver.unobserve(bubble);
|
||||
if(this.unreadedObserver) {
|
||||
this.unreadedObserver.unobserve(bubble);
|
||||
}
|
||||
//this.unreaded.findAndSplice(mid => mid == id);
|
||||
bubble.remove();
|
||||
//bubble.remove();
|
||||
@ -854,7 +850,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
msgIds.forEach((msgId: number) => {
|
||||
let message = this.appMessagesManager.getMessage(msgId);
|
||||
let message = this.chat.getMessage(msgId);
|
||||
|
||||
/////////this.log('got new message to append:', message);
|
||||
|
||||
@ -937,7 +933,9 @@ export default class ChatBubbles {
|
||||
this.chatInner.append(container);
|
||||
}
|
||||
|
||||
this.stickyIntersector.observeStickyHeaderChanges(container);
|
||||
if(this.stickyIntersector) {
|
||||
this.stickyIntersector.observeStickyHeaderChanges(container);
|
||||
}
|
||||
}
|
||||
|
||||
return this.dateMessages[dateTimestamp];
|
||||
@ -951,12 +949,12 @@ export default class ChatBubbles {
|
||||
this.listenerSetter.removeAll();
|
||||
|
||||
this.lazyLoadQueue.clear();
|
||||
this.unreadedObserver.disconnect();
|
||||
this.stickyIntersector.disconnect();
|
||||
this.unreadedObserver && this.unreadedObserver.disconnect();
|
||||
this.stickyIntersector && this.stickyIntersector.disconnect();
|
||||
|
||||
delete this.lazyLoadQueue;
|
||||
delete this.unreadedObserver;
|
||||
delete this.stickyIntersector;
|
||||
this.unreadedObserver && delete this.unreadedObserver;
|
||||
this.stickyIntersector && delete this.stickyIntersector;
|
||||
}
|
||||
|
||||
public cleanup(bubblesToo = false) {
|
||||
@ -990,10 +988,14 @@ export default class ChatBubbles {
|
||||
|
||||
this.getHistoryTopPromise = this.getHistoryBottomPromise = undefined;
|
||||
|
||||
this.stickyIntersector.disconnect();
|
||||
if(this.stickyIntersector) {
|
||||
this.stickyIntersector.disconnect();
|
||||
}
|
||||
|
||||
this.unreadedObserver.disconnect();
|
||||
this.unreaded.length = 0;
|
||||
if(this.unreadedObserver) {
|
||||
this.unreadedObserver.disconnect();
|
||||
this.unreaded.length = 0;
|
||||
}
|
||||
|
||||
this.loadedTopTimes = this.loadedBottomTimes = 0;
|
||||
|
||||
@ -1350,7 +1352,7 @@ export default class ChatBubbles {
|
||||
|
||||
if(!our && !message.pFlags.out) {
|
||||
//this.log('not our message', message, message.pFlags.unread);
|
||||
if(message.pFlags.unread) {
|
||||
if(message.pFlags.unread && this.unreadedObserver) {
|
||||
this.unreadedObserver.observe(bubble);
|
||||
if(!this.unreaded.indexOf(message.mid)) {
|
||||
this.unreaded.push(message.mid);
|
||||
@ -1539,7 +1541,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
const button = row.buttons[column];
|
||||
this.appInlineBotsManager.callbackButtonClick(message.mid, button);
|
||||
this.appInlineBotsManager.callbackButtonClick(this.peerId, message.mid, button);
|
||||
});
|
||||
|
||||
const offset = rows.length * 45 + 'px';
|
||||
@ -1585,7 +1587,8 @@ export default class ChatBubbles {
|
||||
groupId: '' + message.id,
|
||||
attachmentDiv,
|
||||
uploading: true,
|
||||
isOut: true
|
||||
isOut: true,
|
||||
chat: this.chat
|
||||
});
|
||||
|
||||
break;
|
||||
@ -1645,7 +1648,8 @@ export default class ChatBubbles {
|
||||
albumMustBeRenderedFull,
|
||||
message,
|
||||
bubble,
|
||||
messageDiv
|
||||
messageDiv,
|
||||
chat: this.chat
|
||||
});
|
||||
|
||||
if(newNameContainer) {
|
||||
@ -1681,7 +1685,8 @@ export default class ChatBubbles {
|
||||
attachmentDiv,
|
||||
middleware: this.getMiddleware(),
|
||||
isOut: our,
|
||||
lazyLoadQueue: this.lazyLoadQueue
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
chat: this.chat
|
||||
});
|
||||
|
||||
break;
|
||||
@ -1748,7 +1753,7 @@ export default class ChatBubbles {
|
||||
});
|
||||
//}
|
||||
} else {
|
||||
const docDiv = wrapDocument(doc, false, false, message.mid);
|
||||
const docDiv = wrapDocument(this.peerId, doc, false, false, message.mid);
|
||||
preview.append(docDiv);
|
||||
preview.classList.add('preview-with-document');
|
||||
//messageDiv.classList.add((webpage.type || 'document') + '-message');
|
||||
@ -1865,7 +1870,8 @@ export default class ChatBubbles {
|
||||
attachmentDiv,
|
||||
middleware: this.getMiddleware(),
|
||||
isOut: our,
|
||||
lazyLoadQueue: this.lazyLoadQueue
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
chat: this.chat
|
||||
});
|
||||
} else {
|
||||
const withTail = !isAndroid && !isApple && doc.type != 'round' && !message.message;
|
||||
@ -1890,7 +1896,8 @@ export default class ChatBubbles {
|
||||
albumMustBeRenderedFull,
|
||||
message,
|
||||
bubble,
|
||||
messageDiv
|
||||
messageDiv,
|
||||
chat: this.chat
|
||||
});
|
||||
|
||||
if(newNameContainer) {
|
||||
@ -1943,7 +1950,7 @@ export default class ChatBubbles {
|
||||
case 'messageMediaPoll': {
|
||||
bubble.classList.remove('is-message-empty');
|
||||
|
||||
const pollElement = wrapPoll(message.media.poll.id, message.mid);
|
||||
const pollElement = wrapPoll(this.peerId, message.media.poll.id, message.mid);
|
||||
messageDiv.prepend(pollElement);
|
||||
messageDiv.classList.add('poll-message');
|
||||
|
||||
@ -2015,7 +2022,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
} else {
|
||||
if(message.reply_to_mid) {
|
||||
let originalMessage = this.appMessagesManager.getMessage(message.reply_to_mid);
|
||||
let originalMessage = this.chat.getMessage(message.reply_to_mid);
|
||||
let originalPeerTitle = this.appPeersManager.getPeerTitle(originalMessage.fromId || originalMessage.fwdFromId, true) || '';
|
||||
|
||||
/////////this.log('message to render reply', originalMessage, originalPeerTitle, bubble, message);
|
||||
@ -2023,7 +2030,7 @@ export default class ChatBubbles {
|
||||
// need to download separately
|
||||
if(originalMessage._ == 'messageEmpty') {
|
||||
//////////this.log('message to render reply empty, need download', message, message.reply_to_mid);
|
||||
this.appMessagesManager.wrapSingleMessage(message.reply_to_mid);
|
||||
this.appMessagesManager.wrapSingleMessage(this.peerId, message.reply_to_mid);
|
||||
this.needUpdate.push({replyMid: message.reply_to_mid, mid: message.mid});
|
||||
|
||||
originalPeerTitle = 'Loading...';
|
||||
@ -2071,7 +2078,7 @@ export default class ChatBubbles {
|
||||
bubble.classList.add('hide-name');
|
||||
}
|
||||
|
||||
if(this.chat.type == 'pinned') {
|
||||
if(this.chat.type === 'pinned') {
|
||||
savedFrom = `${this.chat.peerId}_${message.mid}`;
|
||||
}
|
||||
|
||||
@ -2163,7 +2170,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
while(history.length) {
|
||||
let message = this.appMessagesManager.getMessage(method());
|
||||
let message = this.chat.getMessage(method());
|
||||
this.renderMessage(message, reverse, true);
|
||||
}
|
||||
|
||||
@ -2223,9 +2230,9 @@ export default class ChatBubbles {
|
||||
|
||||
public requestHistory(maxId: number, loadCount: number, backLimit: number) {
|
||||
//const middleware = this.getMiddleware();
|
||||
if(this.chat.type == 'chat') {
|
||||
if(this.chat.type === 'chat') {
|
||||
return this.appMessagesManager.getHistory(this.peerId, maxId, loadCount, backLimit);
|
||||
} else if(this.chat.type == 'pinned') {
|
||||
} else if(this.chat.type === 'pinned') {
|
||||
const promise = this.appMessagesManager.getSearch(this.peerId, '', {_: 'inputMessagesFilterPinned'}, maxId, loadCount, 0, backLimit);
|
||||
|
||||
/* if(maxId) {
|
||||
@ -2238,6 +2245,8 @@ export default class ChatBubbles {
|
||||
} */
|
||||
|
||||
return promise;
|
||||
} else if(this.chat.type === 'scheduled') {
|
||||
return this.appMessagesManager.getScheduledMessages(this.peerId).then(mids => ({history: mids}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2293,7 +2302,7 @@ export default class ChatBubbles {
|
||||
|
||||
// * filter last album, because we don't know is this the last item
|
||||
for(let i = additionMsgIds.length - 1; i >= 0; --i) {
|
||||
const message = this.appMessagesManager.getMessage(additionMsgIds[i]);
|
||||
const message = this.chat.getMessage(additionMsgIds[i]);
|
||||
if(message.grouped_id) additionMsgIds.splice(i, 1);
|
||||
else break;
|
||||
}
|
||||
@ -2438,7 +2447,7 @@ export default class ChatBubbles {
|
||||
|
||||
// preload more
|
||||
//if(!isFirstMessageRender) {
|
||||
if(this.chat.type == 'chat') {
|
||||
if(this.chat.type === 'chat') {
|
||||
const storage = this.appMessagesManager.historiesStorage[peerId];
|
||||
const isMaxIdInHistory = storage.history.indexOf(maxId) !== -1;
|
||||
if(isMaxIdInHistory) { // * otherwise it is a search or jump
|
||||
@ -2490,7 +2499,9 @@ export default class ChatBubbles {
|
||||
|
||||
if(dateMessage.container.childElementCount == 2) { // only date div + sentinel div
|
||||
dateMessage.container.remove();
|
||||
this.stickyIntersector.unobserve(dateMessage.container, dateMessage.div);
|
||||
if(this.stickyIntersector) {
|
||||
this.stickyIntersector.unobserve(dateMessage.container, dateMessage.div);
|
||||
}
|
||||
delete this.dateMessages[i];
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import ChatInput from "./input";
|
||||
import ChatSelection from "./selection";
|
||||
import ChatTopbar from "./topbar";
|
||||
|
||||
export type ChatType = 'chat' | 'pinned' | 'replies' | 'discussion';
|
||||
export type ChatType = 'chat' | 'pinned' | 'replies' | 'discussion' | 'scheduled';
|
||||
|
||||
export default class Chat extends EventListenerBase<{
|
||||
setPeer: (mid: number, isTopMessage: boolean) => void
|
||||
@ -61,6 +61,14 @@ export default class Chat extends EventListenerBase<{
|
||||
this.appImManager.chatsContainer.append(this.container);
|
||||
}
|
||||
|
||||
public setType(type: ChatType) {
|
||||
this.type = type;
|
||||
|
||||
if(this.type === 'scheduled') {
|
||||
this.getMessage = (mid) => this.appMessagesManager.getMessageFromStorage(this.appMessagesManager.getScheduledMessagesStorage(this.peerId), mid);
|
||||
}
|
||||
}
|
||||
|
||||
private init() {
|
||||
this.topbar = new ChatTopbar(this, appSidebarRight, this.appMessagesManager, this.appPeersManager, this.appChatsManager);
|
||||
this.bubbles = new ChatBubbles(this, this.appMessagesManager, this.appSidebarRight, this.appStickersManager, this.appUsersManager, this.appInlineBotsManager, this.appPhotosManager, this.appDocsManager, this.appPeersManager, this.appChatsManager);
|
||||
@ -68,20 +76,23 @@ export default class Chat extends EventListenerBase<{
|
||||
this.selection = new ChatSelection(this.bubbles, this.input, this.appMessagesManager);
|
||||
this.contextMenu = new ChatContextMenu(this.bubbles.bubblesContainer, this, this.appMessagesManager, this.appChatsManager, this.appPeersManager, this.appPollsManager);
|
||||
|
||||
if(this.type == 'chat') {
|
||||
if(this.type === 'chat') {
|
||||
this.topbar.constructPeerHelpers();
|
||||
} else if(this.type == 'pinned') {
|
||||
} else if(this.type === 'pinned') {
|
||||
this.topbar.constructPinnedHelpers();
|
||||
}
|
||||
|
||||
this.topbar.construct();
|
||||
this.input.construct();
|
||||
|
||||
if(this.type == 'chat') { // * гений в деле, разный порядок из-за разной последовательности действий
|
||||
if(this.type === 'chat') { // * гений в деле, разный порядок из-за разной последовательности действий
|
||||
this.bubbles.constructPeerHelpers();
|
||||
this.input.constructPeerHelpers();
|
||||
} else if(this.type == 'pinned') {
|
||||
this.input.constructPinnedHelpers();
|
||||
} else if(this.type === 'pinned') {
|
||||
this.bubbles.constructPinnedHelpers();
|
||||
this.input.constructPinnedHelpers();
|
||||
} else if(this.type === 'scheduled') {
|
||||
this.bubbles.constructScheduledHelpers();
|
||||
}
|
||||
|
||||
this.container.classList.add('type-' + this.type);
|
||||
@ -187,4 +198,12 @@ export default class Chat extends EventListenerBase<{
|
||||
|
||||
rootScope.broadcast('peer_changed', peerId);
|
||||
}
|
||||
|
||||
public getMessage(mid: number) {
|
||||
return this.appMessagesManager.getMessageByPeer(this.peerId, mid);
|
||||
}
|
||||
|
||||
public getMidsByMid(mid: number) {
|
||||
return this.appMessagesManager.getMidsByMid(this.peerId, mid);
|
||||
}
|
||||
}
|
@ -50,7 +50,7 @@ export default class ChatContextMenu {
|
||||
|
||||
// * если открыть контекстное меню для альбома не по бабблу, и последний элемент не выбран, чтобы показать остальные пункты
|
||||
if(chat.selection.isSelecting && !bubbleContainer) {
|
||||
const mids = appMessagesManager.getMidsByMid(mid);
|
||||
const mids = this.chat.getMidsByMid(mid);
|
||||
if(mids.length > 1) {
|
||||
const selectedMid = chat.selection.selectedMids.has(mid) ? mid : mids.find(mid => chat.selection.selectedMids.has(mid));
|
||||
if(selectedMid) {
|
||||
@ -147,17 +147,17 @@ export default class ChatContextMenu {
|
||||
icon: 'edit',
|
||||
text: 'Edit',
|
||||
onClick: this.onEditClick,
|
||||
verify: () => this.appMessagesManager.canEditMessage(this.mid, 'text') && !!this.chat.input.messageInput
|
||||
verify: () => this.appMessagesManager.canEditMessage(this.peerId, this.mid, 'text') && !!this.chat.input.messageInput
|
||||
}, {
|
||||
icon: 'copy',
|
||||
text: 'Copy',
|
||||
onClick: this.onCopyClick,
|
||||
verify: () => !!this.appMessagesManager.getMessage(this.mid).message
|
||||
verify: () => !!this.chat.getMessage(this.mid).message
|
||||
}, {
|
||||
icon: 'copy',
|
||||
text: 'Copy selected',
|
||||
onClick: this.onCopyClick,
|
||||
verify: () => this.chat.selection.selectedMids.has(this.mid) && !![...this.chat.selection.selectedMids].find(mid => !!this.appMessagesManager.getMessage(mid).message),
|
||||
verify: () => this.chat.selection.selectedMids.has(this.mid) && !![...this.chat.selection.selectedMids].find(mid => !!this.chat.getMessage(mid).message),
|
||||
notDirect: () => true,
|
||||
withSelection: true
|
||||
}, {
|
||||
@ -165,7 +165,7 @@ export default class ChatContextMenu {
|
||||
text: 'Pin',
|
||||
onClick: this.onPinClick,
|
||||
verify: () => {
|
||||
const message = this.appMessagesManager.getMessage(this.mid);
|
||||
const message = this.chat.getMessage(this.mid);
|
||||
return this.mid > 0 && message._ != 'messageService' && !message.pFlags.pinned && this.appPeersManager.canPinMessage(this.peerId);
|
||||
}
|
||||
}, {
|
||||
@ -173,7 +173,7 @@ export default class ChatContextMenu {
|
||||
text: 'Unpin',
|
||||
onClick: this.onUnpinClick,
|
||||
verify: () => {
|
||||
const message = this.appMessagesManager.getMessage(this.mid);
|
||||
const message = this.chat.getMessage(this.mid);
|
||||
return message.pFlags.pinned && this.appPeersManager.canPinMessage(this.peerId);
|
||||
}
|
||||
}, {
|
||||
@ -181,7 +181,7 @@ export default class ChatContextMenu {
|
||||
text: 'Revote',
|
||||
onClick: this.onRetractVote,
|
||||
verify: () => {
|
||||
const message = this.appMessagesManager.getMessage(this.mid);
|
||||
const message = this.chat.getMessage(this.mid);
|
||||
const poll = message.media?.poll as Poll;
|
||||
return poll && poll.chosenIndexes.length && !poll.pFlags.closed && !poll.pFlags.quiz;
|
||||
}/* ,
|
||||
@ -191,9 +191,9 @@ export default class ChatContextMenu {
|
||||
text: 'Stop poll',
|
||||
onClick: this.onStopPoll,
|
||||
verify: () => {
|
||||
const message = this.appMessagesManager.getMessage(this.mid);
|
||||
const message = this.chat.getMessage(this.mid);
|
||||
const poll = message.media?.poll;
|
||||
return this.appMessagesManager.canEditMessage(this.mid, 'poll') && poll && !poll.pFlags.closed && this.mid > 0;
|
||||
return this.appMessagesManager.canEditMessage(this.peerId, this.mid, 'poll') && poll && !poll.pFlags.closed && this.mid > 0;
|
||||
}/* ,
|
||||
cancelEvent: true */
|
||||
}, {
|
||||
@ -213,7 +213,7 @@ export default class ChatContextMenu {
|
||||
text: 'Select',
|
||||
onClick: this.onSelectClick,
|
||||
verify: () => {
|
||||
const message = this.appMessagesManager.getMessage(this.mid);
|
||||
const message = this.chat.getMessage(this.mid);
|
||||
return !message.action && !this.chat.selection.selectedMids.has(this.mid);
|
||||
},
|
||||
notDirect: () => true,
|
||||
@ -229,7 +229,7 @@ export default class ChatContextMenu {
|
||||
icon: 'delete danger',
|
||||
text: 'Delete',
|
||||
onClick: this.onDeleteClick,
|
||||
verify: () => this.appMessagesManager.canDeleteMessage(this.mid)
|
||||
verify: () => this.appMessagesManager.canDeleteMessage(this.peerId, this.mid)
|
||||
}, {
|
||||
icon: 'delete danger',
|
||||
text: 'Delete selected',
|
||||
@ -245,7 +245,7 @@ export default class ChatContextMenu {
|
||||
};
|
||||
|
||||
private onReplyClick = () => {
|
||||
const message = this.appMessagesManager.getMessage(this.mid);
|
||||
const message = this.chat.getMessage(this.mid);
|
||||
const chatInputC = this.chat.input;
|
||||
const f = () => {
|
||||
chatInputC.setTopInfo('reply', f, this.appPeersManager.getPeerTitle(message.fromId, true), message.message, undefined, message);
|
||||
@ -261,7 +261,7 @@ export default class ChatContextMenu {
|
||||
private onCopyClick = () => {
|
||||
const mids = this.chat.selection.isSelecting ? [...this.chat.selection.selectedMids] : [this.mid];
|
||||
const str = mids.reduce((acc, mid) => {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.chat.getMessage(mid);
|
||||
return acc + (message?.message ? message.message + '\n' : '');
|
||||
}, '').trim();
|
||||
|
||||
@ -277,18 +277,18 @@ export default class ChatContextMenu {
|
||||
};
|
||||
|
||||
private onRetractVote = () => {
|
||||
this.appPollsManager.sendVote(this.mid, []);
|
||||
this.appPollsManager.sendVote(this.peerId, this.mid, []);
|
||||
};
|
||||
|
||||
private onStopPoll = () => {
|
||||
this.appPollsManager.stopPoll(this.mid);
|
||||
this.appPollsManager.stopPoll(this.peerId, this.mid);
|
||||
};
|
||||
|
||||
private onForwardClick = () => {
|
||||
if(this.chat.selection.isSelecting) {
|
||||
this.chat.selection.selectionForwardBtn.click();
|
||||
} else {
|
||||
new PopupForward(this.isTargetAGroupedItem ? [this.mid] : this.appMessagesManager.getMidsByMid(this.mid));
|
||||
new PopupForward(this.peerId, this.isTargetAGroupedItem ? [this.mid] : this.chat.getMidsByMid(this.mid));
|
||||
}
|
||||
};
|
||||
|
||||
@ -304,7 +304,7 @@ export default class ChatContextMenu {
|
||||
if(this.chat.selection.isSelecting) {
|
||||
this.chat.selection.selectionDeleteBtn.click();
|
||||
} else {
|
||||
new PopupDeleteMessages(this.isTargetAGroupedItem ? [this.mid] : this.appMessagesManager.getMidsByMid(this.mid));
|
||||
new PopupDeleteMessages(this.peerId, this.isTargetAGroupedItem ? [this.mid] : this.chat.getMidsByMid(this.mid));
|
||||
}
|
||||
};
|
||||
}
|
@ -68,6 +68,7 @@ export default class ChatInput {
|
||||
|
||||
public willSendWebPage: any = null;
|
||||
public forwardingMids: number[] = [];
|
||||
public forwardingFromPeerId: number = 0;
|
||||
public replyToMsgId = 0;
|
||||
public editMsgId = 0;
|
||||
public noWebPage: true;
|
||||
@ -102,6 +103,7 @@ export default class ChatInput {
|
||||
|
||||
public goDownBtn: HTMLButtonElement;
|
||||
public goDownUnreadBadge: HTMLElement;
|
||||
btnScheduled: HTMLButtonElement;
|
||||
|
||||
constructor(private chat: Chat, private appMessagesManager: AppMessagesManager, private appDocsManager: AppDocsManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private appWebPagesManager: AppWebPagesManager, private appImManager: AppImManager) {
|
||||
this.listenerSetter = new ListenerSetter();
|
||||
@ -158,6 +160,9 @@ export default class ChatInput {
|
||||
|
||||
this.inputScroll = new Scrollable(this.inputMessageContainer);
|
||||
|
||||
this.btnScheduled = ButtonIcon('schedule', {noRipple: true});
|
||||
this.btnScheduled.classList.add('btn-scheduled', 'hide');
|
||||
|
||||
this.attachMenuButtons = [{
|
||||
icon: 'photo',
|
||||
text: 'Photo or Video',
|
||||
@ -219,7 +224,7 @@ export default class ChatInput {
|
||||
this.fileInput.multiple = true;
|
||||
this.fileInput.style.display = 'none';
|
||||
|
||||
this.newMessageWrapper.append(this.btnToggleEmoticons, this.inputMessageContainer, this.attachMenu, this.recordTimeEl, this.fileInput);
|
||||
this.newMessageWrapper.append(this.btnToggleEmoticons, this.inputMessageContainer, this.btnScheduled, this.attachMenu, this.recordTimeEl, this.fileInput);
|
||||
|
||||
this.rowsWrapper.append(this.replyElements.container, this.newMessageWrapper);
|
||||
|
||||
@ -311,6 +316,10 @@ export default class ChatInput {
|
||||
}); */
|
||||
attachClickEvent(this.btnSend, this.onBtnSendClick, {listenerSetter: this.listenerSetter});
|
||||
|
||||
attachClickEvent(this.btnScheduled, (e) => {
|
||||
this.appImManager.setInnerPeer(this.chat.peerId, 0, 'scheduled');
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
|
||||
if(this.recorder) {
|
||||
const onCancelRecordClick = (e: Event) => {
|
||||
cancelEvent(e);
|
||||
@ -450,6 +459,13 @@ export default class ChatInput {
|
||||
|
||||
if(this.chat.type == 'pinned') {
|
||||
this.chatInput.classList.toggle('can-pin', this.appPeersManager.canPinMessage(peerId));
|
||||
} else if(this.chat.type == 'chat') {
|
||||
this.btnScheduled.classList.add('hide');
|
||||
const middleware = this.chat.bubbles.getMiddleware();
|
||||
this.appMessagesManager.getScheduledMessages(peerId).then(mids => {
|
||||
if(!middleware()) return;
|
||||
this.btnScheduled.classList.toggle('hide', !mids.length);
|
||||
});
|
||||
}
|
||||
|
||||
if(this.messageInput) {
|
||||
@ -953,11 +969,12 @@ export default class ChatInput {
|
||||
if(this.helperWaitingForward) return;
|
||||
this.helperWaitingForward = true;
|
||||
|
||||
const fromId = this.forwardingFromPeerId;
|
||||
const mids = this.forwardingMids.slice();
|
||||
const helperFunc = this.helperFunc;
|
||||
this.clearHelper();
|
||||
let selected = false;
|
||||
new PopupForward(mids, () => {
|
||||
new PopupForward(fromId, mids, () => {
|
||||
selected = true;
|
||||
}, () => {
|
||||
this.helperWaitingForward = false;
|
||||
@ -1032,7 +1049,7 @@ export default class ChatInput {
|
||||
//return;
|
||||
|
||||
if(this.editMsgId) {
|
||||
this.appMessagesManager.editMessage(this.editMsgId, str, {
|
||||
this.appMessagesManager.editMessage(this.chat.peerId, this.editMsgId, str, {
|
||||
noWebPage: this.noWebPage
|
||||
});
|
||||
} else {
|
||||
@ -1046,8 +1063,10 @@ export default class ChatInput {
|
||||
// * wait for sendText set messageId for invokeAfterMsg
|
||||
if(this.forwardingMids.length) {
|
||||
const mids = this.forwardingMids.slice();
|
||||
const fromPeerId = this.forwardingFromPeerId;
|
||||
const peerId = this.chat.peerId;
|
||||
setTimeout(() => {
|
||||
this.appMessagesManager.forwardMessages(this.chat.peerId, mids);
|
||||
this.appMessagesManager.forwardMessages(peerId, fromPeerId, mids);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@ -1071,7 +1090,7 @@ export default class ChatInput {
|
||||
}
|
||||
|
||||
public initMessageEditing(mid: number) {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.chat.getMessage(mid);
|
||||
|
||||
let input = RichTextProcessor.wrapDraftText(message.message, {entities: message.totalEntities});
|
||||
const f = () => {
|
||||
@ -1082,11 +1101,11 @@ export default class ChatInput {
|
||||
f();
|
||||
}
|
||||
|
||||
public initMessagesForward(mids: number[]) {
|
||||
public initMessagesForward(fromPeerId: number, mids: number[]) {
|
||||
const f = () => {
|
||||
//const peerTitles: string[]
|
||||
const smth: Set<string | number> = new Set(mids.map(mid => {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.appMessagesManager.getMessageByPeer(fromPeerId, mid);
|
||||
if(message.fwd_from && message.fwd_from.from_name && !message.fromId && !message.fwdFromId) {
|
||||
return message.fwd_from.from_name;
|
||||
} else {
|
||||
@ -1103,13 +1122,14 @@ export default class ChatInput {
|
||||
|
||||
const title = peerTitles.length < 3 ? peerTitles.join(' and ') : peerTitles[0] + ' and ' + (peerTitles.length - 1) + ' others';
|
||||
if(mids.length == 1) {
|
||||
const message = this.appMessagesManager.getMessage(mids[0]);
|
||||
const message = this.appMessagesManager.getMessageByPeer(fromPeerId, mids[0]);
|
||||
this.setTopInfo('forward', f, title, message.message, undefined, message);
|
||||
} else {
|
||||
this.setTopInfo('forward', f, title, mids.length + ' forwarded messages');
|
||||
}
|
||||
|
||||
this.forwardingMids = mids.slice();
|
||||
this.forwardingFromPeerId = fromPeerId;
|
||||
};
|
||||
|
||||
f();
|
||||
@ -1128,6 +1148,7 @@ export default class ChatInput {
|
||||
|
||||
this.replyToMsgId = 0;
|
||||
this.forwardingMids.length = 0;
|
||||
this.forwardingFromPeerId = 0;
|
||||
this.editMsgId = 0;
|
||||
this.helperType = this.helperFunc = undefined;
|
||||
this.chat.container.classList.remove('is-helper-active');
|
||||
|
@ -524,7 +524,7 @@ export default class ChatPinnedMessage {
|
||||
}
|
||||
|
||||
public async followPinnedMessage(mid: number) {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.chat.getMessage(mid);
|
||||
if(message && !message.deleted) {
|
||||
this.chat.setPeer(this.topbar.peerId, mid);
|
||||
(this.chat.setPeerPromise || Promise.resolve()).then(() => { // * debounce fast clicker
|
||||
@ -550,7 +550,7 @@ export default class ChatPinnedMessage {
|
||||
const count = this.count;
|
||||
if(count) {
|
||||
const pinnedIndex = this.pinnedIndex;
|
||||
const message = this.appMessagesManager.getMessage(this.pinnedMid);
|
||||
const message = this.chat.getMessage(this.pinnedMid);
|
||||
|
||||
//this.animatedCounter.prepareNumber(count);
|
||||
|
||||
|
@ -207,7 +207,7 @@ export default class ChatSelection {
|
||||
|
||||
let cantForward = !this.selectedMids.size, cantDelete = !this.selectedMids.size;
|
||||
for(const mid of this.selectedMids.values()) {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.appMessagesManager.getMessageByPeer(this.bubbles.peerId, mid);
|
||||
if(!cantForward) {
|
||||
if(message.action) {
|
||||
cantForward = true;
|
||||
@ -216,7 +216,7 @@ export default class ChatSelection {
|
||||
|
||||
|
||||
if(!cantDelete) {
|
||||
const canDelete = this.appMessagesManager.canDeleteMessage(mid);
|
||||
const canDelete = this.appMessagesManager.canDeleteMessage(this.bubbles.peerId, mid);
|
||||
if(!canDelete) {
|
||||
cantDelete = true;
|
||||
}
|
||||
@ -295,7 +295,7 @@ export default class ChatSelection {
|
||||
this.selectionForwardBtn = Button('btn-primary btn-transparent selection-container-forward', {icon: 'forward'});
|
||||
this.selectionForwardBtn.append('Forward');
|
||||
this.listenerSetter.add(this.selectionForwardBtn, 'click', () => {
|
||||
new PopupForward([...this.selectedMids], () => {
|
||||
new PopupForward(this.bubbles.peerId, [...this.selectedMids], () => {
|
||||
this.cancelSelection();
|
||||
});
|
||||
});
|
||||
@ -303,7 +303,7 @@ export default class ChatSelection {
|
||||
this.selectionDeleteBtn = Button('btn-primary btn-transparent danger selection-container-delete', {icon: 'delete'});
|
||||
this.selectionDeleteBtn.append('Delete');
|
||||
this.listenerSetter.add(this.selectionDeleteBtn, 'click', () => {
|
||||
new PopupDeleteMessages([...this.selectedMids], () => {
|
||||
new PopupDeleteMessages(this.bubbles.peerId, [...this.selectedMids], () => {
|
||||
this.cancelSelection();
|
||||
});
|
||||
});
|
||||
@ -365,7 +365,7 @@ export default class ChatSelection {
|
||||
}
|
||||
|
||||
public isGroupedMidsSelected(mid: number) {
|
||||
const mids = this.appMessagesManager.getMidsByMid(mid);
|
||||
const mids = this.appMessagesManager.getMidsByMid(this.bubbles.peerId, mid);
|
||||
const selectedMids = mids.filter(mid => this.selectedMids.has(mid));
|
||||
return mids.length == selectedMids.length;
|
||||
}
|
||||
@ -376,7 +376,7 @@ export default class ChatSelection {
|
||||
const isGrouped = bubble.classList.contains('is-grouped');
|
||||
if(isGrouped) {
|
||||
if(!this.isGroupedBubbleSelected(bubble)) {
|
||||
const mids = this.appMessagesManager.getMidsByMid(mid);
|
||||
const mids = this.appMessagesManager.getMidsByMid(this.bubbles.peerId, mid);
|
||||
mids.forEach(mid => this.selectedMids.delete(mid));
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ export default class ChatTopbar {
|
||||
this.pinnedMessage.followPinnedMessage(mid);
|
||||
//}
|
||||
} else {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const message = this.appMessagesManager.getMessageByPeer(this.peerId, mid);
|
||||
|
||||
this.chat.appImManager.setInnerPeer(message.peerId, mid);
|
||||
}
|
||||
@ -373,7 +373,7 @@ export default class ChatTopbar {
|
||||
|
||||
public setTitle(count?: number) {
|
||||
let title = '';
|
||||
if(this.chat.type == 'pinned') {
|
||||
if(this.chat.type === 'pinned') {
|
||||
title = count === -1 ? 'Pinned Messages' : (count === 1 ? 'Pinned Message' : (count + ' Pinned Messages'));
|
||||
|
||||
if(count === undefined) {
|
||||
@ -393,7 +393,15 @@ export default class ChatTopbar {
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
} else if(this.chat.type === 'scheduled') {
|
||||
title = count === -1 ? 'Scheduled Messages' : (count === 1 ? 'Scheduled Message' : (count + ' Scheduled Messages'));
|
||||
|
||||
if(count === undefined) {
|
||||
this.appMessagesManager.getScheduledMessages(this.peerId).then(mids => {
|
||||
this.setTitle(mids.length);
|
||||
});
|
||||
}
|
||||
} else if(this.chat.type === 'chat') {
|
||||
if(this.peerId == rootScope.myId) title = 'Saved Messages';
|
||||
else title = this.appPeersManager.getPeerTitle(this.peerId);
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ export default class PollElement extends HTMLElement {
|
||||
private chosenIndexes: number[] = [];
|
||||
private percents: number[];
|
||||
|
||||
private peerId: number;
|
||||
private pollId: string;
|
||||
private mid: number;
|
||||
|
||||
@ -178,6 +179,7 @@ export default class PollElement extends HTMLElement {
|
||||
//console.log('line total length:', lineTotalLength);
|
||||
}
|
||||
|
||||
this.peerId = +this.getAttribute('peer-id');
|
||||
this.pollId = this.getAttribute('poll-id');
|
||||
this.mid = +this.getAttribute('message-id');
|
||||
const {poll, results} = appPollsManager.getPoll(this.pollId);
|
||||
@ -307,7 +309,7 @@ export default class PollElement extends HTMLElement {
|
||||
|
||||
setTimeout(() => {
|
||||
// нужно запросить апдейт чтобы опрос обновился
|
||||
appPollsManager.getResults(this.mid);
|
||||
appPollsManager.getResults(this.peerId, this.mid);
|
||||
}, 3e3);
|
||||
}
|
||||
}, 1e3);
|
||||
@ -324,7 +326,7 @@ export default class PollElement extends HTMLElement {
|
||||
|
||||
this.viewResults.addEventListener('click', (e) => {
|
||||
cancelEvent(e);
|
||||
appSidebarRight.pollResultsTab.init(this.pollId, this.mid);
|
||||
appSidebarRight.pollResultsTab.init(this.peerId, this.pollId, this.mid);
|
||||
});
|
||||
ripple(this.viewResults);
|
||||
|
||||
@ -464,7 +466,7 @@ export default class PollElement extends HTMLElement {
|
||||
|
||||
this.classList.add('disable-hover');
|
||||
this.sentVote = true;
|
||||
return this.sendVotePromise = appPollsManager.sendVote(this.mid, indexes).then(() => {
|
||||
return this.sendVotePromise = appPollsManager.sendVote(this.peerId, this.mid, indexes).then(() => {
|
||||
targets.forEach(target => {
|
||||
target.classList.remove('is-voting');
|
||||
});
|
||||
|
@ -6,14 +6,13 @@ import { PopupButton } from "./popup";
|
||||
import PopupPeer from "./popupPeer";
|
||||
|
||||
export default class PopupDeleteMessages {
|
||||
constructor(mids: number[], onConfirm?: () => void) {
|
||||
const peerId = appMessagesManager.getMessage(mids[0]).peerId;
|
||||
constructor(peerId: number, mids: number[], onConfirm?: () => void) {
|
||||
const firstName = appPeersManager.getPeerTitle(peerId, false, true);
|
||||
|
||||
mids = mids.slice();
|
||||
const callback = (revoke: boolean) => {
|
||||
onConfirm && onConfirm();
|
||||
appMessagesManager.deleteMessages(mids, revoke);
|
||||
appMessagesManager.deleteMessages(peerId, mids, revoke);
|
||||
};
|
||||
|
||||
let title: string, description: string, buttons: PopupButton[];
|
||||
@ -45,7 +44,7 @@ export default class PopupDeleteMessages {
|
||||
const hasRights = appChatsManager.hasRights(-peerId, 'deleteRevoke');
|
||||
if(chat._ == 'chat') {
|
||||
const canRevoke = hasRights ? mids.slice() : mids.filter(mid => {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, mid);
|
||||
return message.fromId == rootScope.myId;
|
||||
});
|
||||
|
||||
|
@ -7,7 +7,7 @@ export default class PopupForward extends PopupElement {
|
||||
private selector: AppSelectPeers;
|
||||
//private scrollable: Scrollable;
|
||||
|
||||
constructor(mids: number[], onSelect?: () => Promise<void> | void, onClose?: () => void) {
|
||||
constructor(fromPeerId: number, mids: number[], onSelect?: () => Promise<void> | void, onClose?: () => void) {
|
||||
super('popup-forward', null, {closable: true, overlayClosable: true, body: true});
|
||||
|
||||
if(onClose) this.onClose = onClose;
|
||||
@ -21,7 +21,7 @@ export default class PopupForward extends PopupElement {
|
||||
await (onSelect ? onSelect() || Promise.resolve() : Promise.resolve());
|
||||
|
||||
appImManager.setInnerPeer(peerId);
|
||||
appImManager.chat.input.initMessagesForward(mids.slice());
|
||||
appImManager.chat.input.initMessagesForward(fromPeerId, mids.slice());
|
||||
}, ['dialogs', 'contacts'], () => {
|
||||
this.show();
|
||||
this.selector.checkForTriggers(); // ! due to zero height before mounting
|
||||
|
@ -224,7 +224,7 @@ export default class PopupNewMedia extends PopupElement {
|
||||
params.objectURL = URL.createObjectURL(file);
|
||||
}
|
||||
|
||||
const docDiv = wrapDocument({
|
||||
const docDiv = wrapDocument(0, {
|
||||
file: file,
|
||||
file_name: file.name || '',
|
||||
size: file.size,
|
||||
|
@ -45,7 +45,7 @@ export default class AppForwardTab implements SliderTab {
|
||||
|
||||
let s = () => {
|
||||
let promises = peerIds.splice(0, 3).map(peerId => {
|
||||
return appMessagesManager.forwardMessages(peerId, this.mids);
|
||||
return appMessagesManager.forwardMessages(peerId, 0, this.mids);
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
|
@ -14,6 +14,7 @@ export default class AppPollResultsTab implements SliderTab {
|
||||
private resultsDiv = this.contentDiv.firstElementChild as HTMLDivElement;
|
||||
private scrollable: Scrollable;
|
||||
|
||||
private peerId: number;
|
||||
private pollId: string;
|
||||
private mid: number;
|
||||
|
||||
@ -31,11 +32,12 @@ export default class AppPollResultsTab implements SliderTab {
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
public init(pollId: string, mid: number) {
|
||||
if(this.pollId == pollId && this.mid == mid) return;
|
||||
public init(peerId: number, pollId: string, mid: number) {
|
||||
if(this.peerId == peerId && this.pollId == pollId && this.mid == mid) return;
|
||||
|
||||
this.cleanup();
|
||||
|
||||
this.peerId = peerId;
|
||||
this.pollId = pollId;
|
||||
this.mid = mid;
|
||||
|
||||
@ -86,7 +88,7 @@ export default class AppPollResultsTab implements SliderTab {
|
||||
if(loading) return;
|
||||
loading = true;
|
||||
|
||||
appPollsManager.getVotes(mid, answer.option, offset, limit).then(votesList => {
|
||||
appPollsManager.getVotes(peerId, mid, answer.option, offset, limit).then(votesList => {
|
||||
votesList.votes.forEach(vote => {
|
||||
const {dom} = appDialogsManager.addDialogNew({
|
||||
dialog: vote.user_id,
|
||||
|
@ -179,7 +179,7 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = appMessagesManager.getMessage(messageId);
|
||||
const message = appMessagesManager.getMessageByPeer(this.peerId, messageId);
|
||||
|
||||
const ids = Object.keys(this.mediaDivsByIds).map(k => +k).sort((a, b) => a - b);
|
||||
const idx = ids.findIndex(i => i == messageId);
|
||||
@ -331,11 +331,11 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
|
||||
if(type != 'inputMessagesFilterUrl') {
|
||||
for(let mid of ids) {
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
let message = appMessagesManager.getMessageByPeer(this.peerId, mid);
|
||||
if(message.media) messages.push(message);
|
||||
}
|
||||
} else {
|
||||
messages = ids.slice().map(mid => appMessagesManager.getMessage(mid));
|
||||
messages = ids.slice().map(mid => appMessagesManager.getMessageByPeer(this.peerId, mid));
|
||||
}
|
||||
|
||||
let filtered: any[] = [];
|
||||
@ -528,7 +528,7 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
case 'inputMessagesFilterMusic':
|
||||
case 'inputMessagesFilterDocument': {
|
||||
for(const message of messages) {
|
||||
const div = wrapDocument(message.media.document, true, false, message.mid, 400);
|
||||
const div = wrapDocument(this.peerId, message.media.document, true, false, message.mid, 400);
|
||||
div.dataset.mid = '' + message.mid;
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import './middleEllipsis';
|
||||
import { nextRandomInt } from '../helpers/random';
|
||||
import RichTextProcessor from '../lib/richtextprocessor';
|
||||
import appImManager from '../lib/appManagers/appImManager';
|
||||
import Chat from './chat/chat';
|
||||
|
||||
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB
|
||||
|
||||
@ -93,7 +94,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
||||
video.setAttribute('playsinline', 'true');
|
||||
if(doc.type == 'round') {
|
||||
//video.muted = true;
|
||||
const globalVideo = appMediaPlaybackController.addMedia(doc, message.mid);
|
||||
const globalVideo = appMediaPlaybackController.addMedia(message.peerId, doc, message.mid);
|
||||
|
||||
video.addEventListener('canplay', () => {
|
||||
if(globalVideo.currentTime > 0) {
|
||||
@ -342,9 +343,9 @@ export const formatDate = (timestamp: number, monthShort = false, withYear = tru
|
||||
return str + ' at ' + date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
|
||||
};
|
||||
|
||||
export function wrapDocument(doc: MyDocument, withTime = false, uploading = false, mid?: number, fontWeight = 500): HTMLElement {
|
||||
export function wrapDocument(peerId: number, doc: MyDocument, withTime = false, uploading = false, mid?: number, fontWeight = 500): HTMLElement {
|
||||
if(doc.type == 'audio' || doc.type == 'voice') {
|
||||
const audioElement = wrapAudio(doc, withTime, mid);
|
||||
const audioElement = wrapAudio(peerId, doc, withTime, mid);
|
||||
audioElement.dataset.fontWeight = '' + fontWeight;
|
||||
return audioElement;
|
||||
}
|
||||
@ -437,8 +438,9 @@ export function wrapDocument(doc: MyDocument, withTime = false, uploading = fals
|
||||
return docDiv;
|
||||
}
|
||||
|
||||
export function wrapAudio(doc: MyDocument, withTime = false, mid?: number): HTMLElement {
|
||||
export function wrapAudio(peerId: number, doc: MyDocument, withTime = false, mid?: number): HTMLElement {
|
||||
let elem = new AudioElement();
|
||||
elem.setAttribute('peer-id', '' + peerId);
|
||||
elem.setAttribute('doc-id', doc.id);
|
||||
elem.setAttribute('with-time', '' + +withTime);
|
||||
elem.setAttribute('message-id', '' + mid);
|
||||
@ -898,20 +900,21 @@ export function prepareAlbum(options: {
|
||||
} */
|
||||
}
|
||||
|
||||
export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLoadQueue, isOut}: {
|
||||
export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLoadQueue, isOut, chat}: {
|
||||
groupId: string,
|
||||
attachmentDiv: HTMLElement,
|
||||
middleware?: () => boolean,
|
||||
lazyLoadQueue?: LazyLoadQueue,
|
||||
uploading?: boolean,
|
||||
isOut: boolean
|
||||
isOut: boolean,
|
||||
chat: Chat
|
||||
}) {
|
||||
const items: {size: PhotoSize.photoSize, media: any, message: any}[] = [];
|
||||
|
||||
// !lowest msgID will be the FIRST in album
|
||||
const storage = appMessagesManager.getMidsByAlbum(groupId);
|
||||
for(const mid of storage) {
|
||||
const m = appMessagesManager.getMessage(mid);
|
||||
const m = chat.getMessage(mid);
|
||||
const media = m.media.photo || m.media.document;
|
||||
|
||||
const size: any = media._ == 'photo' ? appPhotosManager.choosePhotoSize(media, 480, 480) : {w: media.w, h: media.h};
|
||||
@ -966,24 +969,25 @@ export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLo
|
||||
});
|
||||
}
|
||||
|
||||
export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv}: {
|
||||
export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat}: {
|
||||
albumMustBeRenderedFull: boolean,
|
||||
message: any,
|
||||
messageDiv: HTMLElement,
|
||||
bubble: HTMLElement,
|
||||
uploading?: boolean
|
||||
uploading?: boolean,
|
||||
chat: Chat
|
||||
}) {
|
||||
let nameContainer: HTMLDivElement;
|
||||
const mids = albumMustBeRenderedFull ? appMessagesManager.getMidsByMid(message.mid) : [message.mid];
|
||||
const mids = albumMustBeRenderedFull ? chat.getMidsByMid(message.mid) : [message.mid];
|
||||
const isPending = message.mid < 0;
|
||||
if(isPending) {
|
||||
mids.reverse();
|
||||
}
|
||||
|
||||
mids.forEach((mid, idx) => {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = chat.getMessage(mid);
|
||||
const doc = message.media.document;
|
||||
const div = wrapDocument(doc, false, isPending, mid);
|
||||
const div = wrapDocument(chat.peerId, doc, false, isPending, mid);
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.classList.add('document-container');
|
||||
@ -1037,8 +1041,9 @@ export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble,
|
||||
return nameContainer;
|
||||
}
|
||||
|
||||
export function wrapPoll(pollId: string, mid: number) {
|
||||
export function wrapPoll(peerId: number, pollId: string, mid: number) {
|
||||
const elem = new PollElement();
|
||||
elem.setAttribute('peer-id', '' + peerId);
|
||||
elem.setAttribute('poll-id', pollId);
|
||||
elem.setAttribute('message-id', '' + mid);
|
||||
return elem;
|
||||
|
@ -4,8 +4,6 @@ import appPeersManager from "./appPeersManager";
|
||||
import apiManagerProxy from "../mtproto/mtprotoworker";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
import appDocsManager from "./appDocsManager";
|
||||
import appMessagesIdsManager from "./appMessagesIdsManager";
|
||||
import appMessagesManager from "./appMessagesManager";
|
||||
import appPhotosManager from "./appPhotosManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
|
||||
@ -270,13 +268,10 @@ export class AppInlineBotsManager {
|
||||
})
|
||||
} */
|
||||
|
||||
public callbackButtonClick(mid: number, button: any) {
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
let peerId = appMessagesManager.getMessagePeer(message);
|
||||
|
||||
public callbackButtonClick(peerId: number, mid: number, button: any) {
|
||||
return apiManagerProxy.invokeApi('messages.getBotCallbackAnswer', {
|
||||
peer: appPeersManager.getInputPeerById(peerId),
|
||||
msg_id: appMessagesIdsManager.getMessageLocalId(mid),
|
||||
msg_id: mid,
|
||||
data: button.data
|
||||
}, {timeout: 1, stopTime: -1, noErrorBox: true}).then((callbackAnswer) => {
|
||||
if(typeof callbackAnswer.message === 'string' && callbackAnswer.message.length) {
|
||||
|
@ -939,7 +939,7 @@ export class AppDialogsManager {
|
||||
}
|
||||
|
||||
if(!lastMessage) {
|
||||
lastMessage = appMessagesManager.getMessage(dialog.top_message);
|
||||
lastMessage = appMessagesManager.getMessageByPeer(dialog.peerId, dialog.top_message);
|
||||
}
|
||||
|
||||
if(lastMessage._ == 'messageEmpty' || (lastMessage._ == 'messageService' && !lastMessage.rReply)) {
|
||||
@ -1048,7 +1048,7 @@ export class AppDialogsManager {
|
||||
dom.listEl.classList.toggle('is-muted', isMuted);
|
||||
}
|
||||
|
||||
const lastMessage = appMessagesManager.getMessage(dialog.top_message);
|
||||
const lastMessage = appMessagesManager.getMessageByPeer(dialog.peerId, dialog.top_message);
|
||||
if(lastMessage._ != 'messageEmpty' && !lastMessage.deleted &&
|
||||
lastMessage.fromId == rootScope.myId && lastMessage.peerId != rootScope.myId/* &&
|
||||
dialog.read_outbox_max_id */) { // maybe comment, 06.20.2020
|
||||
|
@ -20,7 +20,7 @@ import appPhotosManager from './appPhotosManager';
|
||||
import appProfileManager from './appProfileManager';
|
||||
import appStickersManager from './appStickersManager';
|
||||
import appWebPagesManager from './appWebPagesManager';
|
||||
import { cancelEvent, findUpClassName, generatePathData, getFilesFromEvent, placeCaretAtEnd } from '../../helpers/dom';
|
||||
import { cancelEvent, getFilesFromEvent, placeCaretAtEnd } from '../../helpers/dom';
|
||||
import PopupNewMedia from '../../components/popupNewMedia';
|
||||
import { TransitionSlider } from '../../components/transition';
|
||||
import { numberWithCommas } from '../../helpers/number';
|
||||
@ -28,9 +28,7 @@ import MarkupTooltip from '../../components/chat/markupTooltip';
|
||||
import { isTouchSupported } from '../../helpers/touchSupport';
|
||||
import appPollsManager from './appPollsManager';
|
||||
import SetTransition from '../../components/singleTransition';
|
||||
import { isSafari } from '../../helpers/userAgent';
|
||||
import ChatDragAndDrop from '../../components/chat/dragAndDrop';
|
||||
import appMessagesIdsManager from './appMessagesIdsManager';
|
||||
|
||||
//console.log('appImManager included33!');
|
||||
|
||||
@ -154,9 +152,6 @@ export class AppImManager {
|
||||
appUsersManager.resolveUsername(p).then(peer => {
|
||||
const isUser = peer._ == 'user';
|
||||
const peerId = isUser ? peer.id : -peer.id;
|
||||
if(postId) {
|
||||
postId = appMessagesIdsManager.getFullMessageId(postId, -peerId);
|
||||
}
|
||||
|
||||
this.setInnerPeer(peerId, postId);
|
||||
});
|
||||
@ -212,11 +207,11 @@ export class AppImManager {
|
||||
if(history?.history) {
|
||||
let goodMid: number;
|
||||
for(const mid of history.history) {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const message = appMessagesManager.getMessageByPeer(chat.peerId, mid);
|
||||
const good = this.myId == chat.peerId ? message.fromId == this.myId : message.pFlags.out;
|
||||
|
||||
if(good) {
|
||||
if(appMessagesManager.canEditMessage(mid, 'text')) {
|
||||
if(appMessagesManager.canEditMessage(this.chat.peerId, mid, 'text')) {
|
||||
goodMid = mid;
|
||||
}
|
||||
|
||||
@ -508,7 +503,7 @@ export class AppImManager {
|
||||
this.createNewChat();
|
||||
|
||||
if(type) {
|
||||
this.chat.type = type;
|
||||
this.chat.setType(type);
|
||||
}
|
||||
|
||||
this.chatsSelectTab(this.chat.container);
|
||||
|
@ -1,85 +0,0 @@
|
||||
import { MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
|
||||
import appStateManager from "./appStateManager";
|
||||
|
||||
export class AppMessagesIdsManager {
|
||||
public channelLocals: {[channelId: string]: number} = {};
|
||||
public channelsByLocals: {[localStart: string]: number} = {};
|
||||
public channelCurLocal = 0;
|
||||
public fullMsgIdModulus = 4294967296;
|
||||
|
||||
constructor() {
|
||||
appStateManager.getState().then(state => {
|
||||
const cached = state.messagesIdsLocals;
|
||||
if(cached) {
|
||||
this.channelLocals = cached.channelLocals;
|
||||
this.channelsByLocals = cached.channelsByLocals;
|
||||
this.channelCurLocal = cached.channelCurLocal;
|
||||
}
|
||||
});
|
||||
|
||||
appStateManager.addListener('save', () => {
|
||||
appStateManager.pushToState('messagesIdsLocals', {
|
||||
channelLocals: this.channelLocals,
|
||||
channelsByLocals: this.channelsByLocals,
|
||||
channelCurLocal: this.channelCurLocal
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public getFullMessageId(msgId: number, channelId: number): number {
|
||||
if(!channelId || msgId <= 0) {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
msgId = this.getMessageLocalId(msgId);
|
||||
let localStart = this.channelLocals[channelId];
|
||||
if(!localStart) {
|
||||
localStart = (++this.channelCurLocal) * this.fullMsgIdModulus;
|
||||
this.channelsByLocals[localStart] = channelId;
|
||||
this.channelLocals[channelId] = localStart;
|
||||
}
|
||||
|
||||
return localStart + msgId;
|
||||
}
|
||||
|
||||
public getMessageIdInfo(fullMsgId: number) {
|
||||
if(fullMsgId < this.fullMsgIdModulus) {
|
||||
return [fullMsgId, 0];
|
||||
}
|
||||
|
||||
const msgId = fullMsgId % this.fullMsgIdModulus;
|
||||
const channelId = this.channelsByLocals[fullMsgId - msgId];
|
||||
|
||||
return [msgId, channelId];
|
||||
}
|
||||
|
||||
public getMessageLocalId(fullMsgId: number) {
|
||||
return fullMsgId ? fullMsgId % this.fullMsgIdModulus : 0;
|
||||
}
|
||||
|
||||
public splitMessageIdsByChannels(mids: number[]) {
|
||||
const msgIdsByChannels: {[channelId: number]: number[]} = {};
|
||||
const midsByChannels: {[channelId: number]: number[]} = {};
|
||||
for(const mid of mids) {
|
||||
const msgChannel = this.getMessageIdInfo(mid);
|
||||
const channelId = msgChannel[1];
|
||||
|
||||
if(msgIdsByChannels[channelId] === undefined) {
|
||||
msgIdsByChannels[channelId] = [];
|
||||
midsByChannels[channelId] = [];
|
||||
}
|
||||
|
||||
msgIdsByChannels[channelId].push(msgChannel[0]);
|
||||
midsByChannels[channelId].push(mid);
|
||||
}
|
||||
|
||||
return {
|
||||
msgIds: msgIdsByChannels,
|
||||
mids: midsByChannels
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const appMessagesIdsManager = new AppMessagesIdsManager();
|
||||
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.appMessagesIdsManager = appMessagesIdsManager);
|
||||
export default appMessagesIdsManager;
|
File diff suppressed because it is too large
Load Diff
@ -159,21 +159,20 @@ export class AppPollsManager {
|
||||
};
|
||||
}
|
||||
|
||||
public sendVote(mid: number, optionIds: number[]): Promise<void> {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
public sendVote(peerId: number, messageId: number, optionIds: number[]): Promise<void> {
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, messageId);
|
||||
const poll: Poll = message.media.poll;
|
||||
|
||||
const options: Uint8Array[] = optionIds.map(index => {
|
||||
return poll.answers[index].option;
|
||||
});
|
||||
|
||||
const inputPeer = appPeersManager.getInputPeerById(message.peerId);
|
||||
const messageId = message.id;
|
||||
const inputPeer = appPeersManager.getInputPeerById(peerId);
|
||||
|
||||
if(mid < 0) {
|
||||
return appMessagesManager.invokeAfterMessageIsSent(mid, 'sendVote', (mid) => {
|
||||
if(messageId < 0) {
|
||||
return appMessagesManager.invokeAfterMessageIsSent(messageId, 'sendVote', (mid) => {
|
||||
this.log('invoke sendVote callback');
|
||||
return this.sendVote(mid, optionIds);
|
||||
return this.sendVote(peerId, mid, optionIds);
|
||||
});
|
||||
}
|
||||
|
||||
@ -187,10 +186,9 @@ export class AppPollsManager {
|
||||
});
|
||||
}
|
||||
|
||||
public getResults(mid: number) {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
public getResults(peerId: number, messageId: number) {
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, messageId);
|
||||
const inputPeer = appPeersManager.getInputPeerById(message.peerId);
|
||||
const messageId = message.id;
|
||||
|
||||
return apiManager.invokeApi('messages.getPollResults', {
|
||||
peer: inputPeer,
|
||||
@ -201,11 +199,7 @@ export class AppPollsManager {
|
||||
});
|
||||
}
|
||||
|
||||
public getVotes(mid: number, option?: Uint8Array, offset?: string, limit = 20) {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const inputPeer = appPeersManager.getInputPeerById(message.peerId);
|
||||
const messageId = message.id;
|
||||
|
||||
public getVotes(peerId: number, messageId: number, option?: Uint8Array, offset?: string, limit = 20) {
|
||||
let flags = 0;
|
||||
if(option) {
|
||||
flags |= 1 << 0;
|
||||
@ -217,7 +211,7 @@ export class AppPollsManager {
|
||||
|
||||
return apiManager.invokeApi('messages.getPollVotes', {
|
||||
flags,
|
||||
peer: inputPeer,
|
||||
peer: appPeersManager.getInputPeerById(peerId),
|
||||
id: messageId,
|
||||
option,
|
||||
offset,
|
||||
@ -231,15 +225,15 @@ export class AppPollsManager {
|
||||
});
|
||||
}
|
||||
|
||||
public stopPoll(mid: number) {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
public stopPoll(peerId: number, messageId: number) {
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, messageId);
|
||||
const poll: Poll = message.media.poll;
|
||||
|
||||
if(poll.pFlags.closed) return Promise.resolve();
|
||||
|
||||
const newPoll = copy(poll);
|
||||
newPoll.pFlags.closed = true;
|
||||
return appMessagesManager.editMessage(mid, undefined, {
|
||||
return appMessagesManager.editMessage(peerId, messageId, undefined, {
|
||||
newMedia: this.getInputMediaPoll(newPoll)
|
||||
}).then(() => {
|
||||
//console.log('stopped poll');
|
||||
|
@ -8,7 +8,6 @@ import { logger } from '../logger';
|
||||
import type { AppUsersManager } from './appUsersManager';
|
||||
import type { AppChatsManager } from './appChatsManager';
|
||||
import type { AuthState } from '../../types';
|
||||
import type { AppMessagesIdsManager } from './appMessagesIdsManager';
|
||||
import type FiltersStorage from '../storages/filters';
|
||||
import type DialogsStorage from '../storages/dialogs';
|
||||
|
||||
@ -33,11 +32,6 @@ type State = Partial<{
|
||||
stickerSets: AppStickersManager['stickerSets'],
|
||||
version: typeof STATE_VERSION,
|
||||
authState: AuthState,
|
||||
messagesIdsLocals: {
|
||||
channelLocals: AppMessagesIdsManager['channelLocals'],
|
||||
channelsByLocals: AppMessagesIdsManager['channelsByLocals'],
|
||||
channelCurLocal: AppMessagesIdsManager['channelCurLocal'],
|
||||
},
|
||||
hiddenPinnedMessages: {[peerId: string]: number}
|
||||
}>;
|
||||
|
||||
|
@ -13,6 +13,7 @@ export namespace ReferenceContext {
|
||||
|
||||
export type referenceContextMessage = {
|
||||
type: 'message',
|
||||
peerId: number,
|
||||
messageId: number
|
||||
};
|
||||
}
|
||||
@ -80,7 +81,7 @@ class ReferenceDatabase {
|
||||
[context, reference] = this.getContext(reference);
|
||||
switch(context?.type) {
|
||||
case 'message': {
|
||||
return appMessagesManager.wrapSingleMessage(context.messageId, true);
|
||||
return appMessagesManager.wrapSingleMessage(context.peerId, context.messageId, true);
|
||||
// .then(() => {
|
||||
// console.log('FILE_REFERENCE_EXPIRED: got message', context, appMessagesManager.getMessage((context as ReferenceContext.referenceContextMessage).messageId).media, reference);
|
||||
// });
|
||||
|
@ -44,14 +44,17 @@ type BroadcastEvents = {
|
||||
'messages_pending': void,
|
||||
'messages_read': void,
|
||||
'messages_downloaded': number[],
|
||||
'messages_media_read': number[],
|
||||
'messages_media_read': {peerId: number, mids: number[]},
|
||||
|
||||
'scheduled_new': {peerId: number, mid: number},
|
||||
'scheduled_delete': {peerId: number, mids: number[]},
|
||||
|
||||
'album_edit': {peerId: number, groupId: string, deletedMids: number[]},
|
||||
|
||||
'stickers_installed': StickerSet.stickerSet,
|
||||
'stickers_deleted': StickerSet.stickerSet,
|
||||
|
||||
'audio_play': {doc: MyDocument, mid: number},
|
||||
'audio_play': {doc: MyDocument, mid: number, peerId: number},
|
||||
'audio_pause': void,
|
||||
|
||||
'state_synchronized': number,
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { tsNow } from "../../helpers/date";
|
||||
import type { Message } from "../../layer";
|
||||
import type { AppChatsManager } from "../appManagers/appChatsManager";
|
||||
import type { AppMessagesIdsManager } from "../appManagers/appMessagesIdsManager";
|
||||
import type { AppMessagesManager, Dialog } from "../appManagers/appMessagesManager";
|
||||
import type { AppPeersManager } from "../appManagers/appPeersManager";
|
||||
import type { ServerTimeManager } from "../mtproto/serverTimeManager";
|
||||
@ -18,7 +17,7 @@ export default class DialogsStorage {
|
||||
};
|
||||
public dialogsNum = 0;
|
||||
|
||||
constructor(private appMessagesManager: AppMessagesManager, private appMessagesIdsManager: AppMessagesIdsManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private serverTimeManager: ServerTimeManager) {
|
||||
constructor(private appMessagesManager: AppMessagesManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private serverTimeManager: ServerTimeManager) {
|
||||
|
||||
}
|
||||
|
||||
@ -92,8 +91,8 @@ export default class DialogsStorage {
|
||||
|
||||
public generateIndexForDialog(dialog: Dialog, justReturn = false) {
|
||||
const channelId = this.appPeersManager.isChannel(dialog.peerId) ? -dialog.peerId : 0;
|
||||
const mid = this.appMessagesIdsManager.getFullMessageId(dialog.top_message, channelId);
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const mid = dialog.top_message;
|
||||
const message = this.appMessagesManager.getMessageByPeer(dialog.peerId, mid);
|
||||
|
||||
let topDate = (message as Message.message).date || Date.now() / 1000;
|
||||
if(channelId) {
|
||||
|
@ -189,7 +189,7 @@ $bubble-margin: .25rem;
|
||||
} */
|
||||
}
|
||||
|
||||
.chat:not(.type-pinned) & .bubble__container {
|
||||
.chat.type-chat & .bubble__container {
|
||||
cursor: pointer;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
@ -199,6 +199,7 @@
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
&-bio {
|
||||
|
Loading…
x
Reference in New Issue
Block a user