From aa09262aae23ab5b3b2d86be296bb87819bebbf1 Mon Sep 17 00:00:00 2001 From: teidesu <86301490+teidesu@users.noreply.github.com> Date: Sat, 17 Jul 2021 18:46:42 +0300 Subject: [PATCH] fix(client): proper handling of last messages --- packages/client/src/client.ts | 7 ++++ packages/client/src/methods/_imports.ts | 1 + .../src/methods/dialogs/_init-conversation.ts | 33 +++++++++++++++++++ .../src/methods/messages/forward-messages.ts | 2 ++ .../src/methods/messages/send-media-group.ts | 6 +++- .../client/src/methods/messages/send-media.ts | 6 +++- .../src/methods/messages/send-scheduled.ts | 2 ++ .../client/src/methods/messages/send-text.ts | 8 +++-- packages/client/src/types/conversation.ts | 27 ++++++++++----- 9 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 packages/client/src/methods/dialogs/_init-conversation.ts diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 0ceba98d..b9c646ba 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -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 + protected _hasConversations: boolean protected _downloadConnections: Record protected _connectionsForInline: Record protected _parseModes: Record @@ -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 diff --git a/packages/client/src/methods/_imports.ts b/packages/client/src/methods/_imports.ts index 65048fa0..866f2e9d 100644 --- a/packages/client/src/methods/_imports.ts +++ b/packages/client/src/methods/_imports.ts @@ -52,6 +52,7 @@ import { PollVoteUpdate, UserStatusUpdate, UserTypingUpdate, + Conversation } from '../types' // @copy diff --git a/packages/client/src/methods/dialogs/_init-conversation.ts b/packages/client/src/methods/dialogs/_init-conversation.ts new file mode 100644 index 00000000..81461a55 --- /dev/null +++ b/packages/client/src/methods/dialogs/_init-conversation.ts @@ -0,0 +1,33 @@ +import { TelegramClient } from '../../client' +import { Conversation, Message } from '../../types' +import { getMarkedPeerId } from '@mtcute/core' + +// @extension +interface ConversationsState { + _pendingConversations: Record + _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 + }) +} diff --git a/packages/client/src/methods/messages/forward-messages.ts b/packages/client/src/methods/messages/forward-messages.ts index 7c83b463..1ba7279d 100644 --- a/packages/client/src/methods/messages/forward-messages.ts +++ b/packages/client/src/methods/messages/forward-messages.ts @@ -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 diff --git a/packages/client/src/methods/messages/send-media-group.ts b/packages/client/src/methods/messages/send-media-group.ts index 2535524a..4574e945 100644 --- a/packages/client/src/methods/messages/send-media-group.ts +++ b/packages/client/src/methods/messages/send-media-group.ts @@ -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 } diff --git a/packages/client/src/methods/messages/send-media.ts b/packages/client/src/methods/messages/send-media.ts index 1a872841..f4e6ac51 100644 --- a/packages/client/src/methods/messages/send-media.ts +++ b/packages/client/src/methods/messages/send-media.ts @@ -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 } diff --git a/packages/client/src/methods/messages/send-scheduled.ts b/packages/client/src/methods/messages/send-scheduled.ts index 8e475a82..ae37cc3f 100644 --- a/packages/client/src/methods/messages/send-scheduled.ts +++ b/packages/client/src/methods/messages/send-scheduled.ts @@ -74,5 +74,7 @@ export async function sendScheduled( ) ) + this._pushConversationMessage(msgs[msgs.length - 1]) + return isSingle ? msgs[0] : msgs } diff --git a/packages/client/src/methods/messages/send-text.ts b/packages/client/src/methods/messages/send-text.ts index 2f20d9a6..ae7ea01b 100644 --- a/packages/client/src/methods/messages/send-text.ts +++ b/packages/client/src/methods/messages/send-text.ts @@ -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 } diff --git a/packages/client/src/types/conversation.ts b/packages/client/src/types/conversation.ts index 2691561c..649e232f 100644 --- a/packages/client/src/types/conversation.ts +++ b/packages/client/src/types/conversation.ts @@ -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 } /**