mirror of https://github.com/velour/catbase.git
counter: use templ and htmx
This commit is contained in:
parent
f83cc32788
commit
b4f9f902ce
|
@ -1,10 +1,8 @@
|
||||||
package counter
|
package counter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/velour/catbase/bot/user"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -18,9 +16,6 @@ import (
|
||||||
"github.com/velour/catbase/bot/msg"
|
"github.com/velour/catbase/bot/msg"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed *.html
|
|
||||||
var embeddedFS embed.FS
|
|
||||||
|
|
||||||
func (p *CounterPlugin) registerWeb() {
|
func (p *CounterPlugin) registerWeb() {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
requests := p.cfg.GetInt("counter.requestsPer", 1)
|
requests := p.cfg.GetInt("counter.requestsPer", 1)
|
||||||
|
@ -33,11 +28,79 @@ func (p *CounterPlugin) registerWeb() {
|
||||||
subrouter.HandleFunc("/api/users/{user}/items/{item}/increment", p.mkIncrementByNAPI(1))
|
subrouter.HandleFunc("/api/users/{user}/items/{item}/increment", p.mkIncrementByNAPI(1))
|
||||||
subrouter.HandleFunc("/api/users/{user}/items/{item}/decrement", p.mkIncrementByNAPI(-1))
|
subrouter.HandleFunc("/api/users/{user}/items/{item}/decrement", p.mkIncrementByNAPI(-1))
|
||||||
r.Mount("/", subrouter)
|
r.Mount("/", subrouter)
|
||||||
r.HandleFunc("/api", p.handleCounterAPI)
|
r.HandleFunc("/users/{user}/items/{item}/increment", p.incHandler(1))
|
||||||
|
r.HandleFunc("/users/{user}/items/{item}/decrement", p.incHandler(-1))
|
||||||
r.HandleFunc("/", p.handleCounter)
|
r.HandleFunc("/", p.handleCounter)
|
||||||
p.b.GetWeb().RegisterWebName(r, "/counter", "Counter")
|
p.b.GetWeb().RegisterWebName(r, "/counter", "Counter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *CounterPlugin) incHandler(delta int) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
userName, _ := url.QueryUnescape(chi.URLParam(r, "user"))
|
||||||
|
itemName, _ := url.QueryUnescape(chi.URLParam(r, "item"))
|
||||||
|
pass := r.FormValue("password")
|
||||||
|
if !p.b.CheckPassword("", pass) {
|
||||||
|
w.WriteHeader(401)
|
||||||
|
fmt.Fprintf(w, "error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
item, err := p.delta(userName, itemName, "", delta)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
fmt.Fprintf(w, "error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.renderItem(userName, item).Render(r.Context(), w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *CounterPlugin) delta(userName, itemName, personalMessage string, delta int) (Item, error) {
|
||||||
|
// Try to find an ID if possible
|
||||||
|
id := ""
|
||||||
|
u, err := p.b.DefaultConnector().Profile(userName)
|
||||||
|
if err == nil {
|
||||||
|
id = u.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
item, err := GetUserItem(p.db, userName, id, itemName)
|
||||||
|
if err != nil {
|
||||||
|
return item, err
|
||||||
|
}
|
||||||
|
|
||||||
|
chs := p.cfg.GetMap("counter.channelItems", map[string]string{})
|
||||||
|
ch, ok := chs[itemName]
|
||||||
|
req := &bot.Request{
|
||||||
|
Conn: p.b.DefaultConnector(),
|
||||||
|
Kind: bot.Message,
|
||||||
|
Msg: msg.Message{
|
||||||
|
User: &u,
|
||||||
|
// Noting here that we're only going to do goals in a "default"
|
||||||
|
// channel even if it should send updates to others.
|
||||||
|
Channel: ch,
|
||||||
|
Body: fmt.Sprintf("%s += %d", itemName, delta),
|
||||||
|
Time: time.Now(),
|
||||||
|
},
|
||||||
|
Values: nil,
|
||||||
|
Args: nil,
|
||||||
|
}
|
||||||
|
msg := fmt.Sprintf("%s changed their %s counter by %d for a total of %d via the amazing %s API. %s",
|
||||||
|
userName, itemName, delta, item.Count+delta, p.cfg.Get("nick", "catbase"), personalMessage)
|
||||||
|
if !ok {
|
||||||
|
chs := p.cfg.GetArray("counter.channels", []string{})
|
||||||
|
for _, ch := range chs {
|
||||||
|
p.b.Send(p.b.DefaultConnector(), bot.Message, ch, msg)
|
||||||
|
req.Msg.Channel = ch
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.b.Send(p.b.DefaultConnector(), bot.Message, ch, msg)
|
||||||
|
req.Msg.Channel = ch
|
||||||
|
}
|
||||||
|
if err := item.UpdateDelta(req, delta); err != nil {
|
||||||
|
return item, err
|
||||||
|
}
|
||||||
|
return item, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWriter, r *http.Request) {
|
func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWriter, r *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
userName, _ := url.QueryUnescape(chi.URLParam(r, "user"))
|
userName, _ := url.QueryUnescape(chi.URLParam(r, "user"))
|
||||||
|
@ -64,15 +127,15 @@ func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWri
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find an ID if possible
|
body, _ := io.ReadAll(r.Body)
|
||||||
id := ""
|
postData := map[string]string{}
|
||||||
u, err := p.b.DefaultConnector().Profile(userName)
|
err = json.Unmarshal(body, &postData)
|
||||||
if err == nil {
|
personalMsg := ""
|
||||||
id = u.ID
|
if inputMsg, ok := postData["message"]; ok {
|
||||||
|
personalMsg = fmt.Sprintf("\nMessage: %s", inputMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
item, err := GetUserItem(p.db, userName, id, itemName)
|
if _, err := p.delta(userName, itemName, personalMsg, delta*direction); err != nil {
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("error finding item")
|
log.Error().Err(err).Msg("error finding item")
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(400)
|
||||||
j, _ := json.Marshal(struct {
|
j, _ := json.Marshal(struct {
|
||||||
|
@ -83,130 +146,13 @@ func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWri
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _ := io.ReadAll(r.Body)
|
|
||||||
postData := map[string]string{}
|
|
||||||
err = json.Unmarshal(body, &postData)
|
|
||||||
personalMsg := ""
|
|
||||||
if inputMsg, ok := postData["message"]; ok {
|
|
||||||
personalMsg = fmt.Sprintf("\nMessage: %s", inputMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
chs := p.cfg.GetMap("counter.channelItems", map[string]string{})
|
|
||||||
ch, ok := chs[itemName]
|
|
||||||
if len(chs) == 0 || !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req := &bot.Request{
|
|
||||||
Conn: p.b.DefaultConnector(),
|
|
||||||
Kind: bot.Message,
|
|
||||||
Msg: msg.Message{
|
|
||||||
User: &u,
|
|
||||||
// Noting here that we're only going to do goals in a "default"
|
|
||||||
// channel even if it should send updates to others.
|
|
||||||
Channel: ch,
|
|
||||||
Body: fmt.Sprintf("%s += %d", itemName, delta),
|
|
||||||
Time: time.Now(),
|
|
||||||
},
|
|
||||||
Values: nil,
|
|
||||||
Args: nil,
|
|
||||||
}
|
|
||||||
msg := fmt.Sprintf("%s changed their %s counter by %d for a total of %d via the amazing %s API. %s",
|
|
||||||
userName, itemName, delta, item.Count+delta*direction, p.cfg.Get("nick", "catbase"), personalMsg)
|
|
||||||
if !ok {
|
|
||||||
chs := p.cfg.GetArray("counter.channels", []string{})
|
|
||||||
for _, ch := range chs {
|
|
||||||
p.b.Send(p.b.DefaultConnector(), bot.Message, ch, msg)
|
|
||||||
req.Msg.Channel = ch
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p.b.Send(p.b.DefaultConnector(), bot.Message, ch, msg)
|
|
||||||
req.Msg.Channel = ch
|
|
||||||
}
|
|
||||||
item.UpdateDelta(req, delta*direction)
|
|
||||||
j, _ := json.Marshal(struct{ Status bool }{true})
|
j, _ := json.Marshal(struct{ Status bool }{true})
|
||||||
fmt.Fprint(w, string(j))
|
fmt.Fprint(w, string(j))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CounterPlugin) handleCounter(w http.ResponseWriter, r *http.Request) {
|
func (p *CounterPlugin) handleCounter(w http.ResponseWriter, r *http.Request) {
|
||||||
index, _ := embeddedFS.ReadFile("index.html")
|
p.b.GetWeb().Index("Counter", p.index()).Render(r.Context(), w)
|
||||||
w.Write(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *CounterPlugin) handleCounterAPI(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method == http.MethodPost {
|
|
||||||
info := struct {
|
|
||||||
User string
|
|
||||||
Thing string
|
|
||||||
Action string
|
|
||||||
Password string
|
|
||||||
}{}
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
|
||||||
err := decoder.Decode(&info)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(500)
|
|
||||||
fmt.Fprint(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Debug().
|
|
||||||
Interface("postbody", info).
|
|
||||||
Msg("Got a POST")
|
|
||||||
if !p.b.CheckPassword("", info.Password) {
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
j, _ := json.Marshal(struct{ Err string }{Err: "Invalid Password"})
|
|
||||||
w.Write(j)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req := bot.Request{
|
|
||||||
Conn: p.b.DefaultConnector(),
|
|
||||||
Kind: bot.Message,
|
|
||||||
Msg: msg.Message{
|
|
||||||
User: &user.User{
|
|
||||||
ID: "",
|
|
||||||
Name: info.User,
|
|
||||||
Admin: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
// resolveUser requires a "full" request object so we are faking it
|
|
||||||
nick, id := p.resolveUser(req, info.User)
|
|
||||||
item, err := GetUserItem(p.db, nick, id, info.Thing)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().
|
|
||||||
Err(err).
|
|
||||||
Str("subject", info.User).
|
|
||||||
Str("itemName", info.Thing).
|
|
||||||
Msg("error finding item")
|
|
||||||
w.WriteHeader(404)
|
|
||||||
fmt.Fprint(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if info.Action == "++" {
|
|
||||||
item.UpdateDelta(nil, 1)
|
|
||||||
} else if info.Action == "--" {
|
|
||||||
item.UpdateDelta(nil, -1)
|
|
||||||
} else {
|
|
||||||
w.WriteHeader(400)
|
|
||||||
fmt.Fprint(w, "Invalid increment")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
all, err := GetAllItems(p.db)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(500)
|
|
||||||
fmt.Fprint(w, err)
|
|
||||||
log.Error().Err(err).Msg("Error getting items")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(all)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(500)
|
|
||||||
fmt.Fprint(w, err)
|
|
||||||
log.Error().Err(err).Msg("Error marshaling items")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Fprint(w, string(data))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update represents a change that gets sent off to other plugins such as goals
|
// Update represents a change that gets sent off to other plugins such as goals
|
||||||
|
|
|
@ -45,7 +45,7 @@ type alias struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetItems returns all counters
|
// GetItems returns all counters
|
||||||
func GetAllItems(db *sqlx.DB) ([]Item, error) {
|
func GetAllItemsByUser(db *sqlx.DB) (map[string][]Item, error) {
|
||||||
var items []Item
|
var items []Item
|
||||||
err := db.Select(&items, `select * from counter`)
|
err := db.Select(&items, `select * from counter`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -55,7 +55,11 @@ func GetAllItems(db *sqlx.DB) ([]Item, error) {
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].DB = db
|
items[i].DB = db
|
||||||
}
|
}
|
||||||
return items, nil
|
out := map[string][]Item{}
|
||||||
|
for _, it := range items {
|
||||||
|
out[it.Nick] = append(out[it.Nick], it)
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetItems returns all counters for a subject
|
// GetItems returns all counters for a subject
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package counter
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func urlFor(who, what, dir string) string {
|
||||||
|
return fmt.Sprintf("/counter/users/%s/items/%s/%s", who, what, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *CounterPlugin) allItems() map[string][]Item {
|
||||||
|
items, err := GetAllItemsByUser(p.db)
|
||||||
|
if err != nil {
|
||||||
|
return map[string][]Item{"error": []Item{}}
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
templ (p *CounterPlugin) index() {
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<label>Password: <input type="text" name="password" /></label>
|
||||||
|
</div>
|
||||||
|
for user, items := range p.allItems() {
|
||||||
|
<div class="row">
|
||||||
|
{ user }:
|
||||||
|
<div class="container">
|
||||||
|
for _, thing := range items {
|
||||||
|
@p.renderItem(user, thing)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ (p *CounterPlugin) renderItem(user string, item Item) {
|
||||||
|
<div class="row" id={ fmt.Sprintf("item%d", item.ID) }>
|
||||||
|
<div class="col offset-1">
|
||||||
|
{ item.Item }
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
{ fmt.Sprintf("%d", item.Count) }
|
||||||
|
</div>
|
||||||
|
<div class="col-2">
|
||||||
|
<button
|
||||||
|
hx-target={ "#"+fmt.Sprintf("item%d", item.ID) }
|
||||||
|
hx-include="[name='password']"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-post={ urlFor(user, item.Item, "decrement") }
|
||||||
|
>-</button>
|
||||||
|
<button
|
||||||
|
hx-target={ "#"+fmt.Sprintf("item%d", item.ID) }
|
||||||
|
hx-include="[name='password']"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-post={ urlFor(user, item.Item, "increment") }
|
||||||
|
>+</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.543
|
||||||
|
package counter
|
||||||
|
|
||||||
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
|
||||||
|
import "github.com/a-h/templ"
|
||||||
|
import "context"
|
||||||
|
import "io"
|
||||||
|
import "bytes"
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func urlFor(who, what, dir string) string {
|
||||||
|
return fmt.Sprintf("/counter/users/%s/items/%s/%s", who, what, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *CounterPlugin) allItems() map[string][]Item {
|
||||||
|
items, err := GetAllItemsByUser(p.db)
|
||||||
|
if err != nil {
|
||||||
|
return map[string][]Item{"error": []Item{}}
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *CounterPlugin) index() templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"container\"><div class=\"row\"><label>Password: <input type=\"text\" name=\"password\"></label></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
for user, items := range p.allItems() {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"row\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var2 string
|
||||||
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(user)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `plugins/counter/counter.templ`, Line: 23, Col: 22}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(":<div class=\"container\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
for _, thing := range items {
|
||||||
|
templ_7745c5c3_Err = p.renderItem(user, thing).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *CounterPlugin) renderItem(user string, item Item) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var3 == nil {
|
||||||
|
templ_7745c5c3_Var3 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"row\" id=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(fmt.Sprintf("item%d", item.ID)))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><div class=\"col offset-1\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(item.Item)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `plugins/counter/counter.templ`, Line: 37, Col: 23}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"col\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var5 string
|
||||||
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", item.Count))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `plugins/counter/counter.templ`, Line: 40, Col: 43}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"col-2\"><button hx-target=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString("#" + fmt.Sprintf("item%d", item.ID)))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" hx-include=\"[name='password']\" hx-swap=\"outerHTML\" hx-post=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(urlFor(user, item.Item, "decrement")))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">-</button> <button hx-target=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString("#" + fmt.Sprintf("item%d", item.ID)))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" hx-include=\"[name='password']\" hx-swap=\"outerHTML\" hx-post=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(urlFor(user, item.Item, "increment")))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">+</button></div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue