render_reply.gno
4.00 Kb · 181 lines
1package boards2
2
3import (
4 "strconv"
5 "strings"
6
7 "gno.land/p/gnoland/boards"
8 "gno.land/p/jeronimoalbi/mdform"
9 "gno.land/p/jeronimoalbi/pager"
10 "gno.land/p/leon/svgbtn"
11 "gno.land/p/moul/md"
12 "gno.land/p/nt/mux/v0"
13 "gno.land/p/nt/ufmt/v0"
14)
15
16func renderReply(res *mux.ResponseWriter, req *mux.Request) {
17 name := req.GetVar("board")
18 board, found := gBoards.GetByName(name)
19 if !found {
20 res.Write("Board not found")
21 return
22 }
23
24 rawID := req.GetVar("thread")
25 threadID, err := strconv.Atoi(rawID)
26 if err != nil {
27 res.Write("Invalid thread ID: " + rawID)
28 return
29 }
30
31 rawID = req.GetVar("reply")
32 replyID, err := strconv.Atoi(rawID)
33 if err != nil {
34 res.Write("Invalid reply ID: " + rawID)
35 return
36 }
37
38 thread, found := getThread(board, boards.ID(threadID))
39 if !found {
40 res.Write("Thread not found")
41 return
42 }
43
44 reply, found := getReply(thread, boards.ID(replyID))
45 if !found {
46 res.Write("Reply not found")
47 return
48 }
49
50 // Call render even for hidden replies to display children.
51 // Original comment content will be hidden under the hood.
52 // See: #3480
53 res.Write(renderPostInner(reply))
54}
55
56func renderTopLevelReplies(post *boards.Post, path, indent string, levels int) string {
57 p, err := pager.New(path, post.Replies.Size(), pager.WithPageSize(pageSizeReplies))
58 if err != nil {
59 panic(err)
60 }
61
62 var (
63 b strings.Builder
64 commentsIndent = indent + "> "
65 )
66
67 render := func(reply *boards.Post) bool {
68 b.WriteString(indent + "\n" + renderPost(reply, "", commentsIndent, levels-1))
69 return false
70 }
71
72 b.WriteString("\n" + md.HorizontalRule() + "Sort by: ")
73
74 r := parseRealmPath(path)
75 sortOrder := r.Query.Get("order")
76 if sortOrder == "desc" {
77 r.Query.Set("order", "asc")
78 b.WriteString(md.Link("newest first", r.String()) + "\n")
79
80 } else {
81 r.Query.Set("order", "desc")
82 b.WriteString(md.Link("oldest first", r.String()) + "\n")
83 }
84
85 count := p.PageSize()
86 if sortOrder == "desc" {
87 count = -count // Reverse iterate
88 }
89
90 post.Replies.Iterate(p.Offset(), count, render)
91
92 if p.HasPages() {
93 b.WriteString(md.HorizontalRule())
94 b.WriteString(pager.Picker(p))
95 }
96 return b.String()
97}
98
99func renderSubReplies(post *boards.Post, indent string, levels int) string {
100 var (
101 b strings.Builder
102 commentsIndent = indent + "> "
103 )
104
105 post.Replies.Iterate(0, post.Replies.Size(), func(reply *boards.Post) bool {
106 b.WriteString(indent + "\n" + renderPost(reply, "", commentsIndent, levels-1))
107 return false
108 })
109 return b.String()
110}
111
112func renderEditReply(res *mux.ResponseWriter, req *mux.Request) {
113 name := req.GetVar("board")
114 board, found := gBoards.GetByName(name)
115 if !found {
116 res.Write("Board not found")
117 return
118 }
119
120 rawID := req.GetVar("thread")
121 threadID, err := strconv.Atoi(rawID)
122 if err != nil {
123 res.Write("Invalid thread ID: " + rawID)
124 return
125 }
126
127 rawID = req.GetVar("reply")
128 replyID, err := strconv.Atoi(rawID)
129 if err != nil {
130 res.Write("Invalid reply ID: " + rawID)
131 return
132 }
133
134 thread, found := getThread(board, boards.ID(threadID))
135 if !found {
136 res.Write("Thread not found")
137 return
138 }
139
140 reply, found := getReply(thread, boards.ID(replyID))
141 if !found {
142 res.Write("Reply not found")
143 return
144 }
145
146 form := mdform.New("exec", "EditReply")
147 form.Input(
148 "boardID",
149 "placeholder", "Board ID",
150 "value", board.ID.String(),
151 "readonly", "true",
152 )
153 form.Input(
154 "threadID",
155 "placeholder", "Thread ID",
156 "value", thread.ID.String(),
157 "readonly", "true",
158 )
159 form.Input(
160 "replyID",
161 "placeholder", "Reply ID",
162 "value", reply.ID.String(),
163 "readonly", "true",
164 )
165 form.Textarea(
166 "body",
167 "placeholder", "Comment",
168 "value", reply.Body,
169 "required", "true",
170 )
171
172 res.Write(md.H1(board.Name + ": Edit Comment"))
173 res.Write(md.Link("← Back to thread", makeThreadURI(thread)) + "\n\n")
174 res.Write(
175 md.Paragraph(
176 ufmt.Sprintf("Editing a comment from the thread: %s", md.Link(thread.Title, makeThreadURI(thread))),
177 ),
178 )
179 res.Write(form.String())
180 res.Write("\n\n**Done?** " + svgbtn.ButtonWithRadius(136, 32, 4, "#E2E2E2", "#54595D", "Return to thread", makeThreadURI(thread)) + "\n")
181}