@@ -8,10 +8,30 @@ <h1>{{.Change.Title}} <span class="gray">#{{.Change.ID}}</span></h1> <div id="change-state-badge" style="margin-bottom: 20px;">{{render (changeStateBadge .Change)}}</div> {{.Tabnav "Files"}} {{define "CommitMessage"}} <div class="list-entry list-entry-border commit-message"> <header class="list-entry-header"> <div style="display: flex;"> <pre style="flex-grow: 1;"><strong>{{.Subject}}</strong>{{with .Body}} {{.}}{{end}}</pre> <span>Button</span> </div> </header> <div class="list-entry-body"> <span style="display: inline-block; vertical-align: bottom; margin-right: 5px;">{{.Avatar}}</span>{{/* */}}<span style="display: inline-block;">{{.User}} committed {{.Time}}</span> <span style="float: right;"> <span>commit <code>{{.CommitHash}}</code></span> </span> </div> </div> {{end}} {{define "FileDiff"}} <div class="list-entry list-entry-border"> <header class="list-entry-header">{{.Title}}</header> <div class="list-entry-body"> <pre class="highlight-diff">{{.Diff}}</pre>
@@ -27,15 +27,17 @@ div.list-entry-border { border: 1px solid #ddd; border-radius: 4px; } header.list-entry-header { font-size: 13px; background-color: #f8f8f8; padding: 10px; border-radius: 4px 4px 0 0; border-bottom: 1px solid #eee; } div:not(.commit-message) header.list-entry-header { background-color: #f8f8f8; } .hash-selected div.list-entry-border { border: 1px solid #8ca2d9; } .hash-selected header.list-entry-header { background-color: #dbe5ff; @@ -55,10 +57,36 @@ div.list-entry-body { div.multilist-entry:not(:first-of-type) { border: 0px solid #ddd; border-top-width: 1px; } div.commit-message.list-entry-border { background-color: #ecf3ff; } .commit-message header.list-entry-header { font-size: 14px; } .commit-message div.list-entry-body { background-color: #fff; } .commit-message pre { font-family: Go; font-size: 14px; tab-size: 4; margin: 0; } .commit-message div.list-entry-body { font-size: 13px; line-height: 24px; padding: 6px; } code { font-family: "Go Mono"; font-size: 12px; } /* Needed in issuesapp only because of something in parent containers... */ .markdown-body { word-break: break-word; }
@@ -60,11 +60,11 @@ func (c Commit) Render() []*html.Node { title := htmlg.Div( &html.Node{ Type: html.ElementNode, Data: atom.A.String(), Attr: []html.Attribute{ {Key: atom.Class.String(), Val: "black"}, {Key: atom.Href.String(), Val: "commit/" + c.SHA}, {Key: atom.Href.String(), Val: "files/" + c.SHA}, }, FirstChild: htmlg.Strong(commitSubject), }, ) if commitBody != "" {
@@ -163,11 +163,16 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) error { case len(elems) == 2 && elems[1] == "commits": return h.ChangeCommitsHandler(w, req, changeID) // "/{changeID}/files". case len(elems) == 2 && elems[1] == "files": return h.ChangeFilesHandler(w, req, changeID) return h.ChangeFilesHandler(w, req, changeID, "") // "/{changeID}/files/{commitID}". case len(elems) == 3 && elems[1] == "files": commitID := elems[2] return h.ChangeFilesHandler(w, req, changeID, commitID) default: return httperror.HTTP{Code: http.StatusNotFound, Err: errors.New("no route")} } } @@ -336,11 +341,11 @@ func (h *handler) ChangeCommitsHandler(w http.ResponseWriter, req *http.Request, } state.Change, err = h.is.Get(req.Context(), state.RepoSpec, state.IssueID) if err != nil { return err } cs, err := h.is.ListCommits(req.Context(), state.RepoSpec, state.IssueID) cs, err := h.is.ListCommits(req.Context(), state.RepoSpec, state.IssueID, nil) if err != nil { return err } w.Header().Set("Content-Type", "text/html; charset=utf-8") err = h.static.ExecuteTemplate(w, "change-commits.html.tmpl", &state) @@ -357,11 +362,11 @@ func (h *handler) ChangeCommitsHandler(w http.ResponseWriter, req *http.Request, } _, err = io.WriteString(w, `</body></html>`) return err } func (h *handler) ChangeFilesHandler(w http.ResponseWriter, req *http.Request, changeID uint64) error { func (h *handler) ChangeFilesHandler(w http.ResponseWriter, req *http.Request, changeID uint64, commitID string) error { if req.Method != http.MethodGet { return httperror.Method{Allowed: []string{http.MethodGet}} } state, err := h.state(req, changeID) if err != nil { @@ -369,11 +374,32 @@ func (h *handler) ChangeFilesHandler(w http.ResponseWriter, req *http.Request, c } state.Change, err = h.is.Get(req.Context(), state.RepoSpec, state.IssueID) if err != nil { return err } rawDiff, err := h.is.GetDiff(req.Context(), state.RepoSpec, state.IssueID) var ( opt *changes.ListCommitsOptions commit commitMessage ) if commitID != "" { opt = &changes.ListCommitsOptions{ Commit: commitID, } cs, err := h.is.ListCommits(req.Context(), state.RepoSpec, state.IssueID, opt) if err != nil { return err } subject, body := splitCommitMessage(cs[0].Message) commit = commitMessage{ CommitHash: cs[0].SHA, Subject: subject, Body: body, Author: cs[0].Author, AuthorTime: cs[0].AuthorTime, } } rawDiff, err := h.is.GetDiff(req.Context(), state.RepoSpec, state.IssueID, opt) if err != nil { return err } fileDiffs, err := diff.ParseMultiFileDiff(rawDiff) if err != nil { @@ -382,10 +408,16 @@ func (h *handler) ChangeFilesHandler(w http.ResponseWriter, req *http.Request, c w.Header().Set("Content-Type", "text/html; charset=utf-8") err = h.static.ExecuteTemplate(w, "change-files.html.tmpl", &state) if err != nil { return err } if commitID != "" { err = h.static.ExecuteTemplate(w, "CommitMessage", commit) if err != nil { return err } } for _, f := range fileDiffs { err = h.static.ExecuteTemplate(w, "FileDiff", fileDiff{FileDiff: f}) if err != nil { return err }
@@ -4,13 +4,16 @@ import ( "bytes" "fmt" "html/template" "sort" "strings" "time" "github.com/shurcooL/highlight_diff" "github.com/shurcooL/htmlg" issuescomponent "github.com/shurcooL/issuesapp/component" "github.com/shurcooL/users" "github.com/sourcegraph/annotate" "golang.org/x/net/html" "golang.org/x/net/html/atom" "sourcegraph.com/sourcegraph/go-diff/diff" ) @@ -84,10 +87,31 @@ func (it iconText) Render() []*html.Node { }) text := htmlg.Text(it.Text) return []*html.Node{icon, text} } // commitMessage ... type commitMessage struct { CommitHash string Subject string Body string Author users.User AuthorTime time.Time } func (c commitMessage) Avatar() template.HTML { return template.HTML(htmlg.RenderComponentsString(issuescomponent.Avatar{User: c.Author, Size: 24})) } func (c commitMessage) User() template.HTML { return template.HTML(htmlg.RenderComponentsString(issuescomponent.User{User: c.Author})) } func (c commitMessage) Time() template.HTML { return template.HTML(htmlg.RenderComponentsString(issuescomponent.Time{Time: c.AuthorTime})) } // fileDiff represents a file diff for display purposes. type fileDiff struct { *diff.FileDiff }