render.gno

3.88 Kb · 140 lines
  1package users
  2
  3import (
  4	"std"
  5
  6	"gno.land/p/moul/md"
  7	"gno.land/p/moul/realmpath"
  8	"gno.land/p/moul/txlink"
  9	"gno.land/p/nt/ufmt"
 10
 11	"gno.land/r/demo/profile"
 12	susers "gno.land/r/sys/users"
 13)
 14
 15func Render(path string) string {
 16	req := realmpath.Parse(path)
 17
 18	if req.Path == "" {
 19		return renderHomePage()
 20	}
 21
 22	// Otherwise, render the user page
 23	return renderUserPage(req.Path)
 24}
 25
 26func renderHomePage() string {
 27	var out string
 28
 29	out += "# gno.land user registry\n"
 30
 31	if paused {
 32		out += md.HorizontalRule()
 33		out += md.H2("This realm is paused.")
 34		out += md.Paragraph("Check out [`gno.land/r/gnoland/users`](/r/gnoland/users) for newer versions of the registry.")
 35		out += md.HorizontalRule()
 36	}
 37
 38	out += renderIntroParagraph()
 39
 40	out += md.H2("Latest registrations")
 41	out += RenderLatestUsersWidget(-1)
 42
 43	return out
 44}
 45
 46func renderIntroParagraph() string {
 47	out := md.Paragraph("Welcome to the gno.land user registry (v1). Please register a username.")
 48	out += md.Paragraph(`Registering a username grants the registering address the right to deploy packages and realms
 49under that username’s namespace. For example, if an address registers the username ` + md.InlineCode("gnome123") + `, it 
 50will gain permission to deploy packages and realms to package paths with the pattern ` + md.InlineCode("gno.land/{p,r}/gnome123/*") + `.`)
 51
 52	out += md.Paragraph("In V1, usernames must follow these rules, in order to prevent username squatting:")
 53	items := []string{
 54		"Must start with 3 letters",
 55		"Letters must be lowercase",
 56		"Must end with 3 numbers",
 57		"Have a maximum length of 20 characters",
 58		"With the only special character allowed being `_`",
 59	}
 60	out += md.BulletList(items)
 61
 62	out += "\n\n"
 63	out += md.Paragraph("In later versions of the registry, vanity usernames will be allowed through specific mechanisms.")
 64
 65	if !paused {
 66		amount := ufmt.Sprintf("%dugnot", registerPrice)
 67		out += md.H3(ufmt.Sprintf(" [[Click here to register]](%s)", txlink.NewLink("Register").SetSend(amount).URL()))
 68		// XXX: Display registration price adjusting for dynamic GNOT price when it becomes possible.
 69		out += ufmt.Sprintf("Registration price: %f GNOT (%s)\n\n", float64(registerPrice)/1_000_000, amount)
 70	}
 71
 72	out += md.HorizontalRule()
 73	out += "\n\n"
 74
 75	return out
 76}
 77
 78// resolveUser resolves the user based on the path, determining if it's a name or address
 79func resolveUser(path string) (*susers.UserData, bool, bool) {
 80	if std.Address(path).IsValid() {
 81		return susers.ResolveAddress(std.Address(path)), false, false
 82	}
 83
 84	data, isLatest := susers.ResolveName(path)
 85	return data, isLatest, true
 86}
 87
 88// renderUserPage generates the user page based on user data and path
 89func renderUserPage(path string) string {
 90	var out string
 91
 92	// Render single user page
 93	data, isLatest, isName := resolveUser(path)
 94	if data == nil {
 95		out += md.H1("User not found.")
 96		out += "This user does not exist or has been deleted.\n"
 97		return out
 98	}
 99
100	out += md.H1("User - " + md.InlineCode(data.Name()))
101
102	if isName && !isLatest {
103		out += md.Paragraph(ufmt.Sprintf(
104			"Note: You searched for `%s`, which is a previous name of [`%s`](/u/%s).",
105			path, data.Name(), data.Name()))
106	} else {
107		out += ufmt.Sprintf("Address: %s\n\n", data.Addr().String())
108
109		out += md.H2("Bio")
110		out += profile.GetStringField(data.Addr(), "Bio", "No bio defined.")
111		out += "\n\n"
112		out += ufmt.Sprintf("[Update bio](%s)", txlink.Realm("gno.land/r/demo/profile").Call("SetStringField", "field", "Bio"))
113		out += "\n\n"
114	}
115
116	return out
117}
118
119// RenderLatestUsersWidget renders the latest num registered users
120// For num = -1, maximum number (10) will be displayed
121func RenderLatestUsersWidget(num int) string {
122	size := latestUsers.Size()
123	if size == 0 {
124		return "No registered users."
125	}
126
127	if num > size || num < 0 {
128		num = size
129	}
130
131	entries := latestUsers.Entries()
132	var out string
133
134	for i := size - 1; i >= size-num; i-- {
135		user := entries[i].(string)
136		out += md.BulletItem(md.UserLink(user))
137	}
138
139	return out
140}