render.gno
3.86 Kb · 138 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 out += md.H3(ufmt.Sprintf(" [[Click here to register]](%s)", txlink.NewLink("Register").SetSend(amount).URL()))
66 // XXX: Display registration price adjusting for dynamic GNOT price when it becomes possible.
67 out += ufmt.Sprintf("Registration price: %f GNOT (%s)\n\n", float64(registerPrice)/1_000_000, amount)
68 }
69
70 out += md.HorizontalRule()
71 out += "\n\n"
72
73 return out
74}
75
76// resolveUser resolves the user based on the path, determining if it's a name or address
77func resolveUser(path string) (*susers.UserData, bool, bool) {
78 if address(path).IsValid() {
79 return susers.ResolveAddress(address(path)), false, false
80 }
81
82 data, isLatest := susers.ResolveName(path)
83 return data, isLatest, true
84}
85
86// renderUserPage generates the user page based on user data and path
87func renderUserPage(path string) string {
88 var out string
89
90 // Render single user page
91 data, isLatest, isName := resolveUser(path)
92 if data == nil {
93 out += md.H1("User not found.")
94 out += "This user does not exist or has been deleted.\n"
95 return out
96 }
97
98 out += md.H1("User - " + md.InlineCode(data.Name()))
99
100 if isName && !isLatest {
101 out += md.Paragraph(ufmt.Sprintf(
102 "Note: You searched for `%s`, which is a previous name of [`%s`](/u/%s).",
103 path, data.Name(), data.Name()))
104 } else {
105 out += ufmt.Sprintf("Address: %s\n\n", data.Addr().String())
106
107 out += md.H2("Bio")
108 out += profile.GetStringField(data.Addr(), "Bio", "No bio defined.")
109 out += "\n\n"
110 out += ufmt.Sprintf("[Update bio](%s)", txlink.Realm("gno.land/r/demo/profile").Call("SetStringField", "field", "Bio"))
111 out += "\n\n"
112 }
113
114 return out
115}
116
117// RenderLatestUsersWidget renders the latest num registered users
118// For num = -1, maximum number (10) will be displayed
119func RenderLatestUsersWidget(num int) string {
120 size := latestUsers.Size()
121 if size == 0 {
122 return "No registered users."
123 }
124
125 if num > size || num < 0 {
126 num = size
127 }
128
129 entries := latestUsers.Entries()
130 var out string
131
132 for i := size - 1; i >= size-num; i-- {
133 user := entries[i].(string)
134 out += md.BulletItem(md.UserLink(user))
135 }
136
137 return out
138}