Search Apps Documentation Source Content File Folder Download Copy Actions Download

memberstore.gno

4.39 Kb ยท 182 lines
  1package memberstore
  2
  3import (
  4	"chain/runtime"
  5	"strings"
  6
  7	"gno.land/p/demo/svg"
  8	"gno.land/p/moul/md"
  9	"gno.land/p/nt/avl"
 10	"gno.land/p/nt/mux"
 11	"gno.land/p/nt/ufmt"
 12	"gno.land/r/gov/dao"
 13)
 14
 15var members MembersByTier
 16var Tiers TiersByName
 17var router *mux.Router
 18
 19const (
 20	T1 = "T1"
 21	T2 = "T2"
 22	T3 = "T3"
 23)
 24
 25func init() {
 26	members = NewMembersByTier()
 27
 28	Tiers = TiersByName{avl.NewTree()}
 29	Tiers.Set(T1, Tier{
 30		InvitationPoints: 3,
 31		MinSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
 32			return 70
 33		},
 34		MaxSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
 35			return 0
 36		},
 37		BasePower: 3,
 38		PowerHandler: func(membersByTier MembersByTier, tiersByName TiersByName) float64 {
 39			return 3
 40		},
 41	})
 42
 43	Tiers.Set(T2, Tier{
 44		InvitationPoints: 2,
 45		MaxSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
 46			return membersByTier.GetTierSize(T1) * 2
 47		},
 48		MinSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
 49			return membersByTier.GetTierSize(T1) / 4
 50		},
 51		BasePower: 2,
 52		PowerHandler: func(membersByTier MembersByTier, tiersByName TiersByName) float64 {
 53			t1ms := float64(membersByTier.GetTierSize(T1))
 54			t1, _ := tiersByName.GetTier(T1)
 55			t2ms := float64(membersByTier.GetTierSize(T2))
 56			t2, _ := tiersByName.GetTier(T2)
 57
 58			t1p := t1.BasePower * t1ms
 59			t2p := t2.BasePower * t2ms
 60
 61			// capped to 2/3 of tier 1
 62			t1ptreshold := t1p * (2.0 / 3.0)
 63			if t2p > t1ptreshold {
 64				return t1ptreshold / t2ms
 65			}
 66
 67			return t2.BasePower
 68		},
 69	})
 70
 71	Tiers.Set(T3, Tier{
 72		InvitationPoints: 1,
 73		MaxSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
 74			return 0
 75		},
 76		MinSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
 77			return 0
 78		},
 79		BasePower: 1,
 80		PowerHandler: func(membersByTier MembersByTier, tiersByName TiersByName) float64 {
 81			t1ms := float64(membersByTier.GetTierSize(T1))
 82			t1, _ := tiersByName.GetTier(T1)
 83			t3ms := float64(membersByTier.GetTierSize(T3))
 84			t3, _ := tiersByName.GetTier(T3)
 85
 86			t1p := t1.BasePower * t1ms
 87			t3p := t3.BasePower * t3ms
 88
 89			//capped to 1/3 of tier 1
 90			t1ptreshold := t1p * (1.0 / 3.0)
 91			if t3p > t1ptreshold {
 92				return t1ptreshold / t3ms
 93			}
 94
 95			return t3.BasePower
 96		},
 97	})
 98
 99	initRouter()
100}
101
102// initRouter initializes the router for the memberstore.
103func initRouter() {
104	router = mux.NewRouter()
105	router.HandleFunc("", renderHome)
106	router.HandleFunc("members", renderMembers)
107	router.NotFoundHandler = renderNotFound
108}
109
110// renderHome displays the tiers data (Number of members and powers) and tiers charts.
111func renderHome(res *mux.ResponseWriter, req *mux.Request) {
112	var sb strings.Builder
113	sb.WriteString(md.Link("> Go to Members list <", "/r/gov/dao/v3/memberstore:members") + "\n")
114
115	members.Iterate("", "", func(tn string, ti interface{}) bool {
116		tree, ok := ti.(*avl.Tree)
117		if !ok {
118			return false
119		}
120
121		tier, ok := Tiers.GetTier(tn)
122		if !ok {
123			return false
124		}
125
126		tp := (tier.PowerHandler(members, Tiers) * float64(members.GetTierSize(tn)))
127
128		sb.WriteString(ufmt.Sprintf("- %v Tier %v contains %v members with power: %v\n", tierColoredChip(tn), tn, tree.Size(), tp))
129
130		return false
131	})
132
133	sb.WriteString("\n" + RenderCharts(members))
134	res.Write(sb.String())
135}
136
137// renderMembers displays the members list.
138func renderMembers(res *mux.ResponseWriter, req *mux.Request) {
139	path := strings.Replace(req.RawPath, "members", "", 1) // We have to clean the path
140	res.Write(RenderMembers(path, members))
141}
142
143func renderNotFound(res *mux.ResponseWriter, req *mux.Request) {
144	res.Write("# 404\n\nThat page was not found. Would you like to [**go home**?](/r/gov/dao/v3/memberstore)")
145}
146
147func tierColor(tn string) string {
148	switch tn {
149	case T1:
150		return "#329175"
151	case T2:
152		return "#21577A"
153	case T3:
154		return "#F3D3BC"
155	default:
156		return "#FFF"
157	}
158}
159
160// tierColoredChip returns a colored chip svg for the given tier name.
161func tierColoredChip(tn string) string {
162	canvas := svg.NewCanvas(16, 16)
163	canvas.Append(svg.NewRectangle(0, 0, 16, 16, tierColor(tn)))
164	return canvas.Render(tn + " colored chip")
165}
166
167func Render(path string) string {
168	var sb strings.Builder
169	sb.WriteString(md.H1("Memberstore Govdao v3"))
170	sb.WriteString(router.Render(path))
171	return sb.String()
172}
173
174// Get gets the Members store
175func Get() MembersByTier {
176	currealm := runtime.CurrentRealm().PkgPath()
177	if !dao.InAllowedDAOs(currealm) {
178		panic("this Realm is not allowed to get the Members data: " + currealm)
179	}
180
181	return members
182}