Finished the node approach to the screens.
This commit is contained in:
parent
061add76a8
commit
7d149558f9
6 changed files with 81 additions and 60 deletions
|
@ -52,6 +52,11 @@ func ExtractSessionData(c *tg.Context) *SessionData {
|
|||
|
||||
var (
|
||||
startScreenButton = tg.NewButton("Home").Go("/")
|
||||
backButton = tg.NewButton("Back").Go("..")
|
||||
backKeyboard = tg.NewKeyboard().Row(
|
||||
backButton,
|
||||
)
|
||||
|
||||
incDecKeyboard = tg.NewKeyboard().Row(
|
||||
tg.NewButton("+").ActionFunc(func(c *tg.Context) {
|
||||
d := ExtractSessionData(c)
|
||||
|
@ -70,10 +75,7 @@ var (
|
|||
navKeyboard = tg.NewKeyboard().Row(
|
||||
tg.NewButton("Inc/Dec").Go("/inc-dec"),
|
||||
).Row(
|
||||
tg.NewButton("Upper case").ActionFunc(func(c *tg.Context){
|
||||
c.Go("/upper-case", "this shit", "works")
|
||||
}),
|
||||
tg.NewButton("Lower case").Go("/case"),
|
||||
tg.NewButton("Mutate messages").Go("/mutate-messages"),
|
||||
).Row(
|
||||
tg.NewButton("Send location").Go("/send-location"),
|
||||
).Reply().WithOneTime(true)
|
||||
|
@ -119,6 +121,37 @@ WithInitFunc(func(c *tg.Context) {
|
|||
navKeyboard.Widget("Choose what you are interested in"),
|
||||
),
|
||||
|
||||
tg.NewNode(
|
||||
"mutate-messages", tg.NewPage().WithReply(
|
||||
tg.NewKeyboard().Row(
|
||||
tg.NewButton("Upper case").Go("upper-case"),
|
||||
tg.NewButton("Lower case").Go("lower-case"),
|
||||
).Row(
|
||||
backButton,
|
||||
).Reply().Widget(
|
||||
"Choose the function to mutate string",
|
||||
),
|
||||
),
|
||||
tg.NewNode(
|
||||
"upper-case", tg.NewPage().WithReply(
|
||||
backKeyboard.Reply().Widget(
|
||||
"Type a string and the bot will convert it to upper case",
|
||||
),
|
||||
).WithSub(
|
||||
NewMutateMessageWidget(strings.ToUpper),
|
||||
),
|
||||
),
|
||||
tg.NewNode(
|
||||
"lower-case", tg.NewPage().WithReply(
|
||||
backKeyboard.Reply().Widget(
|
||||
"Type a string and the bot will convert it to lower case",
|
||||
),
|
||||
).WithSub(
|
||||
NewMutateMessageWidget(strings.ToLower),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
tg.NewNode(
|
||||
"inc-dec", tg.NewPage().WithReply(
|
||||
incDecKeyboard.Reply().Widget("Press the buttons to increment and decrement"),
|
||||
|
@ -129,26 +162,6 @@ WithInitFunc(func(c *tg.Context) {
|
|||
}),
|
||||
),
|
||||
|
||||
tg.NewNode(
|
||||
"upper-case", tg.NewPage().WithText(
|
||||
"Type text and the bot will send you the upper case version to you",
|
||||
).WithReply(
|
||||
navToStartKeyboard.Widget(""),
|
||||
).WithSub(
|
||||
NewMutateMessageWidget(strings.ToUpper),
|
||||
),
|
||||
),
|
||||
|
||||
tg.NewNode(
|
||||
"lower-case", tg.NewPage().WithText(
|
||||
"Type text and the bot will send you the lower case version",
|
||||
).WithReply(
|
||||
navToStartKeyboard.Widget(""),
|
||||
).WithSub(
|
||||
NewMutateMessageWidget(strings.ToLower),
|
||||
),
|
||||
),
|
||||
|
||||
tg.NewNode(
|
||||
"send-location", tg.NewPage().WithReply(
|
||||
sendLocationKeyboard.Widget("Press the button to send your location!"),
|
||||
|
@ -169,8 +182,7 @@ WithInitFunc(func(c *tg.Context) {
|
|||
tg.NewCommand("start").
|
||||
Desc("start or restart the bot or move to the start screen").
|
||||
ActionFunc(func(c *tg.Context){
|
||||
c.Sendf("Your username is %q", c.Message.From.UserName)
|
||||
c.Go("/start")
|
||||
c.Go("/")
|
||||
}),
|
||||
tg.NewCommand("hello").
|
||||
Desc("sends the 'Hello, World!' message back").
|
||||
|
@ -227,7 +239,6 @@ func main() {
|
|||
}
|
||||
bot = bot.
|
||||
WithBehaviour(beh).
|
||||
WithGroupBehaviour(gBeh).
|
||||
Debug(true)
|
||||
|
||||
bot.Data = &BotData{
|
||||
|
|
|
@ -63,8 +63,11 @@ func (btn *Button) ActionFunc(fn ActionFunc) *Button {
|
|||
return btn.WithAction(fn)
|
||||
}
|
||||
|
||||
func (btn *Button) Go(sc ScreenChange) *Button {
|
||||
return btn.WithAction(sc)
|
||||
func (btn *Button) Go(pth Path, args ...any) *Button {
|
||||
return btn.WithAction(ScreenGo{
|
||||
Path: pth,
|
||||
Args: args,
|
||||
})
|
||||
}
|
||||
|
||||
func (btn *Button) ToTelegram() apix.KeyboardButton {
|
||||
|
|
|
@ -13,7 +13,7 @@ var (
|
|||
func initEncoding() {
|
||||
actions := map[string]Action{
|
||||
"action-func": ActionFunc(nil),
|
||||
"screen-change": ScreenChange(""),
|
||||
"screen-change": ScreenGo{},
|
||||
}
|
||||
for k, action := range actions {
|
||||
DefineAction(k, action)
|
||||
|
|
|
@ -143,33 +143,22 @@ func (af ActionFunc) Act(c *Context) {
|
|||
af(c)
|
||||
}
|
||||
|
||||
// The type implements changing screen to the underlying ScreenId
|
||||
type ScreenChange Path
|
||||
|
||||
func (sc ScreenChange) Act(c *Context) {
|
||||
if !c.Bot.behaviour.PathExist(Path(sc)) {
|
||||
panic(ScreenNotExistErr)
|
||||
}
|
||||
err := c.Go(Path(sc))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type C = Context
|
||||
|
||||
// Changes screen of user to the Id one.
|
||||
func (c *Context) Go(pth Path, args ...any) error {
|
||||
if !c.PathExist(pth) {
|
||||
return ScreenNotExistErr
|
||||
}
|
||||
|
||||
// Getting the screen and changing to
|
||||
// then executing its widget.
|
||||
if !pth.IsAbs() {
|
||||
pth = (c.Path() + "/" + pth).Clean()
|
||||
}
|
||||
|
||||
c.Sendf("path: %q\nmap: %v", pth, c.Bot.behaviour.Screens)
|
||||
|
||||
if !c.PathExist(pth) {
|
||||
return ScreenNotExistErr
|
||||
}
|
||||
c.prevPath = c.path
|
||||
c.path = pth
|
||||
|
||||
|
@ -217,16 +206,6 @@ func (c *Context) RunWidget(widget Widget, args ...any) *UpdateChan {
|
|||
return updates
|
||||
}
|
||||
|
||||
// Go to the root screen.
|
||||
func (c *Context) GoRoot() {
|
||||
c.Go("/")
|
||||
}
|
||||
|
||||
// Go one level upper in the screen hierarchy.
|
||||
func (c *Context) GoUp() {
|
||||
c.Go(c.Path().Dir())
|
||||
}
|
||||
|
||||
// Change screen to the previous.
|
||||
// To get to the parent screen use GoUp.
|
||||
func (c *Context) GoPrev() {
|
||||
|
|
20
tg/screen.go
20
tg/screen.go
|
@ -4,6 +4,24 @@ import (
|
|||
"path"
|
||||
)
|
||||
|
||||
// The type implements changing screen to the underlying ScreenId
|
||||
type ScreenGo struct {
|
||||
Path Path
|
||||
Args []any
|
||||
}
|
||||
|
||||
func (sc ScreenGo) Act(c *Context) {
|
||||
err := c.Go(sc.Path, sc.Args...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// The same as Act.
|
||||
func (sc ScreenGo) Serve(c *Context) {
|
||||
sc.Act(c)
|
||||
}
|
||||
|
||||
// Unique identifier for the screen
|
||||
// and relative paths to the screen.
|
||||
type Path string
|
||||
|
@ -89,7 +107,7 @@ func (n *Node) ScreenMap(root Path) ScreenMap {
|
|||
pth := (root + n.Path).Clean()
|
||||
m[pth] = n.Screen
|
||||
for _, sub := range n.Subs {
|
||||
buf := sub.ScreenMap((pth + "/").Clean())
|
||||
buf := sub.ScreenMap(pth + "/")
|
||||
for k, v := range buf {
|
||||
_, ok := m[k]
|
||||
if ok {
|
||||
|
|
16
tg/widget.go
16
tg/widget.go
|
@ -20,11 +20,11 @@ type Widget interface {
|
|||
Serve(*Context)
|
||||
}
|
||||
|
||||
// Needs implementation.
|
||||
// Behaviour can be the root widget or something like
|
||||
// that.
|
||||
// Implementing the interface provides ability to
|
||||
// be used as the root widget for contexts.
|
||||
type RootWidget interface {
|
||||
Widget
|
||||
SetSub(Widget)
|
||||
}
|
||||
|
||||
// Implementing the interface provides way
|
||||
|
@ -36,6 +36,15 @@ type Filterer interface {
|
|||
Filter(*Update, MessageMap) bool
|
||||
}
|
||||
|
||||
// General type function for faster typing.
|
||||
type Func func(*Context)
|
||||
func (f Func) Act(c *Context) {
|
||||
f(c)
|
||||
}
|
||||
func (f Func) Serve(c *Context) {
|
||||
f(c)
|
||||
}
|
||||
|
||||
// The type represents general update channel.
|
||||
type UpdateChan struct {
|
||||
chn chan *Update
|
||||
|
@ -48,6 +57,7 @@ func NewUpdateChan() *UpdateChan {
|
|||
return ret
|
||||
}
|
||||
|
||||
|
||||
func (updates *UpdateChan) Chan() chan *Update {
|
||||
return updates.chn
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue