internal/httpd/reactions.go

v1.43.1
gitbay/internal/httpd/reactions.go history · blame · raw

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}