internal/httpd/notifyweb.go
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}