internal/httpd/page.go
61 lines · 1787 bytes
1package httpd
2
3import (
4 "net/http"
5
6 "gitbay.org/gitbay/internal/store"
7)
8
9// rail is the viewer's cross-repo state the layout needs. The rail itself
10// is icons only, so what is left is the unread count on its bell; the
11// pinned repositories it used to list are rendered by the dashboard.
12type rail struct {
13 Unread int
14}
15
16// basePage is what the layout needs on every page, repo or not. Page
17// structs embed it so the rail and the site name are always in scope.
18type basePage struct {
19 // Site is the instance's display name; Host is the name a command or
20 // URL must use. Anything copy-pasteable takes Host.
21 Site string
22 Host string
23 Viewer string
24 Admin bool // the viewer is an instance admin: the rail shows /admin
25 Rail rail
26 // Theme is stamped on <html> as data-theme: light or dark when the
27 // viewer chose one, empty when the browser's own scheme decides.
28 Theme string
29}
30
31// base builds the layout-wide data for a request that has not already
32// resolved a viewer.
33func (s *Server) base(r *http.Request) basePage {
34 if s.cfg.Web.Mode != "accounts" {
35 return basePage{Site: s.siteName(), Host: s.cfg.SiteHost()}
36 }
37 return s.baseFor(s.viewer(r))
38}
39
40// baseFor is base for a handler that already holds the viewer, so the
41// session lookup is not repeated.
42func (s *Server) baseFor(viewer store.User) basePage {
43 b := basePage{Site: s.siteName(), Host: s.cfg.SiteHost()}
44 if viewer.ID == 0 {
45 return b
46 }
47 b.Viewer = viewer.Username
48 b.Admin = viewer.IsAdmin
49 b.Rail = s.railFor(viewer)
50 if theme, err := s.st.Theme(viewer.ID); err == nil && theme != "system" {
51 b.Theme = theme
52 }
53 return b
54}
55
56// railFor collects the viewer's unread count.
57func (s *Server) railFor(viewer store.User) rail {
58 var rl rail
59 rl.Unread = s.st.UnreadNotices(viewer.ID)
60 return rl
61}