render.gno
2.86 Kb · 100 lines
1package social
2
3import (
4 "strconv"
5 "strings"
6
7 "gno.land/p/nt/markdown/sanitize/v0"
8 "gno.land/r/sys/users"
9)
10
11// resolveAddr looks up an address by registered name first, then falls back
12// to treating the input as a raw address. This allows unregistered users to
13// be found by their address string.
14func resolveAddr(nameOrAddr string) address {
15 user, _ := users.ResolveName(nameOrAddr)
16 if user != nil {
17 return user.Addr()
18 }
19 return address(nameOrAddr)
20}
21
22func Render(path string) string {
23 if path == "" {
24 str := "Welcome to dSocial!\n\n"
25
26 // List the users who have posted. gUserAddressByName is already sorted by name.
27 gUserAddressByName.Iterate("", "", func(name string, value interface{}) bool {
28 str += " * [@" + name + "](" + gRealmPath + ":" + name + ")" + "\n"
29 return false
30 })
31
32 return str
33 }
34
35 parts := strings.Split(path, "/")
36 if len(parts) == 1 {
37 // /r/berty/social:USER_NAME_OR_ADDR
38 userAddr := resolveAddr(path)
39 userPosts := getUserPosts(userAddr)
40 if userPosts == nil {
41 return "No posts by: " + sanitize.InlineText(path)
42 }
43
44 return userPosts.RenderUserPosts(false)
45 } else if len(parts) == 2 {
46 userAddr := resolveAddr(parts[0])
47 userPosts := getUserPosts(userAddr)
48 if userPosts == nil {
49 return "No posts by: " + sanitize.InlineText(parts[0])
50 }
51
52 if parts[1] == "home" {
53 // /r/berty/social:USER_NAME_OR_ADDR/home
54 return userPosts.RenderUserPosts(true)
55 } else if parts[1] == "followers" {
56 // /r/berty/social:USER_NAME_OR_ADDR/followers
57 return userPosts.RenderFollowers()
58 } else if parts[1] == "following" {
59 // /r/berty/social:USER_NAME_OR_ADDR/following
60 return userPosts.RenderFollowing()
61 } else {
62 // /r/berty/social:USER_NAME_OR_ADDR/THREAD_ID
63 pid, err := strconv.Atoi(parts[1])
64 if err != nil {
65 return "invalid thread id: " + sanitize.InlineText(parts[1])
66 }
67 thread := userPosts.GetThread(PostID(pid))
68 if thread == nil {
69 return "thread does not exist with id: " + sanitize.InlineText(parts[1])
70 }
71 return thread.RenderPost("", 5)
72 }
73 } else if len(parts) == 3 {
74 // /r/berty/social:USER_NAME_OR_ADDR/THREAD_ID/REPLY_ID
75 userAddr := resolveAddr(parts[0])
76 userPosts := getUserPosts(userAddr)
77 if userPosts == nil {
78 return "No posts by: " + sanitize.InlineText(parts[0])
79 }
80 pid, err := strconv.Atoi(parts[1])
81 if err != nil {
82 return "invalid thread id: " + sanitize.InlineText(parts[1])
83 }
84 thread := userPosts.GetThread(PostID(pid))
85 if thread == nil {
86 return "thread does not exist with id: " + sanitize.InlineText(parts[1])
87 }
88 rid, err := strconv.Atoi(parts[2])
89 if err != nil {
90 return "invalid reply id: " + sanitize.InlineText(parts[2])
91 }
92 reply := thread.GetReply(PostID(rid))
93 if reply == nil {
94 return "reply does not exist with id: " + sanitize.InlineText(parts[2])
95 }
96 return reply.RenderInner()
97 } else {
98 return "unrecognized path: " + sanitize.InlineText(path)
99 }
100}