Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

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}