From a5e919733cf952300435bce74fb282e674b1033e Mon Sep 17 00:00:00 2001
From: Chris Sexton <3216719+chrissexton@users.noreply.github.com>
Date: Tue, 27 Feb 2024 17:16:45 -0500
Subject: [PATCH] meme: use templ and htmx
---
plugins/meme/meme.templ | 83 ++++++++++
plugins/meme/meme_templ.go | 236 +++++++++++++++++++++++++++++
plugins/meme/webHandlers.go | 98 ++++++------
plugins/pagecomment/pagecomment.go | 2 +-
plugins/roles/roles.go | 2 +-
plugins/secrets/secrets.go | 2 +-
6 files changed, 371 insertions(+), 52 deletions(-)
create mode 100644 plugins/meme/meme.templ
create mode 100644 plugins/meme/meme_templ.go
diff --git a/plugins/meme/meme.templ b/plugins/meme/meme.templ
new file mode 100644
index 0000000..3d6c4dc
--- /dev/null
+++ b/plugins/meme/meme.templ
@@ -0,0 +1,83 @@
+package meme
+
+templ (p *MemePlugin) index(all webResps) {
+
+
+
+
+ for _, meme := range all {
+ @p.Show(meme)
+ }
+
+}
+
+templ (p *MemePlugin) Show(meme webResp) {
+
+
+ { meme.Name }
+
+
+
+
+
+
+
+}
+
+templ (p *MemePlugin) Edit(meme webResp) {
+
+}
\ No newline at end of file
diff --git a/plugins/meme/meme_templ.go b/plugins/meme/meme_templ.go
new file mode 100644
index 0000000..1520a2b
--- /dev/null
+++ b/plugins/meme/meme_templ.go
@@ -0,0 +1,236 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.2.543
+package meme
+
+//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"
+
+func (p *MemePlugin) index(all webResps) 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("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for _, meme := range all {
+ templ_7745c5c3_Err = p.Show(meme).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
+ 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 *MemePlugin) Show(meme webResp) 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_Var2 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var2 == nil {
+ templ_7745c5c3_Var2 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var3 string
+ templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(meme.Name)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `plugins/meme/meme.templ`, Line: 39, Col: 27}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var4 string
+ templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(meme.Config)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `plugins/meme/meme.templ`, Line: 43, Col: 29}
+ }
+ _, 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("
")
+ 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 *MemePlugin) Edit(meme webResp) 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_Var5 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var5 == nil {
+ templ_7745c5c3_Var5 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ 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
+ })
+}
diff --git a/plugins/meme/webHandlers.go b/plugins/meme/webHandlers.go
index 3f9c548..58c8974 100644
--- a/plugins/meme/webHandlers.go
+++ b/plugins/meme/webHandlers.go
@@ -20,11 +20,12 @@ var embeddedFS embed.FS
func (p *MemePlugin) registerWeb(c bot.Connector) {
r := chi.NewRouter()
r.HandleFunc("/slash", p.slashMeme(c))
- r.HandleFunc("/img", p.img)
- r.HandleFunc("/all", p.all)
- r.HandleFunc("/add", p.addMeme)
- r.HandleFunc("/rm", p.rmMeme)
- r.HandleFunc("/", p.webRoot)
+ r.Get("/img", p.img)
+ r.Put("/save/{name}", p.saveMeme)
+ r.Post("/add", p.saveMeme)
+ r.Delete("/rm/{name}", p.rmMeme)
+ r.Get("/edit/{name}", p.editMeme)
+ r.Get("/", p.webRoot)
p.bot.GetWeb().RegisterWebName(r, "/meme", "Memes")
}
@@ -43,7 +44,7 @@ type ByName struct{ webResps }
func (s ByName) Less(i, j int) bool { return s.webResps[i].Name < s.webResps[j].Name }
-func (p *MemePlugin) all(w http.ResponseWriter, r *http.Request) {
+func (p *MemePlugin) all() webResps {
memes := p.c.GetMap("meme.memes", defaultFormats)
configs := p.c.GetMap("meme.memeconfigs", map[string]string{})
@@ -51,7 +52,7 @@ func (p *MemePlugin) all(w http.ResponseWriter, r *http.Request) {
for n, u := range memes {
config, ok := configs[n]
if !ok {
- b, _ := json.Marshal(p.defaultFormatConfig())
+ b, _ := json.MarshalIndent(p.defaultFormatConfig(), " ", " ")
config = string(b)
}
realURL, err := url.Parse(u)
@@ -64,13 +65,7 @@ func (p *MemePlugin) all(w http.ResponseWriter, r *http.Request) {
}
sort.Sort(ByName{values})
- out, err := json.Marshal(values)
- if err != nil {
- w.WriteHeader(500)
- log.Error().Err(err).Msgf("could not serve all memes route")
- return
- }
- w.Write(out)
+ return values
}
func mkCheckError(w http.ResponseWriter) func(error) bool {
@@ -87,56 +82,61 @@ func mkCheckError(w http.ResponseWriter) func(error) bool {
}
func (p *MemePlugin) rmMeme(w http.ResponseWriter, r *http.Request) {
- if r.Method != http.MethodDelete {
- w.WriteHeader(405)
- fmt.Fprintf(w, "Incorrect HTTP method")
- return
- }
- checkError := mkCheckError(w)
- decoder := json.NewDecoder(r.Body)
- values := webResp{}
- err := decoder.Decode(&values)
- if checkError(err) {
- return
- }
+ name := chi.URLParam(r, "name")
formats := p.c.GetMap("meme.memes", defaultFormats)
- delete(formats, values.Name)
- err = p.c.SetMap("meme.memes", formats)
- checkError(err)
+ delete(formats, name)
+ err := p.c.SetMap("meme.memes", formats)
+ mkCheckError(w)(err)
}
-func (p *MemePlugin) addMeme(w http.ResponseWriter, r *http.Request) {
- if r.Method != http.MethodPost {
- w.WriteHeader(405)
- fmt.Fprintf(w, "Incorrect HTTP method")
- return
+func (p *MemePlugin) saveMeme(w http.ResponseWriter, r *http.Request) {
+ name := chi.URLParam(r, "name")
+ if name == "" {
+ name = r.FormValue("name")
}
checkError := mkCheckError(w)
- decoder := json.NewDecoder(r.Body)
- values := webResp{}
- err := decoder.Decode(&values)
- if checkError(err) {
- log.Error().Err(err).Msgf("could not decode body")
- return
- }
- log.Debug().Msgf("POSTed values: %+v", values)
+
formats := p.c.GetMap("meme.memes", defaultFormats)
- formats[values.Name] = values.URL
- err = p.c.SetMap("meme.memes", formats)
+ formats[name] = r.FormValue("url")
+ err := p.c.SetMap("meme.memes", formats)
checkError(err)
- if values.Config == "" {
- values.Config = p.defaultFormatConfigJSON()
+ config := r.FormValue("config")
+ if config == "" {
+ config = p.defaultFormatConfigJSON()
}
configs := p.c.GetMap("meme.memeconfigs", map[string]string{})
- configs[values.Name] = values.Config
+ configs[name] = config
err = p.c.SetMap("meme.memeconfigs", configs)
checkError(err)
+
+ meme := webResp{
+ Name: name,
+ URL: formats[name],
+ Config: configs[name],
+ }
+
+ p.Show(meme).Render(r.Context(), w)
}
func (p *MemePlugin) webRoot(w http.ResponseWriter, r *http.Request) {
- index, _ := embeddedFS.ReadFile("index.html")
- w.Write(index)
+ p.bot.GetWeb().Index("Meme", p.index(p.all())).Render(r.Context(), w)
+}
+
+func (p *MemePlugin) editMeme(w http.ResponseWriter, r *http.Request) {
+ name := chi.URLParam(r, "name")
+ memes := p.c.GetMap("meme.memes", defaultFormats)
+ configs := p.c.GetMap("meme.memeconfigs", map[string]string{})
+ meme, ok := memes[name]
+ if !ok {
+ fmt.Fprintf(w, "Didn't find that meme.")
+ }
+ resp := webResp{
+ Name: name,
+ URL: meme,
+ Config: configs[name],
+ }
+ p.Edit(resp).Render(r.Context(), w)
}
func (p *MemePlugin) img(w http.ResponseWriter, r *http.Request) {
diff --git a/plugins/pagecomment/pagecomment.go b/plugins/pagecomment/pagecomment.go
index 32c8b81..92871b5 100644
--- a/plugins/pagecomment/pagecomment.go
+++ b/plugins/pagecomment/pagecomment.go
@@ -18,7 +18,7 @@ type PageComment struct {
c *config.Config
}
-func New(b bot.Bot) *PageComment {
+func New(b bot.Bot) bot.Plugin {
p := &PageComment{
b: b,
c: b.Config(),
diff --git a/plugins/roles/roles.go b/plugins/roles/roles.go
index b8efb4e..7501428 100644
--- a/plugins/roles/roles.go
+++ b/plugins/roles/roles.go
@@ -19,7 +19,7 @@ type RolesPlugin struct {
h bot.HandlerTable
}
-func New(b bot.Bot) *RolesPlugin {
+func New(b bot.Bot) bot.Plugin {
p := &RolesPlugin{
b: b,
c: b.Config(),
diff --git a/plugins/secrets/secrets.go b/plugins/secrets/secrets.go
index 041abe4..7e6d0e2 100644
--- a/plugins/secrets/secrets.go
+++ b/plugins/secrets/secrets.go
@@ -19,7 +19,7 @@ type SecretsPlugin struct {
db *sqlx.DB
}
-func New(b bot.Bot) *SecretsPlugin {
+func New(b bot.Bot) bot.Plugin {
p := &SecretsPlugin{
b: b,
c: b.Config(),