Browse Source

Groups online count

master
morethanwords 3 years ago
parent
commit
dbff308579
  1. 36
      src/helpers/cacheFunctionPolyfill.ts
  2. 3
      src/index.ts
  3. 4
      src/lang.ts
  4. 2
      src/lib/appManagers/appChatsManager.ts
  5. 26
      src/lib/appManagers/appImManager.ts
  6. 577
      src/lib/appManagers/appMessagesManager.ts
  7. 63
      src/lib/appManagers/appProfileManager.ts
  8. 9
      src/lib/appManagers/appUsersManager.ts

36
src/helpers/cacheFunctionPolyfill.ts

@ -0,0 +1,36 @@ @@ -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 {};

3
src/index.ts

@ -99,7 +99,7 @@ console.timeEnd('get storage1'); */ @@ -99,7 +99,7 @@ console.timeEnd('get storage1'); */
const workerProxy = new Proxy(Worker, workerHandler);
Worker = workerProxy;
const [_, touchSupport, userAgent, rootScope, appStateManager, I18n, __] = await Promise.all([
const [_, touchSupport, userAgent, rootScope, appStateManager, I18n, __/* , ___ */] = await Promise.all([
import('./lib/polyfill'),
import('./environment/touchSupport'),
import('./environment/userAgent'),
@ -107,6 +107,7 @@ console.timeEnd('get storage1'); */ @@ -107,6 +107,7 @@ console.timeEnd('get storage1'); */
import('./lib/appManagers/appStateManager'),
import('./lib/langPack'),
import('./helpers/peerIdPolyfill'),
// import('./helpers/cacheFunctionPolyfill')
]);
//console.timeEnd('get storage');

4
src/lang.ts

@ -588,6 +588,10 @@ const lang = { @@ -588,6 +588,10 @@ const lang = {
"AudioUnknownArtist": "Unknown artist",
"AudioUnknownTitle": "Unknown title",
"LogOut": "Log out",
"OnlineCount": {
"one_value": "%1$d online",
"other_value": "%1$d online"
},
// * macos
"AccountSettings.Filters": "Chat Folders",

2
src/lib/appManagers/appChatsManager.ts

@ -111,6 +111,8 @@ export class AppChatsManager { @@ -111,6 +111,8 @@ export class AppChatsManager {
}
public saveApiChats(apiChats: any[], override?: boolean) {
if((apiChats as any).saved) return;
(apiChats as any).saved = true;
apiChats.forEach(chat => this.saveApiChat(chat, override));
}

26
src/lib/appManagers/appImManager.ts

@ -42,7 +42,7 @@ import { MOUNT_CLASS_TO } from '../../config/debug'; @@ -42,7 +42,7 @@ import { MOUNT_CLASS_TO } from '../../config/debug';
import appNavigationController from '../../components/appNavigationController';
import appNotificationsManager from './appNotificationsManager';
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 { hslaStringToHex } from '../../helpers/color';
import { copy, getObjectKeysAndSort } from '../../helpers/object';
@ -71,6 +71,7 @@ import MEDIA_MIME_TYPES_SUPPORTED from '../../environment/mediaMimeTypesSupport' @@ -71,6 +71,7 @@ import MEDIA_MIME_TYPES_SUPPORTED from '../../environment/mediaMimeTypesSupport'
import { NULL_PEER_ID } from '../mtproto/mtproto_config';
import telegramMeWebManager from '../mtproto/telegramMeWebManager';
import { ONE_DAY } from '../../helpers/date';
import { numberThousandSplitter } from '../../helpers/number';
//console.log('appImManager included33!');
@ -1423,7 +1424,7 @@ export class AppImManager { @@ -1423,7 +1424,7 @@ export class AppImManager {
public async getPeerStatus(peerId: PeerId) {
let subtitle: HTMLElement;
if(!peerId) return '';
if(!peerId) return;
if(peerId.isAnyChat()) { // not human
let span = this.getPeerTyping(peerId);
@ -1431,18 +1432,25 @@ export class AppImManager { @@ -1431,18 +1432,25 @@ export class AppImManager {
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);
const participants_count = chatInfo.participants_count || (chatInfo.participants && chatInfo.participants.participants && chatInfo.participants.participants.length) || 1;
//if(participants_count) {
subtitle = appProfileManager.getChatMembersString(peerId.toChatId());
subtitle = appProfileManager.getChatMembersString(chatId);
if(participants_count < 2) return subtitle;
/* const onlines = await appChatsManager.getOnlines(chat.id);
if(participants_count < 2) {
return subtitle;
}
const onlines = await appProfileManager.getOnlines(chatId);
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;
//}
@ -1450,7 +1458,7 @@ export class AppImManager { @@ -1450,7 +1458,7 @@ export class AppImManager {
const user = appUsersManager.getUser(peerId);
if(rootScope.myId === peerId) {
return '';
return;
} else if(user) {
subtitle = appUsersManager.getUserStatusString(user.id);

577
src/lib/appManagers/appMessagesManager.ts

@ -19,7 +19,7 @@ import { randomLong } from "../../helpers/random"; @@ -19,7 +19,7 @@ import { randomLong } from "../../helpers/random";
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 { 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 type { ApiFileManager } from '../mtproto/apiFileManager';
//import apiManager from '../mtproto/apiManager';
@ -41,7 +41,7 @@ import appPollsManager from "./appPollsManager"; @@ -41,7 +41,7 @@ import appPollsManager from "./appPollsManager";
import appStateManager from "./appStateManager";
import appUsersManager from "./appUsersManager";
import appWebPagesManager from "./appWebPagesManager";
import appDraftsManager from "./appDraftsManager";
import appDraftsManager, { MyDraftMessage } from "./appDraftsManager";
import { getFileNameByLocation } from "../../helpers/fileName";
import appProfileManager from "./appProfileManager";
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
@ -2332,330 +2332,342 @@ export class AppMessagesManager { @@ -2332,330 +2332,342 @@ export class AppMessagesManager {
return appMessagesIdsManager.generateMessageId(dialog?.top_message || 0, true);
}
public saveMessages(messages: any[], options: Partial<{
public saveMessage(message: any, options: Partial<{
storage: MessagesStorage,
isScheduled: true,
isOutgoing: true,
//isNew: boolean, // * new - from update
}> = {}) {
//let groups: Set<string>;
messages.forEach((message) => {
if(message.pFlags === undefined) {
message.pFlags = {};
}
if(message.pFlags === undefined) {
message.pFlags = {};
}
if(message._ === 'messageEmpty') {
message.deleted = true;
return;
}
if(message._ === 'messageEmpty') {
message.deleted = true;
return;
}
// * exclude from state
// defineNotNumerableProperties(message, ['rReply', 'mid', 'savedFrom', 'fwdFromId', 'fromId', 'peerId', 'reply_to_mid', 'viaBotId']);
// * 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());
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.isScheduled) {
message.pFlags.is_scheduled = true;
}
if(options.isOutgoing) {
message.pFlags.is_outgoing = true;
}
const mid = appMessagesIdsManager.generateMessageId(message.id);
message.mid = mid;
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);
}
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;
}
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'])
}
// 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) {
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.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);
}
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;
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;
}
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;
/* 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);
message.fwdFromId = appPeersManager.getPeerId(fwdHeader.from_id);
if(!overwriting) {
fwdHeader.date -= serverTimeManager.serverTimeOffset;
}
if(!overwriting) {
fwdHeader.date -= serverTimeManager.serverTimeOffset;
}
}
if(message.via_bot_id > 0) {
message.viaBotId = message.via_bot_id;
}
if(message.via_bot_id > 0) {
message.viaBotId = message.via_bot_id;
}
const mediaContext: ReferenceContext = {
type: 'message',
peerId,
messageId: mid
};
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) {
switch(message.media._) {
case 'messageMediaEmpty': {
delete message.media;
break;
}
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
}
case 'messageMediaPhoto': {
if(message.media.ttl_seconds) {
message.media = {_: 'messageMediaUnsupportedWeb'};
} else {
message.media.photo = appPhotosManager.savePhoto(message.media.photo, mediaContext);
}
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':
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'};
break;
} 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(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 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);
}
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) {
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._ = isBroadcast ? 'messageActionChannelEditVideo' : 'messageActionChatEditVideo';
} else {
if(isBroadcast) { // ! messageActionChannelEditPhoto не существует в принципе, это используется для перевода.
// @ts-ignore
action._ = 'messageActionChannelEditPhoto';
}
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;
}
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;
// @ts-ignore
action.type = type;
break;
}
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 '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 '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;
}
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;
} 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 '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 'messageActionChannelMigrateFrom':
migrateFrom = action.chat_id.toPeerId(true);
migrateTo = peerId;
break
case 'messageActionChatMigrateTo':
migrateFrom = peerId;
migrateTo = action.channel_id.toPeerId(true);
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 '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);
}
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();
}
/* if(message.grouped_id) {
if(!groups) {
groups = new Set();
}
groups.add(message.grouped_id);
} else {
message.rReply = this.getRichReplyText(message);
} */
groups.add(message.grouped_id);
} else {
message.rReply = this.getRichReplyText(message);
} */
if(message.message && message.message.length && !message.totalEntities) {
this.wrapMessageEntities(message);
}
if(message.message && message.message.length && !message.totalEntities) {
this.wrapMessageEntities(message);
}
storage.set(mid, message);
}
storage.set(mid, message);
public saveMessages(messages: any[], options: Partial<{
storage: MessagesStorage,
isScheduled: true,
isOutgoing: true,
//isNew: boolean, // * new - from update
}> = {}) {
if((messages as any).saved) return;
(messages as any).saved = true;
messages.forEach((message) => {
this.saveMessage(message, options);
});
/* 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() : [];
message.message = RichTextProcessor.fixEmoji(message.message, apiEntities);
@ -2663,9 +2675,9 @@ export class AppMessagesManager { @@ -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
}
public wrapMessageForReply(message: any, 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: any, text: string = message.message, usingMids?: number[], plain?: boolean, highlightWord?: string, withoutMediaType?: boolean): DocumentFragment | string {
public wrapMessageForReply(message: MyMessage | MyDraftMessage, text: string, usingMids: number[], plain: true, highlightWord?: string, withoutMediaType?: boolean): string;
public wrapMessageForReply(message: MyMessage | MyDraftMessage, text?: string, usingMids?: number[], plain?: false, highlightWord?: string, withoutMediaType?: boolean): DocumentFragment;
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 addPart = (langKey: LangPackKey, part?: string | HTMLElement, text?: string) => {
@ -2687,7 +2699,7 @@ export class AppMessagesManager { @@ -2687,7 +2699,7 @@ export class AppMessagesManager {
}
};
if(message.media) {
if('media' in message) {
let usingFullAlbum = true;
if(message.grouped_id) {
if(usingMids) {
@ -2784,7 +2796,7 @@ export class AppMessagesManager { @@ -2784,7 +2796,7 @@ export class AppMessagesManager {
}
}
if(message.action) {
if('action' in message) {
const actionWrapped = this.wrapMessageActionTextNew(message, plain);
if(actionWrapped) {
addPart(undefined, actionWrapped);
@ -2865,20 +2877,21 @@ export class AppMessagesManager { @@ -2865,20 +2877,21 @@ export class AppMessagesManager {
return el;
}
public wrapMessageActionTextNew(message: any, plain: true): string;
public wrapMessageActionTextNew(message: any, plain?: false): HTMLElement;
public wrapMessageActionTextNew(message: any, plain: boolean): HTMLElement | string;
public wrapMessageActionTextNew(message: any, plain?: boolean): HTMLElement | string {
public wrapMessageActionTextNew(message: MyMessage, plain: true): string;
public wrapMessageActionTextNew(message: MyMessage, plain?: false): HTMLElement;
public wrapMessageActionTextNew(message: MyMessage, plain: boolean): HTMLElement | string;
public wrapMessageActionTextNew(message: MyMessage, plain?: boolean): HTMLElement | string {
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);
if((action as MessageAction.messageActionCustomAction).message) {
const unsafeMessage = (action as MessageAction.messageActionCustomAction).message;
if(plain) {
return RichTextProcessor.wrapPlainText(message.message);
return RichTextProcessor.wrapPlainText(unsafeMessage);
} else {
element.innerHTML = RichTextProcessor.wrapRichText((action as MessageAction.messageActionCustomAction).message, {noLinebreaks: true});
element.innerHTML = RichTextProcessor.wrapRichText(unsafeMessage, {noLinebreaks: true});
return element;
}
} else {
@ -2912,7 +2925,7 @@ export class AppMessagesManager { @@ -2912,7 +2925,7 @@ export class AppMessagesManager {
}
case 'messageActionInviteToGroupCall': {
const peerIds = [message.fromId, action.users[0]];
const peerIds = [message.fromId, action.users[0].toPeerId()];
let a = 'ActionGroupCall';
const myId = appUsersManager.getSelf().id;
if(peerIds[0] === myId) a += 'You';
@ -2942,7 +2955,7 @@ export class AppMessagesManager { @@ -2942,7 +2955,7 @@ export class AppMessagesManager {
args.push(getNameDivHTML(message.fromId, plain));
}
let k: LangPackKey, _args: any[] = [];
let k: LangPackKey, _args: FormatterArguments = [];
if(daysToStart < 1 && date.getDate() === today.getDate()) {
k = 'TodayAtFormattedWithToday';
} else if(daysToStart < 2 && date.getDate() === tomorrowDate.getDate()) {

63
src/lib/appManagers/appProfileManager.ts

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
import { MOUNT_CLASS_TO } from "../../config/debug";
import { tsNow } from "../../helpers/date";
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 apiManager from '../mtproto/apiManager';
import apiManager from '../mtproto/mtprotoworker';
@ -34,9 +34,6 @@ export class AppProfileManager { @@ -34,9 +34,6 @@ export class AppProfileManager {
public usersFull: {[id: UserId]: UserFull.userFull} = {};
public chatsFull: {[id: ChatId]: ChatFull} = {};
private fullPromises: {[peerId: PeerId]: Promise<ChatFull.chatFull | ChatFull.channelFull | UserFull>} = {};
private megagroupOnlines: {[id: ChatId]: {timestamp: number, onlines: number}};
private typingsInPeer: {[peerId: PeerId]: UserTyping[]};
constructor() {
@ -129,7 +126,6 @@ export class AppProfileManager { @@ -129,7 +126,6 @@ export class AppProfileManager {
this.invalidateChannelParticipants(chatId);
});
this.megagroupOnlines = {};
this.typingsInPeer = {};
}
@ -404,7 +400,7 @@ export class AppProfileManager { @@ -404,7 +400,7 @@ export class AppProfileManager {
break;
}
return Promise.reject(error);
throw error;
}) as any;
}
@ -461,7 +457,7 @@ export class AppProfileManager { @@ -461,7 +457,7 @@ export class AppProfileManager {
public invalidateChannelParticipants(id: ChatId) {
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);
rootScope.dispatchEvent('chat_full_update', id);
}
@ -494,7 +490,7 @@ export class AppProfileManager { @@ -494,7 +490,7 @@ export class AppProfileManager {
_: 'updateUserPhoto',
user_id: myId,
date: tsNow(true),
photo: appUsersManager.getUser(myId).photo,
photo: appUsersManager.getUser(myId.toUserId()).photo,
previous: true
});
});
@ -536,42 +532,43 @@ export class AppProfileManager { @@ -536,42 +532,43 @@ export class AppProfileManager {
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> {
const minOnline = 1;
if(appChatsManager.isBroadcast(id)) {
return minOnline;
}
const chatInfo = await this.getChatFull(id);
if(appChatsManager.isMegagroup(id)) {
const timestamp = Date.now() / 1000 | 0;
const cached = this.megagroupOnlines[id] ?? (this.megagroupOnlines[id] = {timestamp: 0, onlines: 1});
if((timestamp - cached.timestamp) < 60) {
return cached.onlines;
if((chatInfo as ChatFull.channelFull).participants_count <= 100) {
const channelParticipants = await this.getChannelParticipants(id, {_: 'channelParticipantsRecent'}, 100);
return this.reduceParticipantsForOnlineCount(channelParticipants.participants as ChannelParticipant.channelParticipant[]);
}
const res = await apiManager.invokeApi('messages.getOnlines', {
const res = await apiManager.invokeApiCacheable('messages.getOnlines', {
peer: appChatsManager.getChannelInputPeer(id)
});
const onlines = res.onlines ?? 1;
cached.timestamp = timestamp;
cached.onlines = onlines;
}, {cacheSeconds: 60});
const onlines = res.onlines ?? minOnline;
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;
if(_participants && _participants.participants) {
const participants = _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);
if(_participants?.participants) {
return this.reduceParticipantsForOnlineCount(_participants.participants);
} else {
return 1;
return minOnline;
}
}

9
src/lib/appManagers/appUsersManager.ts

@ -360,6 +360,8 @@ export class AppUsersManager { @@ -360,6 +360,8 @@ export class AppUsersManager {
}
public saveApiUsers(apiUsers: MTUser[], override?: boolean) {
if((apiUsers as any).saved) return;
(apiUsers as any).saved = true;
apiUsers.forEach((user) => this.saveApiUser(user, override));
}
@ -691,7 +693,6 @@ export class AppUsersManager { @@ -691,7 +693,6 @@ export class AppUsersManager {
if(user.status &&
user.status._ === 'userStatusOnline' &&
user.status.expires < timestampNow) {
user.status = {_: 'userStatusOffline', was_online: user.status.expires};
rootScope.dispatchEvent('user_update', user.id);
@ -902,17 +903,19 @@ export class AppUsersManager { @@ -902,17 +903,19 @@ export class AppUsersManager {
const user = this.users[userId];
if(user) {
const status: any = offline ? {
const status: UserStatus = offline ? {
_: 'userStatusOffline',
was_online: tsNow(true)
} : {
_: 'userStatusOnline',
expires: tsNow(true) + 500
expires: tsNow(true) + 50
};
user.status = status;
//user.sortStatus = this.getUserStatusForSort(user.status);
rootScope.dispatchEvent('user_update', userId);
this.setUserToStateIfNeeded(user);
}
}

Loading…
Cancel
Save