Search Apps Documentation Source Content File Folder Download Copy Actions Download

render.gno

4.56 Kb · 173 lines
  1package treasury
  2
  3import (
  4	"chain/runtime"
  5	"net/url"
  6	"strconv"
  7	"strings"
  8
  9	"gno.land/p/moul/md"
 10	"gno.land/p/moul/mdtable"
 11	"gno.land/p/nt/avl/v0/pager"
 12	"gno.land/p/nt/mux/v0"
 13	"gno.land/p/nt/ufmt/v0"
 14)
 15
 16const (
 17	DefaultHistoryPreviewSize = 5  // Number of payments in the history preview.
 18	DefaultHistoryPageSize    = 20 // Number of payments per page in the history.
 19)
 20
 21// Render renders content based on the given path.
 22func (t *Treasury) Render(path string) string {
 23	return t.router.Render(path)
 24}
 25
 26// RenderLanding renders the landing page of the treasury.
 27func (t *Treasury) RenderLanding(path string) string {
 28	var out string
 29
 30	// Render each banker.
 31	for _, bankerID := range t.ListBankerIDs() {
 32		out += t.RenderBanker(bankerID, path)
 33	}
 34
 35	return out
 36}
 37
 38// RenderBanker renders the details of a specific banker.
 39func (t *Treasury) RenderBanker(bankerID string, path string) string {
 40	// Get the banker associated to this ID.
 41	br, ok := t.bankers.Get(bankerID)
 42	if !ok {
 43		return md.Paragraph("Banker not found: " + bankerID)
 44	}
 45	banker := br.(*bankerRecord).banker
 46
 47	// Render banker title.
 48	out := md.H2(bankerID + " Banker")
 49
 50	// Render address section.
 51	out += md.H3("Address")
 52	out += md.Paragraph(banker.Address())
 53
 54	// Render balances section.
 55	out += md.H3("Balances")
 56	balances := banker.Balances()
 57	if len(balances) == 0 {
 58		out += md.Paragraph("No balances found.")
 59	} else {
 60		table := mdtable.Table{Headers: []string{"Denom", "Amount"}}
 61		for _, balance := range balances {
 62			table.Append([]string{balance.Denom, strconv.FormatInt(balance.Amount, 10)})
 63		}
 64		out += table.String()
 65	}
 66
 67	historySize := DefaultHistoryPreviewSize
 68
 69	// Check if the query parameter "history_size" is present and parse it.
 70	if req, err := url.Parse(path); err == nil && req.Query() != nil {
 71		size, err := strconv.Atoi(req.Query().Get("history_size"))
 72		if err == nil && size >= 0 {
 73			historySize = size
 74		}
 75	}
 76
 77	// Skip history rendering if historySize is 0.
 78	if historySize == 0 {
 79		return out
 80	}
 81
 82	// Render history section.
 83	out += md.H3("History")
 84	history, _ := t.History(bankerID, 1, historySize)
 85	if len(history) == 0 {
 86		out += md.Paragraph("No payments sent yet.")
 87	} else {
 88		if len(history) == 1 {
 89			out += md.Paragraph("Last payment:")
 90		} else {
 91			count := strconv.FormatInt(int64(len(history)), 10)
 92			out += md.Paragraph("Last " + count + " payments:")
 93		}
 94
 95		// Render each payment in the history.
 96		for _, payment := range history {
 97			out += md.BulletItem(payment.String())
 98		}
 99		out += "\n"
100
101		// Get the current Realm's package path for linking.
102		curRealm := runtime.CurrentRealm().PkgPath()
103		if from := strings.IndexRune(curRealm, '/'); from >= 0 {
104			out += md.Link(
105				"See full history",
106				ufmt.Sprintf("%s:%s/history", curRealm[from:], bankerID),
107			)
108		}
109	}
110
111	return out
112}
113
114// RenderBankerHistory renders the payment history of a specific banker.
115func (t *Treasury) RenderBankerHistory(bankerID string, path string) string {
116	// Get the banker record corresponding to this ID if it exists.
117	br, ok := t.bankers.Get(bankerID)
118	if !ok {
119		return md.Paragraph("Banker not found: " + bankerID)
120	}
121	history := br.(*bankerRecord).history
122
123	// Render banker history title.
124	out := md.H2(bankerID + " Banker History")
125
126	// Get the current page of tokens based on the request path.
127	p := pager.NewPager(history.Tree(), DefaultHistoryPageSize, true)
128	page, err := p.GetPageByPath(path)
129	if err != nil {
130		return md.Paragraph("Error retrieving page: " + err.Error())
131	}
132
133	// Render full history section.
134	if history.Len() == 0 {
135		out += md.Paragraph("No payments sent yet.")
136	} else {
137		if history.Len() == 1 {
138			out += md.Paragraph("1 payment:")
139		} else {
140			count := strconv.FormatInt(int64(history.Len()), 10)
141			out += md.Paragraph(count + " payments (sorted by latest, descending):")
142		}
143		for _, item := range page.Items {
144			out += md.BulletItem(item.Value.(Payment).String())
145		}
146	}
147	out += "\n"
148
149	// Add the page picker.
150	out += md.Paragraph(page.Picker(path))
151
152	return out
153}
154
155// initRenderRouter registers the routes for rendering the treasury pages.
156func (t *Treasury) initRenderRouter() {
157	t.router = mux.NewRouter()
158
159	// Landing page.
160	t.router.HandleFunc("", func(res *mux.ResponseWriter, req *mux.Request) {
161		res.Write(t.RenderLanding(req.RawPath))
162	})
163
164	// Banker details.
165	t.router.HandleFunc("{banker}", func(res *mux.ResponseWriter, req *mux.Request) {
166		res.Write(t.RenderBanker(req.GetVar("banker"), req.RawPath))
167	})
168
169	// Banker full history.
170	t.router.HandleFunc("{banker}/history", func(res *mux.ResponseWriter, req *mux.Request) {
171		res.Write(t.RenderBankerHistory(req.GetVar("banker"), req.RawPath))
172	})
173}