internal/httpd/notifyweb.go

ff759b53942049b2043e132f5482b442a7265b98
gitbay/internal/httpd/notifyweb.go history · blame · raw

73 lines · 2273 bytes

 1package httpd
 2
 3import (
 4	"net/http"
 5	"strconv"
 6
 7	"gitbay.org/gitbay/internal/policy"
 8	"gitbay.org/gitbay/internal/store"
 9)
10
11// noticeView is one inbox row with the pieces the template needs: the
12// sigil for its kind and the link, already absolute.
13type noticeView struct {
14	store.Notice
15	Href string
16	Read bool
17}
18
19// notifications is /notifications: the inbox behind the rail's badge.
20// Unread by default; ?all=1 keeps what has been read.
21func (s *Server) notifications(w http.ResponseWriter, r *http.Request, u store.User) {
22	all := r.URL.Query().Get("all") == "1"
23	rows, err := s.st.Inbox(u.ID, !all, 200, 0)
24	if err != nil {
25		http.Error(w, "internal error", http.StatusInternalServerError)
26		return
27	}
28	views := make([]noticeView, 0, len(rows))
29	for _, n := range rows {
30		views = append(views, noticeView{n, "/" + n.Path, n.ReadAt != ""})
31	}
32	s.render(w, "notifications.html", struct {
33		basePage
34		Tab     string
35		All     bool
36		Notices []noticeView
37	}{s.baseFor(u), "notifications", all, views})
38}
39
40// notificationsRead marks one notice read, or the whole inbox when no id
41// is given, then returns to the list.
42func (s *Server) notificationsRead(w http.ResponseWriter, r *http.Request, u store.User) {
43	var ids []int64
44	if v := r.FormValue("id"); v != "" {
45		n, err := strconv.ParseInt(v, 10, 64)
46		if err != nil {
47			http.Error(w, "bad id", http.StatusBadRequest)
48			return
49		}
50		ids = append(ids, n)
51	}
52	if _, err := s.st.MarkNoticesRead(u.ID, ids); err != nil {
53		http.Error(w, "internal error", http.StatusInternalServerError)
54		return
55	}
56	http.Redirect(w, r, "/notifications", http.StatusSeeOther)
57}
58
59// watchToggle cycles the viewer's watch state on a repository: default,
60// watching, muted, back to default — through repo watch/repo mute/repo
61// unwatch, the same commands the CLI runs (#261, #271).
62func (s *Server) watchToggle(w http.ResponseWriter, r *http.Request, u store.User) {
63	repo, ok := s.repoForUser(w, r, u, policy.CanRead)
64	if !ok {
65		return
66	}
67	next := map[string]string{"": "watch", "watching": "mute", "muted": "unwatch"}
68	verb := next[s.st.RepoWatchState(repo.ID, u.ID)]
69	if _, msg, ok := s.runControl(u, []string{"repo", verb, repo.Path()}); !ok {
70		s.setFlash(w, msg)
71	}
72	http.Redirect(w, r, "/"+repo.Path(), http.StatusSeeOther)
73}