feat: better custom methods for panels.

This commit is contained in:
Andrey Parhomenko 2024-07-25 19:48:02 +05:00
parent 7f23e5a13e
commit 045a15cbea
6 changed files with 88 additions and 60 deletions

View file

@ -9,54 +9,47 @@ import (
// how to store and get session data values
// and working with dynamic panels.
var IncDecWidget = tg.RenderFunc(func(c tg.Context) tg.UI {
var (
kbd *tg.InlineCompo
//cntMsg *tg.MessageCompo
inline, std, onlyInc, onlyDec tg.Inline
)
d := ExtractSessionData(c)
format := "Press the buttons to increment and decrement.\n" +
const format = "Press the buttons" +
"to increment and decrement.\n" +
"Current counter value = %d"
incBtn := tg.Buttonf("+").WithAction(tg.Func(func(c tg.Context) {
d.Counter++
kbd.Text = fmt.Sprintf(format, d.Counter)
if d.Counter == 5 {
kbd.Inline = onlyDec
} else {
kbd.Inline = std
}
kbd.Update(c)
}))
decBtn := tg.Buttonf("-").WithAction(tg.Func(func(c tg.Context) {
d.Counter--
kbd.Text = fmt.Sprintf(format, d.Counter)
if d.Counter == -5 {
kbd.Inline = onlyInc
} else {
kbd.Inline = std
}
kbd.Update(c)
//c.Sendf("%d", d.Counter)
}))
onlyInc = tg.NewKeyboard().Row(incBtn).Inline()
onlyDec = tg.NewKeyboard().Row(decBtn).Inline()
std = tg.NewKeyboard().Row(incBtn, decBtn).Inline()
if d.Counter == 5 {
inline = onlyDec
} else if d.Counter == -5 {
inline = onlyInc
} else {
inline = std
}
kbd = tg.Messagef(format, d.Counter).Inline(inline)
d := ExtractSessionData(c)
return tg.UI{
kbd,
tg.Messagef(format, d.Counter).Panel(
c,
tg.PanelFunc(func(
panel *tg.PanelCompo,
c tg.Context,
) []tg.ButtonRow {
d := ExtractSessionData(c)
row := tg.ButtonRow{}
if d.Counter != -5 {
row = append(
row,
tg.Buttonf(
"-",
).WithAction(tg.Func(func(c tg.Context){
d.Counter--
panel.Text = fmt.Sprintf(format, d.Counter)
c.Update(panel)
})),
)
}
if d.Counter != +5 {
row = append(
row,
tg.Buttonf(
"+",
).WithAction(tg.Func(func(c tg.Context){
d.Counter++
panel.Text = fmt.Sprintf(format, d.Counter)
c.Update(panel)
})),
)
}
return []tg.ButtonRow{row}
}),
),
tg.Messagef("Use the reply keyboard to get back").Reply(
BackKeyboard.Reply(),
),

View file

@ -8,7 +8,10 @@ var DynamicPanelWidget = tg.RenderFunc(func(c tg.Context) tg.UI {
return tg.UI{
tg.Messagef("Paged panel").PanelPager(
c, 0, 5,
tg.PanelPagerFunc(func(c tg.Context, page, size int) tg.PanelPage {
tg.PanelPagerFunc(func(
panel *tg.PanelPagerCompo,
c tg.Context, page, size int,
) tg.PanelPage {
rows := []tg.ButtonRow{}
for i := 0; i < size; i++ {
num := 1 + page*size + i

View file

@ -178,6 +178,10 @@ func (c Context) ReadString(promptf string, args ...any) string {
return text
}
func (c Context) Update(updater Updater) error {
return updater.Update(c)
}
func (c Context) CallbackUpdate() *Update {
return &c.update
}

View file

@ -1,7 +1,10 @@
package tg
type PanelPager interface {
GetPanelPage(c Context, page, size int) PanelPage
GetPanelPage(
panel *PanelPagerCompo,
c Context, page, size int,
) PanelPage
}
type PanelPage struct {
@ -10,12 +13,13 @@ type PanelPage struct {
}
type PanelPagerFunc func(
panel *PanelPagerCompo,
c Context, page, size int,
) PanelPage
func (fn PanelPagerFunc) GetPanelPage(
c Context, page, size int,
panel *PanelPagerCompo, c Context, page, size int,
) PanelPage {
return fn(c, page, size)
return fn(panel, c, page, size)
}
type PanelPagerCompo struct {
@ -46,11 +50,11 @@ func (compo *MessageCompo) PanelPager(
return ret
}
func (panel *PanelPagerCompo) MakeRows(
c Context,
func (panel *PanelPagerCompo) GetPanelRows(
pcompo *PanelCompo, c Context,
) []ButtonRow {
page := panel.pager.GetPanelPage(
c, panel.page, panel.size,
panel, c, panel.page, panel.size,
)
controlRow := ButtonRow{}

View file

@ -1,5 +1,7 @@
package tg
// Using the interface and all related is
// deprecated. Use the Paneler interface and function.
type Rowser interface {
MakeRows(c Context) []ButtonRow
}
@ -9,32 +11,45 @@ func (fn RowserFunc) MakeRows(c Context) []ButtonRow {
return fn(c)
}
type Paneler interface {
GetPanelRows(*PanelCompo, Context) []ButtonRow
}
type PanelFunc func(*PanelCompo, Context) []ButtonRow
func (fn PanelFunc) GetPanelRows(
panel *PanelCompo, c Context,
) []ButtonRow {
return fn(panel, c)
}
// The type represents the inline panel with
// scrollable via buttons content.
// Can be used for example to show users via SQL and offset
// or something like that.
type PanelCompo struct {
InlineCompo
Rowser Rowser
Paneler Paneler
}
// Transform to the panel with dynamic rows.
func (compo *MessageCompo) Panel(
c Context, // The context to generate the first page of buttons.
rowser Rowser, // The rows generator.
paneler Paneler, // The rows generator.
) *PanelCompo {
ret := &PanelCompo{}
ret.Paneler = paneler
ret.InlineCompo = (*compo.Inline(
NewKeyboard(
rowser.MakeRows(c)...,
ret.Paneler.GetPanelRows(ret, c)...,
).Inline(),
))
ret.Rowser = rowser
return ret
}
func (compo *PanelCompo) Update(c Context) {
compo.Rows = compo.Rowser.MakeRows(c)
compo.InlineCompo.Update(c)
// Implementing the Updater.
func (panel *PanelCompo) Update(c Context) error {
panel.Rows = panel.Paneler.GetPanelRows(panel, c)
return panel.InlineCompo.Update(c)
}

9
updater.go Normal file
View file

@ -0,0 +1,9 @@
package tg
// Implementing the type provides
// way to update stuff on the client side.
// Things like panels, messages etc.
type Updater interface {
Update(Context) error
}