package glist import ( "encoding/json" "fmt" "sync" ) type Entry struct { Text string `json:"text"` Checked bool `json:"checked"` } type GList struct { AllMsgCounter int `json:"-"` Mutex sync.Mutex `json:"-"` ChatID int `json:"chat_id"` MessageID *int `json:"message_id"` Items []Entry `json:"items"` } func NewGList(chatID int, items ...string) *GList { g := GList{ChatID: chatID} for _, text := range items { g.Items = append(g.Items, Entry{text, false}) } return &g } func (g *GList) Add(text string) error { for _, item := range g.Items { if item.Text == text { return fmt.Errorf("dupe:%s", text) } } g.Items = append(g.Items, Entry{text, false}) return nil } func (g *GList) Toggle(text string) error { for i, item := range g.Items { if item.Text == text { g.Items[i].Checked = !g.Items[i].Checked return nil } } return fmt.Errorf("not found:%s", text) } func (g *GList) ClearChecked() { var remaining []Entry for _, item := range g.Items { if !item.Checked { remaining = append(remaining, item) } } g.Items = remaining } type button struct { Text string `json:"text"` CallbackData string `json:"callback_data"` } type newListReq struct { ChatID int `json:"chat_id"` MessageID *int `json:"message_id,omitempty"` Text string `json:"text"` ReplyMarkup struct { InlineKeyboard [][]button `json:"inline_keyboard"` } `json:"reply_markup"` } func makeButton(e Entry) button { b := button{Text: e.Text, CallbackData: e.Text} if e.Checked { b.Text = fmt.Sprintf("✓ %s", e.Text) } return b } func makeButtons(items []Entry) [][]button { var buttons [][]button var current []button for _, item := range items { current = append(current, makeButton(item)) if len(current) == 2 { buttons = append(buttons, current) current = []button{} } } if len(current) != 0 { buttons = append(buttons, current) } return buttons } func (g *GList) GenSendListReq() ([]byte, error) { req := newListReq{ChatID: g.ChatID, MessageID: g.MessageID, Text: "List:"} itemButtons := makeButtons(g.Items) controlButtons := []button{{"clear checked", "clear"}} req.ReplyMarkup.InlineKeyboard = append(itemButtons, controlButtons) data, err := json.Marshal(req) return data, err }