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

render.gno

3.66 Kb · 124 lines
  1package skins
  2
  3import "strings"
  4
  5// Render returns the shop as markdown, for gnoweb:
  6//
  7//	""               the catalog
  8//	"skin/<id>"      one design
  9//	"player/<addr>"  the skins of one address
 10//
 11// Everything printed went through validate.gno when it was written, or is
 12// an address the chain gave the realm; the caller-supplied id and address are
 13// printed only once found valid.
 14func Render(path string) string {
 15	switch {
 16	case path == "":
 17		return renderHome()
 18	case strings.HasPrefix(path, "skin/"):
 19		if d := getDesign(strings.TrimPrefix(path, "skin/")); d != nil {
 20			return renderDesign(d)
 21		}
 22	case strings.HasPrefix(path, "player/"):
 23		if addr := address(strings.TrimPrefix(path, "player/")); validAddress(addr) {
 24			return renderPlayer(addr)
 25		}
 26	}
 27	return "# gnofly skins\n\nPage not found. Go back to the [shop](" + link("") + ").\n"
 28}
 29
 30func link(path string) string {
 31	if path == "" {
 32		return webPath
 33	}
 34	return webPath + ":" + path
 35}
 36
 37func renderHome() string {
 38	var b strings.Builder
 39	b.WriteString("# gnofly skins\n\n")
 40	b.WriteString("Paint jobs for the planes of gnofly. Each one bought is a token bound to its buyer: it cannot be\n")
 41	b.WriteString("transferred. Buy one with `Buy` and its price attached, then fly it from the hangar of the game.\n")
 42	b.WriteString("Classic is free for everyone and is not sold here.\n\n")
 43	b.WriteString("| Skin | Model | Price | Sold | Supply | For sale |\n|---|---|---|---|---|---|\n")
 44	designs.Iterate("", "", func(_ string, v any) bool {
 45		d := v.(*design)
 46		b.WriteString("| " + designLink(d) + " | " + d.model + " | " + gnot(d.price) + " | " + itoa(d.minted) +
 47			" | " + supplyText(d.maxSupply) + " | " + yesNo(d.listed) + " |\n")
 48		return false
 49	})
 50	b.WriteString("\nTreasury: " + roles.Treasury().String() + "\n")
 51	return b.String()
 52}
 53
 54func renderDesign(d *design) string {
 55	var b strings.Builder
 56	b.WriteString("# " + d.name + "\n\n")
 57	b.WriteString("| | |\n|---|---|\n")
 58	b.WriteString("| Id | " + d.id + " |\n")
 59	b.WriteString("| Model | " + d.model + " |\n")
 60	b.WriteString("| Pilot | " + d.pilot + " |\n")
 61	b.WriteString("| Body | `" + d.body + "` |\n")
 62	b.WriteString("| Wing | `" + d.wing + "` |\n")
 63	b.WriteString("| Accent | `" + d.accent + "` |\n")
 64	b.WriteString("| Price | " + gnot(d.price) + " |\n")
 65	b.WriteString("| Sold | " + itoa(d.minted) + " of " + supplyText(d.maxSupply) + " |\n")
 66	b.WriteString("| For sale | " + yesNo(d.listed) + " |\n")
 67	b.WriteString("| Metadata | `" + uriBase + d.id + ".json` |\n")
 68	b.WriteString("\n[Shop](" + link("") + ")\n")
 69	return b.String()
 70}
 71
 72func renderPlayer(addr address) string {
 73	var b strings.Builder
 74	b.WriteString("# Pilot " + addr.String() + "\n\n")
 75	n := 0
 76	prefix := addr.String() + "/"
 77	owned.Iterate(prefix, addr.String()+"0", func(key string, v any) bool {
 78		if n == 0 {
 79			b.WriteString("| Skin | Token |\n|---|---|\n")
 80		}
 81		d := getDesign(strings.TrimPrefix(key, prefix))
 82		if d != nil {
 83			b.WriteString("| " + designLink(d) + " | " + itoa(v.(int64)) + " |\n")
 84		}
 85		n++
 86		return false
 87	})
 88	if n == 0 {
 89		b.WriteString("No skin yet: this pilot flies Classic.\n")
 90	}
 91	b.WriteString("\n[Shop](" + link("") + ")\n")
 92	return b.String()
 93}
 94
 95func designLink(d *design) string {
 96	return "[" + d.name + "](" + link("skin/"+d.id) + ")"
 97}
 98
 99func supplyText(n int64) string {
100	if n == 0 {
101		return "unlimited"
102	}
103	return itoa(n)
104}
105
106// gnot writes ugnot as GNOT: 1000000 -> "1 GNOT", 1500000 -> "1.5 GNOT".
107func gnot(ugnot int64) string {
108	whole, frac := ugnot/1000000, ugnot%1000000
109	if frac == 0 {
110		return itoa(whole) + " GNOT"
111	}
112	f := itoa(frac + 1000000)[1:]
113	for f[len(f)-1] == '0' {
114		f = f[:len(f)-1]
115	}
116	return itoa(whole) + "." + f + " GNOT"
117}
118
119func yesNo(b bool) string {
120	if b {
121		return "yes"
122	}
123	return "no"
124}