Implemented path history to make easier movement between screens.

This commit is contained in:
Andrey Parhomenko 2023-10-03 14:49:56 +03:00
parent 05844d2bc0
commit 223f8a5b29
2 changed files with 32 additions and 23 deletions

View file

@ -55,7 +55,7 @@ func ExtractSessionData(c *tg.Context) *SessionData {
var ( var (
homeButton = tg.NewButton("Home").Go("/") homeButton = tg.NewButton("Home").Go("/")
backButton = tg.NewButton("Back").Go("..") backButton = tg.NewButton("Back").Go("-")
backKeyboard = tg.NewKeyboard().Row( backKeyboard = tg.NewKeyboard().Row(
backButton, backButton,
) )
@ -292,8 +292,12 @@ WithUsage(tg.Func(func(c *tg.Context){
Desc("check of the dynamic work"). Desc("check of the dynamic work").
WithWidget(tg.Func(func(c *tg.Context){ WithWidget(tg.Func(func(c *tg.Context){
})), })),
tg.NewCommand("history").
Desc("print go history").
WithAction(tg.Func(func(c *tg.Context){
c.Sendf("%q", c.History())
})),
)) ))
func main() { func main() {
log.Println(beh.Screens) log.Println(beh.Screens)
token := os.Getenv("BOT_TOKEN") token := os.Getenv("BOT_TOKEN")

View file

@ -43,7 +43,8 @@ type context struct {
updates *UpdateChan updates *UpdateChan
skippedUpdates *UpdateChan skippedUpdates *UpdateChan
// Current screen ID. // Current screen ID.
path, prevPath Path pathHistory []Path
//path, prevPath Path
} }
// Goroutie function to handle each user. // Goroutie function to handle each user.
@ -59,11 +60,11 @@ func (c *context) run(a Action, u *Update) {
} }
func (c *Context) Path() Path { func (c *Context) Path() Path {
return c.path ln := len(c.pathHistory)
if ln == 0 {
return ""
} }
return c.pathHistory[ln-1]
func (c *Context) PrevPath() Path {
return c.prevPath
} }
func (c *Context) Run(a Action) { func (c *Context) Run(a Action) {
@ -168,10 +169,18 @@ func (af ActionFunc) Act(c *Context) {
af(c) af(c)
} }
func (c *Context) History() []Path {
return c.pathHistory
}
// Changes screen of user to the Id one. // Changes screen of user to the Id one.
func (c *Context) Go(pth Path, args ...any) { func (c *Context) Go(pth Path, args ...any) {
var back bool
if pth == "-" { if pth == "-" {
pth = c.PrevPath() ln := len(c.pathHistory)
pth = c.pathHistory[ln-2]
c.pathHistory = c.pathHistory[:ln-1]
back = true
} }
// Getting the screen and changing to // Getting the screen and changing to
// then executing its widget. // then executing its widget.
@ -182,8 +191,10 @@ func (c *Context) Go(pth Path, args ...any) {
if !c.PathExist(pth) { if !c.PathExist(pth) {
panic(ScreenNotExistErr) panic(ScreenNotExistErr)
} }
c.prevPath = c.path
c.path = pth if !back && c.Path() != pth {
c.pathHistory = append(c.pathHistory, pth)
}
// Stopping the current widget. // Stopping the current widget.
screen := c.Bot.behaviour.Screens[pth] screen := c.Bot.behaviour.Screens[pth]
@ -199,7 +210,7 @@ func (c *Context) PathExist(pth Path) bool {
return c.Bot.behaviour.PathExist(pth) return c.Bot.behaviour.PathExist(pth)
} }
func (c *Context) MakeArg(args []any) any { func (c *Context) makeArg(args []any) any {
var arg any var arg any
if len(args) == 1 { if len(args) == 1 {
arg = args[0] arg = args[0]
@ -210,6 +221,9 @@ func (c *Context) MakeArg(args []any) any {
} }
func (c *Context) RunCompo(compo Component, args ...any) *UpdateChan { func (c *Context) RunCompo(compo Component, args ...any) *UpdateChan {
if compo == nil {
return nil
}
s, ok := compo.(Sendable) s, ok := compo.(Sendable)
if ok { if ok {
msg, err := c.Send(s) msg, err := c.Send(s)
@ -222,7 +236,7 @@ func (c *Context) RunCompo(compo Component, args ...any) *UpdateChan {
go func() { go func() {
compo.Serve( compo.Serve(
c.WithInput(updates). c.WithInput(updates).
WithArg(c.MakeArg(args)), WithArg(c.makeArg(args)),
) )
// To let widgets finish themselves before // To let widgets finish themselves before
// the channel is closed and close it by themselves. // the channel is closed and close it by themselves.
@ -238,7 +252,7 @@ func (c *Context) RunWidget(widget Widget, args ...any) *UpdateChan {
} }
pth := c.Path() pth := c.Path()
compos := widget.Render(c.WithArg(c.MakeArg(args))) compos := widget.Render(c.WithArg(c.makeArg(args)))
// Leave if changed path. // Leave if changed path.
if compos == nil || pth != c.Path() { if compos == nil || pth != c.Path() {
return nil return nil
@ -300,12 +314,3 @@ func (c *Context) ReadString(pref string, args ...any) string {
return text return text
} }
// Change screen to the previous.
// To get to the parent screen use GoUp.
func (c *Context) GoPrev() {
pth := c.PrevPath()
if pth == "" {
c.Go("/")
}
c.Go(pth)
}