Implemented the new way of thinking about ScreenIds. As PATHS.

This commit is contained in:
Andrey Parhomenko 2023-09-20 23:38:29 +03:00
parent 1fc2acbbd6
commit 88d4310db5
5 changed files with 28 additions and 16 deletions

View file

@ -27,7 +27,7 @@ func NewMutateMessageWidget(fn func(string) string) *MutateMessageWidget {
} }
func (w *MutateMessageWidget) Serve(c *tg.Context) { func (w *MutateMessageWidget) Serve(c *tg.Context) {
args, ok := c.Arg.([]any) args, ok := c.Arg.(tg.ArgSlice)
if ok { if ok {
for _, arg := range args { for _, arg := range args {
c.Sendf("%v", arg) c.Sendf("%v", arg)
@ -51,8 +51,9 @@ func ExtractSessionData(c *tg.Context) *SessionData {
} }
var ( var (
startScreenButton = tg.NewButton("🏠 To the start screen"). startScreenButton = tg.NewButton("Back").ActionFunc(func(c *tg.Context){
ScreenChange("/start") c.GoUp()
})
incDecKeyboard = tg.NewKeyboard().Row( incDecKeyboard = tg.NewKeyboard().Row(
tg.NewButton("+").ActionFunc(func(c *tg.Context) { tg.NewButton("+").ActionFunc(func(c *tg.Context) {
@ -73,7 +74,7 @@ var (
tg.NewButton("Inc/Dec").ScreenChange("/start/inc-dec"), tg.NewButton("Inc/Dec").ScreenChange("/start/inc-dec"),
).Row( ).Row(
tg.NewButton("Upper case").ActionFunc(func(c *tg.Context){ tg.NewButton("Upper case").ActionFunc(func(c *tg.Context){
c.ChangeScreen("/start/upper-case", "this shit", "works") c.Go("/start/upper-case", "this shit", "works")
}), }),
tg.NewButton("Lower case").ScreenChange("/start/lower-case"), tg.NewButton("Lower case").ScreenChange("/start/lower-case"),
).Row( ).Row(
@ -175,7 +176,7 @@ var beh = tg.NewBehaviour().
Desc("start or restart the bot or move to the start screen"). Desc("start or restart the bot or move to the start screen").
ActionFunc(func(c *tg.Context){ ActionFunc(func(c *tg.Context){
c.Sendf("Your username is %q", c.Message.From.UserName) c.Sendf("Your username is %q", c.Message.From.UserName)
c.ChangeScreen("/start") c.Go("/start")
}), }),
tg.NewCommand("hello"). tg.NewCommand("hello").
Desc("sends the 'Hello, World!' message back"). Desc("sends the 'Hello, World!' message back").

View file

@ -165,7 +165,7 @@ func (widget *CommandWidget) Serve(c *Context) {
var cmdUpdates *UpdateChan var cmdUpdates *UpdateChan
for u := range c.Input() { for u := range c.Input() {
if c.ScreenId() == "" && u.Message != nil { if c.CurScreen() == "" && u.Message != nil {
// Skipping and executing the preinit action // Skipping and executing the preinit action
// while we have the empty screen. // while we have the empty screen.
// E. g. the session did not start. // E. g. the session did not start.

View file

@ -92,7 +92,7 @@ func (p *Page) Serve(c *Context) {
msgs, _ := c.Render(p) msgs, _ := c.Render(p)
inlineMsg := msgs["page/inline"] inlineMsg := msgs["page/inline"]
subUpdates := c.RunWidget(p.SubWidget) subUpdates := c.RunWidget(p.SubWidget, c.Arg)
defer subUpdates.Close() defer subUpdates.Close()
inlineUpdates := c.RunWidget(p.Inline) inlineUpdates := c.RunWidget(p.Inline)

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
//tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" //tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"path"
) )
type ContextType string type ContextType string
@ -41,11 +42,11 @@ func (c *context) run(a Action, u *Update) {
a.Act(&Context{context: c, Update: u}) a.Act(&Context{context: c, Update: u})
} }
func (c *Context) ScreenId() ScreenId { func (c *Context) CurScreen() ScreenId {
return c.screenId return c.screenId
} }
func (c *Context) PrevScreenId() ScreenId { func (c *Context) PrevScreen() ScreenId {
return c.prevScreenId return c.prevScreenId
} }
@ -149,7 +150,7 @@ func (sc ScreenChange) Act(c *Context) {
if !c.Bot.behaviour.ScreenExist(ScreenId(sc)) { if !c.Bot.behaviour.ScreenExist(ScreenId(sc)) {
panic(ScreenNotExistErr) panic(ScreenNotExistErr)
} }
err := c.ChangeScreen(ScreenId(sc)) err := c.Go(ScreenId(sc))
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -158,7 +159,7 @@ func (sc ScreenChange) Act(c *Context) {
type C = Context type C = Context
// Changes screen of user to the Id one. // Changes screen of user to the Id one.
func (c *Context) ChangeScreen(screenId ScreenId, args ...any) error { func (c *Context) Go(screenId ScreenId, args ...any) error {
if !c.Bot.behaviour.ScreenExist(screenId) { if !c.Bot.behaviour.ScreenExist(screenId) {
return ScreenNotExistErr return ScreenNotExistErr
} }
@ -171,9 +172,8 @@ func (c *Context) ChangeScreen(screenId ScreenId, args ...any) error {
// Stopping the current widget. // Stopping the current widget.
c.skippedUpdates.Close() c.skippedUpdates.Close()
c.skippedUpdates = nil
if screen.Widget != nil { if screen.Widget != nil {
c.skippedUpdates = c.RunWidget(screen.Widget, args) c.skippedUpdates = c.RunWidget(screen.Widget, args...)
} else { } else {
panic("no widget defined for the screen") panic("no widget defined for the screen")
} }
@ -187,7 +187,6 @@ func (c *Context) RunWidget(widget Widget, args ...any) *UpdateChan {
return nil return nil
} }
var arg any var arg any
if len(args) == 1 { if len(args) == 1 {
arg = args[0] arg = args[0]
@ -202,12 +201,20 @@ func (c *Context) RunWidget(widget Widget, args ...any) *UpdateChan {
WithInput(updates). WithInput(updates).
WithArg(arg), WithArg(arg),
) )
// To let widgets finish themselves before
// the channel is closed.
updates.Close() updates.Close()
}() }()
return updates return updates
} }
func (c *Context) ChangeToPrevScreen() { func (c *Context) GoUp() {
c.ChangeScreen(c.PrevScreenId()) c.Go(ScreenId(path.Dir(string(c.CurScreen()))))
}
// Change screen to the previous.
// To get to the parent screen use GoUp.
func (c *Context) GoPrev() {
c.Go(c.PrevScreen())
} }

View file

@ -5,6 +5,10 @@ import (
//"fmt" //"fmt"
) )
type ArgMap = map[string] any
type ArgSlice = []any
type ArgList[V any] []V
// Implementing the interface provides // Implementing the interface provides
// ability to build your own widgets, // ability to build your own widgets,
// aka components. // aka components.