views.gno
4.25 Kb · 176 lines
1package shop
2
3import "strconv"
4
5// InfoJSON is the collection header. ready is false until Init.
6func InfoJSON() string {
7 if !ready {
8 return `{"ready":false}`
9 }
10 return `{"ready":true,"name":` + quote(token.GetName()) +
11 `,"symbol":` + quote(token.GetSymbol()) +
12 `,"creator":` + quote(creator.String()) +
13 `,"admins":` + adminsJSON() +
14 `,"supply":` + i64(token.TotalSupply()) +
15 `,"listings":` + strconv.Itoa(listings.Size()) + `}`
16}
17
18func adminsJSON() string {
19 parts := make([]string, 0)
20 admins.IterateByOffset(0, pageMax, func(key string, value any) bool {
21 parts = append(parts, quote(key))
22 return false
23 })
24 return "[" + join(parts) + "]"
25}
26
27// ListingsJSON returns one page of listings, oldest key first.
28func ListingsJSON(offset, limit int) string {
29 if !ready {
30 return "[]"
31 }
32 offset, limit = page(offset, limit)
33 parts := make([]string, 0)
34 listings.IterateByOffset(offset, limit, func(key string, value any) bool {
35 parts = append(parts, lotJSON(key, value.(listing)))
36 return false
37 })
38 return "[" + join(parts) + "]"
39}
40
41// ListingJSON returns one listing or "null".
42func ListingJSON(tid string) string {
43 if !ready {
44 return "null"
45 }
46 id := parseTid(tid)
47 got := listings.Get(string(id))
48 if got == nil {
49 return "null"
50 }
51 return lotJSON(string(id), got.(listing))
52}
53
54// TokenJSON returns one token, listed or not.
55func TokenJSON(tid string) string {
56 if !ready {
57 return "null"
58 }
59 id := parseTid(tid)
60 owner := ownerOf(id)
61 name, image := metaNameImage(id)
62 body := `{"tid":` + quote(string(id)) +
63 `,"owner":` + quote(owner.String()) +
64 `,"name":` + quote(name) +
65 `,"image":` + quote(image)
66 got := listings.Get(string(id))
67 if got == nil {
68 return body + `,"listed":false}`
69 }
70 lot := got.(listing)
71 return body + `,"listed":true,"seller":` + quote(lot.Seller.String()) +
72 `,"price":` + i64(lot.Price) +
73 `,"live":` + boolJSON(owner == lot.Seller) + `}`
74}
75
76// TokensJSON lists tokens owned by owner.
77func TokensJSON(owner address, offset, limit int) string {
78 if !ready {
79 return "[]"
80 }
81 if !owner.IsValid() {
82 panic("market: owner")
83 }
84 offset, limit = page(offset, limit)
85 balance, err := token.BalanceOf(owner)
86 if err != nil {
87 panic("market: balance")
88 }
89 parts := make([]string, 0)
90 end := int64(offset + limit)
91 for i := int64(offset); i < balance && i < end; i++ {
92 id, err := enumView.TokenOfOwnerByIndex(owner, i)
93 if err != nil {
94 panic("market: index")
95 }
96 name, image := metaNameImage(id)
97 item := `{"tid":` + quote(string(id)) + `,"name":` + quote(name) + `,"image":` + quote(image)
98 got := listings.Get(string(id))
99 if got == nil {
100 item += `,"listed":false}`
101 } else {
102 lot := got.(listing)
103 item += `,"listed":true,"price":` + i64(lot.Price) + `}`
104 }
105 parts = append(parts, item)
106 }
107 return "[" + join(parts) + "]"
108}
109
110// SalesJSON returns the newest sales first.
111func SalesJSON(offset, limit int) string {
112 if !ready {
113 return "[]"
114 }
115 offset, limit = page(offset, limit)
116 n := saleN
117 if n > saleCap {
118 n = saleCap
119 }
120 parts := make([]string, 0)
121 for i := offset; i < offset+limit && i < n; i++ {
122 // i = 0 is the newest stored sale.
123 idx := saleN - 1 - i
124 s := sales[idx%saleCap]
125 parts = append(parts, `{"tid":`+quote(s.Tid)+
126 `,"name":`+quote(s.Name)+
127 `,"seller":`+quote(s.Seller.String())+
128 `,"buyer":`+quote(s.Buyer.String())+
129 `,"price":`+i64(s.Price)+`}`)
130 }
131 return "[" + join(parts) + "]"
132}
133
134func lotJSON(tid string, lot listing) string {
135 id := parseTid(tid)
136 owner := ownerOf(id)
137 name, image := metaNameImage(id)
138 return `{"tid":` + quote(tid) +
139 `,"seller":` + quote(lot.Seller.String()) +
140 `,"owner":` + quote(owner.String()) +
141 `,"price":` + i64(lot.Price) +
142 `,"name":` + quote(name) +
143 `,"image":` + quote(image) +
144 `,"live":` + boolJSON(owner == lot.Seller) + `}`
145}
146
147func boolJSON(v bool) string {
148 if v {
149 return "true"
150 }
151 return "false"
152}
153
154func join(parts []string) string {
155 out := ""
156 for i, p := range parts {
157 if i > 0 {
158 out += ","
159 }
160 out += p
161 }
162 return out
163}
164
165func Render(path string) string {
166 if path != "" {
167 return "404\n"
168 }
169 if !ready {
170 return "# market\n\ncall Init first\n"
171 }
172 return "# " + token.GetName() + " ($" + token.GetSymbol() + ")\n\n" +
173 "* creator: " + creator.String() + "\n" +
174 "* supply: " + i64(token.TotalSupply()) + "\n" +
175 "* listings: " + strconv.Itoa(listings.Size()) + "\n"
176}