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.
727 lines
22 KiB
727 lines
22 KiB
/* |
|
* 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 |
|
*/ |
|
|
|
import deepEqual from "../../helpers/object/deepEqual"; |
|
import isObject from "../../helpers/object/isObject"; |
|
import safeReplaceObject from "../../helpers/object/safeReplaceObject"; |
|
import { ChannelParticipant, ChannelsCreateChannel, Chat, ChatAdminRights, ChatBannedRights, ChatInvite, ChatPhoto, InputChannel, InputChatPhoto, InputFile, InputPeer, SponsoredMessage, Update, Updates } from "../../layer"; |
|
import { isRestricted } from "../../helpers/restrictions"; |
|
import { AppManager } from "./manager"; |
|
import getPeerId from "./utils/peers/getPeerId"; |
|
import hasRights from "./utils/chats/hasRights"; |
|
import getParticipantPeerId from "./utils/chats/getParticipantPeerId"; |
|
import { AppStoragesManager } from "./appStoragesManager"; |
|
|
|
export type Channel = Chat.channel; |
|
export type ChatRights = keyof ChatBannedRights['pFlags'] | keyof ChatAdminRights['pFlags'] | 'change_type' | 'change_permissions' | 'delete_chat' | 'view_participants'; |
|
|
|
export class AppChatsManager extends AppManager { |
|
private storage: AppStoragesManager['storages']['chats']; |
|
|
|
private chats: {[id: ChatId]: Chat.channel | Chat.chat | any}; |
|
//private usernames: any; |
|
//private channelAccess: any; |
|
//private megagroups: {[id: number]: true}; |
|
|
|
protected after() { |
|
this.clear(true); |
|
|
|
this.apiUpdatesManager.addMultipleEventsListeners({ |
|
/* updateChannel: (update) => { |
|
const channelId = update.channel_id; |
|
//console.log('updateChannel:', update); |
|
rootScope.broadcast('channel_settings', {channelId}); |
|
}, */ |
|
|
|
updateChannelParticipant: (update) => { |
|
this.apiManager.clearCache('channels.getParticipants', (params) => { |
|
return (params.channel as InputChannel.inputChannel).channel_id === update.channel_id; |
|
}); |
|
}, |
|
|
|
updateChatDefaultBannedRights: (update) => { |
|
const chatId = getPeerId(update.peer).toChatId(); |
|
const chat: Chat.chat = this.chats[chatId]; |
|
if(chat) { |
|
chat.default_banned_rights = update.default_banned_rights; |
|
this.rootScope.dispatchEvent('chat_update', chatId); |
|
} |
|
} |
|
}); |
|
|
|
return Promise.all([ |
|
this.appStateManager.getState(), |
|
this.appStoragesManager.loadStorage('chats') |
|
]).then(([state, {results: chats, storage}]) => { |
|
this.storage = storage; |
|
|
|
if(chats.length) { |
|
for(let i = 0, length = chats.length; i < length; ++i) { |
|
const chat = chats[i]; |
|
if(chat) { |
|
this.chats[chat.id] = chat; |
|
} |
|
} |
|
} |
|
|
|
this.peersStorage.addEventListener('peerNeeded', (peerId) => { |
|
if(peerId.isUser() || this.storage.getFromCache(peerId.toChatId())) { |
|
return; |
|
} |
|
|
|
this.storage.set({ |
|
[peerId.toChatId()]: this.getChat(peerId.toChatId()) |
|
}); |
|
}); |
|
|
|
this.peersStorage.addEventListener('peerUnneeded', (peerId) => { |
|
if(peerId.isUser() || !this.storage.getFromCache(peerId.toChatId())) { |
|
return; |
|
} |
|
|
|
this.storage.delete(peerId.toChatId()); |
|
}); |
|
}); |
|
} |
|
|
|
public clear = (init = false) => { |
|
if(!init) { |
|
for(const chatId in this.chats) { |
|
if(!chatId) continue; |
|
if(!this.peersStorage.isPeerNeeded(chatId.toPeerId(true))) { |
|
/* const chat = this.chats[chatId]; |
|
if(chat.username) { |
|
delete this.usernames[cleanUsername(chat.username)]; |
|
} */ |
|
|
|
this.storage.delete(chatId); |
|
delete this.chats[chatId]; |
|
} |
|
} |
|
} else { |
|
this.chats = {}; |
|
} |
|
}; |
|
|
|
public saveApiChats(apiChats: any[], override?: boolean) { |
|
if((apiChats as any).saved) return; |
|
(apiChats as any).saved = true; |
|
apiChats.forEach((chat) => this.saveApiChat(chat, override)); |
|
} |
|
|
|
public saveApiChat(chat: Chat, override?: boolean) { |
|
if(chat._ === 'chatEmpty') return; |
|
/* if(chat._ !== 'chat' && chat._ !== 'channel') { |
|
return; |
|
} */ |
|
|
|
// * exclude from state |
|
// defineNotNumerableProperties(chat, ['rTitle', 'initials']); |
|
|
|
const oldChat: Exclude<Chat, Chat.chatEmpty> = this.chats[chat.id]; |
|
|
|
/* if(oldChat && !override) { |
|
return; |
|
} */ |
|
|
|
if((chat as Chat.chat).pFlags === undefined) { |
|
(chat as Chat.chat).pFlags = {}; |
|
} |
|
|
|
if((chat as Chat.channel).pFlags.min && oldChat !== undefined) { |
|
return; |
|
} |
|
|
|
if(chat._ === 'channel' && |
|
chat.participants_count === undefined && |
|
oldChat !== undefined && |
|
(oldChat as Chat.channel).participants_count) { |
|
chat.participants_count = (oldChat as Chat.channel).participants_count; |
|
} |
|
|
|
/* if(chat.username) { |
|
let searchUsername = searchIndexManager.cleanUsername(chat.username); |
|
this.usernames[searchUsername] = chat.id; |
|
} */ |
|
|
|
let changedPhoto = false, changedTitle = false; |
|
if(oldChat === undefined) { |
|
this.chats[chat.id] = chat; |
|
} else { |
|
const oldPhotoId = ((oldChat as Chat.chat).photo as ChatPhoto.chatPhoto)?.photo_id; |
|
const newPhotoId = ((chat as Chat.chat).photo as ChatPhoto.chatPhoto)?.photo_id; |
|
if(oldPhotoId !== newPhotoId) { |
|
changedPhoto = true; |
|
} |
|
|
|
if(oldChat.title !== chat.title) { |
|
changedTitle = true; |
|
} |
|
|
|
safeReplaceObject(oldChat, chat); |
|
this.rootScope.dispatchEvent('chat_update', chat.id); |
|
} |
|
|
|
const peerId = chat.id.toPeerId(true); |
|
if(changedPhoto) { |
|
this.rootScope.dispatchEvent('avatar_update', peerId); |
|
} |
|
|
|
if(changedTitle) { |
|
this.rootScope.dispatchEvent('peer_title_edit', peerId); |
|
} |
|
|
|
if(this.peersStorage.isPeerNeeded(peerId)) { |
|
this.storage.set({ |
|
[chat.id]: chat |
|
}); |
|
} |
|
} |
|
|
|
public getChat(id: ChatId) { |
|
return this.chats[id] || {_: 'chatEmpty', id, deleted: true, access_hash: '', pFlags: {}/* this.channelAccess[id] */}; |
|
} |
|
|
|
public getChatTyped(id: ChatId): Chat { |
|
return this.getChat(id); |
|
} |
|
|
|
/** |
|
* Check the user's ability to do an action in chat |
|
* @param id |
|
* @param action creator can still send messages to left channel. so this function shows server rights. see canSendToPeer for local rights in messages manager. |
|
* @param rights do not provide this parameter when checking rights for self |
|
* @param isThread |
|
* @returns |
|
*/ |
|
public hasRights(id: ChatId, action: ChatRights, rights?: ChatAdminRights | ChatBannedRights, isThread?: boolean) { |
|
return hasRights(this.getChat(id), action, rights, isThread); |
|
} |
|
|
|
public editChatDefaultBannedRights(id: ChatId, banned_rights: ChatBannedRights) { |
|
const chat: Chat.chat = this.getChat(id); |
|
if(chat.default_banned_rights) { |
|
if(chat.default_banned_rights.until_date === banned_rights.until_date && deepEqual(chat.default_banned_rights.pFlags, banned_rights.pFlags)) { |
|
return Promise.resolve(); |
|
} |
|
} |
|
|
|
return this.apiManager.invokeApi('messages.editChatDefaultBannedRights', { |
|
peer: this.appPeersManager.getInputPeerById(id.toPeerId(true)), |
|
banned_rights |
|
}).then(this.onChatUpdated.bind(this, id)); |
|
} |
|
|
|
/* public resolveUsername(username: string) { |
|
return this.usernames[username] || 0; |
|
} */ |
|
|
|
/* public saveChannelAccess(id: ChatId, accessHash: string) { |
|
this.channelAccess[id] = accessHash; |
|
} */ |
|
|
|
/* public saveIsMegagroup(id: ChatId) { |
|
this.megagroups[id] = true; |
|
} */ |
|
|
|
public isChannel(id: ChatId) { |
|
const chat = this.chats[id]; |
|
return !!(chat && (chat._ === 'channel' || chat._ === 'channelForbidden')/* || this.channelAccess[id] */); |
|
} |
|
|
|
public isMegagroup(id: ChatId) { |
|
/* if(this.megagroups[id]) { |
|
return true; |
|
} */ |
|
|
|
const chat: Chat = this.chats[id]; |
|
return !!(chat as Chat.channel)?.pFlags?.megagroup; |
|
} |
|
|
|
public isBroadcast(id: ChatId) { |
|
return this.isChannel(id) && !this.isMegagroup(id); |
|
} |
|
|
|
public isInChat(id: ChatId) { |
|
let good = true; |
|
const chat: Chat = this.getChat(id); |
|
if(chat._ === 'channelForbidden' |
|
|| chat._ === 'chatForbidden' |
|
|| chat._ === 'chatEmpty' |
|
|| (chat as Chat.chat).pFlags.left |
|
// || (chat as any).pFlags.kicked |
|
|| (chat as Chat.chat).pFlags.deactivated) { |
|
good = false; |
|
} |
|
|
|
return good; |
|
} |
|
|
|
public getChannelInput(id: ChatId): InputChannel { |
|
const chat: Chat = this.getChat(id); |
|
if(chat._ === 'chatEmpty' || !(chat as Chat.channel).access_hash) { |
|
return { |
|
_: 'inputChannelEmpty' |
|
}; |
|
} else { |
|
return { |
|
_: 'inputChannel', |
|
channel_id: id, |
|
access_hash: (chat as Chat.channel).access_hash/* || this.channelAccess[id] */ || '0' |
|
}; |
|
} |
|
} |
|
|
|
public getInputPeer(id: ChatId) { |
|
return this.isChannel(id) ? this.getChannelInputPeer(id) : this.getChatInputPeer(id); |
|
} |
|
|
|
public getChatInputPeer(id: ChatId): InputPeer.inputPeerChat { |
|
return { |
|
_: 'inputPeerChat', |
|
chat_id: id |
|
}; |
|
} |
|
|
|
public getChannelInputPeer(id: ChatId): InputPeer.inputPeerChannel { |
|
return { |
|
_: 'inputPeerChannel', |
|
channel_id: id, |
|
access_hash: this.getChat(id).access_hash/* || this.channelAccess[id] */ || 0 |
|
}; |
|
} |
|
|
|
public hasChat(id: ChatId, allowMin?: true) { |
|
const chat = this.chats[id]; |
|
return isObject(chat) && (allowMin || !chat.pFlags.min); |
|
} |
|
|
|
public getChatPhoto(id: ChatId) { |
|
const chat: Chat.chat = this.getChat(id); |
|
|
|
return chat && chat.photo || { |
|
_: 'chatPhotoEmpty' |
|
}; |
|
} |
|
|
|
public getChatString(id: ChatId) { |
|
const chat = this.getChat(id); |
|
if(this.isChannel(id)) { |
|
return (this.isMegagroup(id) ? 's' : 'c') + id + '_' + chat.access_hash; |
|
} |
|
return 'g' + id; |
|
} |
|
|
|
/* public wrapForFull(id: number, fullChat: any) { |
|
const chatFull = copy(fullChat); |
|
const chat = this.getChat(id); |
|
|
|
if(!chatFull.participants_count) { |
|
chatFull.participants_count = chat.participants_count; |
|
} |
|
|
|
if(chatFull.participants && |
|
chatFull.participants._ === 'chatParticipants') { |
|
chatFull.participants.participants = this.wrapParticipants(id, chatFull.participants.participants); |
|
} |
|
|
|
if(chatFull.about) { |
|
chatFull.rAbout = wrapRichText(chatFull.about, {noLinebreaks: true}); |
|
} |
|
|
|
//chatFull.peerString = this.getChatString(id); |
|
chatFull.chat = chat; |
|
|
|
return chatFull; |
|
} |
|
|
|
public wrapParticipants(id: number, participants: any[]) { |
|
const chat = this.getChat(id); |
|
const myId = appUsersManager.getSelf().id; |
|
if(this.isChannel(id)) { |
|
const isAdmin = chat.pFlags.creator; |
|
participants.forEach((participant) => { |
|
participant.canLeave = myId === participant.user_id; |
|
participant.canKick = isAdmin && participant._ === 'channelParticipant'; |
|
|
|
// just for order by last seen |
|
participant.user = appUsersManager.getUser(participant.user_id); |
|
}); |
|
} else { |
|
const isAdmin = chat.pFlags.creator || chat.pFlags.admins_enabled && chat.pFlags.admin; |
|
participants.forEach((participant) => { |
|
participant.canLeave = myId === participant.user_id; |
|
participant.canKick = !participant.canLeave && ( |
|
chat.pFlags.creator || |
|
participant._ === 'chatParticipant' && (isAdmin || myId === participant.inviter_id) |
|
); |
|
|
|
// just for order by last seen |
|
participant.user = appUsersManager.getUser(participant.user_id); |
|
}); |
|
} |
|
|
|
return participants; |
|
} */ |
|
|
|
public createChannel(options: ChannelsCreateChannel): Promise<ChatId> { |
|
return this.apiManager.invokeApi('channels.createChannel', options).then((updates) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
|
|
const channelId = (updates as any).chats[0].id; |
|
return channelId; |
|
}); |
|
} |
|
|
|
public inviteToChannel(id: ChatId, userIds: UserId[]) { |
|
const input = this.getChannelInput(id); |
|
const usersInputs = userIds.map((u) => this.appUsersManager.getUserInput(u)); |
|
|
|
return this.apiManager.invokeApi('channels.inviteToChannel', { |
|
channel: input, |
|
users: usersInputs |
|
}).then(this.onChatUpdated.bind(this, id)); |
|
} |
|
|
|
public createChat(title: string, userIds: UserId[]): Promise<ChatId> { |
|
return this.apiManager.invokeApi('messages.createChat', { |
|
users: userIds.map((u) => this.appUsersManager.getUserInput(u)), |
|
title |
|
}).then((updates) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
|
|
const chatId = (updates as any as Updates.updates).chats[0].id; |
|
return chatId; |
|
}); |
|
} |
|
|
|
private onChatUpdated = (chatId: ChatId, updates?: any) => { |
|
//console.log('onChatUpdated', chatId, updates); |
|
|
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
if(updates?.updates?.length && this.isChannel(chatId)) { |
|
this.rootScope.dispatchEvent('invalidate_participants', chatId); |
|
} |
|
}; |
|
|
|
public leaveChannel(id: ChatId) { |
|
return this.apiManager.invokeApi('channels.leaveChannel', { |
|
channel: this.getChannelInput(id) |
|
}).then(this.onChatUpdated.bind(this, id)); |
|
} |
|
|
|
public joinChannel(id: ChatId) { |
|
return this.apiManager.invokeApi('channels.joinChannel', { |
|
channel: this.getChannelInput(id) |
|
}).then(this.onChatUpdated.bind(this, id)); |
|
} |
|
|
|
public addChatUser(id: ChatId, userId: UserId, fwdLimit = 100) { |
|
return this.apiManager.invokeApi('messages.addChatUser', { |
|
chat_id: id, |
|
user_id: this.appUsersManager.getUserInput(userId), |
|
fwd_limit: fwdLimit |
|
}).then(this.onChatUpdated.bind(this, id)); |
|
} |
|
|
|
public deleteChatUser(id: ChatId, userId: UserId) { |
|
return this.apiManager.invokeApi('messages.deleteChatUser', { |
|
chat_id: id, |
|
user_id: this.appUsersManager.getUserInput(userId) |
|
}).then(this.onChatUpdated.bind(this, id)); |
|
} |
|
|
|
public leaveChat(id: ChatId) { |
|
return this.deleteChatUser(id, this.appUsersManager.getSelf().id); |
|
} |
|
|
|
public leave(id: ChatId) { |
|
return this.isChannel(id) ? this.leaveChannel(id) : this.leaveChat(id); |
|
} |
|
|
|
public delete(id: ChatId) { |
|
return this.isChannel(id) ? this.deleteChannel(id) : this.deleteChat(id); |
|
} |
|
|
|
public deleteChannel(id: ChatId) { |
|
return this.apiManager.invokeApi('channels.deleteChannel', { |
|
channel: this.getChannelInput(id) |
|
}).then(this.onChatUpdated.bind(this, id)); |
|
} |
|
|
|
public deleteChat(id: ChatId) { |
|
//return this.leaveChat(id).then(() => { |
|
return this.apiManager.invokeApi('messages.deleteChat', { |
|
chat_id: id |
|
}); |
|
//}); |
|
} |
|
|
|
public migrateChat(id: ChatId): Promise<ChatId> { |
|
const chat: Chat = this.getChat(id); |
|
if(chat._ === 'channel') return Promise.resolve(chat.id); |
|
return this.apiManager.invokeApi('messages.migrateChat', { |
|
chat_id: id |
|
}).then((updates) => { |
|
this.onChatUpdated(id, updates); |
|
const update: Update.updateChannel = (updates as Updates.updates).updates.find((u) => u._ === 'updateChannel') as any; |
|
return update.channel_id; |
|
}); |
|
} |
|
|
|
public updateUsername(id: ChatId, username: string) { |
|
return this.apiManager.invokeApi('channels.updateUsername', { |
|
channel: this.getChannelInput(id), |
|
username |
|
}).then((bool) => { |
|
if(bool) { |
|
const chat: Chat.channel = this.getChat(id); |
|
chat.username = username; |
|
} |
|
|
|
return bool; |
|
}); |
|
} |
|
|
|
public editPhoto(id: ChatId, inputFile: InputFile) { |
|
const inputChatPhoto: InputChatPhoto = { |
|
_: 'inputChatUploadedPhoto', |
|
file: inputFile |
|
}; |
|
|
|
let promise: any; |
|
if(this.isChannel(id)) { |
|
promise = this.apiManager.invokeApi('channels.editPhoto', { |
|
channel: this.getChannelInput(id), |
|
photo: inputChatPhoto |
|
}); |
|
} else { |
|
promise = this.apiManager.invokeApi('messages.editChatPhoto', { |
|
chat_id: id, |
|
photo: inputChatPhoto |
|
}); |
|
} |
|
|
|
return promise.then((updates: any) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
}); |
|
} |
|
|
|
public editTitle(id: ChatId, title: string) { |
|
let promise: any; |
|
|
|
if(this.isChannel(id)) { |
|
promise = this.apiManager.invokeApi('channels.editTitle', { |
|
channel: this.getChannelInput(id), |
|
title |
|
}); |
|
} else { |
|
promise = this.apiManager.invokeApi('messages.editChatTitle', { |
|
chat_id: id, |
|
title |
|
}); |
|
} |
|
|
|
return promise.then((updates: any) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
}); |
|
} |
|
|
|
public editAbout(id: ChatId, about: string) { |
|
const peerId = id.toPeerId(true); |
|
return this.apiManager.invokeApi('messages.editChatAbout', { |
|
peer: this.appPeersManager.getInputPeerById(peerId), |
|
about |
|
}).then((bool) => { |
|
if(bool) { |
|
this.rootScope.dispatchEvent('peer_bio_edit', peerId); |
|
} |
|
|
|
return bool; |
|
}); |
|
} |
|
|
|
public editBanned(id: ChatId, participant: PeerId | ChannelParticipant, banned_rights: ChatBannedRights) { |
|
const peerId = typeof(participant) !== 'object' ? participant : getParticipantPeerId(participant); |
|
return this.apiManager.invokeApi('channels.editBanned', { |
|
channel: this.getChannelInput(id), |
|
participant: this.appPeersManager.getInputPeerById(peerId), |
|
banned_rights |
|
}).then((updates) => { |
|
this.onChatUpdated(id, updates); |
|
|
|
if(typeof(participant) === 'object') { |
|
const timestamp = Date.now() / 1000 | 0; |
|
this.apiUpdatesManager.processLocalUpdate({ |
|
_: 'updateChannelParticipant', |
|
channel_id: id, |
|
date: timestamp, |
|
actor_id: undefined, |
|
qts: undefined, |
|
user_id: peerId, |
|
prev_participant: participant, |
|
new_participant: Object.keys(banned_rights.pFlags).length ? { |
|
_: 'channelParticipantBanned', |
|
date: timestamp, |
|
banned_rights, |
|
kicked_by: this.appUsersManager.getSelf().id, |
|
peer: this.appPeersManager.getOutputPeer(peerId), |
|
pFlags: {} |
|
} : undefined |
|
}); |
|
} |
|
}); |
|
} |
|
|
|
public clearChannelParticipantBannedRights(id: ChatId, participant: PeerId | ChannelParticipant) { |
|
return this.editBanned(id, participant, { |
|
_: 'chatBannedRights', |
|
until_date: 0, |
|
pFlags: {} |
|
}); |
|
} |
|
|
|
public kickFromChannel(id: ChatId, participant: PeerId | ChannelParticipant) { |
|
return this.editBanned(id, participant, { |
|
_: 'chatBannedRights', |
|
until_date: 0, |
|
pFlags: { |
|
view_messages: true |
|
} |
|
}); |
|
} |
|
|
|
public kickFromChat(id: ChatId, participant: PeerId | ChannelParticipant) { |
|
if(this.isChannel(id)) return this.kickFromChannel(id, participant); |
|
else return this.deleteChatUser(id, (participant as PeerId).toUserId()); |
|
} |
|
|
|
public resolveChannel(id: ChatId) { |
|
return this.apiManager.invokeApiSingle('channels.getChannels', { |
|
id: [{ |
|
_: 'inputChannel', |
|
channel_id: id, |
|
access_hash: '0' |
|
}] |
|
}).then((messagesChats) => { |
|
this.saveApiChats(messagesChats.chats); |
|
}); |
|
} |
|
|
|
public togglePreHistoryHidden(id: ChatId, enabled: boolean) { |
|
return this.migrateChat(id).then((channelId) => { |
|
return this.apiManager.invokeApi('channels.togglePreHistoryHidden', { |
|
channel: this.getChannelInput(channelId), |
|
enabled |
|
}); |
|
}).then((updates) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
}); |
|
} |
|
|
|
public toggleSignatures(id: ChatId, enabled: boolean) { |
|
return this.apiManager.invokeApi('channels.toggleSignatures', { |
|
channel: this.getChannelInput(id), |
|
enabled |
|
}).then((updates) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
}); |
|
} |
|
|
|
public toggleNoForwards(id: ChatId, enabled: boolean) { |
|
return this.apiManager.invokeApi('messages.toggleNoForwards', { |
|
peer: this.getInputPeer(id), |
|
enabled |
|
}).then((updates) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
}); |
|
} |
|
|
|
public setChatAvailableReactions(id: ChatId, reactions: Array<string>) { |
|
return this.apiManager.invokeApi('messages.setChatAvailableReactions', { |
|
peer: this.getInputPeer(id), |
|
available_reactions: reactions |
|
}).then((updates) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
}); |
|
} |
|
|
|
public isRestricted(chatId: ChatId) { |
|
const chat: Chat.channel = this.getChat(chatId); |
|
const restrictionReasons = chat.restriction_reason; |
|
|
|
return !!(chat.pFlags.restricted && restrictionReasons && isRestricted(restrictionReasons)); |
|
} |
|
|
|
public getSendAs(channelId: ChatId) { |
|
return this.apiManager.invokeApiSingleProcess({ |
|
method: 'channels.getSendAs', |
|
params: { |
|
peer: this.getChannelInputPeer(channelId) |
|
}, |
|
processResult: (sendAsPeers) => { |
|
this.appUsersManager.saveApiUsers(sendAsPeers.users); |
|
this.saveApiChats(sendAsPeers.chats); |
|
|
|
return sendAsPeers.peers; |
|
} |
|
}); |
|
} |
|
|
|
public importChatInvite(hash: string) { |
|
return this.apiManager.invokeApi('messages.importChatInvite', {hash}) |
|
.then((updates) => { |
|
this.apiUpdatesManager.processUpdateMessage(updates); |
|
const chat = (updates as Updates.updates).chats[0]; |
|
return chat.id; |
|
}); |
|
} |
|
|
|
public checkUsername(chatId: ChatId, username: string) { |
|
return this.apiManager.invokeApi('channels.checkUsername', { |
|
channel: this.getChannelInput(chatId), |
|
username |
|
}); |
|
} |
|
|
|
public getSponsoredMessage(chatId: ChatId) { |
|
return this.apiManager.invokeApiCacheable('channels.getSponsoredMessages', { |
|
channel: this.getChannelInput(chatId) |
|
}, {cacheSeconds: 300}).then((sponsoredMessages) => { |
|
this.appUsersManager.saveApiUsers(sponsoredMessages.users); |
|
this.appChatsManager.saveApiChats(sponsoredMessages.chats); |
|
|
|
const sponsoredMessage = sponsoredMessages.messages.shift(); |
|
sponsoredMessages.messages.push(sponsoredMessage); |
|
|
|
return sponsoredMessages; |
|
}); |
|
} |
|
|
|
public viewSponsoredMessage(chatId: ChatId, randomId: SponsoredMessage['random_id']) { |
|
return this.apiManager.invokeApiSingle('channels.viewSponsoredMessage', { |
|
channel: this.getChannelInput(chatId), |
|
random_id: randomId |
|
}); |
|
} |
|
|
|
public checkChatInvite(hash: string) { |
|
return this.apiManager.invokeApi('messages.checkChatInvite', { |
|
hash: hash |
|
}).then((chatInvite) => { |
|
if((chatInvite as ChatInvite.chatInvitePeek).chat) { |
|
this.saveApiChat((chatInvite as ChatInvite.chatInvitePeek).chat, true); |
|
} |
|
|
|
return chatInvite; |
|
}); |
|
} |
|
}
|
|
|