| @@ -83,35 +83,61 @@ func (s *Server) describeAll(repos []store.Repo) []describedRepo { |
| 83 | 83 | return out |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | // index is the homepage: a dashboard for logged-in users, a landing page |
| 87 | // for everyone else. The full public listing lives at /explore. |
| 86 | 88 | func (s *Server) index(w http.ResponseWriter, r *http.Request) { |
| 89 | if s.cfg.Web.Mode == "accounts" { |
| 90 | if viewer := s.viewer(r); viewer.ID != 0 { |
| 91 | s.dashboard(w, r, viewer) |
| 92 | return |
| 93 | } |
| 94 | } |
| 95 | host := strings.TrimSuffix(strings.TrimPrefix(strings.TrimPrefix( |
| 96 | s.cfg.Server.SiteURL, "https://"), "http://"), "/") |
| 97 | s.render(w, "landing.html", struct { |
| 98 | Site string |
| 99 | Host string |
| 100 | Accounts bool |
| 101 | }{s.siteName(), host, s.cfg.Web.Mode == "accounts"}) |
| 102 | } |
| 103 | |
| 104 | func (s *Server) dashboard(w http.ResponseWriter, r *http.Request, viewer store.User) { |
| 105 | pinned, _ := s.st.PinnedRepos(viewer.ID) |
| 106 | var visible []store.Repo |
| 107 | for _, rp := range pinned { |
| 108 | grant, _ := s.st.AccessRole(rp.ID, viewer.ID) |
| 109 | if policy.CanRead(viewer, rp, grant) { |
| 110 | visible = append(visible, rp) |
| 111 | } |
| 112 | } |
| 113 | mrs, _ := s.st.DashboardMRs(viewer.ID) |
| 114 | issues, _ := s.st.DashboardIssues(viewer.ID) |
| 115 | s.render(w, "dashboard.html", struct { |
| 116 | Site string |
| 117 | Viewer string |
| 118 | Pinned []describedRepo |
| 119 | MRs []store.DashboardItem |
| 120 | Issues []store.DashboardItem |
| 121 | }{s.siteName(), viewer.Username, s.describeAll(visible), mrs, issues}) |
| 122 | } |
| 123 | |
| 124 | func (s *Server) explore(w http.ResponseWriter, r *http.Request) { |
| 87 | 125 | repos, err := s.st.ListPublicRepos() |
| 88 | 126 | if err != nil { |
| 89 | 127 | http.Error(w, "internal error", http.StatusInternalServerError) |
| 90 | 128 | return |
| 91 | 129 | } |
| 92 | 130 | var viewer store.User |
| 93 | | var mine []store.Repo |
| 94 | 131 | if s.cfg.Web.Mode == "accounts" { |
| 95 | | if viewer = s.viewer(r); viewer.ID != 0 { |
| 96 | | all, err := s.st.ListReposForUser(viewer.ID) |
| 97 | | if err == nil { |
| 98 | | for _, rp := range all { |
| 99 | | if rp.Visibility == "private" { |
| 100 | | mine = append(mine, rp) |
| 101 | | } |
| 102 | | } |
| 103 | | } |
| 104 | | } |
| 132 | viewer = s.viewer(r) |
| 105 | 133 | } |
| 106 | 134 | q := strings.TrimSpace(r.URL.Query().Get("q")) |
| 107 | | s.render(w, "index.html", struct { |
| 135 | s.render(w, "explore.html", struct { |
| 108 | 136 | Site string |
| 109 | 137 | Viewer string |
| 110 | 138 | Query string |
| 111 | 139 | Repos []describedRepo |
| 112 | | Mine []describedRepo |
| 113 | | }{s.siteName(), viewer.Username, q, |
| 114 | | s.filterRepos(q, s.describeAll(repos)), s.filterRepos(q, s.describeAll(mine))}) |
| 140 | }{s.siteName(), viewer.Username, q, s.filterRepos(q, s.describeAll(repos))}) |
| 115 | 141 | } |
| 116 | 142 | |
| 117 | 143 | // filterRepos keeps repos whose path, description, or topics contain the |
| @@ -1041,6 +1067,21 @@ func (s *Server) mr(w http.ResponseWriter, r *http.Request) { |
| 1041 | 1067 | md := s.ugcFor(r, p.Repo) |
| 1042 | 1068 | var detachedThreads []diffThread |
| 1043 | 1069 | lines, detachedThreads = attachThreads(lines, diffComments, m.HeadSHA, md) |
| 1070 | type diffStat struct{ Files, Adds, Dels int } |
| 1071 | var stat diffStat |
| 1072 | seenFiles := map[string]bool{} |
| 1073 | for _, l := range lines { |
| 1074 | switch l.Class { |
| 1075 | case "add": |
| 1076 | stat.Adds++ |
| 1077 | case "del": |
| 1078 | stat.Dels++ |
| 1079 | } |
| 1080 | if l.Path != "" && !seenFiles[l.Path] { |
| 1081 | seenFiles[l.Path] = true |
| 1082 | stat.Files++ |
| 1083 | } |
| 1084 | } |
| 1044 | 1085 | s.render(w, "mr.html", struct { |
| 1045 | 1086 | repoPage |
| 1046 | 1087 | MR store.MR |
| @@ -1050,8 +1091,9 @@ func (s *Server) mr(w http.ResponseWriter, r *http.Request) { |
| 1050 | 1091 | Comments []renderedComment |
| 1051 | 1092 | Reviews []store.MRReview |
| 1052 | 1093 | DiffLines []diffLine |
| 1094 | Stat diffStat |
| 1053 | 1095 | DetachedThreads []diffThread |
| 1054 | | }{p, m, md(m.Body), checks, store.CombinedStatus(checks), renderComments(comments, md), reviews, lines, detachedThreads}) |
| 1096 | }{p, m, md(m.Body), checks, store.CombinedStatus(checks), renderComments(comments, md), reviews, lines, stat, detachedThreads}) |
| 1055 | 1097 | } |
| 1056 | 1098 | |
| 1057 | 1099 | func (s *Server) refs(w http.ResponseWriter, r *http.Request) { |