chore(core)!: moved full-specific fields to FullChat
breaking: `Chat` constructor signature changed. also removed some fields from`Chat`, but any code depending on them would be incorrect anyway
This commit is contained in:
parent
80ddf85083
commit
de8033e6d2
6 changed files with 217 additions and 220 deletions
|
@ -261,6 +261,7 @@ import {
|
|||
FileDownloadLocation,
|
||||
FileDownloadParameters,
|
||||
ForumTopic,
|
||||
FullChat,
|
||||
GameHighScore,
|
||||
HistoryReadUpdate,
|
||||
InlineCallbackQuery,
|
||||
|
@ -1562,7 +1563,7 @@ export interface TelegramClient extends ITelegramClient {
|
|||
* In case you are trying to get info about private chat that you haven't joined.
|
||||
* Use {@link getChatPreview} instead.
|
||||
*/
|
||||
getFullChat(chatId: InputPeerLike): Promise<Chat>
|
||||
getFullChat(chatId: InputPeerLike): Promise<FullChat>
|
||||
/**
|
||||
* Get nearby chats
|
||||
*
|
||||
|
|
|
@ -42,6 +42,7 @@ import {
|
|||
FileDownloadLocation,
|
||||
FileDownloadParameters,
|
||||
ForumTopic,
|
||||
FullChat,
|
||||
GameHighScore,
|
||||
HistoryReadUpdate,
|
||||
InlineCallbackQuery,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { tl } from '@mtcute/tl'
|
|||
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat, InputPeerLike } from '../../types/index.js'
|
||||
import { FullChat, InputPeerLike } from '../../types/index.js'
|
||||
import {
|
||||
INVITE_LINK_REGEX,
|
||||
isInputPeerChannel,
|
||||
|
@ -22,7 +22,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* In case you are trying to get info about private chat that you haven't joined.
|
||||
* Use {@link getChatPreview} instead.
|
||||
*/
|
||||
export async function getFullChat(client: ITelegramClient, chatId: InputPeerLike): Promise<Chat> {
|
||||
export async function getFullChat(client: ITelegramClient, chatId: InputPeerLike): Promise<FullChat> {
|
||||
if (typeof chatId === 'string') {
|
||||
const m = chatId.match(INVITE_LINK_REGEX)
|
||||
|
||||
|
@ -61,5 +61,5 @@ export async function getFullChat(client: ITelegramClient, chatId: InputPeerLike
|
|||
})
|
||||
} else throw new Error('should not happen')
|
||||
|
||||
return Chat._parseFull(res)
|
||||
return FullChat._parse(res)
|
||||
}
|
||||
|
|
|
@ -4,11 +4,9 @@ import { MtArgumentError, MtTypeAssertionError } from '../../../types/errors.js'
|
|||
import { getMarkedPeerId } from '../../../utils/peer-utils.js'
|
||||
import { makeInspectable } from '../../utils/index.js'
|
||||
import { memoizeGetters } from '../../utils/memoize.js'
|
||||
import { Photo } from '../media/photo.js'
|
||||
import { MessageEntity } from '../messages/message-entity.js'
|
||||
import { EmojiStatus } from '../reactions/emoji-status.js'
|
||||
import { ChatColors } from './chat-colors.js'
|
||||
import { ChatLocation } from './chat-location.js'
|
||||
import { ChatPermissions } from './chat-permissions.js'
|
||||
import { ChatPhoto } from './chat-photo.js'
|
||||
import { PeersIndex } from './peers-index.js'
|
||||
|
@ -36,10 +34,7 @@ export class Chat {
|
|||
*/
|
||||
readonly peer: tl.RawUser | tl.RawChat | tl.RawChannel | tl.RawChatForbidden | tl.RawChannelForbidden
|
||||
|
||||
constructor(
|
||||
peer: tl.TypeUser | tl.TypeChat,
|
||||
readonly fullPeer?: tl.TypeUserFull | tl.TypeChatFull,
|
||||
) {
|
||||
constructor(peer: tl.TypeUser | tl.TypeChat) {
|
||||
if (!peer) throw new MtArgumentError('peer is not available')
|
||||
|
||||
switch (peer._) {
|
||||
|
@ -283,15 +278,6 @@ export class Chat {
|
|||
return (this.peer._ === 'channel' || this.peer._ === 'chat') && this.peer.noforwards!
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this chat (user) has restricted sending them voice/video messages.
|
||||
*
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get hasBlockedVoices(): boolean {
|
||||
return this.fullPeer?._ === 'userFull' && this.fullPeer.voiceMessagesForbidden!
|
||||
}
|
||||
|
||||
/**
|
||||
* Title, for supergroups, channels and groups
|
||||
*/
|
||||
|
@ -357,7 +343,7 @@ export class Chat {
|
|||
* Chat photo, if any.
|
||||
* Suitable for downloads only.
|
||||
*
|
||||
* If full chat information is available, prefer {@link fullPhoto} instead.
|
||||
* If full chat information is available, prefer {@link FullChat#fullPhoto} instead.
|
||||
*/
|
||||
get photo(): ChatPhoto | null {
|
||||
if (
|
||||
|
@ -371,89 +357,6 @@ export class Chat {
|
|||
return new ChatPhoto(this.inputPeer, this.peer.photo)
|
||||
}
|
||||
|
||||
/**
|
||||
* Full information about this chat's photo, if any.
|
||||
*
|
||||
* Unlike {@link Chat.photo}, this field contains additional information
|
||||
* about the photo, such as its date, more sizes, and is the only
|
||||
* way to get the animated profile photo.
|
||||
*
|
||||
* This field takes into account any personal/fallback photo
|
||||
* that the user may have set
|
||||
*
|
||||
* Only available in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get fullPhoto(): Photo | null {
|
||||
if (!this.fullPeer) return null
|
||||
|
||||
let photo: tl.TypePhoto | undefined = undefined
|
||||
|
||||
switch (this.fullPeer._) {
|
||||
case 'userFull':
|
||||
photo = this.fullPeer.personalPhoto ?? this.fullPeer.profilePhoto ?? this.fullPeer.fallbackPhoto
|
||||
break
|
||||
case 'chatFull':
|
||||
case 'channelFull':
|
||||
photo = this.fullPeer.chatPhoto
|
||||
}
|
||||
|
||||
if (photo?._ !== 'photo') return null
|
||||
|
||||
return new Photo(photo)
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom photo (set by the current user) that should be displayed
|
||||
* instead of the actual chat photo.
|
||||
*
|
||||
* Currently only available for users.
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get personalPhoto(): Photo | null {
|
||||
if (!this.fullPeer || this.fullPeer._ !== 'userFull') return null
|
||||
if (this.fullPeer.personalPhoto?._ !== 'photo') return null
|
||||
|
||||
return new Photo(this.fullPeer.personalPhoto)
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual profile photo of the user, bypassing the custom one.
|
||||
*
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get realPhoto(): Photo | null {
|
||||
if (!this.fullPeer) return null
|
||||
if (this.fullPeer._ !== 'userFull') return this.fullPhoto
|
||||
if (this.fullPeer.personalPhoto?._ !== 'photo') return null
|
||||
|
||||
return new Photo(this.fullPeer.personalPhoto)
|
||||
}
|
||||
|
||||
/**
|
||||
* A photo that the user has set to be shown
|
||||
* in case their actual profile photo is not available
|
||||
* due to privacy settings.
|
||||
*
|
||||
* Currently only available for users.
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get publicPhoto(): Photo | null {
|
||||
if (!this.fullPeer || this.fullPeer._ !== 'userFull') return null
|
||||
if (this.fullPeer.fallbackPhoto?._ !== 'photo') return null
|
||||
|
||||
return new Photo(this.fullPeer.fallbackPhoto)
|
||||
}
|
||||
|
||||
/**
|
||||
* Bio of the other party in a private chat, or description of a
|
||||
* group, supergroup or channel.
|
||||
*
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get bio(): string | null {
|
||||
return this.fullPeer?.about ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* User's or bot's assigned DC (data center).
|
||||
* Available only in case the user has set a public profile photo.
|
||||
|
@ -472,55 +375,6 @@ export class Chat {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat's permanent invite link, for groups, supergroups and channels.
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get inviteLink(): string | null {
|
||||
if (this.fullPeer && this.fullPeer._ !== 'userFull') {
|
||||
switch (this.fullPeer.exportedInvite?._) {
|
||||
case 'chatInvitePublicJoinRequests':
|
||||
return null
|
||||
case 'chatInviteExported':
|
||||
return this.fullPeer.exportedInvite.link
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* For supergroups, name of the group sticker set.
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get stickerSetName(): string | null {
|
||||
return this.fullPeer && this.fullPeer._ === 'channelFull' ? this.fullPeer.stickerset?.shortName ?? null : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the group sticker set can be changed by you.
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get canSetStickerSet(): boolean | null {
|
||||
return this.fullPeer && this.fullPeer._ === 'channelFull' ? this.fullPeer.canSetStickers ?? null : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat members count, for groups, supergroups and channels only.
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get membersCount(): number | null {
|
||||
if (this.fullPeer && this.fullPeer._ !== 'userFull') {
|
||||
if (this.fullPeer._ === 'chatFull' && this.fullPeer.participants._ === 'chatParticipants') {
|
||||
return this.fullPeer.participants.participants.length
|
||||
} else if (this.fullPeer._ === 'channelFull') {
|
||||
return this.fullPeer.participantsCount ?? null
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of reasons why this chat might be unavailable to some users.
|
||||
* This field is available only in case {@link isRestricted} is `true`
|
||||
|
@ -565,38 +419,6 @@ export class Chat {
|
|||
*/
|
||||
readonly distance?: number
|
||||
|
||||
/**
|
||||
* Location of the chat.
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get location(): ChatLocation | null {
|
||||
if (!this.fullPeer || this.fullPeer._ !== 'channelFull' || this.fullPeer.location?._ !== 'channelLocation') {
|
||||
return null
|
||||
}
|
||||
|
||||
return new ChatLocation(this.fullPeer.location)
|
||||
}
|
||||
|
||||
private _linkedChat?: Chat
|
||||
/**
|
||||
* The linked discussion group (in case of channels)
|
||||
* or the linked channel (in case of supergroups).
|
||||
*
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get linkedChat(): Chat | null {
|
||||
return this._linkedChat ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* TTL of all messages in this chat, in seconds
|
||||
*
|
||||
* Returned only in {@link TelegramClient.getFullChat}
|
||||
*/
|
||||
get ttlPeriod(): number | null {
|
||||
return this.fullPeer?.ttlPeriod ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum ID of stories this chat has (or 0 if none)
|
||||
*/
|
||||
|
@ -676,37 +498,6 @@ export class Chat {
|
|||
return new Chat(peers.chat(peer.channelId))
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
static _parseFull(full: tl.messages.RawChatFull | tl.users.TypeUserFull): Chat {
|
||||
if (full._ === 'users.userFull') {
|
||||
const user = full.users.find((it) => it.id === full.fullUser.id)
|
||||
|
||||
if (!user || user._ === 'userEmpty') {
|
||||
throw new MtTypeAssertionError('Chat._parseFull', 'user', user?._ ?? 'undefined')
|
||||
}
|
||||
|
||||
return new Chat(user, full.fullUser)
|
||||
}
|
||||
|
||||
const fullChat = full.fullChat
|
||||
let chat: tl.TypeChat | undefined = undefined
|
||||
let linked: tl.TypeChat | undefined = undefined
|
||||
|
||||
for (const c of full.chats) {
|
||||
if (fullChat.id === c.id) {
|
||||
chat = c
|
||||
}
|
||||
if (fullChat._ === 'channelFull' && fullChat.linkedChatId === c.id) {
|
||||
linked = c
|
||||
}
|
||||
}
|
||||
|
||||
const ret = new Chat(chat!, fullChat)
|
||||
ret._linkedChat = linked ? new Chat(linked) : undefined
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mention for the chat.
|
||||
*
|
||||
|
@ -758,13 +549,8 @@ memoizeGetters(Chat, [
|
|||
'chatType',
|
||||
'usernames',
|
||||
'photo',
|
||||
'fullPhoto',
|
||||
'personalPhoto',
|
||||
'realPhoto',
|
||||
'publicPhoto',
|
||||
'permissions',
|
||||
'defaultPermissions',
|
||||
'location',
|
||||
'user',
|
||||
'color',
|
||||
])
|
||||
|
|
208
packages/core/src/highlevel/types/peers/full-chat.ts
Normal file
208
packages/core/src/highlevel/types/peers/full-chat.ts
Normal file
|
@ -0,0 +1,208 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtTypeAssertionError } from '../../../types/errors.js'
|
||||
import { makeInspectable } from '../../utils/inspectable.js'
|
||||
import { memoizeGetters } from '../../utils/memoize.js'
|
||||
import { Photo } from '../media/photo.js'
|
||||
import { Chat } from './chat.js'
|
||||
import { ChatLocation } from './chat-location.js'
|
||||
|
||||
/**
|
||||
* Complete information about a particular chat.
|
||||
*/
|
||||
export class FullChat extends Chat {
|
||||
constructor(
|
||||
peer: tl.TypeUser | tl.TypeChat,
|
||||
readonly fullPeer: tl.TypeUserFull | tl.TypeChatFull,
|
||||
) {
|
||||
super(peer)
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
static _parse(full: tl.messages.RawChatFull | tl.users.TypeUserFull): FullChat {
|
||||
if (full._ === 'users.userFull') {
|
||||
const user = full.users.find((it) => it.id === full.fullUser.id)
|
||||
|
||||
if (!user || user._ === 'userEmpty') {
|
||||
throw new MtTypeAssertionError('Chat._parseFull', 'user', user?._ ?? 'undefined')
|
||||
}
|
||||
|
||||
return new FullChat(user, full.fullUser)
|
||||
}
|
||||
|
||||
const fullChat = full.fullChat
|
||||
let chat: tl.TypeChat | undefined = undefined
|
||||
let linked: tl.TypeChat | undefined = undefined
|
||||
|
||||
for (const c of full.chats) {
|
||||
if (fullChat.id === c.id) {
|
||||
chat = c
|
||||
}
|
||||
if (fullChat._ === 'channelFull' && fullChat.linkedChatId === c.id) {
|
||||
linked = c
|
||||
}
|
||||
}
|
||||
|
||||
const ret = new FullChat(chat!, fullChat)
|
||||
ret._linkedChat = linked ? new Chat(linked) : undefined
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this chat (user) has restricted sending them voice/video messages.
|
||||
*/
|
||||
get hasBlockedVoices(): boolean {
|
||||
return this.fullPeer?._ === 'userFull' && this.fullPeer.voiceMessagesForbidden!
|
||||
}
|
||||
|
||||
/**
|
||||
* Full information about this chat's photo, if any.
|
||||
*
|
||||
* Unlike {@link Chat.photo}, this field contains additional information
|
||||
* about the photo, such as its date, more sizes, and is the only
|
||||
* way to get the animated profile photo.
|
||||
*
|
||||
* This field takes into account any personal/fallback photo
|
||||
* that the user may have set
|
||||
*/
|
||||
get fullPhoto(): Photo | null {
|
||||
if (!this.fullPeer) return null
|
||||
|
||||
let photo: tl.TypePhoto | undefined = undefined
|
||||
|
||||
switch (this.fullPeer._) {
|
||||
case 'userFull':
|
||||
photo = this.fullPeer.personalPhoto ?? this.fullPeer.profilePhoto ?? this.fullPeer.fallbackPhoto
|
||||
break
|
||||
case 'chatFull':
|
||||
case 'channelFull':
|
||||
photo = this.fullPeer.chatPhoto
|
||||
}
|
||||
|
||||
if (photo?._ !== 'photo') return null
|
||||
|
||||
return new Photo(photo)
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom photo (set by the current user) that should be displayed
|
||||
* instead of the actual chat photo.
|
||||
*
|
||||
* Currently only available for users.
|
||||
*/
|
||||
get personalPhoto(): Photo | null {
|
||||
if (!this.fullPeer || this.fullPeer._ !== 'userFull') return null
|
||||
if (this.fullPeer.personalPhoto?._ !== 'photo') return null
|
||||
|
||||
return new Photo(this.fullPeer.personalPhoto)
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual profile photo of the user, bypassing the custom one.
|
||||
*/
|
||||
get realPhoto(): Photo | null {
|
||||
if (!this.fullPeer) return null
|
||||
if (this.fullPeer._ !== 'userFull') return this.fullPhoto
|
||||
if (this.fullPeer.personalPhoto?._ !== 'photo') return null
|
||||
|
||||
return new Photo(this.fullPeer.personalPhoto)
|
||||
}
|
||||
|
||||
/**
|
||||
* A photo that the user has set to be shown
|
||||
* in case their actual profile photo is not available
|
||||
* due to privacy settings.
|
||||
*
|
||||
* Currently only available for users.
|
||||
*/
|
||||
get publicPhoto(): Photo | null {
|
||||
if (!this.fullPeer || this.fullPeer._ !== 'userFull') return null
|
||||
if (this.fullPeer.fallbackPhoto?._ !== 'photo') return null
|
||||
|
||||
return new Photo(this.fullPeer.fallbackPhoto)
|
||||
}
|
||||
|
||||
/**
|
||||
* Bio of the other party in a private chat, or description of a
|
||||
* group, supergroup or channel.
|
||||
*/
|
||||
get bio(): string | null {
|
||||
return this.fullPeer?.about ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat's permanent invite link, for groups, supergroups and channels.
|
||||
*/
|
||||
get inviteLink(): string | null {
|
||||
if (this.fullPeer && this.fullPeer._ !== 'userFull') {
|
||||
switch (this.fullPeer.exportedInvite?._) {
|
||||
case 'chatInvitePublicJoinRequests':
|
||||
return null
|
||||
case 'chatInviteExported':
|
||||
return this.fullPeer.exportedInvite.link
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* For supergroups, name of the group sticker set.
|
||||
*/
|
||||
get stickerSetName(): string | null {
|
||||
return this.fullPeer && this.fullPeer._ === 'channelFull' ? this.fullPeer.stickerset?.shortName ?? null : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the group sticker set can be changed by you.
|
||||
*/
|
||||
get canSetStickerSet(): boolean | null {
|
||||
return this.fullPeer && this.fullPeer._ === 'channelFull' ? this.fullPeer.canSetStickers ?? null : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat members count, for groups, supergroups and channels only.
|
||||
*/
|
||||
get membersCount(): number | null {
|
||||
if (this.fullPeer && this.fullPeer._ !== 'userFull') {
|
||||
if (this.fullPeer._ === 'chatFull' && this.fullPeer.participants._ === 'chatParticipants') {
|
||||
return this.fullPeer.participants.participants.length
|
||||
} else if (this.fullPeer._ === 'channelFull') {
|
||||
return this.fullPeer.participantsCount ?? null
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Location of the chat.
|
||||
*/
|
||||
get location(): ChatLocation | null {
|
||||
if (!this.fullPeer || this.fullPeer._ !== 'channelFull' || this.fullPeer.location?._ !== 'channelLocation') {
|
||||
return null
|
||||
}
|
||||
|
||||
return new ChatLocation(this.fullPeer.location)
|
||||
}
|
||||
|
||||
private _linkedChat?: Chat
|
||||
/**
|
||||
* The linked discussion group (in case of channels)
|
||||
* or the linked channel (in case of supergroups).
|
||||
*/
|
||||
get linkedChat(): Chat | null {
|
||||
return this._linkedChat ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* TTL of all messages in this chat, in seconds
|
||||
*/
|
||||
get ttlPeriod(): number | null {
|
||||
return this.fullPeer?.ttlPeriod ?? null
|
||||
}
|
||||
}
|
||||
|
||||
memoizeGetters(FullChat, ['fullPhoto', 'personalPhoto', 'realPhoto', 'publicPhoto', 'location'])
|
||||
makeInspectable(FullChat)
|
|
@ -8,6 +8,7 @@ export * from './chat-permissions.js'
|
|||
export * from './chat-photo.js'
|
||||
export * from './chat-preview.js'
|
||||
export * from './forum-topic.js'
|
||||
export * from './full-chat.js'
|
||||
export * from './peer.js'
|
||||
export * from './peers-index.js'
|
||||
export * from './typing-status.js'
|
||||
|
|
Loading…
Reference in a new issue