fix(client): proper handling of last messages

This commit is contained in:
teidesu 2021-07-17 18:46:42 +03:00
parent 627fdbed2f
commit aa09262aae
9 changed files with 79 additions and 13 deletions

View file

@ -73,6 +73,7 @@ import { getDialogs } from './methods/dialogs/get-dialogs'
import { getFolders } from './methods/dialogs/get-folders'
import { getPeerDialogs } from './methods/dialogs/get-peer-dialogs'
import { _parseDialogs } from './methods/dialogs/parse-dialogs'
import { _pushConversationMessage } from './methods/dialogs/_init-conversation'
import { downloadAsBuffer } from './methods/files/download-buffer'
import { downloadToFile } from './methods/files/download-file'
import { downloadAsIterable } from './methods/files/download-iterable'
@ -177,6 +178,7 @@ import {
ChatPreview,
ChatsIndex,
ChosenInlineResult,
Conversation,
DeleteMessageUpdate,
Dialog,
FileDownloadParameters,
@ -3445,6 +3447,8 @@ export class TelegramClient extends BaseTelegramClient {
protected _userId: number | null
protected _isBot: boolean
protected _selfUsername: string | null
protected _pendingConversations: Record<number, Conversation[]>
protected _hasConversations: boolean
protected _downloadConnections: Record<number, TelegramConnection>
protected _connectionsForInline: Record<number, TelegramConnection>
protected _parseModes: Record<string, IMessageEntityParser>
@ -3465,6 +3469,8 @@ export class TelegramClient extends BaseTelegramClient {
this._userId = null
this._isBot = false
this._selfUsername = null
this._pendingConversations = {}
this._hasConversations = false
this._downloadConnections = {}
this._connectionsForInline = {}
this._parseModes = {}
@ -3556,6 +3562,7 @@ export class TelegramClient extends BaseTelegramClient {
getFolders = getFolders
getPeerDialogs = getPeerDialogs
protected _parseDialogs = _parseDialogs
protected _pushConversationMessage = _pushConversationMessage
downloadAsBuffer = downloadAsBuffer
downloadToFile = downloadToFile
downloadAsIterable = downloadAsIterable

View file

@ -52,6 +52,7 @@ import {
PollVoteUpdate,
UserStatusUpdate,
UserTypingUpdate,
Conversation
} from '../types'
// @copy

View file

@ -0,0 +1,33 @@
import { TelegramClient } from '../../client'
import { Conversation, Message } from '../../types'
import { getMarkedPeerId } from '@mtcute/core'
// @extension
interface ConversationsState {
_pendingConversations: Record<number, Conversation[]>
_hasConversations: boolean
}
// @initialize
function _initializeConversation(this: TelegramClient) {
this._pendingConversations = {}
this._hasConversations = false
}
/** @internal */
export function _pushConversationMessage(
this: TelegramClient,
msg: Message,
incoming = false
): void {
// shortcut
if (!this._hasConversations) return
const chatId = getMarkedPeerId(msg.raw.peerId)
const msgId = msg.raw.id
this._pendingConversations[chatId]?.forEach((conv) => {
conv['_lastMessage'] = msgId
if (incoming) conv['_lastReceivedMessage'] = msgId
})
}

View file

@ -255,6 +255,8 @@ export async function forwardMessages(
}
})
this._pushConversationMessage(forwarded[forwarded.length - 1])
if (isSingle) return forwarded[0]
if (captionMessage) forwarded.unshift(captionMessage)
return forwarded

View file

@ -189,7 +189,7 @@ export async function sendMediaGroup(
const { users, chats } = createUsersChatsIndex(res)
return res.updates
const msgs = res.updates
.filter(
(u) =>
u._ === 'updateNewMessage' ||
@ -206,4 +206,8 @@ export async function sendMediaGroup(
u._ === 'updateNewScheduledMessage'
)
)
this._pushConversationMessage(msgs[msgs.length - 1])
return msgs
}

View file

@ -175,5 +175,9 @@ export async function sendMedia(
clearDraft: params.clearDraft,
})
return this._findMessageInUpdate(res)
const msg = this._findMessageInUpdate(res)
this._pushConversationMessage(msg)
return msg
}

View file

@ -74,5 +74,7 @@ export async function sendScheduled(
)
)
this._pushConversationMessage(msgs[msgs.length - 1])
return isSingle ? msgs[0] : msgs
}

View file

@ -226,8 +226,12 @@ export async function sendText(
await fetchPeer(peer)
await fetchPeer(msg.fromId!)
return new Message(this, msg, users, chats)
const ret = new Message(this, msg, users, chats)
this._pushConversationMessage(ret)
return ret
}
return this._findMessageInUpdate(res)
const msg = this._findMessageInUpdate(res)
this._pushConversationMessage(msg)
return msg
}

View file

@ -109,6 +109,12 @@ export class Conversation {
this.client.on('new_message', this._onNewMessage)
this.client.on('edit_message', this._onEditMessage)
this.client.on('history_read', this._onHistoryRead)
if (!(this._chatId in this.client['_pendingConversations'])) {
this.client['_pendingConversations'][this._chatId] = []
}
this.client['_pendingConversations'][this._chatId].push(this)
this.client['_hasConversations'] = true
}
/**
@ -121,6 +127,15 @@ export class Conversation {
this.client.off('edit_message', this._onEditMessage)
this.client.off('history_read', this._onHistoryRead)
const idx = this.client['_pendingConversations'][this._chatId].indexOf(this)
if (idx > -1) { // just in case
this.client['_pendingConversations'][this._chatId].splice(idx, 1)
}
if (!this.client['_pendingConversations'][this._chatId].length) {
delete this.client['_pendingConversations'][this._chatId]
}
this.client['_hasConversations'] = Object.keys(this.client['_pendingConversations']).length > 0
// reset pending status
this._queuedNewMessage.clear()
this._pendingNewMessages.clear()
@ -145,9 +160,7 @@ export class Conversation {
throw new MtCuteArgumentError("Conversation hasn't started yet")
}
const res = await this.client.sendText(this._inputPeer, text, params)
this._lastMessage = res.id
return res
return this.client.sendText(this._inputPeer, text, params)
}
/**
@ -164,9 +177,7 @@ export class Conversation {
throw new MtCuteArgumentError("Conversation hasn't started yet")
}
const res = await this.client.sendMedia(this._inputPeer, media, params)
this._lastMessage = res.id
return res
return this.client.sendMedia(this._inputPeer, media, params)
}
/**
@ -183,13 +194,11 @@ export class Conversation {
throw new MtCuteArgumentError("Conversation hasn't started yet")
}
const res = await this.client.sendMediaGroup(
return this.client.sendMediaGroup(
this._inputPeer,
medias,
params
)
this._lastMessage = res[res.length - 1].id
return res
}
/**