Search Apps Documentation Source Content File Folder Download Copy Actions Download

render.gno

4.63 Kb · 173 lines
  1package treasury
  2
  3import (
  4	"net/url"
  5	"strconv"
  6	"strings"
  7
  8	"gno.land/p/moul/md"
  9	"gno.land/p/moul/mdtable"
 10	"gno.land/p/nt/bptree/v0/pager"
 11	"gno.land/p/nt/mux/v0"
 12	"gno.land/p/nt/ufmt/v0"
 13)
 14
 15const (
 16	DefaultHistoryPreviewSize = 5  // Number of payments in the history preview.
 17	DefaultHistoryPageSize    = 20 // Number of payments per page in the history.
 18)
 19
 20// Render renders content based on the given path.
 21func (t *Treasury) Render(path string) string {
 22	return t.router.Render(path)
 23}
 24
 25// RenderLanding renders the landing page of the treasury.
 26func (t *Treasury) RenderLanding(path string) string {
 27	var out string
 28
 29	// Render each banker.
 30	for _, bankerID := range t.ListBankerIDs() {
 31		out += t.RenderBanker(bankerID, path)
 32	}
 33
 34	return out
 35}
 36
 37// RenderBanker renders the details of a specific banker.
 38func (t *Treasury) RenderBanker(bankerID string, path string) string {
 39	// Get the banker associated to this ID.
 40	br, ok := t.bankers.Get(bankerID)
 41	if !ok {
 42		return md.Paragraph("Banker not found: " + bankerID)
 43	}
 44	banker := br.(*bankerRecord).banker
 45
 46	// Render banker title.
 47	out := md.H2(bankerID + " Banker")
 48
 49	// Render address section.
 50	out += md.H3("Address")
 51	out += md.Paragraph(banker.Address())
 52
 53	// Render balances section.
 54	out += md.H3("Balances")
 55	balances := banker.Balances()
 56	if len(balances) == 0 {
 57		out += md.Paragraph("No balances found.")
 58	} else {
 59		table := mdtable.Table{Headers: []string{"Denom", "Amount"}}
 60		for _, balance := range balances {
 61			table.Append([]string{balance.Denom, strconv.FormatInt(balance.Amount, 10)})
 62		}
 63		out += table.String()
 64	}
 65
 66	historySize := DefaultHistoryPreviewSize
 67
 68	// Check if the query parameter "history_size" is present and parse it.
 69	if req, err := url.Parse(path); err == nil && req.Query() != nil {
 70		size, err := strconv.Atoi(req.Query().Get("history_size"))
 71		if err == nil && size >= 0 {
 72			historySize = size
 73		}
 74	}
 75
 76	// Skip history rendering if historySize is 0.
 77	if historySize == 0 {
 78		return out
 79	}
 80
 81	// Render history section.
 82	out += md.H3("History")
 83	history, _ := t.History(bankerID, 1, historySize)
 84	if len(history) == 0 {
 85		out += md.Paragraph("No payments sent yet.")
 86	} else {
 87		if len(history) == 1 {
 88			out += md.Paragraph("Last payment:")
 89		} else {
 90			count := strconv.FormatInt(int64(len(history)), 10)
 91			out += md.Paragraph("Last " + count + " payments:")
 92		}
 93
 94		// Render each payment in the history.
 95		for _, payment := range history {
 96			out += md.BulletItem(payment.String())
 97		}
 98		out += "\n"
 99
100		// Build the "See full history" link from the owning realm's
101		// path captured at New() time. Skipped if no path was supplied
102		// (e.g. /p/ filetests that don't exercise rendering).
103		if from := strings.IndexRune(t.realmPath, '/'); from >= 0 {
104			out += md.Link(
105				"See full history",
106				ufmt.Sprintf("%s:%s/history", t.realmPath[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}