Groups online count
This commit is contained in:
parent
596ae8453a
commit
dbff308579
36
src/helpers/cacheFunctionPolyfill.ts
Normal file
36
src/helpers/cacheFunctionPolyfill.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* https://github.com/morethanwords/tweb
|
||||||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ctx from "../environment/ctx";
|
||||||
|
|
||||||
|
type CacheFunction = (...args: any[]) => any;
|
||||||
|
const cache: Map<CacheFunction, {result: any, timeout: number}> = new Map();
|
||||||
|
|
||||||
|
Function.prototype.cache = function(thisArg, ...args: any[]) {
|
||||||
|
let cached = cache.get(this);
|
||||||
|
if(cached) {
|
||||||
|
return cached.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = this.apply(thisArg, args as any);
|
||||||
|
|
||||||
|
cache.set(this, cached = {
|
||||||
|
result,
|
||||||
|
timeout: ctx.setTimeout(() => {
|
||||||
|
cache.delete(this);
|
||||||
|
}, 60000)
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Function {
|
||||||
|
cache<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg?: T, ...args: A): R;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
@ -99,7 +99,7 @@ console.timeEnd('get storage1'); */
|
|||||||
const workerProxy = new Proxy(Worker, workerHandler);
|
const workerProxy = new Proxy(Worker, workerHandler);
|
||||||
Worker = workerProxy;
|
Worker = workerProxy;
|
||||||
|
|
||||||
const [_, touchSupport, userAgent, rootScope, appStateManager, I18n, __] = await Promise.all([
|
const [_, touchSupport, userAgent, rootScope, appStateManager, I18n, __/* , ___ */] = await Promise.all([
|
||||||
import('./lib/polyfill'),
|
import('./lib/polyfill'),
|
||||||
import('./environment/touchSupport'),
|
import('./environment/touchSupport'),
|
||||||
import('./environment/userAgent'),
|
import('./environment/userAgent'),
|
||||||
@ -107,6 +107,7 @@ console.timeEnd('get storage1'); */
|
|||||||
import('./lib/appManagers/appStateManager'),
|
import('./lib/appManagers/appStateManager'),
|
||||||
import('./lib/langPack'),
|
import('./lib/langPack'),
|
||||||
import('./helpers/peerIdPolyfill'),
|
import('./helpers/peerIdPolyfill'),
|
||||||
|
// import('./helpers/cacheFunctionPolyfill')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
//console.timeEnd('get storage');
|
//console.timeEnd('get storage');
|
||||||
|
@ -588,6 +588,10 @@ const lang = {
|
|||||||
"AudioUnknownArtist": "Unknown artist",
|
"AudioUnknownArtist": "Unknown artist",
|
||||||
"AudioUnknownTitle": "Unknown title",
|
"AudioUnknownTitle": "Unknown title",
|
||||||
"LogOut": "Log out",
|
"LogOut": "Log out",
|
||||||
|
"OnlineCount": {
|
||||||
|
"one_value": "%1$d online",
|
||||||
|
"other_value": "%1$d online"
|
||||||
|
},
|
||||||
|
|
||||||
// * macos
|
// * macos
|
||||||
"AccountSettings.Filters": "Chat Folders",
|
"AccountSettings.Filters": "Chat Folders",
|
||||||
|
@ -111,6 +111,8 @@ export class AppChatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public saveApiChats(apiChats: any[], override?: boolean) {
|
public saveApiChats(apiChats: any[], override?: boolean) {
|
||||||
|
if((apiChats as any).saved) return;
|
||||||
|
(apiChats as any).saved = true;
|
||||||
apiChats.forEach(chat => this.saveApiChat(chat, override));
|
apiChats.forEach(chat => this.saveApiChat(chat, override));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ import { MOUNT_CLASS_TO } from '../../config/debug';
|
|||||||
import appNavigationController from '../../components/appNavigationController';
|
import appNavigationController from '../../components/appNavigationController';
|
||||||
import appNotificationsManager from './appNotificationsManager';
|
import appNotificationsManager from './appNotificationsManager';
|
||||||
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
|
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
|
||||||
import { i18n, LangPackKey } from '../langPack';
|
import { i18n, join, LangPackKey } from '../langPack';
|
||||||
import { ChatInvite, Dialog, SendMessageAction } from '../../layer';
|
import { ChatInvite, Dialog, SendMessageAction } from '../../layer';
|
||||||
import { hslaStringToHex } from '../../helpers/color';
|
import { hslaStringToHex } from '../../helpers/color';
|
||||||
import { copy, getObjectKeysAndSort } from '../../helpers/object';
|
import { copy, getObjectKeysAndSort } from '../../helpers/object';
|
||||||
@ -71,6 +71,7 @@ import MEDIA_MIME_TYPES_SUPPORTED from '../../environment/mediaMimeTypesSupport'
|
|||||||
import { NULL_PEER_ID } from '../mtproto/mtproto_config';
|
import { NULL_PEER_ID } from '../mtproto/mtproto_config';
|
||||||
import telegramMeWebManager from '../mtproto/telegramMeWebManager';
|
import telegramMeWebManager from '../mtproto/telegramMeWebManager';
|
||||||
import { ONE_DAY } from '../../helpers/date';
|
import { ONE_DAY } from '../../helpers/date';
|
||||||
|
import { numberThousandSplitter } from '../../helpers/number';
|
||||||
|
|
||||||
//console.log('appImManager included33!');
|
//console.log('appImManager included33!');
|
||||||
|
|
||||||
@ -1423,7 +1424,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
public async getPeerStatus(peerId: PeerId) {
|
public async getPeerStatus(peerId: PeerId) {
|
||||||
let subtitle: HTMLElement;
|
let subtitle: HTMLElement;
|
||||||
if(!peerId) return '';
|
if(!peerId) return;
|
||||||
|
|
||||||
if(peerId.isAnyChat()) { // not human
|
if(peerId.isAnyChat()) { // not human
|
||||||
let span = this.getPeerTyping(peerId);
|
let span = this.getPeerTyping(peerId);
|
||||||
@ -1431,18 +1432,25 @@ export class AppImManager {
|
|||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
|
|
||||||
const chatInfo = await appProfileManager.getChatFull(peerId.toChatId()) as any;
|
const chatId = peerId.toChatId();
|
||||||
|
const chatInfo = await appProfileManager.getChatFull(chatId) as any;
|
||||||
this.chat.log('chatInfo res:', chatInfo);
|
this.chat.log('chatInfo res:', chatInfo);
|
||||||
|
|
||||||
const participants_count = chatInfo.participants_count || (chatInfo.participants && chatInfo.participants.participants && chatInfo.participants.participants.length) || 1;
|
const participants_count = chatInfo.participants_count || (chatInfo.participants && chatInfo.participants.participants && chatInfo.participants.participants.length) || 1;
|
||||||
//if(participants_count) {
|
//if(participants_count) {
|
||||||
subtitle = appProfileManager.getChatMembersString(peerId.toChatId());
|
subtitle = appProfileManager.getChatMembersString(chatId);
|
||||||
|
|
||||||
if(participants_count < 2) return subtitle;
|
if(participants_count < 2) {
|
||||||
/* const onlines = await appChatsManager.getOnlines(chat.id);
|
return subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onlines = await appProfileManager.getOnlines(chatId);
|
||||||
if(onlines > 1) {
|
if(onlines > 1) {
|
||||||
subtitle += ', ' + numberThousandSplitter(onlines) + ' online';
|
const span = document.createElement('span');
|
||||||
} */
|
|
||||||
|
span.append(...join([subtitle, i18n('OnlineCount', [numberThousandSplitter(onlines)])], false));
|
||||||
|
subtitle = span;
|
||||||
|
}
|
||||||
|
|
||||||
return subtitle;
|
return subtitle;
|
||||||
//}
|
//}
|
||||||
@ -1450,7 +1458,7 @@ export class AppImManager {
|
|||||||
const user = appUsersManager.getUser(peerId);
|
const user = appUsersManager.getUser(peerId);
|
||||||
|
|
||||||
if(rootScope.myId === peerId) {
|
if(rootScope.myId === peerId) {
|
||||||
return '';
|
return;
|
||||||
} else if(user) {
|
} else if(user) {
|
||||||
subtitle = appUsersManager.getUserStatusString(user.id);
|
subtitle = appUsersManager.getUserStatusString(user.id);
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import { randomLong } from "../../helpers/random";
|
|||||||
import { splitStringByLength, limitSymbols, escapeRegExp } from "../../helpers/string";
|
import { splitStringByLength, limitSymbols, escapeRegExp } from "../../helpers/string";
|
||||||
import { Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageMedia, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update, Photo, Updates, ReplyMarkup, InputPeer, InputPhoto, InputDocument, InputGeoPoint, WebPage, GeoPoint, ReportReason, MessagesGetDialogs, InputChannel, InputDialogPeer } from "../../layer";
|
import { Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageMedia, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update, Photo, Updates, ReplyMarkup, InputPeer, InputPhoto, InputDocument, InputGeoPoint, WebPage, GeoPoint, ReportReason, MessagesGetDialogs, InputChannel, InputDialogPeer } from "../../layer";
|
||||||
import { InvokeApiOptions } from "../../types";
|
import { InvokeApiOptions } from "../../types";
|
||||||
import I18n, { i18n, join, langPack, LangPackKey, _i18n } from "../langPack";
|
import I18n, { FormatterArguments, i18n, join, langPack, LangPackKey, _i18n } from "../langPack";
|
||||||
import { logger, LogTypes } from "../logger";
|
import { logger, LogTypes } from "../logger";
|
||||||
import type { ApiFileManager } from '../mtproto/apiFileManager';
|
import type { ApiFileManager } from '../mtproto/apiFileManager';
|
||||||
//import apiManager from '../mtproto/apiManager';
|
//import apiManager from '../mtproto/apiManager';
|
||||||
@ -41,7 +41,7 @@ import appPollsManager from "./appPollsManager";
|
|||||||
import appStateManager from "./appStateManager";
|
import appStateManager from "./appStateManager";
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
import appWebPagesManager from "./appWebPagesManager";
|
import appWebPagesManager from "./appWebPagesManager";
|
||||||
import appDraftsManager from "./appDraftsManager";
|
import appDraftsManager, { MyDraftMessage } from "./appDraftsManager";
|
||||||
import { getFileNameByLocation } from "../../helpers/fileName";
|
import { getFileNameByLocation } from "../../helpers/fileName";
|
||||||
import appProfileManager from "./appProfileManager";
|
import appProfileManager from "./appProfileManager";
|
||||||
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
|
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
@ -2332,330 +2332,342 @@ export class AppMessagesManager {
|
|||||||
return appMessagesIdsManager.generateMessageId(dialog?.top_message || 0, true);
|
return appMessagesIdsManager.generateMessageId(dialog?.top_message || 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public saveMessage(message: any, options: Partial<{
|
||||||
|
storage: MessagesStorage,
|
||||||
|
isScheduled: true,
|
||||||
|
isOutgoing: true,
|
||||||
|
//isNew: boolean, // * new - from update
|
||||||
|
}> = {}) {
|
||||||
|
if(message.pFlags === undefined) {
|
||||||
|
message.pFlags = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message._ === 'messageEmpty') {
|
||||||
|
message.deleted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * exclude from state
|
||||||
|
// defineNotNumerableProperties(message, ['rReply', 'mid', 'savedFrom', 'fwdFromId', 'fromId', 'peerId', 'reply_to_mid', 'viaBotId']);
|
||||||
|
|
||||||
|
const peerId = this.getMessagePeer(message);
|
||||||
|
const storage = options.storage || this.getMessagesStorage(peerId);
|
||||||
|
const isChannel = message.peer_id._ === 'peerChannel';
|
||||||
|
const isBroadcast = isChannel && appChatsManager.isBroadcast(peerId.toChatId());
|
||||||
|
|
||||||
|
if(options.isScheduled) {
|
||||||
|
message.pFlags.is_scheduled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.isOutgoing) {
|
||||||
|
message.pFlags.is_outgoing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mid = appMessagesIdsManager.generateMessageId(message.id);
|
||||||
|
message.mid = mid;
|
||||||
|
|
||||||
|
if(message.grouped_id) {
|
||||||
|
const storage = this.groupedMessagesStorage[message.grouped_id] ?? (this.groupedMessagesStorage[message.grouped_id] = new Map());
|
||||||
|
storage.set(mid, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dialog = this.getDialogOnly(peerId);
|
||||||
|
if(dialog && mid) {
|
||||||
|
if(mid > dialog[message.pFlags.out
|
||||||
|
? 'read_outbox_max_id'
|
||||||
|
: 'read_inbox_max_id']) {
|
||||||
|
message.pFlags.unread = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this.log(dT(), 'msg unread', mid, apiMessage.pFlags.out, dialog && dialog[apiMessage.pFlags.out ? 'read_outbox_max_id' : 'read_inbox_max_id'])
|
||||||
|
|
||||||
|
if(message.reply_to) {
|
||||||
|
if(message.reply_to.reply_to_msg_id) {
|
||||||
|
message.reply_to.reply_to_msg_id = message.reply_to_mid = appMessagesIdsManager.generateMessageId(message.reply_to.reply_to_msg_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.reply_to.reply_to_top_id) message.reply_to.reply_to_top_id = appMessagesIdsManager.generateMessageId(message.reply_to.reply_to_top_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.replies) {
|
||||||
|
if(message.replies.max_id) message.replies.max_id = appMessagesIdsManager.generateMessageId(message.replies.max_id);
|
||||||
|
if(message.replies.read_max_id) message.replies.read_max_id = appMessagesIdsManager.generateMessageId(message.replies.read_max_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const overwriting = !!peerId;
|
||||||
|
if(!overwriting) {
|
||||||
|
message.date -= serverTimeManager.serverTimeOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
//storage.generateIndex(message);
|
||||||
|
const myId = appUsersManager.getSelf().id;
|
||||||
|
|
||||||
|
message.peerId = peerId;
|
||||||
|
if(peerId === myId/* && !message.from_id && !message.fwd_from */) {
|
||||||
|
message.fromId = message.fwd_from ? (message.fwd_from.from_id ? appPeersManager.getPeerId(message.fwd_from.from_id) : 0) : myId;
|
||||||
|
} else {
|
||||||
|
//message.fromId = message.pFlags.post || (!message.pFlags.out && !message.from_id) ? peerId : appPeersManager.getPeerId(message.from_id);
|
||||||
|
message.fromId = message.pFlags.post || !message.from_id ? peerId : appPeersManager.getPeerId(message.from_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fwdHeader = message.fwd_from as MessageFwdHeader;
|
||||||
|
if(fwdHeader) {
|
||||||
|
//if(peerId === myID) {
|
||||||
|
if(fwdHeader.saved_from_msg_id) fwdHeader.saved_from_msg_id = appMessagesIdsManager.generateMessageId(fwdHeader.saved_from_msg_id);
|
||||||
|
if(fwdHeader.channel_post) fwdHeader.channel_post = appMessagesIdsManager.generateMessageId(fwdHeader.channel_post);
|
||||||
|
|
||||||
|
const peer = fwdHeader.saved_from_peer || fwdHeader.from_id;
|
||||||
|
const msgId = fwdHeader.saved_from_msg_id || fwdHeader.channel_post;
|
||||||
|
if(peer && msgId) {
|
||||||
|
const savedFromPeerId = appPeersManager.getPeerId(peer);
|
||||||
|
const savedFromMid = appMessagesIdsManager.generateMessageId(msgId);
|
||||||
|
message.savedFrom = savedFromPeerId + '_' + savedFromMid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if(peerId.isAnyChat() || peerId === myID) {
|
||||||
|
message.fromId = appPeersManager.getPeerID(!message.from_id || deepEqual(message.from_id, fwdHeader.from_id) ? fwdHeader.from_id : message.from_id);
|
||||||
|
} */
|
||||||
|
/* } else {
|
||||||
|
apiMessage.fwdPostID = fwdHeader.channel_post;
|
||||||
|
} */
|
||||||
|
|
||||||
|
message.fwdFromId = appPeersManager.getPeerId(fwdHeader.from_id);
|
||||||
|
|
||||||
|
if(!overwriting) {
|
||||||
|
fwdHeader.date -= serverTimeManager.serverTimeOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.via_bot_id > 0) {
|
||||||
|
message.viaBotId = message.via_bot_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mediaContext: ReferenceContext = {
|
||||||
|
type: 'message',
|
||||||
|
peerId,
|
||||||
|
messageId: mid
|
||||||
|
};
|
||||||
|
|
||||||
|
if(message.media) {
|
||||||
|
switch(message.media._) {
|
||||||
|
case 'messageMediaEmpty': {
|
||||||
|
delete message.media;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'messageMediaPhoto': {
|
||||||
|
if(message.media.ttl_seconds) {
|
||||||
|
message.media = {_: 'messageMediaUnsupportedWeb'};
|
||||||
|
} else {
|
||||||
|
message.media.photo = appPhotosManager.savePhoto(message.media.photo, mediaContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!message.media.photo) { // * found this bug on test DC
|
||||||
|
delete message.media;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'messageMediaPoll': {
|
||||||
|
const result = appPollsManager.savePoll(message.media.poll, message.media.results, message);
|
||||||
|
message.media.poll = result.poll;
|
||||||
|
message.media.results = result.results;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'messageMediaDocument': {
|
||||||
|
if(message.media.ttl_seconds) {
|
||||||
|
message.media = {_: 'messageMediaUnsupportedWeb'};
|
||||||
|
} else {
|
||||||
|
message.media.document = appDocsManager.saveDoc(message.media.document, mediaContext); // 11.04.2020 warning
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'messageMediaWebPage': {
|
||||||
|
const messageKey = appWebPagesManager.getMessageKeyForPendingWebPage(peerId, mid, options.isScheduled);
|
||||||
|
message.media.webpage = appWebPagesManager.saveWebPage(message.media.webpage, messageKey, mediaContext);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*case 'messageMediaGame':
|
||||||
|
AppGamesManager.saveGame(apiMessage.media.game, apiMessage.mid, mediaContext);
|
||||||
|
apiMessage.media.handleMessage = true;
|
||||||
|
break; */
|
||||||
|
|
||||||
|
case 'messageMediaInvoice': {
|
||||||
|
message.media = {_: 'messageMediaUnsupportedWeb'};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.action) {
|
||||||
|
const action = message.action as MessageAction;
|
||||||
|
let migrateFrom: PeerId;
|
||||||
|
let migrateTo: PeerId;
|
||||||
|
const suffix = message.fromId === appUsersManager.getSelf().id ? 'You' : '';
|
||||||
|
|
||||||
|
if((action as MessageAction.messageActionChatEditPhoto).photo) {
|
||||||
|
(action as MessageAction.messageActionChatEditPhoto).photo = appPhotosManager.savePhoto((action as MessageAction.messageActionChatEditPhoto).photo, mediaContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((action as any).document) {
|
||||||
|
(action as any).document = appDocsManager.saveDoc((action as any).photo, mediaContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(action._) {
|
||||||
|
//case 'messageActionChannelEditPhoto':
|
||||||
|
case 'messageActionChatEditPhoto':
|
||||||
|
// action.photo = appPhotosManager.savePhoto(action.photo, mediaContext);
|
||||||
|
if((action.photo as Photo.photo)?.video_sizes) {
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = isBroadcast ? 'messageActionChannelEditVideo' : 'messageActionChatEditVideo';
|
||||||
|
} else {
|
||||||
|
if(isBroadcast) { // ! messageActionChannelEditPhoto не существует в принципе, это используется для перевода.
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = 'messageActionChannelEditPhoto';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'messageActionGroupCall': {
|
||||||
|
//assumeType<MessageAction.messageActionGroupCall>(action);
|
||||||
|
|
||||||
|
let type: string;
|
||||||
|
if(action.duration === undefined) {
|
||||||
|
type = 'started';
|
||||||
|
if(peerId !== message.fromId) {
|
||||||
|
type += '_by' + suffix;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = 'ended_by' + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
action.type = type;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'messageActionChatEditTitle':
|
||||||
|
/* if(options.isNew) {
|
||||||
|
const chat = appChatsManager.getChat(peerId.toChatId());
|
||||||
|
chat.title = action.title;
|
||||||
|
appChatsManager.saveApiChat(chat, true);
|
||||||
|
} */
|
||||||
|
|
||||||
|
if(isBroadcast) {
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = 'messageActionChannelEditTitle';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'messageActionChatDeletePhoto':
|
||||||
|
if(isBroadcast) {
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = 'messageActionChannelDeletePhoto';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'messageActionChatAddUser':
|
||||||
|
if(action.users.length === 1) {
|
||||||
|
// @ts-ignore
|
||||||
|
action.user_id = action.users[0];
|
||||||
|
// @ts-ignore
|
||||||
|
if(message.fromId === action.user_id) {
|
||||||
|
if(isChannel) {
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = 'messageActionChatJoined' + suffix;
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = 'messageActionChatReturn' + suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(action.users.length > 1) {
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = 'messageActionChatAddUsers';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'messageActionChatDeleteUser':
|
||||||
|
if(message.fromId === action.user_id) {
|
||||||
|
// @ts-ignore
|
||||||
|
action._ = 'messageActionChatLeave' + suffix;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'messageActionChannelMigrateFrom':
|
||||||
|
migrateFrom = action.chat_id.toPeerId(true);
|
||||||
|
migrateTo = peerId;
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'messageActionChatMigrateTo':
|
||||||
|
migrateFrom = peerId;
|
||||||
|
migrateTo = action.channel_id.toPeerId(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'messageActionHistoryClear':
|
||||||
|
//apiMessage.deleted = true;
|
||||||
|
message.clear_history = true;
|
||||||
|
delete message.pFlags.out;
|
||||||
|
delete message.pFlags.unread;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'messageActionPhoneCall':
|
||||||
|
// @ts-ignore
|
||||||
|
action.type =
|
||||||
|
(message.pFlags.out ? 'out_' : 'in_') +
|
||||||
|
(
|
||||||
|
action.reason._ === 'phoneCallDiscardReasonMissed' ||
|
||||||
|
action.reason._ === 'phoneCallDiscardReasonBusy'
|
||||||
|
? 'missed'
|
||||||
|
: 'ok'
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(migrateFrom &&
|
||||||
|
migrateTo &&
|
||||||
|
!this.migratedFromTo[migrateFrom] &&
|
||||||
|
!this.migratedToFrom[migrateTo]) {
|
||||||
|
this.migrateChecks(migrateFrom, migrateTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if(message.grouped_id) {
|
||||||
|
if(!groups) {
|
||||||
|
groups = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
groups.add(message.grouped_id);
|
||||||
|
} else {
|
||||||
|
message.rReply = this.getRichReplyText(message);
|
||||||
|
} */
|
||||||
|
|
||||||
|
if(message.message && message.message.length && !message.totalEntities) {
|
||||||
|
this.wrapMessageEntities(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.set(mid, message);
|
||||||
|
}
|
||||||
|
|
||||||
public saveMessages(messages: any[], options: Partial<{
|
public saveMessages(messages: any[], options: Partial<{
|
||||||
storage: MessagesStorage,
|
storage: MessagesStorage,
|
||||||
isScheduled: true,
|
isScheduled: true,
|
||||||
isOutgoing: true,
|
isOutgoing: true,
|
||||||
//isNew: boolean, // * new - from update
|
//isNew: boolean, // * new - from update
|
||||||
}> = {}) {
|
}> = {}) {
|
||||||
//let groups: Set<string>;
|
if((messages as any).saved) return;
|
||||||
|
(messages as any).saved = true;
|
||||||
messages.forEach((message) => {
|
messages.forEach((message) => {
|
||||||
if(message.pFlags === undefined) {
|
this.saveMessage(message, options);
|
||||||
message.pFlags = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message._ === 'messageEmpty') {
|
|
||||||
message.deleted = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// * exclude from state
|
|
||||||
// defineNotNumerableProperties(message, ['rReply', 'mid', 'savedFrom', 'fwdFromId', 'fromId', 'peerId', 'reply_to_mid', 'viaBotId']);
|
|
||||||
|
|
||||||
const peerId = this.getMessagePeer(message);
|
|
||||||
const storage = options.storage || this.getMessagesStorage(peerId);
|
|
||||||
const isChannel = message.peer_id._ === 'peerChannel';
|
|
||||||
const isBroadcast = isChannel && appChatsManager.isBroadcast(peerId.toChatId());
|
|
||||||
|
|
||||||
if(options.isScheduled) {
|
|
||||||
message.pFlags.is_scheduled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(options.isOutgoing) {
|
|
||||||
message.pFlags.is_outgoing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mid = appMessagesIdsManager.generateMessageId(message.id);
|
|
||||||
message.mid = mid;
|
|
||||||
|
|
||||||
if(message.grouped_id) {
|
|
||||||
const storage = this.groupedMessagesStorage[message.grouped_id] ?? (this.groupedMessagesStorage[message.grouped_id] = new Map());
|
|
||||||
storage.set(mid, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
const dialog = this.getDialogOnly(peerId);
|
|
||||||
if(dialog && mid) {
|
|
||||||
if(mid > dialog[message.pFlags.out
|
|
||||||
? 'read_outbox_max_id'
|
|
||||||
: 'read_inbox_max_id']) {
|
|
||||||
message.pFlags.unread = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// this.log(dT(), 'msg unread', mid, apiMessage.pFlags.out, dialog && dialog[apiMessage.pFlags.out ? 'read_outbox_max_id' : 'read_inbox_max_id'])
|
|
||||||
|
|
||||||
if(message.reply_to) {
|
|
||||||
if(message.reply_to.reply_to_msg_id) {
|
|
||||||
message.reply_to.reply_to_msg_id = message.reply_to_mid = appMessagesIdsManager.generateMessageId(message.reply_to.reply_to_msg_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message.reply_to.reply_to_top_id) message.reply_to.reply_to_top_id = appMessagesIdsManager.generateMessageId(message.reply_to.reply_to_top_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message.replies) {
|
|
||||||
if(message.replies.max_id) message.replies.max_id = appMessagesIdsManager.generateMessageId(message.replies.max_id);
|
|
||||||
if(message.replies.read_max_id) message.replies.read_max_id = appMessagesIdsManager.generateMessageId(message.replies.read_max_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const overwriting = !!peerId;
|
|
||||||
if(!overwriting) {
|
|
||||||
message.date -= serverTimeManager.serverTimeOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
//storage.generateIndex(message);
|
|
||||||
const myId = appUsersManager.getSelf().id;
|
|
||||||
|
|
||||||
message.peerId = peerId;
|
|
||||||
if(peerId === myId/* && !message.from_id && !message.fwd_from */) {
|
|
||||||
message.fromId = message.fwd_from ? (message.fwd_from.from_id ? appPeersManager.getPeerId(message.fwd_from.from_id) : 0) : myId;
|
|
||||||
} else {
|
|
||||||
//message.fromId = message.pFlags.post || (!message.pFlags.out && !message.from_id) ? peerId : appPeersManager.getPeerId(message.from_id);
|
|
||||||
message.fromId = message.pFlags.post || !message.from_id ? peerId : appPeersManager.getPeerId(message.from_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fwdHeader = message.fwd_from as MessageFwdHeader;
|
|
||||||
if(fwdHeader) {
|
|
||||||
//if(peerId === myID) {
|
|
||||||
if(fwdHeader.saved_from_msg_id) fwdHeader.saved_from_msg_id = appMessagesIdsManager.generateMessageId(fwdHeader.saved_from_msg_id);
|
|
||||||
if(fwdHeader.channel_post) fwdHeader.channel_post = appMessagesIdsManager.generateMessageId(fwdHeader.channel_post);
|
|
||||||
|
|
||||||
const peer = fwdHeader.saved_from_peer || fwdHeader.from_id;
|
|
||||||
const msgId = fwdHeader.saved_from_msg_id || fwdHeader.channel_post;
|
|
||||||
if(peer && msgId) {
|
|
||||||
const savedFromPeerId = appPeersManager.getPeerId(peer);
|
|
||||||
const savedFromMid = appMessagesIdsManager.generateMessageId(msgId);
|
|
||||||
message.savedFrom = savedFromPeerId + '_' + savedFromMid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if(peerId.isAnyChat() || peerId === myID) {
|
|
||||||
message.fromId = appPeersManager.getPeerID(!message.from_id || deepEqual(message.from_id, fwdHeader.from_id) ? fwdHeader.from_id : message.from_id);
|
|
||||||
} */
|
|
||||||
/* } else {
|
|
||||||
apiMessage.fwdPostID = fwdHeader.channel_post;
|
|
||||||
} */
|
|
||||||
|
|
||||||
message.fwdFromId = appPeersManager.getPeerId(fwdHeader.from_id);
|
|
||||||
|
|
||||||
if(!overwriting) {
|
|
||||||
fwdHeader.date -= serverTimeManager.serverTimeOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message.via_bot_id > 0) {
|
|
||||||
message.viaBotId = message.via_bot_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mediaContext: ReferenceContext = {
|
|
||||||
type: 'message',
|
|
||||||
peerId,
|
|
||||||
messageId: mid
|
|
||||||
};
|
|
||||||
|
|
||||||
if(message.media) {
|
|
||||||
switch(message.media._) {
|
|
||||||
case 'messageMediaEmpty':
|
|
||||||
delete message.media;
|
|
||||||
break;
|
|
||||||
case 'messageMediaPhoto':
|
|
||||||
if(message.media.ttl_seconds) {
|
|
||||||
message.media = {_: 'messageMediaUnsupportedWeb'};
|
|
||||||
} else {
|
|
||||||
message.media.photo = appPhotosManager.savePhoto(message.media.photo, mediaContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!message.media.photo) { // * found this bug on test DC
|
|
||||||
delete message.media;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'messageMediaPoll':
|
|
||||||
const result = appPollsManager.savePoll(message.media.poll, message.media.results, message);
|
|
||||||
message.media.poll = result.poll;
|
|
||||||
message.media.results = result.results;
|
|
||||||
break;
|
|
||||||
case 'messageMediaDocument':
|
|
||||||
if(message.media.ttl_seconds) {
|
|
||||||
message.media = {_: 'messageMediaUnsupportedWeb'};
|
|
||||||
} else {
|
|
||||||
message.media.document = appDocsManager.saveDoc(message.media.document, mediaContext); // 11.04.2020 warning
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'messageMediaWebPage':
|
|
||||||
const messageKey = appWebPagesManager.getMessageKeyForPendingWebPage(peerId, mid, options.isScheduled);
|
|
||||||
message.media.webpage = appWebPagesManager.saveWebPage(message.media.webpage, messageKey, mediaContext);
|
|
||||||
break;
|
|
||||||
/*case 'messageMediaGame':
|
|
||||||
AppGamesManager.saveGame(apiMessage.media.game, apiMessage.mid, mediaContext);
|
|
||||||
apiMessage.media.handleMessage = true;
|
|
||||||
break; */
|
|
||||||
case 'messageMediaInvoice':
|
|
||||||
message.media = {_: 'messageMediaUnsupportedWeb'};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message.action) {
|
|
||||||
const action = message.action as MessageAction;
|
|
||||||
let migrateFrom: PeerId;
|
|
||||||
let migrateTo: PeerId;
|
|
||||||
const suffix = message.fromId === appUsersManager.getSelf().id ? 'You' : '';
|
|
||||||
|
|
||||||
if((action as MessageAction.messageActionChatEditPhoto).photo) {
|
|
||||||
(action as MessageAction.messageActionChatEditPhoto).photo = appPhotosManager.savePhoto((action as MessageAction.messageActionChatEditPhoto).photo, mediaContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((action as any).document) {
|
|
||||||
(action as any).document = appDocsManager.saveDoc((action as any).photo, mediaContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(action._) {
|
|
||||||
//case 'messageActionChannelEditPhoto':
|
|
||||||
case 'messageActionChatEditPhoto':
|
|
||||||
// action.photo = appPhotosManager.savePhoto(action.photo, mediaContext);
|
|
||||||
if((action.photo as Photo.photo)?.video_sizes) {
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = isBroadcast ? 'messageActionChannelEditVideo' : 'messageActionChatEditVideo';
|
|
||||||
} else {
|
|
||||||
if(isBroadcast) { // ! messageActionChannelEditPhoto не существует в принципе, это используется для перевода.
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = 'messageActionChannelEditPhoto';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'messageActionGroupCall': {
|
|
||||||
//assumeType<MessageAction.messageActionGroupCall>(action);
|
|
||||||
|
|
||||||
let type: string;
|
|
||||||
if(action.duration === undefined) {
|
|
||||||
type = 'started';
|
|
||||||
if(peerId !== message.fromId) {
|
|
||||||
type += '_by' + suffix;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
type = 'ended_by' + suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
action.type = type;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'messageActionChatEditTitle':
|
|
||||||
/* if(options.isNew) {
|
|
||||||
const chat = appChatsManager.getChat(peerId.toChatId());
|
|
||||||
chat.title = action.title;
|
|
||||||
appChatsManager.saveApiChat(chat, true);
|
|
||||||
} */
|
|
||||||
|
|
||||||
if(isBroadcast) {
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = 'messageActionChannelEditTitle';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'messageActionChatDeletePhoto':
|
|
||||||
if(isBroadcast) {
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = 'messageActionChannelDeletePhoto';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'messageActionChatAddUser':
|
|
||||||
if(action.users.length === 1) {
|
|
||||||
// @ts-ignore
|
|
||||||
action.user_id = action.users[0];
|
|
||||||
// @ts-ignore
|
|
||||||
if(message.fromId === action.user_id) {
|
|
||||||
if(isChannel) {
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = 'messageActionChatJoined' + suffix;
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = 'messageActionChatReturn' + suffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(action.users.length > 1) {
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = 'messageActionChatAddUsers';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'messageActionChatDeleteUser':
|
|
||||||
if(message.fromId === action.user_id) {
|
|
||||||
// @ts-ignore
|
|
||||||
action._ = 'messageActionChatLeave' + suffix;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'messageActionChannelMigrateFrom':
|
|
||||||
migrateFrom = action.chat_id.toPeerId(true);
|
|
||||||
migrateTo = peerId;
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'messageActionChatMigrateTo':
|
|
||||||
migrateFrom = peerId;
|
|
||||||
migrateTo = action.channel_id.toPeerId(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'messageActionHistoryClear':
|
|
||||||
//apiMessage.deleted = true;
|
|
||||||
message.clear_history = true;
|
|
||||||
delete message.pFlags.out;
|
|
||||||
delete message.pFlags.unread;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'messageActionPhoneCall':
|
|
||||||
// @ts-ignore
|
|
||||||
action.type =
|
|
||||||
(message.pFlags.out ? 'out_' : 'in_') +
|
|
||||||
(
|
|
||||||
action.reason._ === 'phoneCallDiscardReasonMissed' ||
|
|
||||||
action.reason._ === 'phoneCallDiscardReasonBusy'
|
|
||||||
? 'missed'
|
|
||||||
: 'ok'
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(migrateFrom &&
|
|
||||||
migrateTo &&
|
|
||||||
!this.migratedFromTo[migrateFrom] &&
|
|
||||||
!this.migratedToFrom[migrateTo]) {
|
|
||||||
this.migrateChecks(migrateFrom, migrateTo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if(message.grouped_id) {
|
|
||||||
if(!groups) {
|
|
||||||
groups = new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
groups.add(message.grouped_id);
|
|
||||||
} else {
|
|
||||||
message.rReply = this.getRichReplyText(message);
|
|
||||||
} */
|
|
||||||
|
|
||||||
if(message.message && message.message.length && !message.totalEntities) {
|
|
||||||
this.wrapMessageEntities(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.set(mid, message);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* if(groups) {
|
|
||||||
for(const groupId of groups) {
|
|
||||||
const mids = this.groupedMessagesStorage[groupId];
|
|
||||||
for(const mid in mids) {
|
|
||||||
const message = this.groupedMessagesStorage[groupId][mid];
|
|
||||||
message.rReply = this.getRichReplyText(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private wrapMessageEntities(message: any) {
|
private wrapMessageEntities(message: Message.message) {
|
||||||
const apiEntities = message.entities ? message.entities.slice() : [];
|
const apiEntities = message.entities ? message.entities.slice() : [];
|
||||||
message.message = RichTextProcessor.fixEmoji(message.message, apiEntities);
|
message.message = RichTextProcessor.fixEmoji(message.message, apiEntities);
|
||||||
|
|
||||||
@ -2663,9 +2675,9 @@ export class AppMessagesManager {
|
|||||||
message.totalEntities = RichTextProcessor.mergeEntities(apiEntities, myEntities); // ! only in this order, otherwise bold and emoji formatting won't work
|
message.totalEntities = RichTextProcessor.mergeEntities(apiEntities, myEntities); // ! only in this order, otherwise bold and emoji formatting won't work
|
||||||
}
|
}
|
||||||
|
|
||||||
public wrapMessageForReply(message: any, text: string, usingMids: number[], plain: true, highlightWord?: string, withoutMediaType?: boolean): string;
|
public wrapMessageForReply(message: MyMessage | MyDraftMessage, text: string, usingMids: number[], plain: true, highlightWord?: string, withoutMediaType?: boolean): string;
|
||||||
public wrapMessageForReply(message: any, text?: string, usingMids?: number[], plain?: false, highlightWord?: string, withoutMediaType?: boolean): DocumentFragment;
|
public wrapMessageForReply(message: MyMessage | MyDraftMessage, text?: string, usingMids?: number[], plain?: false, highlightWord?: string, withoutMediaType?: boolean): DocumentFragment;
|
||||||
public wrapMessageForReply(message: any, text: string = message.message, usingMids?: number[], plain?: boolean, highlightWord?: string, withoutMediaType?: boolean): DocumentFragment | string {
|
public wrapMessageForReply(message: MyMessage | MyDraftMessage, text: string = (message as Message.message).message, usingMids?: number[], plain?: boolean, highlightWord?: string, withoutMediaType?: boolean): DocumentFragment | string {
|
||||||
const parts: (HTMLElement | string)[] = [];
|
const parts: (HTMLElement | string)[] = [];
|
||||||
|
|
||||||
const addPart = (langKey: LangPackKey, part?: string | HTMLElement, text?: string) => {
|
const addPart = (langKey: LangPackKey, part?: string | HTMLElement, text?: string) => {
|
||||||
@ -2687,7 +2699,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(message.media) {
|
if('media' in message) {
|
||||||
let usingFullAlbum = true;
|
let usingFullAlbum = true;
|
||||||
if(message.grouped_id) {
|
if(message.grouped_id) {
|
||||||
if(usingMids) {
|
if(usingMids) {
|
||||||
@ -2784,7 +2796,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message.action) {
|
if('action' in message) {
|
||||||
const actionWrapped = this.wrapMessageActionTextNew(message, plain);
|
const actionWrapped = this.wrapMessageActionTextNew(message, plain);
|
||||||
if(actionWrapped) {
|
if(actionWrapped) {
|
||||||
addPart(undefined, actionWrapped);
|
addPart(undefined, actionWrapped);
|
||||||
@ -2865,20 +2877,21 @@ export class AppMessagesManager {
|
|||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
public wrapMessageActionTextNew(message: any, plain: true): string;
|
public wrapMessageActionTextNew(message: MyMessage, plain: true): string;
|
||||||
public wrapMessageActionTextNew(message: any, plain?: false): HTMLElement;
|
public wrapMessageActionTextNew(message: MyMessage, plain?: false): HTMLElement;
|
||||||
public wrapMessageActionTextNew(message: any, plain: boolean): HTMLElement | string;
|
public wrapMessageActionTextNew(message: MyMessage, plain: boolean): HTMLElement | string;
|
||||||
public wrapMessageActionTextNew(message: any, plain?: boolean): HTMLElement | string {
|
public wrapMessageActionTextNew(message: MyMessage, plain?: boolean): HTMLElement | string {
|
||||||
const element: HTMLElement = plain ? undefined : document.createElement('span');
|
const element: HTMLElement = plain ? undefined : document.createElement('span');
|
||||||
const action = message.action as MessageAction;
|
const action = 'action' in message && message.action;
|
||||||
|
|
||||||
// this.log('message action:', action);
|
// this.log('message action:', action);
|
||||||
|
|
||||||
if((action as MessageAction.messageActionCustomAction).message) {
|
if((action as MessageAction.messageActionCustomAction).message) {
|
||||||
|
const unsafeMessage = (action as MessageAction.messageActionCustomAction).message;
|
||||||
if(plain) {
|
if(plain) {
|
||||||
return RichTextProcessor.wrapPlainText(message.message);
|
return RichTextProcessor.wrapPlainText(unsafeMessage);
|
||||||
} else {
|
} else {
|
||||||
element.innerHTML = RichTextProcessor.wrapRichText((action as MessageAction.messageActionCustomAction).message, {noLinebreaks: true});
|
element.innerHTML = RichTextProcessor.wrapRichText(unsafeMessage, {noLinebreaks: true});
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2912,7 +2925,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'messageActionInviteToGroupCall': {
|
case 'messageActionInviteToGroupCall': {
|
||||||
const peerIds = [message.fromId, action.users[0]];
|
const peerIds = [message.fromId, action.users[0].toPeerId()];
|
||||||
let a = 'ActionGroupCall';
|
let a = 'ActionGroupCall';
|
||||||
const myId = appUsersManager.getSelf().id;
|
const myId = appUsersManager.getSelf().id;
|
||||||
if(peerIds[0] === myId) a += 'You';
|
if(peerIds[0] === myId) a += 'You';
|
||||||
@ -2942,7 +2955,7 @@ export class AppMessagesManager {
|
|||||||
args.push(getNameDivHTML(message.fromId, plain));
|
args.push(getNameDivHTML(message.fromId, plain));
|
||||||
}
|
}
|
||||||
|
|
||||||
let k: LangPackKey, _args: any[] = [];
|
let k: LangPackKey, _args: FormatterArguments = [];
|
||||||
if(daysToStart < 1 && date.getDate() === today.getDate()) {
|
if(daysToStart < 1 && date.getDate() === today.getDate()) {
|
||||||
k = 'TodayAtFormattedWithToday';
|
k = 'TodayAtFormattedWithToday';
|
||||||
} else if(daysToStart < 2 && date.getDate() === tomorrowDate.getDate()) {
|
} else if(daysToStart < 2 && date.getDate() === tomorrowDate.getDate()) {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
import { tsNow } from "../../helpers/date";
|
import { tsNow } from "../../helpers/date";
|
||||||
import { numberThousandSplitter } from "../../helpers/number";
|
import { numberThousandSplitter } from "../../helpers/number";
|
||||||
import { ChannelParticipantsFilter, ChannelsChannelParticipants, Chat, ChatFull, ChatParticipants, ChatPhoto, ExportedChatInvite, InputChannel, InputFile, InputFileLocation, PhotoSize, SendMessageAction, Update, UserFull, UserProfilePhoto } from "../../layer";
|
import { ChannelParticipantsFilter, ChannelsChannelParticipants, ChannelParticipant, Chat, ChatFull, ChatParticipants, ChatPhoto, ExportedChatInvite, InputChannel, InputFile, InputFileLocation, PhotoSize, SendMessageAction, Update, UserFull, UserProfilePhoto } from "../../layer";
|
||||||
import { LangPackKey, i18n } from "../langPack";
|
import { LangPackKey, i18n } from "../langPack";
|
||||||
//import apiManager from '../mtproto/apiManager';
|
//import apiManager from '../mtproto/apiManager';
|
||||||
import apiManager from '../mtproto/mtprotoworker';
|
import apiManager from '../mtproto/mtprotoworker';
|
||||||
@ -34,9 +34,6 @@ export class AppProfileManager {
|
|||||||
public usersFull: {[id: UserId]: UserFull.userFull} = {};
|
public usersFull: {[id: UserId]: UserFull.userFull} = {};
|
||||||
public chatsFull: {[id: ChatId]: ChatFull} = {};
|
public chatsFull: {[id: ChatId]: ChatFull} = {};
|
||||||
private fullPromises: {[peerId: PeerId]: Promise<ChatFull.chatFull | ChatFull.channelFull | UserFull>} = {};
|
private fullPromises: {[peerId: PeerId]: Promise<ChatFull.chatFull | ChatFull.channelFull | UserFull>} = {};
|
||||||
|
|
||||||
private megagroupOnlines: {[id: ChatId]: {timestamp: number, onlines: number}};
|
|
||||||
|
|
||||||
private typingsInPeer: {[peerId: PeerId]: UserTyping[]};
|
private typingsInPeer: {[peerId: PeerId]: UserTyping[]};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -129,7 +126,6 @@ export class AppProfileManager {
|
|||||||
this.invalidateChannelParticipants(chatId);
|
this.invalidateChannelParticipants(chatId);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.megagroupOnlines = {};
|
|
||||||
this.typingsInPeer = {};
|
this.typingsInPeer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +400,7 @@ export class AppProfileManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(error);
|
throw error;
|
||||||
}) as any;
|
}) as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +457,7 @@ export class AppProfileManager {
|
|||||||
|
|
||||||
public invalidateChannelParticipants(id: ChatId) {
|
public invalidateChannelParticipants(id: ChatId) {
|
||||||
delete this.chatsFull[id];
|
delete this.chatsFull[id];
|
||||||
delete this.fullPromises[-id];
|
delete this.fullPromises[id.toPeerId(true)];
|
||||||
apiManager.clearCache('channels.getParticipants', (params) => (params.channel as InputChannel.inputChannel).channel_id === id);
|
apiManager.clearCache('channels.getParticipants', (params) => (params.channel as InputChannel.inputChannel).channel_id === id);
|
||||||
rootScope.dispatchEvent('chat_full_update', id);
|
rootScope.dispatchEvent('chat_full_update', id);
|
||||||
}
|
}
|
||||||
@ -494,7 +490,7 @@ export class AppProfileManager {
|
|||||||
_: 'updateUserPhoto',
|
_: 'updateUserPhoto',
|
||||||
user_id: myId,
|
user_id: myId,
|
||||||
date: tsNow(true),
|
date: tsNow(true),
|
||||||
photo: appUsersManager.getUser(myId).photo,
|
photo: appUsersManager.getUser(myId.toUserId()).photo,
|
||||||
previous: true
|
previous: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -536,42 +532,43 @@ export class AppProfileManager {
|
|||||||
return i18n(key, [numberThousandSplitter(count)]);
|
return i18n(key, [numberThousandSplitter(count)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private verifyParticipantForOnlineCount(participant: {user_id: UserId}) {
|
||||||
|
const user = appUsersManager.getUser(participant.user_id);
|
||||||
|
return !!(user && user.status && user.status._ === 'userStatusOnline');
|
||||||
|
}
|
||||||
|
|
||||||
|
private reduceParticipantsForOnlineCount(participants: {user_id: UserId}[]) {
|
||||||
|
return participants.reduce((acc, participant) => {
|
||||||
|
return acc + +this.verifyParticipantForOnlineCount(participant);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public async getOnlines(id: ChatId): Promise<number> {
|
public async getOnlines(id: ChatId): Promise<number> {
|
||||||
|
const minOnline = 1;
|
||||||
|
if(appChatsManager.isBroadcast(id)) {
|
||||||
|
return minOnline;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatInfo = await this.getChatFull(id);
|
||||||
if(appChatsManager.isMegagroup(id)) {
|
if(appChatsManager.isMegagroup(id)) {
|
||||||
const timestamp = Date.now() / 1000 | 0;
|
if((chatInfo as ChatFull.channelFull).participants_count <= 100) {
|
||||||
const cached = this.megagroupOnlines[id] ?? (this.megagroupOnlines[id] = {timestamp: 0, onlines: 1});
|
const channelParticipants = await this.getChannelParticipants(id, {_: 'channelParticipantsRecent'}, 100);
|
||||||
if((timestamp - cached.timestamp) < 60) {
|
return this.reduceParticipantsForOnlineCount(channelParticipants.participants as ChannelParticipant.channelParticipant[]);
|
||||||
return cached.onlines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await apiManager.invokeApi('messages.getOnlines', {
|
const res = await apiManager.invokeApiCacheable('messages.getOnlines', {
|
||||||
peer: appChatsManager.getChannelInputPeer(id)
|
peer: appChatsManager.getChannelInputPeer(id)
|
||||||
});
|
}, {cacheSeconds: 60});
|
||||||
|
|
||||||
const onlines = res.onlines ?? 1;
|
|
||||||
cached.timestamp = timestamp;
|
|
||||||
cached.onlines = onlines;
|
|
||||||
|
|
||||||
|
const onlines = res.onlines ?? minOnline;
|
||||||
return onlines;
|
return onlines;
|
||||||
} else if(appChatsManager.isBroadcast(id)) {
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const chatInfo = await this.getChatFull(id);
|
|
||||||
const _participants = (chatInfo as ChatFull.chatFull).participants as ChatParticipants.chatParticipants;
|
const _participants = (chatInfo as ChatFull.chatFull).participants as ChatParticipants.chatParticipants;
|
||||||
if(_participants && _participants.participants) {
|
if(_participants?.participants) {
|
||||||
const participants = _participants.participants;
|
return this.reduceParticipantsForOnlineCount(_participants.participants);
|
||||||
|
|
||||||
return participants.reduce((acc: number, participant) => {
|
|
||||||
const user = appUsersManager.getUser(participant.user_id);
|
|
||||||
if(user && user.status && user.status._ === 'userStatusOnline') {
|
|
||||||
return acc + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, 0);
|
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return minOnline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +360,8 @@ export class AppUsersManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public saveApiUsers(apiUsers: MTUser[], override?: boolean) {
|
public saveApiUsers(apiUsers: MTUser[], override?: boolean) {
|
||||||
|
if((apiUsers as any).saved) return;
|
||||||
|
(apiUsers as any).saved = true;
|
||||||
apiUsers.forEach((user) => this.saveApiUser(user, override));
|
apiUsers.forEach((user) => this.saveApiUser(user, override));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,7 +693,6 @@ export class AppUsersManager {
|
|||||||
if(user.status &&
|
if(user.status &&
|
||||||
user.status._ === 'userStatusOnline' &&
|
user.status._ === 'userStatusOnline' &&
|
||||||
user.status.expires < timestampNow) {
|
user.status.expires < timestampNow) {
|
||||||
|
|
||||||
user.status = {_: 'userStatusOffline', was_online: user.status.expires};
|
user.status = {_: 'userStatusOffline', was_online: user.status.expires};
|
||||||
rootScope.dispatchEvent('user_update', user.id);
|
rootScope.dispatchEvent('user_update', user.id);
|
||||||
|
|
||||||
@ -902,17 +903,19 @@ export class AppUsersManager {
|
|||||||
|
|
||||||
const user = this.users[userId];
|
const user = this.users[userId];
|
||||||
if(user) {
|
if(user) {
|
||||||
const status: any = offline ? {
|
const status: UserStatus = offline ? {
|
||||||
_: 'userStatusOffline',
|
_: 'userStatusOffline',
|
||||||
was_online: tsNow(true)
|
was_online: tsNow(true)
|
||||||
} : {
|
} : {
|
||||||
_: 'userStatusOnline',
|
_: 'userStatusOnline',
|
||||||
expires: tsNow(true) + 500
|
expires: tsNow(true) + 50
|
||||||
};
|
};
|
||||||
|
|
||||||
user.status = status;
|
user.status = status;
|
||||||
//user.sortStatus = this.getUserStatusForSort(user.status);
|
//user.sortStatus = this.getUserStatusForSort(user.status);
|
||||||
rootScope.dispatchEvent('user_update', userId);
|
rootScope.dispatchEvent('user_update', userId);
|
||||||
|
|
||||||
|
this.setUserToStateIfNeeded(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user