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.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}