internal/httpd/reactions.go
84 lines · 2434 bytes
1package httpd
2
3import (
4 "net/http"
5 "strings"
6
7 "gitbay.org/gitbay/internal/store"
8)
9
10// reactionView is one reaction button (or count) under an item.
11type reactionView struct {
12 Name string
13 Emoji string
14 Count int
15 Me bool
16 Label string
17}
18
19// reactionBar is what the reactions partial renders for one item:
20// Comment is 0 for the issue or merge request body.
21type reactionBar struct {
22 Action string
23 Comment int64
24 Signed bool
25 Items []reactionView
26}
27
28// reactionBars builds the bars for a thread body (key 0) and its
29// comments. A signed-in viewer is offered every reaction; anyone else
30// sees only the ones somebody gave.
31func (s *Server) reactionBars(r *http.Request, noun string, threadID int64, comments []store.IssueComment, action string) map[int64]reactionBar {
32 viewer := s.webViewer(r)
33 counts, _ := s.st.ReactionCounts(noun, threadID, viewer.ID)
34 bar := func(id int64) reactionBar {
35 b := reactionBar{Action: action, Comment: id, Signed: viewer.ID != 0}
36 given := map[string]store.ReactionCount{}
37 for _, rc := range counts[id] {
38 given[rc.Reaction] = rc
39 }
40 for _, r := range store.Reactions {
41 rc := given[r.Name]
42 if rc.Count == 0 && !b.Signed {
43 continue
44 }
45 label := r.Name
46 if rc.Me {
47 label = "remove " + r.Name
48 }
49 b.Items = append(b.Items, reactionView{r.Name, r.Emoji, rc.Count, rc.Me, label})
50 }
51 return b
52 }
53 out := map[int64]reactionBar{0: bar(0)}
54 for _, c := range comments {
55 if c.Kind != "system" {
56 out[c.ID] = bar(c.ID)
57 }
58 }
59 return out
60}
61
62// reactArgs turns the form into the react command's arguments. The
63// button pressed is named add or remove and carries the reaction.
64func reactArgs(r *http.Request, noun string) []string {
65 repo := r.PathValue("owner") + "/" + r.PathValue("repo")
66 args := []string{noun, "react", repo, r.PathValue("n")}
67 if c := strings.TrimSpace(r.FormValue("comment")); c != "" {
68 args = append(args, "--comment", c)
69 }
70 if v := r.FormValue("remove"); v != "" {
71 return append(args, "--remove", v)
72 }
73 return append(args, r.FormValue("add"))
74}
75
76func (s *Server) issueReactSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
77 _, msg, code := s.runControlCode(u, reactArgs(r, "issue"))
78 s.done(w, r, code, msg, s.issueRedirect)
79}
80
81func (s *Server) mrReactSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
82 _, msg, code := s.runControlCode(u, reactArgs(r, "mr"))
83 s.done(w, r, code, msg, s.mrRedirect)
84}