Search Apps Documentation Source Content File Folder Download Copy Actions Download

render.gno

3.59 Kb · 143 lines
  1package memba_collections
  2
  3import (
  4	"strings"
  5
  6	"gno.land/p/nt/ufmt/v0"
  7)
  8
  9const renderPageSize = 50
 10
 11// CollectionView is a structured read of a collection's public fields.
 12type CollectionView struct {
 13	ID           string
 14	Creator      address
 15	Admin        address
 16	Name         string
 17	Symbol       string
 18	RoyaltyBPS   int64
 19	RoyaltyRecip address
 20	Phase        int
 21	MintPrice    int64
 22	PayDenom     string
 23	MaxSupply    int64
 24	MaxPerWallet int64
 25	Minted       int64
 26	Paused       bool
 27}
 28
 29// CollectionInfo returns a structured view of a collection.
 30func CollectionInfo(id string) CollectionView {
 31	c := mustGet(id)
 32	return CollectionView{
 33		ID:           id,
 34		Creator:      c.creator,
 35		Admin:        c.admin,
 36		Name:         c.nft.Name(),
 37		Symbol:       c.nft.Symbol(),
 38		RoyaltyBPS:   c.royaltyBPS,
 39		RoyaltyRecip: c.royaltyRecip,
 40		Phase:        c.phase,
 41		MintPrice:    c.mintPrice,
 42		PayDenom:     denomKey(c.payDenom),
 43		MaxSupply:    c.maxSupply,
 44		MaxPerWallet: c.maxPerWallet,
 45		Minted:       c.nextAutoTokenID,
 46		Paused:       c.paused,
 47	}
 48}
 49
 50// MintedBy returns how many tokens an address has minted in a collection.
 51func MintedBy(id string, who address) int64 {
 52	return walletCount(mustGet(id), who)
 53}
 54
 55// Render mux:
 56//   ""                 → paginated collection list (?page=N)
 57//   "collection/<id>"  → collection detail
 58func Render(path string) string {
 59	if path == "" || strings.HasPrefix(path, "?") {
 60		return renderList(parsePage(path))
 61	}
 62	if strings.HasPrefix(path, "collection/") {
 63		return renderCollection(strings.TrimPrefix(path, "collection/"))
 64	}
 65	return "# Not found\n\nUnknown path: " + path
 66}
 67
 68func parsePage(path string) int {
 69	idx := strings.Index(path, "page=")
 70	if idx < 0 {
 71		return 1
 72	}
 73	rest := path[idx+5:]
 74	if amp := strings.IndexByte(rest, '&'); amp >= 0 {
 75		rest = rest[:amp]
 76	}
 77	n := 0
 78	for i := 0; i < len(rest); i++ {
 79		c := rest[i]
 80		if c < '0' || c > '9' {
 81			break
 82		}
 83		n = n*10 + int(c-'0')
 84	}
 85	if n < 1 {
 86		return 1
 87	}
 88	return n
 89}
 90
 91func renderList(page int) string {
 92	var b strings.Builder
 93	b.WriteString("# Memba Collections\n\n")
 94	if paused {
 95		b.WriteString("> ⚠️ Registry is globally paused.\n\n")
 96	}
 97	total := collections.Size()
 98	if total == 0 {
 99		b.WriteString("_No collections yet._\n")
100		return b.String()
101	}
102	start := (page - 1) * renderPageSize
103	end := start + renderPageSize
104	i := 0
105	shown := 0
106	collections.Iterate("", "", func(key string, v any) bool {
107		if i >= start && i < end {
108			c := v.(*collection)
109			b.WriteString(ufmt.Sprintf("- **%s** (%s) — phase %d, minted %d\n",
110				c.nft.Name(), key, c.phase, c.nextAutoTokenID))
111			shown++
112		}
113		i++
114		return i >= end
115	})
116	b.WriteString(ufmt.Sprintf("\n_Page %d — %d of %d collections._\n", page, shown, total))
117	return b.String()
118}
119
120func renderCollection(id string) string {
121	v, ok := collections.Get(id)
122	if !ok {
123		return "# Not found\n\nNo collection: " + id
124	}
125	c := v.(*collection)
126	var b strings.Builder
127	b.WriteString(ufmt.Sprintf("# %s (%s)\n\n", c.nft.Name(), c.nft.Symbol()))
128	b.WriteString(ufmt.Sprintf("- ID: `%s`\n", id))
129	b.WriteString(ufmt.Sprintf("- Creator: %s\n", c.creator.String()))
130	b.WriteString(ufmt.Sprintf("- Admin: %s\n", c.admin.String()))
131	b.WriteString(ufmt.Sprintf("- Royalty: %d bps → %s\n", c.royaltyBPS, c.royaltyRecip.String()))
132	b.WriteString(ufmt.Sprintf("- Phase: %d\n", c.phase))
133	b.WriteString(ufmt.Sprintf("- Mint price: %d %s\n", c.mintPrice, denomKey(c.payDenom)))
134	b.WriteString(ufmt.Sprintf("- Supply: %d", c.nextAutoTokenID))
135	if c.maxSupply > 0 {
136		b.WriteString(ufmt.Sprintf(" / %d", c.maxSupply))
137	}
138	b.WriteString("\n")
139	if c.paused {
140		b.WriteString("- ⚠️ Paused\n")
141	}
142	return b.String()
143}