render.gno

4.75 Kb ยท 213 lines
  1package hor
  2
  3import (
  4	"net/url"
  5	"strings"
  6
  7	"gno.land/p/demo/avl"
  8	"gno.land/p/demo/avl/pager"
  9	"gno.land/p/demo/fqname"
 10	"gno.land/p/demo/ufmt"
 11	"gno.land/p/moul/md"
 12	"gno.land/p/moul/txlink"
 13
 14	"gno.land/r/sys/users"
 15)
 16
 17const colsPerRow = 3
 18
 19func Render(path string) string {
 20	out := md.H1("The Hall of Realms\n\n")
 21
 22	if !strings.Contains(path, "hall") && !strings.Contains(path, "dashboard") {
 23		out += renderAbout()
 24		return out
 25	}
 26
 27	dashboardEnabled := strings.Contains(path, "dashboard")
 28	if dashboardEnabled {
 29		out += renderDashboard()
 30		out += renderActions(path)
 31		return out
 32	}
 33
 34	out += renderActions(path)
 35	out += exhibition.Render(path, dashboardEnabled)
 36
 37	return out
 38}
 39
 40func (e Exhibition) Render(path string, dashboard bool) string {
 41	tree := getTreeByPath(&e, path)
 42
 43	u, _ := url.Parse(path)
 44	reversed := u.Query().Get("sort") != "oldest"
 45
 46	page := pager.NewPager(tree, colsPerRow*3, reversed).MustGetPageByPath(path)
 47	out := ufmt.Sprintf("%s\n\n", e.description)
 48
 49	if e.items.Size() == 0 {
 50		out += "No items in this exhibition currently.\n\n"
 51		return out
 52	}
 53
 54	str := make([]string, len(page.Items))
 55	for i, item := range page.Items {
 56		itemValue := item.Value.(*Item)
 57		str[i] += itemValue.Render(dashboard)
 58	}
 59
 60	out += md.ColumnsN(str, 3, true)
 61	out += md.H3(page.Picker(path))
 62
 63	return out
 64}
 65
 66func (i Item) Render(dashboard bool) string {
 67	out := ufmt.Sprintf("### [%s](%s)\n",
 68		i.title,
 69		strings.TrimPrefix(i.pkgpath, "gno.land"),
 70	)
 71
 72	if i.description == "" {
 73		i.description = "_No description provided._\n"
 74	}
 75	out += ufmt.Sprintf("%s\n\n", i.description)
 76
 77	namespace := strings.Split(i.pkgpath, "/")[2]
 78	user, _ := users.ResolveAny(namespace)
 79	if user != nil {
 80		namespace = user.RenderLink("")
 81	}
 82	out += ufmt.Sprintf("by %s\n\n", namespace)
 83
 84	blockMsg := "Submitted via the [Monorepo](https://github.com/gnolang/gno)"
 85	if i.blockNum > 0 {
 86		blockMsg = ufmt.Sprintf("Submitted at Block #%d", i.blockNum)
 87	}
 88	out += ufmt.Sprintf("%s\n\n", blockMsg)
 89
 90	out += md.Bold(ufmt.Sprintf("[%d๐Ÿ‘](%s) - [%d๐Ÿ‘Ž](%s)",
 91		i.upvote.Size(), txlink.Call("Upvote", "pkgpath", i.pkgpath),
 92		i.downvote.Size(), txlink.Call("Downvote", "pkgpath", i.pkgpath),
 93	))
 94
 95	if dashboard {
 96		out += md.Link("Delete", txlink.Call("Delete", "pkgpath", i.pkgpath))
 97	}
 98
 99	return out
100}
101
102func renderDashboard() string {
103	out := md.H3("Dashboard\n\n")
104	out += ufmt.Sprintf("Total submissions: %d\n\n", exhibition.items.Size())
105
106	out += ufmt.Sprintf("Exhibition admin: %s\n\n", Ownable.Owner().String())
107
108	if !Pausable.IsPaused() {
109		out += md.Link("Pause exhibition", txlink.Call("Pause"))
110	} else {
111		out += md.Link("Unpause exhibition", txlink.Call("Unpause"))
112	}
113
114	out += "\n\n"
115	return out
116}
117
118func RenderExhibWidget(itemsToRender int) string {
119	if itemsToRender < 1 {
120		return ""
121	}
122
123	if exhibition.items.Size() == 0 {
124		return "No items in the Hall of Realms.\n\n"
125	}
126
127	out := ""
128	i := 0
129	exhibition.items.Iterate("", "", func(key string, value any) bool {
130		item := value.(*Item)
131
132		out += ufmt.Sprintf("- %s\n", fqname.RenderLink(item.pkgpath, ""))
133
134		i++
135		return i >= itemsToRender
136	})
137
138	return out
139}
140
141func getTreeByPath(e *Exhibition, path string) *avl.Tree {
142	u, _ := url.Parse(path)
143	switch u.Query().Get("sort") {
144	case "upvotes":
145		return e.itemsSortedByUpvotes
146	case "downvotes":
147		return e.itemsSortedByDownvotes
148	case "creation":
149		return e.itemsSortedByCreation
150	case "oldest":
151		return e.itemsSortedByCreation
152	default:
153		return e.itemsSortedByCreation
154	}
155}
156
157func renderAbout() string {
158	out := `
159Welcome, gnomes!
160
161The Hall of Realms is a simple & permissionless dashboard for gnomes to share 
162their work with the community.
163
164Here, anyone is welcome to submit their own code. This realm utilizes a common
165Gno pattern - the registry pattern - to allow anyone to programmatically submit 
166their work. 
167
168Simply import the Hall of Realms in your code, and call the "Register()" function
169inside your realm init, as shown below:
170
171"""go
172package myrealm
173
174import "gno.land/r/leon/hor"
175
176func init() {
177	cross(hor.Register)("My Gnome App", "This is my submission to the Hall of Realms.")
178}
179...
180"""
181
182%s
183
184`
185
186	out = ufmt.Sprintf(out, "## [Visit The Hall ->](/r/leon/hor:hall)")
187
188	out = strings.ReplaceAll(out, "\"", "`")
189
190	return out
191}
192
193func renderActions(path string) string {
194	out := md.HorizontalRule()
195	out += md.Link("Reset Sort", "?") + " | "
196	out += md.Link("Sort by Upvotes", "?sort=upvotes") + " | "
197	out += md.Link("Sort by Downvotes", "?sort=downvotes") + " | "
198	out += md.Link("Sort by Most Recent", "?sort=creation") + " | "
199	out += md.Link("Sort by Oldest", "?sort=oldest") + " | "
200
201	if !strings.Contains(path, "dashboard") {
202		out += md.Link("Dashboard", "/r/leon/hor:dashboard")
203	} else {
204		out += md.Link("Dashboard off", "/r/leon/hor:hall")
205	}
206
207	out += " | "
208	out += md.Link("About", "/r/leon/hor") + "\n\n"
209
210	out += md.HorizontalRule()
211
212	return out
213}