From 77d597e4db4c5fb79b0d1d1134fac6d27a229015 Mon Sep 17 00:00:00 2001 From: teidesu <86301490+teidesu@users.noreply.github.com> Date: Fri, 9 Jul 2021 19:41:02 +0300 Subject: [PATCH] feat(dispatcher): history read update also fixed imports/exports --- packages/dispatcher/scripts/update-types.txt | 1 + packages/dispatcher/src/builders.ts | 48 ++++++- packages/dispatcher/src/dispatcher.ts | 66 +++++++++- packages/dispatcher/src/handler.ts | 22 +++- .../src/updates/history-read-update.ts | 123 ++++++++++++++++++ packages/dispatcher/src/updates/index.ts | 7 + 6 files changed, 246 insertions(+), 21 deletions(-) create mode 100644 packages/dispatcher/src/updates/history-read-update.ts diff --git a/packages/dispatcher/scripts/update-types.txt b/packages/dispatcher/scripts/update-types.txt index 4af49999..23a88143 100644 --- a/packages/dispatcher/scripts/update-types.txt +++ b/packages/dispatcher/scripts/update-types.txt @@ -12,3 +12,4 @@ poll: PollUpdate = PollUpdate poll_vote = PollVoteUpdate user_status: UserStatusUpdate = UserStatusUpdate user_typing = UserTypingUpdate +history_read = HistoryReadUpdate diff --git a/packages/dispatcher/src/builders.ts b/packages/dispatcher/src/builders.ts index c6cfc4d2..2f34d152 100644 --- a/packages/dispatcher/src/builders.ts +++ b/packages/dispatcher/src/builders.ts @@ -14,17 +14,21 @@ import { PollVoteHandler, UserStatusUpdateHandler, UserTypingHandler, + HistoryReadHandler, } from './handler' // end-codegen-imports import { filters, UpdateFilter } from './filters' import { CallbackQuery, InlineQuery, Message } from '@mtcute/client' -import { ChatMemberUpdate } from './updates' -import { ChosenInlineResult } from './updates/chosen-inline-result' -import { PollUpdate } from './updates/poll-update' -import { PollVoteUpdate } from './updates/poll-vote' -import { UserStatusUpdate } from './updates/user-status-update' -import { UserTypingUpdate } from './updates/user-typing-update' -import { DeleteMessageUpdate } from './updates/delete-message-update' +import { + ChatMemberUpdate, + ChosenInlineResult, + PollUpdate, + PollVoteUpdate, + UserStatusUpdate, + UserTypingUpdate, + DeleteMessageUpdate, + HistoryReadUpdate, +} from './updates' function _create( type: T['type'], @@ -385,5 +389,35 @@ export namespace handlers { return _create('user_typing', filter, handler) } + /** + * Create a history read handler + * + * @param handler History read handler + */ + export function historyRead( + handler: HistoryReadHandler['callback'] + ): HistoryReadHandler + + /** + * Create a history read handler with a filter + * + * @param filter Update filter + * @param handler History read handler + */ + export function historyRead( + filter: UpdateFilter, + handler: HistoryReadHandler< + filters.Modify + >['callback'] + ): HistoryReadHandler + + /** @internal */ + export function historyRead( + filter: any, + handler?: any + ): HistoryReadHandler { + return _create('history_read', filter, handler) + } + // end-codegen } diff --git a/packages/dispatcher/src/dispatcher.ts b/packages/dispatcher/src/dispatcher.ts index 5391f38f..254ae1e6 100644 --- a/packages/dispatcher/src/dispatcher.ts +++ b/packages/dispatcher/src/dispatcher.ts @@ -25,18 +25,22 @@ import { PollVoteHandler, UserStatusUpdateHandler, UserTypingHandler, + HistoryReadHandler, } from './handler' // end-codegen-imports import { UpdateInfo } from './handler' import { filters, UpdateFilter } from './filters' import { handlers } from './builders' -import { ChatMemberUpdate } from './updates' -import { ChosenInlineResult } from './updates/chosen-inline-result' -import { PollUpdate } from './updates/poll-update' -import { PollVoteUpdate } from './updates/poll-vote' -import { UserStatusUpdate } from './updates/user-status-update' -import { UserTypingUpdate } from './updates/user-typing-update' -import { DeleteMessageUpdate } from './updates/delete-message-update' +import { + ChatMemberUpdate, + ChosenInlineResult, + PollUpdate, + PollVoteUpdate, + UserStatusUpdate, + UserTypingUpdate, + DeleteMessageUpdate, + HistoryReadUpdate, +} from './updates' import { IStateStorage, UpdateState, StateKeyDelegate } from './state' import { defaultStateKeyDelegate } from './state' import { PropagationAction } from './propagation' @@ -85,6 +89,10 @@ const deleteMessageParser: UpdateParser = [ 'delete_message', (client, upd) => new DeleteMessageUpdate(client, upd as any), ] +const historyReadParser: UpdateParser = [ + 'history_read', + (client, upd) => new HistoryReadUpdate(client, upd as any), +] const PARSERS: Partial< Record<(tl.TypeUpdate | tl.TypeMessage)['_'], UpdateParser> @@ -127,6 +135,12 @@ const PARSERS: Partial< updateUserTyping: userTypingParser, updateDeleteChannelMessages: deleteMessageParser, updateDeleteMessages: deleteMessageParser, + updateReadHistoryInbox: historyReadParser, + updateReadHistoryOutbox: historyReadParser, + updateReadChannelInbox: historyReadParser, + updateReadChannelOutbox: historyReadParser, + updateReadChannelDiscussionInbox: historyReadParser, + updateReadChannelDiscussionOutbox: historyReadParser, } const HANDLER_TYPE_TO_UPDATE: Record = {} @@ -138,7 +152,9 @@ Object.keys(PARSERS).forEach((upd: keyof typeof PARSERS) => { }) export declare interface Dispatcher< + // eslint-disable-next-line @typescript-eslint/no-unused-vars State = never, + // eslint-disable-next-line @typescript-eslint/no-unused-vars SceneName extends string = string > { on( @@ -247,6 +263,14 @@ export declare interface Dispatcher< */ on(name: 'user_typing', handler: UserTypingHandler['callback']): this + /** + * Register a plain old history read handler + * + * @param name Event name + * @param handler History read handler + */ + on(name: 'history_read', handler: HistoryReadHandler['callback']): this + // end-codegen-declare } @@ -1674,5 +1698,33 @@ export class Dispatcher< this._addKnownHandler('userTyping', filter, handler, group) } + /** + * Register a history read handler without any filters + * + * @param handler History read handler + * @param group Handler group index + */ + onHistoryRead(handler: HistoryReadHandler['callback'], group?: number): void + + /** + * Register a history read handler with a filter + * + * @param filter Update filter + * @param handler History read handler + * @param group Handler group index + */ + onHistoryRead( + filter: UpdateFilter, + handler: HistoryReadHandler< + filters.Modify + >['callback'], + group?: number + ): void + + /** @internal */ + onHistoryRead(filter: any, handler?: any, group?: number): void { + this._addKnownHandler('historyRead', filter, handler, group) + } + // end-codegen } diff --git a/packages/dispatcher/src/handler.ts b/packages/dispatcher/src/handler.ts index 5a381845..7223c68a 100644 --- a/packages/dispatcher/src/handler.ts +++ b/packages/dispatcher/src/handler.ts @@ -9,13 +9,16 @@ import { } from '@mtcute/client' import { tl } from '@mtcute/tl' import { PropagationAction } from './propagation' -import { ChatMemberUpdate } from './updates' -import { ChosenInlineResult } from './updates/chosen-inline-result' -import { PollUpdate } from './updates/poll-update' -import { PollVoteUpdate } from './updates/poll-vote' -import { UserStatusUpdate } from './updates/user-status-update' -import { UserTypingUpdate } from './updates/user-typing-update' -import { DeleteMessageUpdate } from './updates/delete-message-update' +import { + ChatMemberUpdate, + ChosenInlineResult, + PollUpdate, + PollVoteUpdate, + UserStatusUpdate, + UserTypingUpdate, + DeleteMessageUpdate, + HistoryReadUpdate, +} from './updates' interface BaseUpdateHandler { type: Type @@ -96,6 +99,10 @@ export type UserTypingHandler = ParsedUpdateHandler< 'user_typing', T > +export type HistoryReadHandler = ParsedUpdateHandler< + 'history_read', + T +> export type UpdateHandler = | RawUpdateHandler @@ -110,5 +117,6 @@ export type UpdateHandler = | PollVoteHandler | UserStatusUpdateHandler | UserTypingHandler + | HistoryReadHandler // end-codegen diff --git a/packages/dispatcher/src/updates/history-read-update.ts b/packages/dispatcher/src/updates/history-read-update.ts new file mode 100644 index 00000000..d41fbbb8 --- /dev/null +++ b/packages/dispatcher/src/updates/history-read-update.ts @@ -0,0 +1,123 @@ +import { tl } from '@mtcute/tl' +import { TelegramClient } from '@mtcute/client' +import { getMarkedPeerId, MAX_CHANNEL_ID } from '@mtcute/core' +import { makeInspectable } from '@mtcute/client/src/types/utils' + +export class HistoryReadUpdate { + constructor ( + readonly client: TelegramClient, + readonly raw: + | tl.RawUpdateReadHistoryInbox + | tl.RawUpdateReadHistoryOutbox + | tl.RawUpdateReadChannelInbox + | tl.RawUpdateReadChannelOutbox + | tl.RawUpdateReadChannelDiscussionInbox + | tl.RawUpdateReadChannelDiscussionOutbox + ) {} + + /** + * Whether this update is about an "outbox" read + * (i.e. a message you have sent earlier was read) + */ + get isOutbox(): boolean { + switch (this.raw._) { + case 'updateReadChannelDiscussionOutbox': + case 'updateReadHistoryOutbox': + case 'updateReadChannelOutbox': + return true + default: + return false + } + } + + /** + * Whether this update is about messages in a discussion group + * (e.g. from a comments thread) + */ + get isDiscussion(): boolean { + switch (this.raw._) { + case 'updateReadChannelDiscussionOutbox': + case 'updateReadChannelDiscussionInbox': + return true + default: + return false + } + } + + /** + * Marked peer ID of the chat where the messages were read. + * + * If `isDiscussion == true`, contains the discussion group. + */ + get chatId(): number { + switch (this.raw._) { + case 'updateReadHistoryOutbox': + case 'updateReadHistoryInbox': + return getMarkedPeerId(this.raw.peer) + case 'updateReadChannelOutbox': + case 'updateReadChannelInbox': + case 'updateReadChannelDiscussionOutbox': + case 'updateReadChannelDiscussionInbox': + return MAX_CHANNEL_ID - this.raw.channelId + } + } + + /** + * For inbox updates (i.e. `isOutbox = false`), + * number of messages that are still unread in the chat. + * + * For other updates, `0` + */ + get unreadCount(): number { + switch (this.raw._) { + case 'updateReadHistoryInbox': + case 'updateReadChannelInbox': + return this.raw.stillUnreadCount + // `updateReadChannelDiscussionInbox` does not contain that data for some reason + case 'updateReadChannelDiscussionInbox': + case 'updateReadHistoryOutbox': + case 'updateReadChannelOutbox': + case 'updateReadChannelDiscussionOutbox': + return 0 + } + } + + /** + * ID of the last read message. + * + * Note that if `isDiscussion == true`, this contains the ID of the + * last read message inside that thread, and not in the group itself. + */ + get maxReadId(): number { + switch (this.raw._) { + case 'updateReadHistoryOutbox': + case 'updateReadHistoryInbox': + case 'updateReadChannelOutbox': + case 'updateReadChannelInbox': + return this.raw.maxId + case 'updateReadChannelDiscussionOutbox': + case 'updateReadChannelDiscussionInbox': + return this.raw.readMaxId + } + } + + /** + * ID of the thread (i.e. ID of the top message). + * + * For non-discussion updates, 0. + */ + get threadId(): number { + switch (this.raw._) { + case 'updateReadHistoryOutbox': + case 'updateReadHistoryInbox': + case 'updateReadChannelOutbox': + case 'updateReadChannelInbox': + return 0 + case 'updateReadChannelDiscussionOutbox': + case 'updateReadChannelDiscussionInbox': + return this.raw.topMsgId + } + } +} + +makeInspectable(HistoryReadUpdate) diff --git a/packages/dispatcher/src/updates/index.ts b/packages/dispatcher/src/updates/index.ts index 37f2ddb6..7a5c6eb3 100644 --- a/packages/dispatcher/src/updates/index.ts +++ b/packages/dispatcher/src/updates/index.ts @@ -1 +1,8 @@ export * from './chat-member-update' +export * from './chosen-inline-result' +export * from './delete-message-update' +export * from './poll-update' +export * from './poll-vote' +export * from './user-status-update' +export * from './user-typing-update' +export * from './history-read-update'