diff --git a/button.go b/button.go index c1472af..bd181b5 100644 --- a/button.go +++ b/button.go @@ -2,6 +2,9 @@ package tg import ( apix "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "fmt" + "crypto/rand" + "encoding/base64" ) // The type wraps Telegram API's button to provide Action functionality. @@ -29,12 +32,22 @@ func (btnMap ButtonMap) LocationButton() *Button { type ButtonRow []*Button // Returns new button with the specified text and no action. -func NewButton(text string) *Button { +func NewButton(format string, v ...any) *Button { return &Button{ - Text: text, + Text: fmt.Sprintf(format, v...), } } +// Randomize buttons data to make the key unique. +func (btn *Button) Rand() *Button { + rData := make([]byte, 8) + rand.Read(rData) + data := make([]byte, base64.StdEncoding.EncodedLen(len(rData))) + base64.StdEncoding.Encode(data, rData) + btn.Data = string(data) + return btn +} + // Set the URL for the button. Only for inline buttons. func (btn *Button) WithUrl(url string) *Button { btn.Url = url diff --git a/context.go b/context.go index 52b6656..7cb2089 100644 --- a/context.go +++ b/context.go @@ -8,6 +8,27 @@ import ( //"path" ) +func Go(pth Path) UI { + return UI{ + GoWidget(pth), + } +} + +type GoWidget string +// Implementing the Server interface. +func (widget GoWidget) Serve(c *Context) { + c.input.Close() + c.Go(Path(widget)) +} + +func (widget GoWidget) Render(c *Context) UI { + return UI{widget} +} + +func (widget GoWidget) Filter(u *Update) bool { + return true +} + // General context for a specific user. // Is always the same and is not reached // inside end function-handlers. diff --git a/inline.go b/inline.go index 66ff0e7..f666a5b 100644 --- a/inline.go +++ b/inline.go @@ -13,8 +13,14 @@ type Inline struct { func (kbd *Inline) ToApi() tgbotapi.InlineKeyboardMarkup { rows := [][]tgbotapi.InlineKeyboardButton{} for _, row := range kbd.Rows { + if row == nil { + continue + } buttons := []tgbotapi.InlineKeyboardButton{} for _, button := range row { + if button == nil { + continue + } buttons = append(buttons, button.ToTelegramInline()) } rows = append(rows, buttons) @@ -40,12 +46,24 @@ func (compo *InlineCompo) SendConfig( } func (compo *InlineCompo) Update(c *Context) { - edit := tgbotapi.NewEditMessageTextAndMarkup( - c.Session.Id.ToApi(), - compo.Message.MessageID, - compo.Text, - compo.Inline.ToApi(), - ) + var edit tgbotapi.Chattable + markup := compo.Inline.ToApi() + ln := len(markup.InlineKeyboard) + c.Sendf("%d shit", ln) + if ln == 0 { + edit = tgbotapi.NewEditMessageText( + c.Session.Id.ToApi(), + compo.Message.MessageID, + compo.Text, + ) + } else { + edit = tgbotapi.NewEditMessageTextAndMarkup( + c.Session.Id.ToApi(), + compo.Message.MessageID, + compo.Text, + markup, + ) + } msg, _ := c.Bot.Api.Send(edit) compo.Message = &msg } @@ -66,6 +84,7 @@ func (compo *InlineCompo) Filter(u *Update) bool { // Implementing the Server interface. func (widget *InlineCompo) Serve(c *Context) { + btns := widget.ButtonMap() for u := range c.Input() { var act Action cb := tgbotapi.NewCallback( @@ -80,7 +99,6 @@ func (widget *InlineCompo) Serve(c *Context) { continue } - btns := widget.ButtonMap() btn, ok := btns[data] if !ok { continue diff --git a/keyboard.go b/keyboard.go index 392cae3..e4d4801 100644 --- a/keyboard.go +++ b/keyboard.go @@ -24,6 +24,17 @@ func NewKeyboard(rows ...ButtonRow) *Keyboard { return ret } +func (kbd *Keyboard) RowNum() int { + return len(kbd.Rows) +} + +func (kbd *Keyboard) RemoveRow(i int) { + if i<0 || i > len(kbd.Rows) - 1 { + return + } + kbd.Rows = append(kbd.Rows[:i], kbd.Rows[i+1:]...) +} + // Adds a new button row to the current keyboard. func (kbd *Keyboard) Row(btns ...*Button) *Keyboard { // For empty row. We do not need that. @@ -70,9 +81,6 @@ func (kbd *Keyboard) ActionFunc(fn ActionFunc) *Keyboard { // Returns the map of buttons. Used to define the Action. func (kbd Keyboard) ButtonMap() ButtonMap { - if kbd.buttonMap != nil { - return kbd.buttonMap - } ret := make(ButtonMap) for _, vi := range kbd.Rows { for _, vj := range vi { diff --git a/message.go b/message.go index e0c482b..2cf0b9b 100644 --- a/message.go +++ b/message.go @@ -4,6 +4,7 @@ import ( tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" //"strings" re "regexp" + "fmt" ) type Message = tgbotapi.Message @@ -42,9 +43,9 @@ func (compo *MessageCompo) SetMessage(msg *Message) { } // Return new message with the specified text. -func NewMessage(text string) *MessageCompo { +func NewMessage(format string, v ...any) *MessageCompo { ret := &MessageCompo{} - ret.Text = text + ret.Text = fmt.Sprintf(format, v...) ret.ParseMode = tgbotapi.ModeMarkdown return ret } diff --git a/reply.go b/reply.go index 64e95a0..06e8108 100644 --- a/reply.go +++ b/reply.go @@ -36,8 +36,14 @@ func (kbd *Reply) ToApi() any { rows := [][]tgbotapi.KeyboardButton{} for _, row := range kbd.Rows { + if row == nil { + continue + } buttons := []tgbotapi.KeyboardButton{} for _, button := range row { + if button == nil { + continue + } buttons = append(buttons, button.ToTelegram()) } rows = append(rows, buttons) diff --git a/ui.go b/ui.go index d926bc8..d952255 100644 --- a/ui.go +++ b/ui.go @@ -1,6 +1,5 @@ package tg - // The type describes dynamic screen widget // That can have multiple UI components. type Widget interface {