feat(client): bot keyboard builder
This commit is contained in:
parent
6215892090
commit
36ba4c3b87
3 changed files with 111 additions and 0 deletions
|
@ -5,3 +5,4 @@ export * from './inline-query'
|
||||||
export * from './callback-query'
|
export * from './callback-query'
|
||||||
export * from './game-high-score'
|
export * from './game-high-score'
|
||||||
export * from './command-scope'
|
export * from './command-scope'
|
||||||
|
export * from './keyboard-builder'
|
||||||
|
|
105
packages/client/src/types/bots/keyboard-builder.ts
Normal file
105
packages/client/src/types/bots/keyboard-builder.ts
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
import type { InlineKeyboardMarkup, ReplyKeyboardMarkup } from './keyboards'
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
type ButtonLike = tl.TypeKeyboardButton | false | null | undefined | void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for bot keyboards
|
||||||
|
*/
|
||||||
|
export class BotKeyboardBuilder {
|
||||||
|
private _buttons: tl.TypeKeyboardButton[][] = []
|
||||||
|
|
||||||
|
constructor(readonly maxRowWidth: number | null = 3) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add buttons, wrapping them once {@link maxRowWidth} is reached
|
||||||
|
*
|
||||||
|
* @param buttons Buttons to add
|
||||||
|
*/
|
||||||
|
push(...buttons: (ButtonLike | (() => ButtonLike))[]): this {
|
||||||
|
if (!buttons.length) return this
|
||||||
|
|
||||||
|
let row: tl.TypeKeyboardButton[] = []
|
||||||
|
buttons.forEach((btn) => {
|
||||||
|
if (typeof btn === 'function') btn = btn()
|
||||||
|
if (!btn) return
|
||||||
|
|
||||||
|
row.push(btn)
|
||||||
|
if (row.length === this.maxRowWidth) {
|
||||||
|
this._buttons.push(row)
|
||||||
|
row = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (row.length) {
|
||||||
|
this._buttons.push(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a row of buttons. Will not be wrapped.
|
||||||
|
*
|
||||||
|
* @param row Row or a function that will populate it
|
||||||
|
*/
|
||||||
|
row(row: ButtonLike[] | ((arr: ButtonLike[]) => void)): this {
|
||||||
|
if (typeof row === 'function') {
|
||||||
|
const fn = row
|
||||||
|
row = []
|
||||||
|
fn(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
const normal = row.filter(Boolean) as tl.TypeKeyboardButton[]
|
||||||
|
if (normal.length) this._buttons.push(normal)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a button to the last row, wrapping if needed.
|
||||||
|
*
|
||||||
|
* @param btn Button to add
|
||||||
|
* @param force Whether to forcefully add the button (i.e. do not wrap)
|
||||||
|
*/
|
||||||
|
append(btn: ButtonLike | (() => ButtonLike), force = false): this {
|
||||||
|
if (typeof btn === 'function') btn = btn()
|
||||||
|
if (!btn) return this
|
||||||
|
|
||||||
|
if (
|
||||||
|
this._buttons.length &&
|
||||||
|
(this.maxRowWidth === null ||
|
||||||
|
force ||
|
||||||
|
this._buttons[this._buttons.length - 1].length <
|
||||||
|
this.maxRowWidth)
|
||||||
|
) {
|
||||||
|
this._buttons[this._buttons.length - 1].push()
|
||||||
|
} else {
|
||||||
|
this._buttons.push([btn])
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return contents of this builder as an inline keyboard
|
||||||
|
*/
|
||||||
|
asInline(): InlineKeyboardMarkup {
|
||||||
|
return {
|
||||||
|
type: 'inline',
|
||||||
|
buttons: this._buttons,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return contents of this builder as a reply keyboard
|
||||||
|
*/
|
||||||
|
asReply(
|
||||||
|
params: Omit<ReplyKeyboardMarkup, 'type' | 'buttons'> = {}
|
||||||
|
): ReplyKeyboardMarkup {
|
||||||
|
const ret = params as tl.Mutable<ReplyKeyboardMarkup>
|
||||||
|
ret.type = 'reply'
|
||||||
|
ret.buttons = this._buttons
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { tl } from '@mtcute/tl'
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { BotKeyboardBuilder } from './keyboard-builder'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reply keyboard markup
|
* Reply keyboard markup
|
||||||
|
@ -57,6 +58,10 @@ export type ReplyMarkup =
|
||||||
* > in the description.
|
* > in the description.
|
||||||
*/
|
*/
|
||||||
export namespace BotKeyboard {
|
export namespace BotKeyboard {
|
||||||
|
export function builder(maxRowWidth?: number | null): BotKeyboardBuilder {
|
||||||
|
return new BotKeyboardBuilder(maxRowWidth)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an inline keyboard markup
|
* Create an inline keyboard markup
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue