Fixed naming. We do not need the "Arg" thing.
This commit is contained in:
parent
94d8c38dd5
commit
3f26d2f916
9 changed files with 195 additions and 150 deletions
44
airfile
Normal file
44
airfile
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
root = "."
|
||||||
|
testdata_dir = "testdata"
|
||||||
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
args_bin = []
|
||||||
|
bin = "./exe/test.exe"
|
||||||
|
cmd = "go build -o ./exe/ ./cmd/..."
|
||||||
|
delay = 0
|
||||||
|
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
|
||||||
|
exclude_file = []
|
||||||
|
exclude_regex = ["_test.go"]
|
||||||
|
exclude_unchanged = false
|
||||||
|
follow_symlink = false
|
||||||
|
full_bin = ""
|
||||||
|
include_dir = []
|
||||||
|
include_ext = ["go", "tpl", "tmpl", "html"]
|
||||||
|
include_file = []
|
||||||
|
kill_delay = "0s"
|
||||||
|
log = "build-errors.log"
|
||||||
|
poll = false
|
||||||
|
poll_interval = 0
|
||||||
|
rerun = false
|
||||||
|
rerun_delay = 500
|
||||||
|
send_interrupt = false
|
||||||
|
stop_on_error = true
|
||||||
|
|
||||||
|
[color]
|
||||||
|
app = ""
|
||||||
|
build = "yellow"
|
||||||
|
main = "magenta"
|
||||||
|
runner = "green"
|
||||||
|
watcher = "cyan"
|
||||||
|
|
||||||
|
[log]
|
||||||
|
main_only = false
|
||||||
|
time = false
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
clean_on_exit = false
|
||||||
|
|
||||||
|
[screen]
|
||||||
|
clear_on_rebuild = false
|
||||||
|
keep_scroll = true
|
|
@ -17,12 +17,12 @@ var (
|
||||||
ScreenChange("start")
|
ScreenChange("start")
|
||||||
|
|
||||||
incDecKeyboard = tx.NewKeyboard("").Row(
|
incDecKeyboard = tx.NewKeyboard("").Row(
|
||||||
tx.NewButton("+").ActionFunc(func(c *tx.A) {
|
tx.NewButton("+").ActionFunc(func(c *tx.Context) {
|
||||||
d := c.V.(*UserData)
|
d := c.V.(*UserData)
|
||||||
d.Counter++
|
d.Counter++
|
||||||
c.Sendf("%d", d.Counter)
|
c.Sendf("%d", d.Counter)
|
||||||
}),
|
}),
|
||||||
tx.NewButton("-").ActionFunc(func(c *tx.A) {
|
tx.NewButton("-").ActionFunc(func(c *tx.Context) {
|
||||||
d := c.V.(*UserData)
|
d := c.V.(*UserData)
|
||||||
d.Counter--
|
d.Counter--
|
||||||
c.Sendf("%d", d.Counter)
|
c.Sendf("%d", d.Counter)
|
||||||
|
@ -46,10 +46,11 @@ var (
|
||||||
Row(
|
Row(
|
||||||
tx.NewButton("Send location").
|
tx.NewButton("Send location").
|
||||||
WithSendLocation(true).
|
WithSendLocation(true).
|
||||||
ActionFunc(func(c *tx.A) {
|
ActionFunc(func(c *tx.Context) {
|
||||||
var err error
|
var err error
|
||||||
if c.U.Message.Location != nil {
|
u := c.Update
|
||||||
l := c.U.Message.Location
|
if u.Message.Location != nil {
|
||||||
|
l := u.Message.Location
|
||||||
err = c.Sendf(
|
err = c.Sendf(
|
||||||
"Longitude: %f\n"+
|
"Longitude: %f\n"+
|
||||||
"Latitude: %f\n"+
|
"Latitude: %f\n"+
|
||||||
|
@ -77,7 +78,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var beh = tx.NewBehaviour().
|
var beh = tx.NewBehaviour().
|
||||||
WithInitFunc(func(c *tx.A) {
|
WithInitFunc(func(c *tx.Context) {
|
||||||
// The session initialization.
|
// The session initialization.
|
||||||
c.V = &UserData{}
|
c.V = &UserData{}
|
||||||
c.ChangeScreen("start")
|
c.ChangeScreen("start")
|
||||||
|
@ -108,7 +109,7 @@ var beh = tx.NewBehaviour().
|
||||||
).
|
).
|
||||||
WithKeyboard(incDecKeyboard).
|
WithKeyboard(incDecKeyboard).
|
||||||
// The function will be called when reaching the screen.
|
// The function will be called when reaching the screen.
|
||||||
ActionFunc(func(c *tx.A) {
|
ActionFunc(func(c *tx.Context) {
|
||||||
d := c.V.(*UserData)
|
d := c.V.(*UserData)
|
||||||
c.Sendf("Current counter value = %d", d.Counter)
|
c.Sendf("Current counter value = %d", d.Counter)
|
||||||
}),
|
}),
|
||||||
|
@ -130,7 +131,7 @@ var beh = tx.NewBehaviour().
|
||||||
tx.NewKeyboard("").Row(
|
tx.NewKeyboard("").Row(
|
||||||
tx.NewButton("Check").
|
tx.NewButton("Check").
|
||||||
WithData("check").
|
WithData("check").
|
||||||
ActionFunc(func(a *tx.A) {
|
ActionFunc(func(a *tx.Context) {
|
||||||
d := a.V.(*UserData)
|
d := a.V.(*UserData)
|
||||||
a.Sendf("Counter = %d", d.Counter)
|
a.Sendf("Counter = %d", d.Counter)
|
||||||
}),
|
}),
|
||||||
|
@ -139,12 +140,12 @@ var beh = tx.NewBehaviour().
|
||||||
).WithCommands(
|
).WithCommands(
|
||||||
tx.NewCommand("hello").
|
tx.NewCommand("hello").
|
||||||
Desc("sends the 'Hello, World!' message back").
|
Desc("sends the 'Hello, World!' message back").
|
||||||
ActionFunc(func(c *tx.A) {
|
ActionFunc(func(c *tx.Context) {
|
||||||
c.Send("Hello, World!")
|
c.Send("Hello, World!")
|
||||||
}),
|
}),
|
||||||
tx.NewCommand("read").
|
tx.NewCommand("read").
|
||||||
Desc("reads a string and sends it back").
|
Desc("reads a string and sends it back").
|
||||||
ActionFunc(func(c *tx.A) {
|
ActionFunc(func(c *tx.Context) {
|
||||||
c.Send("Type some text:")
|
c.Send("Type some text:")
|
||||||
msg, err := c.ReadTextMessage()
|
msg, err := c.ReadTextMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -155,7 +156,7 @@ var beh = tx.NewBehaviour().
|
||||||
)
|
)
|
||||||
|
|
||||||
func mutateMessage(fn func(string) string) tx.ActionFunc {
|
func mutateMessage(fn func(string) string) tx.ActionFunc {
|
||||||
return func(c *tx.A) {
|
return func(c *tx.Context) {
|
||||||
for {
|
for {
|
||||||
msg, err := c.ReadTextMessage()
|
msg, err := c.ReadTextMessage()
|
||||||
if err == tx.NotAvailableErr {
|
if err == tx.NotAvailableErr {
|
||||||
|
@ -173,15 +174,15 @@ func mutateMessage(fn func(string) string) tx.ActionFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
var gBeh = tx.NewGroupBehaviour().
|
var gBeh = tx.NewGroupBehaviour().
|
||||||
InitFunc(func(a *tx.GA) {
|
InitFunc(func(c *tx.GC) {
|
||||||
}).
|
}).
|
||||||
WithCommands(
|
WithCommands(
|
||||||
tx.NewGroupCommand("hello").ActionFunc(func(a *tx.GA) {
|
tx.NewGroupCommand("hello").ActionFunc(func(c *tx.GC) {
|
||||||
a.Send("Hello, World!")
|
c.Send("Hello, World!")
|
||||||
}),
|
}),
|
||||||
tx.NewGroupCommand("mycounter").ActionFunc(func(a *tx.GA) {
|
tx.NewGroupCommand("mycounter").ActionFunc(func(c *tx.GC) {
|
||||||
d := a.GetSessionValue().(*UserData)
|
d := c.GetSessionValue().(*UserData)
|
||||||
a.Sendf("Your counter value is %d", d.Counter)
|
c.Sendf("Your counter value is %d", d.Counter)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
3
mkfile
3
mkfile
|
@ -1,5 +1,8 @@
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
|
run-air:V:
|
||||||
|
air -c airfile
|
||||||
|
|
||||||
build:V:
|
build:V:
|
||||||
go build -o exe/ ./cmd/...
|
go build -o exe/ ./cmd/...
|
||||||
|
|
||||||
|
|
100
src/tx/action.go
100
src/tx/action.go
|
@ -22,106 +22,16 @@ func newAction(a Action) *action {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) Act(arg *A) {
|
func (a *action) Act(c *Context) {
|
||||||
if a.Action != nil {
|
if a.Action != nil {
|
||||||
a.Action.Act(arg)
|
a.Action.Act(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Customized actions for the bot.
|
|
||||||
type Action interface {
|
|
||||||
Act(*Arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Customized actions for the
|
|
||||||
type GroupAction interface {
|
|
||||||
Act(*GroupArg)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ActionFunc func(*Arg)
|
|
||||||
|
|
||||||
func (af ActionFunc) Act(a *Arg) {
|
|
||||||
af(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
type GroupActionFunc func(*GroupArg)
|
|
||||||
|
|
||||||
func (af GroupActionFunc) Act(a *GroupArg) {
|
|
||||||
af(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The type implements changing screen to the underlying ScreenId
|
|
||||||
type ScreenChange ScreenId
|
|
||||||
|
|
||||||
func (sc ScreenChange) Act(c *Arg) {
|
|
||||||
if !c.B.behaviour.ScreenExist(ScreenId(sc)) {
|
|
||||||
panic(ScreenNotExistErr)
|
|
||||||
}
|
|
||||||
err := c.ChangeScreen(ScreenId(sc))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The argument for handling.
|
|
||||||
type Arg struct {
|
|
||||||
// Current context.
|
|
||||||
*Context
|
|
||||||
// The update that made the action to be called.
|
|
||||||
U *Update
|
|
||||||
}
|
|
||||||
type A = Arg
|
|
||||||
|
|
||||||
// Changes screen of user to the Id one.
|
|
||||||
func (c *Arg) ChangeScreen(screenId ScreenId) error {
|
|
||||||
if !c.B.behaviour.ScreenExist(screenId) {
|
|
||||||
return ScreenNotExistErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
if screen.Action != nil {
|
|
||||||
c.run(screen.Action, c.U)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// The argument for handling in group behaviour.
|
|
||||||
type GroupArg struct {
|
|
||||||
*GroupContext
|
|
||||||
*Update
|
|
||||||
}
|
|
||||||
type GA = GroupArg
|
|
||||||
|
|
||||||
func (a *GA) SentFromSid() SessionId {
|
|
||||||
return SessionId(a.SentFrom().ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *GA) GetSessionValue() any {
|
|
||||||
v, _ := a.B.GetSessionValueBySid(a.SentFromSid())
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// The argument for handling in channenl behaviours.
|
// The argument for handling in channenl behaviours.
|
||||||
type ChannelArg struct {
|
type ChannelContext struct {
|
||||||
}
|
}
|
||||||
type CA = ChannelArg
|
type CC = ChannelContext
|
||||||
type ChannelAction struct {
|
type ChannelAction struct {
|
||||||
Act (*ChannelArg)
|
Act (*ChannelContext)
|
||||||
}
|
|
||||||
|
|
||||||
type JsonTyper interface {
|
|
||||||
JsonType() string
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,13 +128,12 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
|
||||||
_, chnOk = chans[sid]
|
_, chnOk = chans[sid]
|
||||||
// Making the bot ignore anything except "start"
|
// Making the bot ignore anything except "start"
|
||||||
// before the session started
|
// before the session started
|
||||||
if u.Message.IsCommand() &&
|
if u.Message.IsCommand() && !sessionOk {
|
||||||
(!sessionOk) {
|
|
||||||
cmdName := CommandName(u.Message.Command())
|
cmdName := CommandName(u.Message.Command())
|
||||||
if cmdName == "start" {
|
if cmdName == "start" {
|
||||||
session := bot.sessions[sid]
|
session := bot.sessions[sid]
|
||||||
ctx := &Context{
|
ctx := &context{
|
||||||
B: bot,
|
Bot: bot,
|
||||||
Session: session,
|
Session: session,
|
||||||
updates: make(chan *Update),
|
updates: make(chan *Update),
|
||||||
}
|
}
|
||||||
|
@ -166,8 +165,8 @@ func (bot *Bot) handleGroup(updates chan *Update) {
|
||||||
if _, ok := bot.groupSessions[sid]; !ok {
|
if _, ok := bot.groupSessions[sid]; !ok {
|
||||||
bot.groupSessions.Add(sid)
|
bot.groupSessions.Add(sid)
|
||||||
session := bot.groupSessions[sid]
|
session := bot.groupSessions[sid]
|
||||||
ctx := &GroupContext{
|
ctx := &groupContext{
|
||||||
B: bot,
|
Bot: bot,
|
||||||
GroupSession: session,
|
GroupSession: session,
|
||||||
updates: make(chan *Update),
|
updates: make(chan *Update),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,9 @@ import (
|
||||||
apix "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
apix "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The type represents way to interact with user in
|
type context struct {
|
||||||
// handling functions. Is provided to Act() function always.
|
|
||||||
type Context struct {
|
|
||||||
*Session
|
*Session
|
||||||
B *Bot
|
*Bot
|
||||||
updates chan *Update
|
updates chan *Update
|
||||||
// Is true if currently reading the Update.
|
// Is true if currently reading the Update.
|
||||||
readingUpdate bool
|
readingUpdate bool
|
||||||
|
@ -18,11 +16,13 @@ type Context struct {
|
||||||
curScreen, prevScreen *Screen
|
curScreen, prevScreen *Screen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The type represents way to interact with user in
|
||||||
|
// handling functions. Is provided to Act() function always.
|
||||||
|
|
||||||
// Goroutie function to handle each user.
|
// Goroutie function to handle each user.
|
||||||
func (c *Context) handleUpdateChan(updates chan *Update) {
|
func (c *context) handleUpdateChan(updates chan *Update) {
|
||||||
var act Action
|
var act Action
|
||||||
bot := c.B
|
beh := c.behaviour
|
||||||
beh := bot.behaviour
|
|
||||||
|
|
||||||
if beh.Init != nil {
|
if beh.Init != nil {
|
||||||
c.run(beh.Init, nil)
|
c.run(beh.Init, nil)
|
||||||
|
@ -73,7 +73,7 @@ func (c *Context) handleUpdateChan(updates chan *Update) {
|
||||||
cb := apix.NewCallback(u.CallbackQuery.ID, u.CallbackQuery.Data)
|
cb := apix.NewCallback(u.CallbackQuery.ID, u.CallbackQuery.Data)
|
||||||
data := u.CallbackQuery.Data
|
data := u.CallbackQuery.Data
|
||||||
|
|
||||||
_, err := bot.Request(cb)
|
_, err := c.Request(cb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -103,15 +103,15 @@ func (c *Context) handleUpdateChan(updates chan *Update) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) run(a Action, u *Update) {
|
func (c *context) run(a Action, u *Update) {
|
||||||
go a.Act(&A{
|
go a.Act(&Context{
|
||||||
Context: c,
|
context: c,
|
||||||
U: u,
|
Update: u,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the next update ignoring current screen.
|
// Returns the next update ignoring current screen.
|
||||||
func (c *Context) ReadUpdate() (*Update, error) {
|
func (c *context) ReadUpdate() (*Update, error) {
|
||||||
c.readingUpdate = true
|
c.readingUpdate = true
|
||||||
u := <-c.updates
|
u := <-c.updates
|
||||||
c.readingUpdate = false
|
c.readingUpdate = false
|
||||||
|
@ -123,7 +123,7 @@ func (c *Context) ReadUpdate() (*Update, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the next text message that the user sends.
|
// Returns the next text message that the user sends.
|
||||||
func (c *Context) ReadTextMessage() (string, error) {
|
func (c *context) ReadTextMessage() (string, error) {
|
||||||
u, err := c.ReadUpdate()
|
u, err := c.ReadUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -136,34 +136,34 @@ func (c *Context) ReadTextMessage() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends to the user specified text.
|
// Sends to the user specified text.
|
||||||
func (c *Context) Send(v ...any) error {
|
func (c *context) Send(v ...any) error {
|
||||||
msg := apix.NewMessage(c.Id.ToTelegram(), fmt.Sprint(v...))
|
msg := apix.NewMessage(c.Id.ToTelegram(), fmt.Sprint(v...))
|
||||||
_, err := c.B.Send(msg)
|
_, err := c.Bot.Send(msg)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends the formatted with fmt.Sprintf message to the user.
|
// Sends the formatted with fmt.Sprintf message to the user.
|
||||||
func (c *Context) Sendf(format string, v ...any) error {
|
func (c *context) Sendf(format string, v ...any) error {
|
||||||
return c.Send(fmt.Sprintf(format, v...))
|
return c.Send(fmt.Sprintf(format, v...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context for interaction inside groups.
|
// Context for interaction inside groups.
|
||||||
type GroupContext struct {
|
type groupContext struct {
|
||||||
*GroupSession
|
*GroupSession
|
||||||
B *Bot
|
*Bot
|
||||||
updates chan *Update
|
updates chan *Update
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GroupContext) run(a GroupAction, u *Update) {
|
func (c *groupContext) run(a GroupAction, u *Update) {
|
||||||
go a.Act(&GA{
|
go a.Act(&GroupContext{
|
||||||
GroupContext: c,
|
groupContext: c,
|
||||||
Update: u,
|
Update: u,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GroupContext) handleUpdateChan(updates chan *Update) {
|
func (c *groupContext) handleUpdateChan(updates chan *Update) {
|
||||||
var act GroupAction
|
var act GroupAction
|
||||||
beh := c.B.groupBehaviour
|
beh := c.groupBehaviour
|
||||||
for u := range updates {
|
for u := range updates {
|
||||||
if u.Message != nil {
|
if u.Message != nil {
|
||||||
msg := u.Message
|
msg := u.Message
|
||||||
|
@ -172,7 +172,7 @@ func (c *GroupContext) handleUpdateChan(updates chan *Update) {
|
||||||
|
|
||||||
// Skipping the commands sent not to us.
|
// Skipping the commands sent not to us.
|
||||||
atName := msg.CommandWithAt()[len(cmdName)+1:]
|
atName := msg.CommandWithAt()[len(cmdName)+1:]
|
||||||
if c.B.Me.UserName != atName {
|
if c.Bot.Me.UserName != atName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cmd, ok := beh.Commands[cmdName]
|
cmd, ok := beh.Commands[cmdName]
|
||||||
|
@ -189,13 +189,13 @@ func (c *GroupContext) handleUpdateChan(updates chan *Update) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GroupContext) Sendf(format string, v ...any) error {
|
func (c *groupContext) Sendf(format string, v ...any) error {
|
||||||
return c.Send(fmt.Sprintf(format, v...))
|
return c.Send(fmt.Sprintf(format, v...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends into the chat specified values converted to strings.
|
// Sends into the chat specified values converted to strings.
|
||||||
func (c *GroupContext) Send(v ...any) error {
|
func (c *groupContext) Send(v ...any) error {
|
||||||
msg := apix.NewMessage(c.Id.ToTelegram(), fmt.Sprint(v...))
|
msg := apix.NewMessage(c.Id.ToTelegram(), fmt.Sprint(v...))
|
||||||
_, err := c.B.Send(msg)
|
_, err := c.Bot.Send(msg)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
29
src/tx/group.go
Normal file
29
src/tx/group.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package tx
|
||||||
|
|
||||||
|
// Customized actions for the group behaviour.
|
||||||
|
type GroupAction interface {
|
||||||
|
Act(*GroupContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The handler function type.
|
||||||
|
type GroupActionFunc func(*GroupContext)
|
||||||
|
|
||||||
|
func (af GroupActionFunc) Act(a *GroupContext) {
|
||||||
|
af(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GC = GroupContext
|
||||||
|
|
||||||
|
func (c *GroupContext) SentFromSid() SessionId {
|
||||||
|
return SessionId(c.SentFrom().ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *GroupContext) GetSessionValue() any {
|
||||||
|
v, _ := a.Bot.GetSessionValueBySid(a.SentFromSid())
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
type GroupContext struct {
|
||||||
|
*groupContext
|
||||||
|
*Update
|
||||||
|
}
|
59
src/tx/private.go
Normal file
59
src/tx/private.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package tx
|
||||||
|
|
||||||
|
// Interface to interact with the user.
|
||||||
|
type Context struct {
|
||||||
|
*context
|
||||||
|
*Update
|
||||||
|
}
|
||||||
|
|
||||||
|
// Customized actions for the bot.
|
||||||
|
type Action interface {
|
||||||
|
Act(*Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActionFunc func(*Context)
|
||||||
|
|
||||||
|
func (af ActionFunc) Act(c *Context) {
|
||||||
|
af(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The type implements changing screen to the underlying ScreenId
|
||||||
|
type ScreenChange ScreenId
|
||||||
|
|
||||||
|
func (sc ScreenChange) Act(c *Context) {
|
||||||
|
if !c.behaviour.ScreenExist(ScreenId(sc)) {
|
||||||
|
panic(ScreenNotExistErr)
|
||||||
|
}
|
||||||
|
err := c.ChangeScreen(ScreenId(sc))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type C = Context
|
||||||
|
|
||||||
|
// Changes screen of user to the Id one.
|
||||||
|
func (c *Context) ChangeScreen(screenId ScreenId) error {
|
||||||
|
if !c.behaviour.ScreenExist(screenId) {
|
||||||
|
return ScreenNotExistErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.behaviour.Screens[screenId]
|
||||||
|
c.prevScreen = c.curScreen
|
||||||
|
c.curScreen = screen
|
||||||
|
screen.Render(c.context)
|
||||||
|
if screen.Action != nil {
|
||||||
|
c.run(screen.Action, c.Update)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -62,7 +62,7 @@ func (s *Screen) ActionFunc(a ActionFunc) *Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renders output of the screen only to the side of the user.
|
// Renders output of the screen only to the side of the user.
|
||||||
func (s *Screen) Render(c *Context) error {
|
func (s *Screen) Render(c *context) error {
|
||||||
id := c.Id.ToTelegram()
|
id := c.Id.ToTelegram()
|
||||||
kbd := s.Keyboard
|
kbd := s.Keyboard
|
||||||
iKbd := s.InlineKeyboard
|
iKbd := s.InlineKeyboard
|
||||||
|
@ -87,13 +87,13 @@ func (s *Screen) Render(c *Context) error {
|
||||||
msg.ReplyMarkup = iKbd.toTelegramInline()
|
msg.ReplyMarkup = iKbd.toTelegramInline()
|
||||||
} else if kbd != nil {
|
} else if kbd != nil {
|
||||||
msg.ReplyMarkup = kbd.toTelegramReply()
|
msg.ReplyMarkup = kbd.toTelegramReply()
|
||||||
if _, err := c.B.Send(msg); err != nil {
|
if _, err := c.Bot.Send(msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
msg.ReplyMarkup = apix.NewRemoveKeyboard(true)
|
msg.ReplyMarkup = apix.NewRemoveKeyboard(true)
|
||||||
if _, err := c.B.Send(msg); err != nil {
|
if _, err := c.Bot.Send(msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -121,7 +121,7 @@ func (s *Screen) Render(c *Context) error {
|
||||||
|
|
||||||
for _, m := range ch {
|
for _, m := range ch {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
if _, err := c.B.Send(m); err != nil {
|
if _, err := c.Bot.Send(m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue