Telegram Web K with changes to work inside I2P https://web.telegram.i2p/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

411 lines
13 KiB

3 years ago
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*
* Originally from:
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
3 years ago
import type { Chat, ChatPhoto, DialogPeer, InputChannel, InputDialogPeer, InputNotifyPeer, InputPeer, Peer, Update, User, UserProfilePhoto } from "../../layer";
3 years ago
import type { LangPackKey } from "../langPack";
import { MOUNT_CLASS_TO } from "../../config/debug";
import { RichTextProcessor } from "../richtextprocessor";
import rootScope from "../rootScope";
import appChatsManager from "./appChatsManager";
import appUsersManager from "./appUsersManager";
import I18n from '../langPack';
3 years ago
import { NULL_PEER_ID } from "../mtproto/mtproto_config";
import { getRestrictionReason } from "../../helpers/restrictions";
import isObject from "../../helpers/object/isObject";
3 years ago
import limitSymbols from "../../helpers/string/limitSymbols";
3 years ago
// https://github.com/eelcohn/Telegram-API/wiki/Calculating-color-for-a-Telegram-user-on-IRC
/*
HTML-color IRC-color Description
#c03d33 4 red
#4fad2d 3 green
#d09306 7 yellow
#168acd 10 blue
#8544d6 6 purple
#cd4073 13 pink
#2996ad 11 sea
#ce671b 5 orange
*/
const DialogColorsFg = ['#fc5c51', '#0fb297', '#d09306', '#3d72ed', '#895dd5', '#cd4073', '#00c1a6', '#fa790f'];
const DialogColors = ['red', 'green', 'yellow', 'blue', 'violet', 'pink', 'cyan', 'orange'];
const DialogColorsMap = [0, 7, 4, 1, 6, 3, 5];
export type PeerType = 'channel' | 'chat' | 'megagroup' | 'group' | 'saved';
export class AppPeersManager {
3 years ago
/* public savePeerInstance(peerId: PeerId, instance: any) {
3 years ago
if(peerId < 0) appChatsManager.saveApiChat(instance);
else appUsersManager.saveApiUser(instance);
} */
3 years ago
public canPinMessage(peerId: PeerId) {
return peerId.isUser() || appChatsManager.hasRights(peerId.toChatId(), 'pin_messages');
3 years ago
}
3 years ago
public getPeerPhoto(peerId: PeerId): UserProfilePhoto.userProfilePhoto | ChatPhoto.chatPhoto {
if(this.isRestricted(peerId)) {
return;
}
3 years ago
const photo = peerId.isUser()
? appUsersManager.getUserPhoto(peerId.toUserId())
: appChatsManager.getChatPhoto(peerId.toChatId());
3 years ago
return photo._ !== 'chatPhotoEmpty' && photo._ !== 'userProfilePhotoEmpty' ? photo : undefined;
3 years ago
}
3 years ago
public getPeerMigratedTo(peerId: PeerId) {
if(peerId.isUser()) {
3 years ago
return false;
}
3 years ago
const chat: Chat.chat = appChatsManager.getChat(peerId.toChatId());
3 years ago
if(chat && chat.migrated_to && chat.pFlags.deactivated) {
3 years ago
return this.getPeerId(chat.migrated_to as InputChannel.inputChannel);
3 years ago
}
return false;
}
public getPeerTitle(peerId: PeerId, plainText: true, onlyFirstName?: boolean, _limitSymbols?: number): string;
public getPeerTitle(peerId: PeerId, plainText?: false, onlyFirstName?: boolean, _limitSymbols?: number): DocumentFragment;
public getPeerTitle(peerId: PeerId, plainText: boolean, onlyFirstName?: boolean, _limitSymbols?: number): DocumentFragment | string;
public getPeerTitle(peerId: PeerId, plainText = false, onlyFirstName = false, _limitSymbols?: number): DocumentFragment | string {
3 years ago
if(!peerId) {
peerId = rootScope.myId;
}
let title = '';
3 years ago
if(peerId.isUser()) {
const user = appUsersManager.getUser(peerId.toUserId());
if(user.first_name) title += user.first_name;
if(user.last_name && (!onlyFirstName || !title)) title += ' ' + user.last_name;
3 years ago
3 years ago
if(!title) title = user.pFlags.deleted ? I18n.format('HiddenName', true) : user.username;
3 years ago
else title = title.trim();
} else {
3 years ago
const chat: Chat.chat = appChatsManager.getChat(peerId.toChatId());
title = chat.title;
3 years ago
if(onlyFirstName) {
title = title.split(' ')[0];
}
3 years ago
}
if(_limitSymbols !== undefined) {
title = limitSymbols(title, _limitSymbols, _limitSymbols);
}
3 years ago
return plainText ? title : RichTextProcessor.wrapEmojiText(title);
}
3 years ago
public getOutputPeer(peerId: PeerId): Peer {
if(peerId.isUser()) {
return {_: 'peerUser', user_id: peerId.toUserId()};
3 years ago
}
3 years ago
const chatId = peerId.toChatId();
3 years ago
if(appChatsManager.isChannel(chatId)) {
return {_: 'peerChannel', channel_id: chatId};
}
return {_: 'peerChat', chat_id: chatId};
}
3 years ago
public getPeerString(peerId: PeerId) {
if(peerId.isUser()) {
return appUsersManager.getUserString(peerId.toUserId());
3 years ago
}
3 years ago
return appChatsManager.getChatString(peerId.toChatId());
3 years ago
}
3 years ago
public getPeerUsername(peerId: PeerId): string {
return this.getPeer(peerId).username || '';
3 years ago
}
3 years ago
public getPeer(peerId: PeerId) {
return peerId.isUser()
? appUsersManager.getUser(peerId.toUserId())
: appChatsManager.getChat(peerId.toChatId());
3 years ago
}
public getPeerInitials(peerId: PeerId) {
const peer: Chat | User = this.getPeer(peerId);
return RichTextProcessor.getAbbreviation(
(peer as Chat.chat).title ?? [(peer as User.user).first_name, (peer as User.user).last_name].filter(Boolean).join(' ')
);
}
3 years ago
public getPeerId(peerId: {user_id: UserId} | {channel_id: ChatId} | {chat_id: ChatId} | InputPeer | PeerId | string): PeerId {
3 years ago
if(peerId !== undefined && ((peerId as string).isPeerId ? (peerId as string).isPeerId() : false)) return peerId as PeerId;
// if(typeof(peerId) === 'string' && /^[uc]/.test(peerId)) return peerId as PeerId;
// if(typeof(peerId) === 'number') return peerId;
else if(isObject(peerId)) {
3 years ago
const userId = (peerId as Peer.peerUser).user_id;
if(userId !== undefined) {
return userId.toPeerId(false);
}
const chatId = (peerId as Peer.peerChannel).channel_id || (peerId as Peer.peerChat).chat_id;
if(chatId !== undefined) {
return chatId.toPeerId(true);
}
return rootScope.myId; // maybe it is an inputPeerSelf
3 years ago
// } else if(!peerId) return 'u0';
3 years ago
} else if(!peerId) return NULL_PEER_ID;
3 years ago
const isUser = (peerId as string).charAt(0) === 'u';
const peerParams = (peerId as string).substr(1).split('_');
3 years ago
return isUser ? peerParams[0].toPeerId() : (peerParams[0] || '').toPeerId(true);
3 years ago
}
3 years ago
public getDialogPeer(peerId: PeerId): DialogPeer {
3 years ago
return {
_: 'dialogPeer',
peer: this.getOutputPeer(peerId)
};
}
3 years ago
public isChannel(peerId: PeerId): boolean {
return !peerId.isUser() && appChatsManager.isChannel(peerId.toChatId());
3 years ago
}
3 years ago
public isMegagroup(peerId: PeerId) {
return !peerId.isUser() && appChatsManager.isMegagroup(peerId.toChatId());
3 years ago
}
3 years ago
public isAnyGroup(peerId: PeerId): boolean {
return !peerId.isUser() && !appChatsManager.isBroadcast(peerId.toChatId());
3 years ago
}
3 years ago
public isBroadcast(peerId: PeerId): boolean {
3 years ago
return this.isChannel(peerId) && !this.isMegagroup(peerId);
}
3 years ago
public isBot(peerId: PeerId): boolean {
return peerId.isUser() && appUsersManager.isBot(peerId.toUserId());
}
public isContact(peerId: PeerId): boolean {
return peerId.isUser() && appUsersManager.isContact(peerId.toUserId());
}
public isUser(peerId: PeerId)/* : peerId is UserId */ {
return +peerId >= 0;
}
public isAnyChat(peerId: PeerId) {
return !this.isUser(peerId);
3 years ago
}
public isRestricted(peerId: PeerId) {
return peerId.isUser() ? appUsersManager.isRestricted(peerId.toUserId()) : appChatsManager.isRestricted(peerId.toChatId());
}
public getRestrictionReasonText(peerId: PeerId) {
const peer: Chat.channel | User.user = this.getPeer(peerId);
const reason = peer.restriction_reason ? getRestrictionReason(peer.restriction_reason) : undefined;
if(reason) {
return reason.text;
} else {
return peerId.isUser() ? 'This user is restricted' : 'This chat is restricted';
}
}
3 years ago
/* public getInputPeer(peerString: string): InputPeer {
var firstChar = peerString.charAt(0);
var peerParams = peerString.substr(1).split('_');
let id = +peerParams[0];
if(firstChar === 'u') {
//appUsersManager.saveUserAccess(id, peerParams[1]);
return {
_: 'inputPeerUser',
user_id: id,
access_hash: peerParams[1]
};
} else if(firstChar === 'c' || firstChar === 's') {
//appChatsManager.saveChannelAccess(id, peerParams[1]);
if(firstChar === 's') {
appChatsManager.saveIsMegagroup(id);
}
return {
_: 'inputPeerChannel',
channel_id: id,
access_hash: peerParams[1] || '0'
};
} else {
return {
_: 'inputPeerChat',
chat_id: id
};
}
} */
3 years ago
public getInputNotifyPeerById(peerId: PeerId, ignorePeerId: true): Exclude<InputNotifyPeer, InputNotifyPeer.inputNotifyPeer>;
public getInputNotifyPeerById(peerId: PeerId, ignorePeerId?: false): InputNotifyPeer.inputNotifyPeer;
public getInputNotifyPeerById(peerId: PeerId, ignorePeerId?: boolean): InputNotifyPeer {
3 years ago
if(ignorePeerId) {
3 years ago
if(peerId.isUser()) {
3 years ago
return {_: 'inputNotifyUsers'};
} else {
3 years ago
if(this.isBroadcast(peerId)) {
3 years ago
return {_: 'inputNotifyBroadcasts'};
} else {
return {_: 'inputNotifyChats'};
}
}
} else {
return {
_: 'inputNotifyPeer',
peer: this.getInputPeerById(peerId)
};
}
}
3 years ago
public getInputPeerById(peerId: PeerId): InputPeer {
3 years ago
if(!peerId) {
return {_: 'inputPeerEmpty'};
}
3 years ago
if(!peerId.isUser()) {
const chatId = peerId.toChatId();
return appChatsManager.getInputPeer(chatId);
3 years ago
}
3 years ago
const userId = peerId.toUserId();
3 years ago
return appUsersManager.getUserInputPeer(userId);
}
public getInputPeerSelf(): InputPeer.inputPeerSelf {
return {_: 'inputPeerSelf'};
3 years ago
}
3 years ago
public getInputDialogPeerById(peerId: PeerId | InputPeer): InputDialogPeer {
3 years ago
return {
_: 'inputDialogPeer',
3 years ago
peer: isObject<InputPeer>(peerId) ? peerId : this.getInputPeerById(peerId)
};
3 years ago
}
3 years ago
public getPeerColorById(peerId: PeerId, pic = true) {
3 years ago
if(!peerId) return '';
3 years ago
const idx = DialogColorsMap[Math.abs(+peerId) % 7];
3 years ago
const color = (pic ? DialogColors : DialogColorsFg)[idx];
return color;
}
3 years ago
public getPeerSearchText(peerId: PeerId) {
let text: string;
if(this.isUser(peerId)) {
text = '%pu ' + appUsersManager.getUserSearchText(peerId.toUserId());
} else {
const chat = appChatsManager.getChat(peerId.toChatId());
3 years ago
text = '%pg ' + (chat.title || '');
}
3 years ago
3 years ago
return text;
}
3 years ago
public getDialogType(peerId: PeerId): PeerType {
if(this.isMegagroup(peerId)) {
3 years ago
return 'megagroup';
3 years ago
} else if(this.isChannel(peerId)) {
3 years ago
return 'channel';
3 years ago
} else if(!this.isUser(peerId)) {
3 years ago
return 'group';
} else {
return peerId === rootScope.myId ? 'saved' : 'chat';
}
}
3 years ago
public getDeleteButtonText(peerId: PeerId): LangPackKey {
3 years ago
switch(this.getDialogType(peerId)) {
case 'channel':
3 years ago
return appChatsManager.hasRights(peerId.toChatId(), 'delete_chat') ? 'ChannelDelete' : 'ChatList.Context.LeaveChannel';
3 years ago
case 'megagroup':
case 'group':
3 years ago
return appChatsManager.hasRights(peerId.toChatId(), 'delete_chat') ? 'DeleteMega' : 'ChatList.Context.LeaveGroup';
3 years ago
default:
return 'ChatList.Context.DeleteChat';
}
}
public noForwards(peerId: PeerId) {
if(peerId.isUser()) return false;
else {
const chat = appChatsManager.getChatTyped(peerId.toChatId());
return !!(chat as Chat.chat).pFlags?.noforwards;
}
}
3 years ago
}
export type IsPeerType = 'isChannel' | 'isMegagroup' | 'isAnyGroup' | 'isBroadcast' | 'isBot' | 'isContact' | 'isUser' | 'isAnyChat';
3 years ago
[
'isChannel',
'isMegagroup',
'isAnyGroup',
'isBroadcast',
'isBot',
'isContact',
'isUser',
'isAnyChat',
].forEach((value) => {
const newMethod = Array.isArray(value) ? value[0] : value;
const originMethod = Array.isArray(value) ? value[1] : value;
// @ts-ignore
String.prototype[newMethod] = function() {
// @ts-ignore
return appPeersManager[originMethod](this.toString());
};
// @ts-ignore
Number.prototype[newMethod] = function() {
// @ts-ignore
return appPeersManager[originMethod](this);
};
});
declare global {
interface String {
isChannel(): boolean;
isMegagroup(): boolean;
isAnyGroup(): boolean;
isBroadcast(): boolean;
isBot(): boolean;
isContact(): boolean;
isUser(): boolean;
isAnyChat(): boolean;
}
interface Number {
isChannel(): boolean;
isMegagroup(): boolean;
isAnyGroup(): boolean;
isBroadcast(): boolean;
isBot(): boolean;
isContact(): boolean;
isUser(): boolean;
isAnyChat(): boolean;
}
}
3 years ago
const appPeersManager = new AppPeersManager();
MOUNT_CLASS_TO.appPeersManager = appPeersManager;
export default appPeersManager;