internal/httpd/notifyweb.go
71 lines · 2298 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, through notifications read, then returns to the list (#261).
42func (s *Server) notificationsRead(w http.ResponseWriter, r *http.Request, u store.User) {
43 argv := []string{"notifications", "read", "--all"}
44 if v := r.FormValue("id"); v != "" {
45 if _, err := strconv.ParseInt(v, 10, 64); err != nil {
46 http.Error(w, "bad id", http.StatusBadRequest)
47 return
48 }
49 argv = []string{"notifications", "read", v}
50 }
51 if _, msg, ok := s.runControl(u, argv); !ok {
52 s.setFlash(w, msg)
53 }
54 http.Redirect(w, r, "/notifications", http.StatusSeeOther)
55}
56
57// watchToggle cycles the viewer's watch state on a repository: default,
58// watching, muted, back to default — through repo watch/repo mute/repo
59// unwatch, the same commands the CLI runs (#261, #271).
60func (s *Server) watchToggle(w http.ResponseWriter, r *http.Request, u store.User) {
61 repo, ok := s.repoForUser(w, r, u, policy.CanRead)
62 if !ok {
63 return
64 }
65 next := map[string]string{"": "watch", "watching": "mute", "muted": "unwatch"}
66 verb := next[s.st.RepoWatchState(repo.ID, u.ID)]
67 if _, msg, ok := s.runControl(u, []string{"repo", verb, repo.Path()}); !ok {
68 s.setFlash(w, msg)
69 }
70 http.Redirect(w, r, "/"+repo.Path(), http.StatusSeeOther)
71}