Surface branch PR entrypoints
Authored by
mfwolffe <wolffemf@dukes.jmu.edu>
- SHA
748915b69f1b9d65b69e788570930b949da6f688- Parents
-
50a1a7e - Tree
e13ab22
748915b
748915b69f1b9d65b69e788570930b949da6f68850a1a7e
e13ab22| Status | File | + | - |
|---|---|---|---|
| M |
internal/web/handlers/repo/code.go
|
33 | 0 |
| M |
internal/web/static/css/shithub.css
|
70 | 0 |
| M |
internal/web/templates/repo/tree.html
|
38 | 0 |
internal/web/handlers/repo/code.gomodified@@ -4,6 +4,7 @@ package repo | ||
| 4 | 4 | |
| 5 | 5 | import ( |
| 6 | 6 | "bytes" |
| 7 | + "context" | |
| 7 | 8 | "errors" |
| 8 | 9 | "fmt" |
| 9 | 10 | "html/template" |
@@ -66,6 +67,17 @@ type codeContext struct { | ||
| 66 | 67 | subpath string // path inside the ref, no leading slash |
| 67 | 68 | } |
| 68 | 69 | |
| 70 | +type codeBranchCompare struct { | |
| 71 | + Show bool | |
| 72 | + HasRecentPush bool | |
| 73 | + Base string | |
| 74 | + Head string | |
| 75 | + Ahead int | |
| 76 | + Behind int | |
| 77 | + CompareHref string | |
| 78 | + PullNewHref string | |
| 79 | +} | |
| 80 | + | |
| 69 | 81 | // loadCodeContext does the resolve dance for tree/blob/raw/find. On |
| 70 | 82 | // any failure it writes the response and returns ok=false. |
| 71 | 83 | func (h *Handlers) loadCodeContext(w http.ResponseWriter, r *http.Request) (*codeContext, bool) { |
@@ -132,6 +144,26 @@ func (cc *codeContext) isBranchRef() bool { | ||
| 132 | 144 | return false |
| 133 | 145 | } |
| 134 | 146 | |
| 147 | +func codeBranchCompareData(ctx context.Context, cc *codeContext) codeBranchCompare { | |
| 148 | + if !cc.isBranchRef() || cc.ref == cc.row.DefaultBranch { | |
| 149 | + return codeBranchCompare{} | |
| 150 | + } | |
| 151 | + ahead, behind, err := repogit.AheadBehind(ctx, cc.gitDir, cc.row.DefaultBranch, cc.ref) | |
| 152 | + if err != nil { | |
| 153 | + return codeBranchCompare{} | |
| 154 | + } | |
| 155 | + return codeBranchCompare{ | |
| 156 | + Show: true, | |
| 157 | + HasRecentPush: ahead > 0, | |
| 158 | + Base: cc.row.DefaultBranch, | |
| 159 | + Head: cc.ref, | |
| 160 | + Ahead: ahead, | |
| 161 | + Behind: behind, | |
| 162 | + CompareHref: compareURL(cc.owner, cc.row.Name, cc.row.DefaultBranch, cc.ref), | |
| 163 | + PullNewHref: pullNewURL(cc.owner, cc.row.Name, cc.row.DefaultBranch, cc.ref), | |
| 164 | + } | |
| 165 | +} | |
| 166 | + | |
| 135 | 167 | func (h *Handlers) canWriteRepo(r *http.Request, row reposdb.Repo) bool { |
| 136 | 168 | viewer := middleware.CurrentUserFromContext(r.Context()) |
| 137 | 169 | if viewer.IsAnonymous() { |
@@ -219,6 +251,7 @@ func (h *Handlers) renderRepoTree(w http.ResponseWriter, r *http.Request, cc *co | ||
| 219 | 251 | "Head": head, |
| 220 | 252 | "HeadFound": headFound, |
| 221 | 253 | "HeadAuthor": headAuthor, |
| 254 | + "BranchCompare": codeBranchCompareData(r.Context(), cc), | |
| 222 | 255 | "CommitCount": commitCount, |
| 223 | 256 | "README": template.HTML(readme.HTML), //nolint:gosec // sanitized by mdrender |
| 224 | 257 | "READMEPath": readme.Path, |
internal/web/static/css/shithub.cssmodified@@ -7895,6 +7895,65 @@ button.shithub-repo-action { | ||
| 7895 | 7895 | margin: 0; |
| 7896 | 7896 | color: var(--fg-muted); |
| 7897 | 7897 | } |
| 7898 | +.shithub-branch-push-banner, | |
| 7899 | +.shithub-branch-compare-bar { | |
| 7900 | + display: flex; | |
| 7901 | + align-items: center; | |
| 7902 | + justify-content: space-between; | |
| 7903 | + gap: 1rem; | |
| 7904 | + margin-bottom: 0.75rem; | |
| 7905 | + padding: 0.75rem 1rem; | |
| 7906 | + border: 1px solid var(--border-default); | |
| 7907 | + border-radius: 6px; | |
| 7908 | +} | |
| 7909 | +.shithub-branch-push-banner { | |
| 7910 | + border-color: rgba(187, 128, 9, 0.45); | |
| 7911 | + background: rgba(187, 128, 9, 0.12); | |
| 7912 | +} | |
| 7913 | +.shithub-branch-push-banner > div, | |
| 7914 | +.shithub-branch-compare-bar > div { | |
| 7915 | + display: flex; | |
| 7916 | + align-items: center; | |
| 7917 | + gap: 0.4rem; | |
| 7918 | + min-width: 0; | |
| 7919 | + flex-wrap: wrap; | |
| 7920 | +} | |
| 7921 | +.shithub-branch-compare-bar { | |
| 7922 | + background: var(--canvas-subtle); | |
| 7923 | +} | |
| 7924 | +.shithub-contribute-menu { | |
| 7925 | + position: relative; | |
| 7926 | + flex: 0 0 auto; | |
| 7927 | +} | |
| 7928 | +.shithub-contribute-menu > summary { | |
| 7929 | + list-style: none; | |
| 7930 | +} | |
| 7931 | +.shithub-contribute-menu > summary::-webkit-details-marker { | |
| 7932 | + display: none; | |
| 7933 | +} | |
| 7934 | +.shithub-contribute-menu-panel { | |
| 7935 | + position: absolute; | |
| 7936 | + z-index: 60; | |
| 7937 | + right: 0; | |
| 7938 | + top: calc(100% + 0.25rem); | |
| 7939 | + width: min(26rem, calc(100vw - 2rem)); | |
| 7940 | + padding: 1rem; | |
| 7941 | + color: var(--fg-default); | |
| 7942 | + background: var(--canvas-overlay, var(--canvas-default)); | |
| 7943 | + border: 1px solid var(--border-default); | |
| 7944 | + border-radius: 8px; | |
| 7945 | + box-shadow: var(--shadow-large, 0 16px 32px rgba(1, 4, 9, 0.35)); | |
| 7946 | +} | |
| 7947 | +.shithub-contribute-menu-panel p { | |
| 7948 | + margin: 0.25rem 0 0; | |
| 7949 | + color: var(--fg-muted); | |
| 7950 | +} | |
| 7951 | +.shithub-contribute-actions { | |
| 7952 | + display: flex; | |
| 7953 | + justify-content: flex-end; | |
| 7954 | + gap: 0.5rem; | |
| 7955 | + margin-top: 1rem; | |
| 7956 | +} | |
| 7898 | 7957 | .shithub-range-editor { |
| 7899 | 7958 | display: flex; |
| 7900 | 7959 | align-items: center; |
@@ -8284,6 +8343,17 @@ button.shithub-repo-action { | ||
| 8284 | 8343 | .shithub-pull-new-sidebar { |
| 8285 | 8344 | order: 2; |
| 8286 | 8345 | } |
| 8346 | + .shithub-branch-push-banner, | |
| 8347 | + .shithub-branch-compare-bar { | |
| 8348 | + align-items: stretch; | |
| 8349 | + flex-direction: column; | |
| 8350 | + } | |
| 8351 | + .shithub-contribute-menu, | |
| 8352 | + .shithub-contribute-menu > summary, | |
| 8353 | + .shithub-branch-push-banner .shithub-button { | |
| 8354 | + width: 100%; | |
| 8355 | + justify-content: center; | |
| 8356 | + } | |
| 8287 | 8357 | } |
| 8288 | 8358 | .shithub-settings-branches form label { display: block; margin: 0.5rem 0; } |
| 8289 | 8359 | .shithub-settings-branches form input[type=text], |
internal/web/templates/repo/tree.htmlmodified@@ -67,6 +67,44 @@ | ||
| 67 | 67 | </div> |
| 68 | 68 | </header> |
| 69 | 69 | |
| 70 | + {{ if .BranchCompare.Show }} | |
| 71 | + {{ if and .BranchCompare.HasRecentPush .HeadFound }} | |
| 72 | + <div class="shithub-branch-push-banner"> | |
| 73 | + <div> | |
| 74 | + {{ octicon "git-pull-request" }} | |
| 75 | + <strong>{{ .BranchCompare.Head }}</strong> had recent pushes <time datetime="{{ .Head.AuthorWhen.Format "2006-01-02T15:04:05Z" }}">{{ relativeTime .Head.AuthorWhen }}</time> | |
| 76 | + </div> | |
| 77 | + <a href="{{ .BranchCompare.PullNewHref }}" class="shithub-button shithub-button-primary">Compare & pull request</a> | |
| 78 | + </div> | |
| 79 | + {{ end }} | |
| 80 | + <div class="shithub-branch-compare-bar"> | |
| 81 | + <div> | |
| 82 | + This branch is | |
| 83 | + <a href="{{ .BranchCompare.CompareHref }}">{{ .BranchCompare.Ahead }} {{ pluralize .BranchCompare.Ahead "commit" "commits" }} ahead</a> | |
| 84 | + of and | |
| 85 | + <a href="{{ .BranchCompare.CompareHref }}">{{ .BranchCompare.Behind }} {{ pluralize .BranchCompare.Behind "commit" "commits" }} behind</a> | |
| 86 | + <code>{{ .BranchCompare.Base }}</code>. | |
| 87 | + </div> | |
| 88 | + <details class="shithub-contribute-menu"> | |
| 89 | + <summary class="shithub-button">{{ octicon "git-pull-request" }} Contribute {{ octicon "triangle-down" }}</summary> | |
| 90 | + <div class="shithub-contribute-menu-panel"> | |
| 91 | + <div> | |
| 92 | + <strong>This branch is {{ .BranchCompare.Ahead }} {{ pluralize .BranchCompare.Ahead "commit" "commits" }} ahead of <code>{{ .BranchCompare.Base }}</code>.</strong> | |
| 93 | + <p>Open a pull request to contribute your changes upstream.</p> | |
| 94 | + </div> | |
| 95 | + <div class="shithub-contribute-actions"> | |
| 96 | + <a href="{{ .BranchCompare.CompareHref }}" class="shithub-button">Compare</a> | |
| 97 | + {{ if gt .BranchCompare.Ahead 0 }} | |
| 98 | + <a href="{{ .BranchCompare.PullNewHref }}" class="shithub-button shithub-button-primary">Open pull request</a> | |
| 99 | + {{ else }} | |
| 100 | + <button type="button" class="shithub-button shithub-button-primary" disabled>Open pull request</button> | |
| 101 | + {{ end }} | |
| 102 | + </div> | |
| 103 | + </div> | |
| 104 | + </details> | |
| 105 | + </div> | |
| 106 | + {{ end }} | |
| 107 | + | |
| 70 | 108 | {{ if .Path }} |
| 71 | 109 | <nav class="shithub-code-crumbs" aria-label="Breadcrumb"> |
| 72 | 110 | {{ range $i, $c := .Crumbs }} |