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}