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