Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

render.gno

3.37 Kb · 103 lines
  1package gnotif
  2
  3import (
  4	"chain"
  5	"chain/runtime/unsafe"
  6	"strconv"
  7	"strings"
  8
  9	"gno.land/p/nt/markdown/sanitize/v0"
 10)
 11
 12const pageSize = 50
 13
 14// Render serves "" (the first page), "page/N", "trigger/<id>" and
 15// "target/<path>".
 16func Render(path string) string {
 17	switch {
 18	case path == "":
 19		return renderPage(1)
 20	case strings.HasPrefix(path, "page/"):
 21		n, err := strconv.Atoi(strings.TrimPrefix(path, "page/"))
 22		if err != nil || n < 1 {
 23			return "Not found."
 24		}
 25		return renderPage(n)
 26	case strings.HasPrefix(path, "trigger/"):
 27		id := strings.TrimPrefix(path, "trigger/")
 28		v := triggers.Get(id)
 29		if v == nil {
 30			return "Not found."
 31		}
 32		return renderTrigger(id, decodeRecord(v))
 33	case strings.HasPrefix(path, "target/"):
 34		target := strings.TrimPrefix(path, "target/")
 35		ids := activeOf(target)
 36		if len(ids) == 0 {
 37			return "Not found."
 38		}
 39		return renderTarget(target, ids)
 40	}
 41	return "Not found."
 42}
 43
 44// renderPage lists the triggers newest first, pageSize to a page.
 45func renderPage(n int) string {
 46	var b strings.Builder
 47	b.WriteString("# gnotif triggers\n\n")
 48	pages := (triggers.Size() + pageSize - 1) / pageSize
 49	if n > pages {
 50		b.WriteString("No triggers on this page.\n")
 51		return b.String()
 52	}
 53	triggers.ReverseIterateByOffset((n-1)*pageSize, pageSize, func(id string, v any) bool {
 54		writeLine(&b, id, decodeRecord(v))
 55		return false
 56	})
 57	if n < pages {
 58		b.WriteString("\n[Next page](" + selfPath + ":page/" + strconv.Itoa(n+1) + ")\n")
 59	}
 60	return b.String()
 61}
 62
 63// renderTarget lists a realm's triggers, newest first. The cap on them keeps
 64// the page to one screen, so it is not paged.
 65func renderTarget(target string, ids []string) string {
 66	var b strings.Builder
 67	b.WriteString("# gnotif triggers for " + sanitize.InlineText(target) + "\n\n")
 68	for i := len(ids) - 1; i >= 0; i-- {
 69		writeLine(&b, ids[i], decodeRecord(triggers.Get(ids[i])))
 70	}
 71	b.WriteString("\n[All triggers](" + selfPath + ")\n")
 72	return b.String()
 73}
 74
 75func writeLine(b *strings.Builder, id string, r record) {
 76	b.WriteString("- [**" + id + "**](" + selfPath + ":trigger/" + id + ") " +
 77		sanitize.InlineText(r.Target) + " · " + sanitize.InlineText(r.Name) + " · " + sanitize.InlineText(r.T.Event))
 78	if r.T.Param != "" {
 79		b.WriteString(" · param " + sanitize.InlineText(r.T.Param))
 80	}
 81	b.WriteString(" · ✓ verified · by " + chain.PackageAddress(r.Target).String() + "\n")
 82}
 83
 84func renderTrigger(id string, r record) string {
 85	var b strings.Builder
 86	b.WriteString("# Trigger " + id + "\n\n")
 87	b.WriteString("- Target: " + sanitize.InlineText(r.Target) + "\n")
 88	b.WriteString("- Name: " + sanitize.InlineText(r.Name) + "\n")
 89	b.WriteString("- Event: " + sanitize.InlineText(r.T.Event) + "\n")
 90	b.WriteString("- Filter: " + sanitize.InlineText(r.T.Filter) + "\n")
 91	b.WriteString("- Param: " + sanitize.InlineText(r.T.Param) + "\n")
 92	b.WriteString("- Title: " + sanitize.InlineText(r.T.Title) + "\n")
 93	b.WriteString("- Body: " + sanitize.InlineText(r.T.Body) + "\n")
 94	b.WriteString("- Link: " + sanitize.InlineText(r.T.Link) + "\n")
 95	b.WriteString("- Declarer: " + chain.PackageAddress(r.Target).String() + "\n")
 96	b.WriteString("- ✓ verified\n")
 97	b.WriteString("\n[All triggers](" + selfPath + ")\n")
 98	return b.String()
 99}
100
101// selfPath is this realm's path on gnoweb, read at package init: Render is not
102// crossing, so reading it there would give the caller's path.
103var selfPath = strings.TrimPrefix(unsafe.CurrentRealm().PkgPath(), "gno.land")