Got rid off map of keyboards.
This commit is contained in:
parent
c2562cc54c
commit
772adb7b8b
9 changed files with 228 additions and 183 deletions
128
cmd/test/main.go
128
cmd/test/main.go
|
@ -12,20 +12,11 @@ type UserData struct {
|
|||
Counter int
|
||||
}
|
||||
|
||||
var startScreenButton = tx.NewButton("🏠 To the start screen").
|
||||
ScreenChange("start")
|
||||
var (
|
||||
startScreenButton = tx.NewButton("🏠 To the start screen").
|
||||
ScreenChange("start")
|
||||
|
||||
var beh = tx.NewBehaviour().
|
||||
|
||||
// The function will be called every time
|
||||
// the bot is started.
|
||||
OnStartFunc(func(c *tx.A) {
|
||||
c.V = &UserData{}
|
||||
c.ChangeScreen("start")
|
||||
}).WithKeyboards(
|
||||
|
||||
// Increment/decrement keyboard.
|
||||
tx.NewKeyboard("inc/dec").Row(
|
||||
incDecKeyboard = tx.NewKeyboard("").Row(
|
||||
tx.NewButton("+").ActionFunc(func(c *tx.A) {
|
||||
d := c.V.(*UserData)
|
||||
d.Counter++
|
||||
|
@ -38,49 +29,60 @@ var beh = tx.NewBehaviour().
|
|||
}),
|
||||
).Row(
|
||||
startScreenButton,
|
||||
),
|
||||
)
|
||||
|
||||
// The navigational keyboard.
|
||||
tx.NewKeyboard("nav").Row(
|
||||
tx.NewButton("Inc/Dec").ScreenChange("inc/dec"),
|
||||
).Row(
|
||||
navKeyboard = tx.NewKeyboard("Choose your interest").
|
||||
WithOneTime(true).
|
||||
Row(
|
||||
tx.NewButton("Inc/Dec").ScreenChange("inc/dec"),
|
||||
).Row(
|
||||
tx.NewButton("Upper case").ScreenChange("upper-case"),
|
||||
tx.NewButton("Lower case").ScreenChange("lower-case"),
|
||||
).Row(
|
||||
tx.NewButton("Send location").
|
||||
WithSendLocation(true).
|
||||
ActionFunc(func(c *tx.A) {
|
||||
var err error
|
||||
if c.U.Message.Location != nil {
|
||||
l := c.U.Message.Location
|
||||
err = c.Sendf(
|
||||
"Longitude: %f\n"+
|
||||
"Latitude: %f\n"+
|
||||
"Heading: %d"+
|
||||
"",
|
||||
l.Longitude,
|
||||
l.Latitude,
|
||||
l.Heading,
|
||||
)
|
||||
} else {
|
||||
err = c.Send("Somehow wrong location was sent")
|
||||
}
|
||||
if err != nil {
|
||||
c.Send(err)
|
||||
}
|
||||
}),
|
||||
),
|
||||
tx.NewButton("Send location").ScreenChange("send-location"),
|
||||
)
|
||||
|
||||
tx.NewKeyboard("istart").Row(
|
||||
tx.NewButton("GoT Github page").
|
||||
WithUrl("https://github.com/mojosa-software/got"),
|
||||
),
|
||||
sendLocationKeyboard = tx.NewKeyboard("Press the button to send your location").
|
||||
Row(
|
||||
tx.NewButton("Send location").
|
||||
WithSendLocation(true).
|
||||
ActionFunc(func(c *tx.A) {
|
||||
var err error
|
||||
if c.U.Message.Location != nil {
|
||||
l := c.U.Message.Location
|
||||
err = c.Sendf(
|
||||
"Longitude: %f\n"+
|
||||
"Latitude: %f\n"+
|
||||
"Heading: %d"+
|
||||
"",
|
||||
l.Longitude,
|
||||
l.Latitude,
|
||||
l.Heading,
|
||||
)
|
||||
} else {
|
||||
err = c.Send("Somehow wrong location was sent")
|
||||
}
|
||||
if err != nil {
|
||||
c.Send(err)
|
||||
}
|
||||
}),
|
||||
).Row(
|
||||
startScreenButton,
|
||||
)
|
||||
|
||||
// The keyboard to return to the start screen.
|
||||
tx.NewKeyboard("nav-start").Row(
|
||||
navToStartKeyboard = tx.NewKeyboard("").Row(
|
||||
startScreenButton,
|
||||
),
|
||||
).WithScreens(
|
||||
)
|
||||
)
|
||||
|
||||
var beh = tx.NewBehaviour().
|
||||
OnStartFunc(func(c *tx.A) {
|
||||
// The function will be called every time
|
||||
// the bot is started.
|
||||
c.V = &UserData{}
|
||||
c.ChangeScreen("start")
|
||||
}).WithScreens(
|
||||
tx.NewScreen("start").
|
||||
WithText(
|
||||
"The bot started!"+
|
||||
|
@ -88,8 +90,14 @@ var beh = tx.NewBehaviour().
|
|||
" understand of how the API works, so just"+
|
||||
" horse around a bit to guess everything out"+
|
||||
" by yourself!",
|
||||
).Keyboard("nav").
|
||||
IKeyboard("istart"),
|
||||
).WithKeyboard(navKeyboard).
|
||||
// The inline keyboard with link to GitHub page.
|
||||
WithIKeyboard(
|
||||
tx.NewKeyboard("istart").Row(
|
||||
tx.NewButton("GoT Github page").
|
||||
WithUrl("https://github.com/mojosa-software/got"),
|
||||
),
|
||||
),
|
||||
|
||||
tx.NewScreen("inc/dec").
|
||||
WithText(
|
||||
|
@ -98,7 +106,7 @@ var beh = tx.NewBehaviour().
|
|||
"by saving the counter for each of users "+
|
||||
"separately. ",
|
||||
).
|
||||
Keyboard("inc/dec").
|
||||
WithKeyboard(incDecKeyboard).
|
||||
// The function will be called when reaching the screen.
|
||||
ActionFunc(func(c *tx.A) {
|
||||
d := c.V.(*UserData)
|
||||
|
@ -107,13 +115,27 @@ var beh = tx.NewBehaviour().
|
|||
|
||||
tx.NewScreen("upper-case").
|
||||
WithText("Type text and the bot will send you the upper case version to you").
|
||||
Keyboard("nav-start").
|
||||
WithKeyboard(navToStartKeyboard).
|
||||
ActionFunc(mutateMessage(strings.ToUpper)),
|
||||
|
||||
tx.NewScreen("lower-case").
|
||||
WithText("Type text and the bot will send you the lower case version").
|
||||
Keyboard("nav-start").
|
||||
WithKeyboard(navToStartKeyboard).
|
||||
ActionFunc(mutateMessage(strings.ToLower)),
|
||||
|
||||
tx.NewScreen("send-location").
|
||||
WithText("Send your location and I will tell where you are!").
|
||||
WithKeyboard(sendLocationKeyboard).
|
||||
WithIKeyboard(
|
||||
tx.NewKeyboard("").Row(
|
||||
tx.NewButton("Check").
|
||||
WithData("check").
|
||||
ActionFunc(func(a *tx.A) {
|
||||
d := a.V.(*UserData)
|
||||
a.Sendf("Counter = %d", d.Counter)
|
||||
}),
|
||||
),
|
||||
),
|
||||
).WithCommands(
|
||||
tx.NewCommand("hello").
|
||||
Desc("sends the 'Hello, World!' message back").
|
||||
|
|
|
@ -48,26 +48,23 @@ type A = Arg
|
|||
|
||||
// Changes screen of user to the Id one.
|
||||
func (c *Arg) ChangeScreen(screenId ScreenId) error {
|
||||
// Return if it will not change anything.
|
||||
if c.CurrentScreenId == screenId {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !c.B.behaviour.ScreenExist(screenId) {
|
||||
return ScreenNotExistErr
|
||||
}
|
||||
|
||||
// Stop the reading by sending the nil.
|
||||
// Stop the reading by sending the nil,
|
||||
// since we change the screen and
|
||||
// current goroutine needs to be stopped.
|
||||
if c.readingUpdate {
|
||||
c.updates <- nil
|
||||
}
|
||||
|
||||
// Getting the screen and changing to
|
||||
// then executing its action.
|
||||
screen := c.B.behaviour.Screens[screenId]
|
||||
c.prevScreen = c.curScreen
|
||||
c.curScreen = screen
|
||||
screen.Render(c.Context)
|
||||
|
||||
c.Session.ChangeScreen(screenId)
|
||||
c.KeyboardId = screen.KeyboardId
|
||||
|
||||
if screen.Action != nil {
|
||||
c.run(screen.Action, c.U)
|
||||
}
|
||||
|
|
|
@ -3,10 +3,6 @@ package tx
|
|||
// The package implements
|
||||
// behaviour for the Telegram bots.
|
||||
|
||||
// The type describes behaviour for the bot in channels.
|
||||
type ChannelBehaviour struct {
|
||||
}
|
||||
|
||||
// The type describes behaviour for the bot in personal chats.
|
||||
type Behaviour struct {
|
||||
Start Action
|
||||
|
@ -35,29 +31,6 @@ func (b *Behaviour) OnStartFunc(
|
|||
return b.WithStart(fn)
|
||||
}
|
||||
|
||||
func (b *Behaviour) OnStartChangeScreen(
|
||||
id ScreenId,
|
||||
) *Behaviour {
|
||||
return b.WithStart(ScreenChange(id))
|
||||
}
|
||||
|
||||
// The function sets keyboards.
|
||||
func (b *Behaviour) WithKeyboards(
|
||||
kbds ...*Keyboard,
|
||||
) *Behaviour {
|
||||
for _, kbd := range kbds {
|
||||
if kbd.Id == "" {
|
||||
panic("empty keyboard ID")
|
||||
}
|
||||
_, ok := b.Keyboards[kbd.Id]
|
||||
if ok {
|
||||
panic("duplicate keyboard IDs")
|
||||
}
|
||||
b.Keyboards[kbd.Id] = kbd
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// The function sets screens.
|
||||
func (b *Behaviour) WithScreens(
|
||||
screens ...*Screen,
|
||||
|
@ -90,21 +63,6 @@ func (b *Behaviour) WithCommands(cmds ...*Command) *Behaviour {
|
|||
return b
|
||||
}
|
||||
|
||||
// The function sets group commands.
|
||||
/*func (b *Behaviour) WithGroupCommands(cmds ...*Command) *Behaviour {
|
||||
for _, cmd := range cmds {
|
||||
if cmd.Name == "" {
|
||||
panic("empty group command name")
|
||||
}
|
||||
_, ok := b.GroupCommands[cmd.Name]
|
||||
if ok {
|
||||
panic("duplicate group command definition")
|
||||
}
|
||||
b.GroupCommands[cmd.Name] = cmd
|
||||
}
|
||||
return b
|
||||
}*/
|
||||
|
||||
// Check whether the screen exists in the behaviour.
|
||||
func (beh *Behaviour) ScreenExist(id ScreenId) bool {
|
||||
_, ok := beh.Screens[id]
|
||||
|
@ -128,21 +86,27 @@ type GroupBehaviour struct {
|
|||
Commands GroupCommandMap
|
||||
}
|
||||
|
||||
// Returns new empty group behaviour object.
|
||||
func NewGroupBehaviour() *GroupBehaviour {
|
||||
return &GroupBehaviour{
|
||||
Commands: make(GroupCommandMap),
|
||||
}
|
||||
}
|
||||
|
||||
// Sets an Action for initialization on each group connected to the
|
||||
// group bot.
|
||||
func (b *GroupBehaviour) WithInitAction(a GroupAction) *GroupBehaviour {
|
||||
b.Init = a
|
||||
return b
|
||||
}
|
||||
|
||||
// The method reciveies a function to be called on initialization of the
|
||||
// bot group bot.
|
||||
func (b *GroupBehaviour) InitFunc(fn GroupActionFunc) *GroupBehaviour {
|
||||
return b.WithInitAction(fn)
|
||||
}
|
||||
|
||||
// The method sets group commands.
|
||||
func (b *GroupBehaviour) WithCommands(
|
||||
cmds ...*GroupCommand,
|
||||
) *GroupBehaviour {
|
||||
|
@ -158,3 +122,7 @@ func (b *GroupBehaviour) WithCommands(
|
|||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// The type describes behaviour for the bot in channels.
|
||||
type ChannelBehaviour struct {
|
||||
}
|
||||
|
|
|
@ -38,6 +38,11 @@ func (btn *Button) WithAction(a Action) *Button {
|
|||
return btn
|
||||
}
|
||||
|
||||
func (btn *Button) WithData(dat string) *Button {
|
||||
btn.Data = dat
|
||||
return btn
|
||||
}
|
||||
|
||||
// Sets whether the button must send owner's location.
|
||||
func (btn *Button) WithSendLocation(ok bool) *Button {
|
||||
btn.SendLocation = ok
|
||||
|
|
|
@ -12,20 +12,20 @@ type Context struct {
|
|||
*Session
|
||||
B *Bot
|
||||
updates chan *Update
|
||||
|
||||
// Is true if currently reading the Update.
|
||||
readingUpdate bool
|
||||
|
||||
curScreen, prevScreen *Screen
|
||||
}
|
||||
|
||||
// Goroutie function to handle each user.
|
||||
func (c *Context) handleUpdateChan(updates chan *Update) {
|
||||
var act Action
|
||||
bot := c.B
|
||||
session := c.Session
|
||||
beh := bot.behaviour
|
||||
c.run(beh.Start, nil)
|
||||
for u := range updates {
|
||||
screen := bot.behaviour.Screens[session.CurrentScreenId]
|
||||
screen := c.curScreen
|
||||
// The part is added to implement custom update handling.
|
||||
if u.Message != nil {
|
||||
if u.Message.IsCommand() && !c.readingUpdate {
|
||||
|
@ -36,7 +36,13 @@ func (c *Context) handleUpdateChan(updates chan *Update) {
|
|||
} else {
|
||||
}
|
||||
} else {
|
||||
kbd := beh.Keyboards[screen.KeyboardId]
|
||||
kbd := screen.Keyboard
|
||||
if kbd == nil {
|
||||
if c.readingUpdate {
|
||||
c.updates <- u
|
||||
}
|
||||
continue
|
||||
}
|
||||
btns := kbd.buttonMap()
|
||||
text := u.Message.Text
|
||||
btn, ok := btns[text]
|
||||
|
@ -68,13 +74,24 @@ func (c *Context) handleUpdateChan(updates chan *Update) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
kbd := beh.Keyboards[screen.InlineKeyboardId]
|
||||
kbd := screen.InlineKeyboard
|
||||
if kbd == nil {
|
||||
if c.readingUpdate {
|
||||
c.updates <- u
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
btns := kbd.buttonMap()
|
||||
btn, ok := btns[data]
|
||||
if !ok && c.readingUpdate {
|
||||
c.updates <- u
|
||||
continue
|
||||
}
|
||||
if !ok {
|
||||
c.Sendf("%q", btns)
|
||||
continue
|
||||
}
|
||||
act = btn.Action
|
||||
}
|
||||
if act != nil {
|
||||
|
|
|
@ -10,10 +10,11 @@ type WrongUpdateType struct {
|
|||
}
|
||||
|
||||
var (
|
||||
ScreenNotExistErr = errors.New("screen does not exist")
|
||||
SessionNotExistErr = errors.New("session does not exist")
|
||||
KeyboardNotExistErr = errors.New("keyboard does not exist")
|
||||
NotAvailableErr = errors.New("the context is not available")
|
||||
ScreenNotExistErr = errors.New("screen does not exist")
|
||||
SessionNotExistErr = errors.New("session does not exist")
|
||||
KeyboardNotExistErr = errors.New("keyboard does not exist")
|
||||
NotAvailableErr = errors.New("the context is not available")
|
||||
EmptyKeyboardTextErr = errors.New("got empty text for a keyboard")
|
||||
)
|
||||
|
||||
func (wut WrongUpdateType) Error() string {
|
||||
|
|
|
@ -23,19 +23,33 @@ type KeyboardId string
|
|||
// The type represents reply keyboard which
|
||||
// is supposed to be showed on a Screen.
|
||||
type Keyboard struct {
|
||||
Id KeyboardId
|
||||
// Text to be displayed with the keyboard.
|
||||
Text string
|
||||
// Rows to be displayed once the
|
||||
// keyboard is sent.
|
||||
Rows []ButtonRow
|
||||
|
||||
OneTime bool
|
||||
Inline bool
|
||||
}
|
||||
|
||||
type KeyboardMap map[KeyboardId]*Keyboard
|
||||
|
||||
// Return the new reply keyboard with rows as specified.
|
||||
func NewKeyboard(id KeyboardId) *Keyboard {
|
||||
func NewKeyboard(text string) *Keyboard {
|
||||
return &Keyboard{
|
||||
Id: id,
|
||||
Text: text,
|
||||
}
|
||||
}
|
||||
|
||||
func (kbd *Keyboard) TelegramMarkup() any {
|
||||
if kbd.Inline {
|
||||
return kbd.toTelegramInline()
|
||||
}
|
||||
|
||||
return kbd.toTelegramReply()
|
||||
}
|
||||
|
||||
// Adds a new button row to the current keyboard.
|
||||
func (kbd *Keyboard) Row(btns ...*Button) *Keyboard {
|
||||
// For empty row. We do not need that.
|
||||
|
@ -46,8 +60,8 @@ func (kbd *Keyboard) Row(btns ...*Button) *Keyboard {
|
|||
return kbd
|
||||
}
|
||||
|
||||
// Convert the Keyboard to the Telegram API type.
|
||||
func (kbd *Keyboard) ToTelegram() apix.ReplyKeyboardMarkup {
|
||||
// Convert the Keyboard to the Telegram API type of reply keyboard.
|
||||
func (kbd *Keyboard) toTelegramReply() apix.ReplyKeyboardMarkup {
|
||||
rows := [][]apix.KeyboardButton{}
|
||||
for _, row := range kbd.Rows {
|
||||
buttons := []apix.KeyboardButton{}
|
||||
|
@ -57,10 +71,14 @@ func (kbd *Keyboard) ToTelegram() apix.ReplyKeyboardMarkup {
|
|||
rows = append(rows, buttons)
|
||||
}
|
||||
|
||||
if kbd.OneTime {
|
||||
return apix.NewOneTimeReplyKeyboard(rows...)
|
||||
}
|
||||
|
||||
return apix.NewReplyKeyboard(rows...)
|
||||
}
|
||||
|
||||
func (kbd *Keyboard) ToTelegramInline() apix.InlineKeyboardMarkup {
|
||||
func (kbd *Keyboard) toTelegramInline() apix.InlineKeyboardMarkup {
|
||||
rows := [][]apix.InlineKeyboardButton{}
|
||||
for _, row := range kbd.Rows {
|
||||
buttons := []apix.InlineKeyboardButton{}
|
||||
|
@ -73,6 +91,16 @@ func (kbd *Keyboard) ToTelegramInline() apix.InlineKeyboardMarkup {
|
|||
return apix.NewInlineKeyboardMarkup(rows...)
|
||||
}
|
||||
|
||||
func (kbd *Keyboard) WithOneTime(oneTime bool) *Keyboard {
|
||||
kbd.OneTime = oneTime
|
||||
return kbd
|
||||
}
|
||||
|
||||
func (kbd *Keyboard) WithInline(inline bool) *Keyboard {
|
||||
kbd.Inline = inline
|
||||
return kbd
|
||||
}
|
||||
|
||||
// Returns the map of buttons. Used to define the Action.
|
||||
func (kbd *Keyboard) buttonMap() ButtonMap {
|
||||
ret := make(ButtonMap)
|
||||
|
|
117
src/tx/screen.go
117
src/tx/screen.go
|
@ -7,24 +7,17 @@ import (
|
|||
// Unique identifier for the screen.
|
||||
type ScreenId string
|
||||
|
||||
// Should be replaced with something that can be
|
||||
// dinamicaly rendered. (WIP)
|
||||
type ScreenText string
|
||||
|
||||
// Screen statement of the bot.
|
||||
// Mostly what buttons to show.
|
||||
type Screen struct {
|
||||
Id ScreenId
|
||||
|
||||
// Text to be sent to the user when changing to the screen.
|
||||
Text ScreenText
|
||||
|
||||
// The text to be displayed when the screen is
|
||||
// reached.
|
||||
Text string
|
||||
// The keyboard to be sent in the message part.
|
||||
InlineKeyboardId KeyboardId
|
||||
|
||||
InlineKeyboard *Keyboard
|
||||
// Keyboard to be displayed on the screen.
|
||||
KeyboardId KeyboardId
|
||||
|
||||
Keyboard *Keyboard
|
||||
// Action called on the reaching the screen.
|
||||
Action Action
|
||||
}
|
||||
|
@ -40,18 +33,22 @@ func NewScreen(id ScreenId) *Screen {
|
|||
}
|
||||
|
||||
// Returns the screen with specified text printing on appearing.
|
||||
func (s *Screen) WithText(text ScreenText) *Screen {
|
||||
func (s *Screen) WithText(text string) *Screen {
|
||||
s.Text = text
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Screen) IKeyboard(kbdId KeyboardId) *Screen {
|
||||
s.InlineKeyboardId = kbdId
|
||||
func (s *Screen) WithInlineKeyboard(ikbd *Keyboard) *Screen {
|
||||
s.InlineKeyboard = ikbd
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Screen) Keyboard(kbdId KeyboardId) *Screen {
|
||||
s.KeyboardId = kbdId
|
||||
func (s *Screen) WithIKeyboard(ikbd *Keyboard) *Screen {
|
||||
return s.WithInlineKeyboard(ikbd)
|
||||
}
|
||||
|
||||
func (s *Screen) WithKeyboard(kbd *Keyboard) *Screen {
|
||||
s.Keyboard = kbd
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -64,49 +61,69 @@ func (s *Screen) ActionFunc(a ActionFunc) *Screen {
|
|||
return s.WithAction(a)
|
||||
}
|
||||
|
||||
// Rendering the screen text to string to be sent or printed.
|
||||
func (st ScreenText) String() string {
|
||||
return string(st)
|
||||
}
|
||||
|
||||
// Renders output of the screen only to the side of the user.
|
||||
func (s *Screen) Render(c *Context) error {
|
||||
id := c.Id.ToTelegram()
|
||||
kbd := s.Keyboard
|
||||
iKbd := s.InlineKeyboard
|
||||
|
||||
msg := apix.NewMessage(id, s.Text.String())
|
||||
var ch [2]apix.Chattable
|
||||
var txt string
|
||||
|
||||
if s.InlineKeyboardId != "" {
|
||||
kbd, ok := c.B.behaviour.Keyboards[s.InlineKeyboardId]
|
||||
if !ok {
|
||||
return KeyboardNotExistErr
|
||||
// Screen text and inline keyboard.
|
||||
if s.Text != "" {
|
||||
txt = s.Text
|
||||
} else if iKbd != nil {
|
||||
if iKbd.Text != "" {
|
||||
txt = iKbd.Text
|
||||
} else {
|
||||
// Default to send the keyboard.
|
||||
txt = ">"
|
||||
}
|
||||
msg.ReplyMarkup = kbd.ToTelegramInline()
|
||||
}
|
||||
|
||||
_, err := c.B.Send(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg = apix.NewMessage(id, ">")
|
||||
// Checking if we need to resend the keyboard.
|
||||
if s.KeyboardId != c.KeyboardId {
|
||||
// Remove keyboard by default.
|
||||
var tkbd any
|
||||
tkbd = apix.NewRemoveKeyboard(true)
|
||||
|
||||
// Replace keyboard with the new one.
|
||||
if s.KeyboardId != "" {
|
||||
kbd, ok := c.B.behaviour.Keyboards[s.KeyboardId]
|
||||
if !ok {
|
||||
return KeyboardNotExistErr
|
||||
if txt != "" {
|
||||
msg := apix.NewMessage(id, txt)
|
||||
if iKbd != nil {
|
||||
msg.ReplyMarkup = iKbd.toTelegramInline()
|
||||
} else if kbd != nil {
|
||||
msg.ReplyMarkup = kbd.toTelegramReply()
|
||||
if _, err := c.B.Send(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
tkbd = kbd.ToTelegram()
|
||||
return nil
|
||||
} else {
|
||||
msg.ReplyMarkup = apix.NewRemoveKeyboard(true)
|
||||
if _, err := c.B.Send(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
ch[0] = msg
|
||||
}
|
||||
|
||||
msg.ReplyMarkup = tkbd
|
||||
if _, err := c.B.Send(msg); err != nil {
|
||||
return err
|
||||
// Screen text and reply keyboard.
|
||||
txt = ""
|
||||
if kbd != nil {
|
||||
if kbd.Text != "" {
|
||||
txt = kbd.Text
|
||||
} else {
|
||||
txt = ">"
|
||||
}
|
||||
msg := apix.NewMessage(id, txt)
|
||||
msg.ReplyMarkup = kbd.toTelegramReply()
|
||||
ch[1] = msg
|
||||
} else {
|
||||
// Removing keyboard if there is none.
|
||||
msg := apix.NewMessage(id, ">")
|
||||
msg.ReplyMarkup = apix.NewRemoveKeyboard(true)
|
||||
ch[1] = msg
|
||||
}
|
||||
|
||||
for _, m := range ch {
|
||||
if m != nil {
|
||||
if _, err := c.B.Send(m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,14 +12,10 @@ func (si SessionId) ToTelegram() int64 {
|
|||
// The type represents current state of
|
||||
// user interaction per each of them.
|
||||
type Session struct {
|
||||
// Id of the chat of the user.
|
||||
Id SessionId
|
||||
// Current screen identifier.
|
||||
CurrentScreenId ScreenId
|
||||
// ID of the previous screen.
|
||||
PreviousScreenId ScreenId
|
||||
// The currently showed on display keyboard inside Action.
|
||||
KeyboardId KeyboardId
|
||||
V any
|
||||
// Custom value for each user.
|
||||
V any
|
||||
}
|
||||
|
||||
// Return new empty session with specified user ID.
|
||||
|
@ -30,12 +26,6 @@ func NewSession(id SessionId) *Session {
|
|||
}
|
||||
}
|
||||
|
||||
// Changes screen of user to the Id one for the session.
|
||||
func (c *Session) ChangeScreen(screenId ScreenId) {
|
||||
c.PreviousScreenId = c.CurrentScreenId
|
||||
c.CurrentScreenId = screenId
|
||||
}
|
||||
|
||||
// The type represents map of sessions using
|
||||
// as key.
|
||||
type SessionMap map[SessionId]*Session
|
||||
|
|
Loading…
Reference in a new issue