tenseleyflow/shithub / 6cb4002

Browse files

S19: wire diff renderer into commit page; unified/split + hide-WS toggles

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
6cb40023e672ef53cd98c98154e6f2b8f4df977d
Parents
4b0cbf3
Tree
01aee09

3 changed files

StatusFile+-
M internal/web/handlers/repo/history.go 35 8
M internal/web/static/css/shithub.css 67 0
M internal/web/templates/repo/commit.html 14 2
internal/web/handlers/repo/history.gomodified
@@ -14,6 +14,9 @@ import (
1414
 	"github.com/go-chi/chi/v5"
1515
 
1616
 	"github.com/tenseleyFlow/shithub/internal/auth/policy"
17
+	diffparse "github.com/tenseleyFlow/shithub/internal/repos/diff/parse"
18
+	diffrender "github.com/tenseleyFlow/shithub/internal/repos/diff/render"
19
+	diffsource "github.com/tenseleyFlow/shithub/internal/repos/diff/source"
1720
 	"github.com/tenseleyFlow/shithub/internal/repos/git"
1821
 	repogit "github.com/tenseleyFlow/shithub/internal/repos/git"
1922
 	"github.com/tenseleyFlow/shithub/internal/repos/identity"
@@ -159,6 +162,27 @@ func (h *Handlers) commitView(w http.ResponseWriter, r *http.Request) {
159162
 	author := resolver.Resolve(r.Context(), detail.AuthorEmail)
160163
 	committer := resolver.Resolve(r.Context(), detail.CommitterEmail)
161164
 
165
+	// S19 diff render: source the patch from the SHA and inline-render.
166
+	mode := diffrender.ModeUnified
167
+	if r.URL.Query().Get("diff") == "split" {
168
+		mode = diffrender.ModeSplit
169
+	}
170
+	hideWS := r.URL.Query().Get("w") == "1"
171
+	patch, perr := diffsource.FromCommit(r.Context(), gitDir, detail.OID, diffsource.Options{
172
+		IgnoreWhitespace: hideWS, FindRenames: true,
173
+	})
174
+	var diffHTML template.HTML
175
+	if perr != nil {
176
+		h.d.Logger.WarnContext(r.Context(), "commit: diff source", "error", perr)
177
+	} else {
178
+		parsed, perr2 := diffparse.ParseBytes(patch)
179
+		if perr2 != nil {
180
+			h.d.Logger.WarnContext(r.Context(), "commit: diff parse", "error", perr2)
181
+		} else {
182
+			diffHTML = template.HTML(diffrender.Diff(parsed, diffrender.Options{Mode: mode})) //nolint:gosec // escapes inside
183
+		}
184
+	}
185
+
162186
 	h.d.Render.RenderPage(w, r, "repo/commit", map[string]any{
163187
 		"Title":      detail.Subject + " · " + row.Name,
164188
 		"CSRFToken":  middleware.CSRFTokenForRequest(r),
@@ -168,6 +192,9 @@ func (h *Handlers) commitView(w http.ResponseWriter, r *http.Request) {
168192
 		"Author":     author,
169193
 		"Committer":  committer,
170194
 		"BodyHTML":   template.HTML(linkifyCommitBody(detail.Body)), //nolint:gosec // escaped inside
195
+		"DiffHTML":   diffHTML,
196
+		"DiffMode":   string(mode),
197
+		"HideWS":     hideWS,
171198
 	})
172199
 }
173200
 
internal/web/static/css/shithub.cssmodified
@@ -1087,3 +1087,70 @@ code {
10871087
   text-align: center;
10881088
   color: var(--fg-muted);
10891089
 }
1090
+
1091
+/* ========== Diff renderer (S19) ========== */
1092
+.shithub-commit-files-head {
1093
+  display: flex;
1094
+  align-items: center;
1095
+  justify-content: space-between;
1096
+  margin-bottom: 0.5rem;
1097
+}
1098
+.shithub-diff-toggles { display: flex; gap: 0.25rem; }
1099
+.shithub-diff-body { margin-top: 1rem; }
1100
+.shithub-diff-file {
1101
+  margin-top: 1rem;
1102
+  border: 1px solid var(--border-default);
1103
+  border-radius: 6px;
1104
+  overflow: hidden;
1105
+}
1106
+.shithub-diff-file-head {
1107
+  display: flex;
1108
+  align-items: center;
1109
+  justify-content: space-between;
1110
+  gap: 0.75rem;
1111
+  padding: 0.5rem 0.75rem;
1112
+  background: var(--canvas-subtle);
1113
+  border-bottom: 1px solid var(--border-default);
1114
+  font-size: 0.875rem;
1115
+}
1116
+.shithub-diff-file-action { color: var(--fg-muted); font-style: italic; }
1117
+.shithub-diff-binary, .shithub-diff-image, .shithub-diff-empty, .shithub-diff-truncated {
1118
+  padding: 1rem;
1119
+  text-align: center;
1120
+  color: var(--fg-muted);
1121
+}
1122
+.shithub-diff-file-toolarge { padding: 0.5rem 0.75rem; }
1123
+.shithub-diff-file-toolarge > summary { cursor: pointer; color: var(--fg-muted); }
1124
+.shithub-diff-table {
1125
+  width: 100%;
1126
+  border-collapse: collapse;
1127
+  font-family: monospace;
1128
+  font-size: 0.85rem;
1129
+  table-layout: fixed;
1130
+}
1131
+.shithub-diff-table td { padding: 0 0.5rem; vertical-align: top; }
1132
+.shithub-diff-table pre { margin: 0; white-space: pre; }
1133
+.shithub-diff-lineno {
1134
+  width: 50px;
1135
+  text-align: right;
1136
+  color: var(--fg-muted);
1137
+  user-select: none;
1138
+  background: var(--canvas-subtle);
1139
+}
1140
+.shithub-diff-content { width: auto; }
1141
+.shithub-diff-add { background: rgba(46, 160, 67, 0.10); }
1142
+.shithub-diff-del { background: rgba(248, 81, 73, 0.10); }
1143
+.shithub-diff-add .shithub-diff-content { background: rgba(46, 160, 67, 0.05); }
1144
+.shithub-diff-del .shithub-diff-content { background: rgba(248, 81, 73, 0.05); }
1145
+.shithub-diff-pad { background: var(--canvas-subtle); }
1146
+.shithub-diff-hunk-head td {
1147
+  padding: 0.4rem 0.75rem;
1148
+  background: var(--canvas-default);
1149
+  border-top: 1px solid var(--border-default);
1150
+  border-bottom: 1px solid var(--border-default);
1151
+  color: var(--fg-muted);
1152
+}
1153
+.shithub-diff-split td.shithub-diff-content {
1154
+  width: 50%;
1155
+  border-left: 1px solid var(--border-default);
1156
+}
internal/web/templates/repo/commit.htmlmodified
@@ -53,7 +53,14 @@
5353
   </article>
5454
 
5555
   <section class="shithub-commit-files">
56
+    <header class="shithub-commit-files-head">
5657
       <h3>{{ len .Detail.Files }} changed file{{ if ne (len .Detail.Files) 1 }}s{{ end }}</h3>
58
+      <nav class="shithub-diff-toggles" aria-label="Diff options">
59
+        <a href="?diff=unified{{ if .HideWS }}&amp;w=1{{ end }}" class="shithub-button {{ if eq .DiffMode "unified" }}shithub-button-primary{{ end }}">Unified</a>
60
+        <a href="?diff=split{{ if .HideWS }}&amp;w=1{{ end }}" class="shithub-button {{ if eq .DiffMode "split" }}shithub-button-primary{{ end }}">Split</a>
61
+        <a href="?diff={{ .DiffMode }}{{ if not .HideWS }}&amp;w=1{{ end }}" class="shithub-button {{ if .HideWS }}shithub-button-primary{{ end }}">Hide whitespace</a>
62
+      </nav>
63
+    </header>
5764
     <table class="shithub-commit-files-table">
5865
       <thead>
5966
         <tr><th>Status</th><th>File</th><th class="shithub-num-col">+</th><th class="shithub-num-col">-</th></tr>
@@ -72,7 +79,12 @@
7279
         {{ end }}
7380
       </tbody>
7481
     </table>
75
-    <p class="shithub-hint">Per-file diff bodies render once S19 ships.</p>
7682
   </section>
83
+
84
+  {{ if .DiffHTML }}
85
+  <section class="shithub-diff-body" aria-label="Per-file diff">
86
+    {{ .DiffHTML }}
87
+  </section>
88
+  {{ end }}
7789
 </section>
7890
 {{- end }}