tenseleyflow/shithub / a32da09

Browse files

Reshape pull commits tab

Authored by espadonne
SHA
a32da09e768c8dbc456d23423692eb7a338b59d3
Parents
04b0fef
Tree
91a802c

3 changed files

StatusFile+-
M internal/web/handlers/repo/pulls.go 65 1
M internal/web/static/css/shithub.css 101 4
M internal/web/templates/repo/pull_view.html 36 9
internal/web/handlers/repo/pulls.gomodified
@@ -11,6 +11,7 @@ import (
1111
 	"sort"
1212
 	"strconv"
1313
 	"strings"
14
+	"time"
1415
 
1516
 	"github.com/go-chi/chi/v5"
1617
 	"github.com/jackc/pgx/v5"
@@ -23,6 +24,7 @@ import (
2324
 	"github.com/tenseleyFlow/shithub/internal/pulls"
2425
 	pullsdb "github.com/tenseleyFlow/shithub/internal/pulls/sqlc"
2526
 	repogit "github.com/tenseleyFlow/shithub/internal/repos/git"
27
+	"github.com/tenseleyFlow/shithub/internal/repos/identity"
2628
 	reposdb "github.com/tenseleyFlow/shithub/internal/repos/sqlc"
2729
 	"github.com/tenseleyFlow/shithub/internal/social"
2830
 	"github.com/tenseleyFlow/shithub/internal/web/middleware"
@@ -58,6 +60,20 @@ type pullFileView struct {
5860
 	Name   string
5961
 }
6062
 
63
+type pullCommitView struct {
64
+	C           pullsdb.PullRequestCommit
65
+	Author      identity.Resolved
66
+	ShortSHA    string
67
+	When        time.Time
68
+	HasWhen     bool
69
+	AuthorLabel string
70
+}
71
+
72
+type pullCommitGroup struct {
73
+	Title   string
74
+	Commits []pullCommitView
75
+}
76
+
6177
 // MountPulls registers /{owner}/{repo}/pulls* routes. Reads are
6278
 // public (subject to policy.Can(ActionPullRead)); writes require auth.
6379
 // The merge route runs synchronously inside the request: pulls.Merge
@@ -538,11 +554,59 @@ func (h *Handlers) pullCommits(w http.ResponseWriter, r *http.Request) {
538554
 		return
539555
 	}
540556
 	commits, _ := pullsdb.New().ListPullRequestCommits(r.Context(), h.d.Pool, pr.IID)
557
+	commitGroups := pullCommitGroups(r.Context(), commits, identity.New(h.d.Pool))
541558
 	h.renderPullPage(w, r, "commits", map[string]any{
542
-		"Commits": commits,
559
+		"CommitGroups": commitGroups,
543560
 	})
544561
 }
545562
 
563
+func pullCommitGroups(ctx context.Context, commits []pullsdb.PullRequestCommit, resolver *identity.Resolver) []pullCommitGroup {
564
+	groups := make([]pullCommitGroup, 0, 2)
565
+	for _, commit := range commits {
566
+		when, hasWhen := pullCommitWhen(commit)
567
+		title := "Commits"
568
+		if hasWhen {
569
+			title = "Commits on " + when.Format("January 2, 2006")
570
+		}
571
+		if len(groups) == 0 || groups[len(groups)-1].Title != title {
572
+			groups = append(groups, pullCommitGroup{Title: title})
573
+		}
574
+		author := identity.Resolved{}
575
+		if resolver != nil {
576
+			author = resolver.Resolve(ctx, commit.AuthorEmail)
577
+		}
578
+		authorLabel := commit.AuthorName
579
+		if author.User && author.DisplayName != "" {
580
+			authorLabel = author.DisplayName
581
+		} else if author.User {
582
+			authorLabel = author.Username
583
+		}
584
+		shortSHA := commit.Sha
585
+		if len(shortSHA) > 7 {
586
+			shortSHA = shortSHA[:7]
587
+		}
588
+		groups[len(groups)-1].Commits = append(groups[len(groups)-1].Commits, pullCommitView{
589
+			C:           commit,
590
+			Author:      author,
591
+			ShortSHA:    shortSHA,
592
+			When:        when,
593
+			HasWhen:     hasWhen,
594
+			AuthorLabel: authorLabel,
595
+		})
596
+	}
597
+	return groups
598
+}
599
+
600
+func pullCommitWhen(commit pullsdb.PullRequestCommit) (time.Time, bool) {
601
+	if commit.CommittedAt.Valid {
602
+		return commit.CommittedAt.Time, true
603
+	}
604
+	if commit.AuthoredAt.Valid {
605
+		return commit.AuthoredAt.Time, true
606
+	}
607
+	return time.Time{}, false
608
+}
609
+
546610
 // pullFiles renders the Files Changed tab. Uses the existing diff
547611
 // renderer fed from base..head (three-dot via FromMergeBase).
548612
 func (h *Handlers) pullFiles(w http.ResponseWriter, r *http.Request) {
internal/web/static/css/shithub.cssmodified
@@ -3095,10 +3095,107 @@ button.shithub-repo-action {
30953095
 .shithub-pull-refs { display: flex; gap: 0.4rem; align-items: flex-end; }
30963096
 .shithub-pull-refs label { flex: 1; }
30973097
 .shithub-pull-arrow { font-size: 1.4rem; padding: 0 0.4rem; align-self: center; }
3098
-.shithub-pull-commits { list-style: none; padding: 0; }
3099
-.shithub-pull-commits li {
3100
-  padding: 0.4rem 0; border-bottom: 1px solid var(--border-default);
3101
-  display: flex; gap: 0.6rem; align-items: baseline;
3098
+.shithub-sr-only {
3099
+  position: absolute;
3100
+  width: 1px;
3101
+  height: 1px;
3102
+  padding: 0;
3103
+  margin: -1px;
3104
+  overflow: hidden;
3105
+  clip: rect(0, 0, 0, 0);
3106
+  white-space: nowrap;
3107
+  border: 0;
3108
+}
3109
+.shithub-pull-commits {
3110
+  display: flex;
3111
+  flex-direction: column;
3112
+  gap: 1rem;
3113
+  max-width: 56rem;
3114
+  margin-top: 1rem;
3115
+}
3116
+.shithub-pull-commit-group {
3117
+  display: grid;
3118
+  grid-template-columns: 2rem minmax(0, 1fr);
3119
+  gap: 0.75rem;
3120
+  position: relative;
3121
+}
3122
+.shithub-pull-commit-group::before {
3123
+  content: "";
3124
+  position: absolute;
3125
+  top: 2rem;
3126
+  bottom: -1rem;
3127
+  left: 1rem;
3128
+  width: 1px;
3129
+  background: var(--border-default);
3130
+}
3131
+.shithub-pull-commit-group:last-child::before { display: none; }
3132
+.shithub-pull-commit-badge {
3133
+  position: relative;
3134
+  z-index: 1;
3135
+  display: inline-flex;
3136
+  align-items: center;
3137
+  justify-content: center;
3138
+  width: 2rem;
3139
+  height: 2rem;
3140
+  border: 1px solid var(--border-default);
3141
+  border-radius: 50%;
3142
+  color: var(--fg-muted);
3143
+  background: var(--canvas-default);
3144
+}
3145
+.shithub-pull-commit-group-body { min-width: 0; }
3146
+.shithub-pull-commit-group h3 {
3147
+  margin: 0.3rem 0 0.65rem;
3148
+  font-size: 0.95rem;
3149
+  font-weight: 400;
3150
+}
3151
+.shithub-pull-commit-panel {
3152
+  list-style: none;
3153
+  padding: 0;
3154
+  margin: 0;
3155
+  border: 1px solid var(--border-default);
3156
+  border-radius: 6px;
3157
+  background: var(--canvas-default);
3158
+}
3159
+.shithub-pull-commit-row {
3160
+  display: grid;
3161
+  grid-template-columns: minmax(0, 1fr) auto;
3162
+  gap: 1rem;
3163
+  align-items: center;
3164
+  padding: 0.75rem;
3165
+  border-bottom: 1px solid var(--border-default);
3166
+}
3167
+.shithub-pull-commit-row:last-child { border-bottom: 0; }
3168
+.shithub-pull-commit-main { min-width: 0; }
3169
+.shithub-pull-commit-title {
3170
+  display: block;
3171
+  overflow: hidden;
3172
+  color: var(--fg-default);
3173
+  font-weight: 600;
3174
+  text-overflow: ellipsis;
3175
+  white-space: nowrap;
3176
+}
3177
+.shithub-pull-commit-meta {
3178
+  display: flex;
3179
+  align-items: center;
3180
+  flex-wrap: wrap;
3181
+  gap: 0.25rem;
3182
+  margin-top: 0.3rem;
3183
+  color: var(--fg-muted);
3184
+  font-size: 0.84rem;
3185
+}
3186
+.shithub-pull-commit-meta .shithub-avatar-sm { width: 16px; height: 16px; margin-right: 0.15rem; }
3187
+.shithub-pull-commit-actions {
3188
+  display: flex;
3189
+  align-items: center;
3190
+  gap: 0.25rem;
3191
+}
3192
+.shithub-pull-commit-sha {
3193
+  font-family: var(--mono, monospace);
3194
+  color: var(--fg-muted);
3195
+}
3196
+@media (max-width: 640px) {
3197
+  .shithub-pull-commit-row { grid-template-columns: 1fr; }
3198
+  .shithub-pull-commit-actions { justify-content: flex-start; }
31023199
 }
31033200
 
31043201
 /* ========== PR Reviews (S23) ========== */
internal/web/templates/repo/pull_view.htmlmodified
@@ -468,17 +468,44 @@
468468
         </aside>
469469
       </div>
470470
     {{ else if eq .Tab "commits" }}
471
-      <ul class="shithub-pull-commits">
472
-        {{ range .Commits }}
473
-        <li>
474
-          <a href="/{{ $.Owner }}/{{ $.Repo.Name }}/commit/{{ .Sha }}"><code>{{ slice .Sha 0 7 }}</code></a>
475
-          {{ .Subject }}
476
-          <small>by {{ .AuthorName }}</small>
477
-        </li>
471
+      <section class="shithub-pull-commits" aria-labelledby="pull-commits-heading">
472
+        <h2 id="pull-commits-heading" class="shithub-sr-only">Commits</h2>
473
+        {{ range .CommitGroups }}
474
+        <div class="shithub-pull-commit-group">
475
+          <span class="shithub-pull-commit-badge">{{ octicon "git-commit" }}</span>
476
+          <div class="shithub-pull-commit-group-body">
477
+            <h3>{{ .Title }}</h3>
478
+            <ul class="shithub-pull-commit-panel">
479
+              {{ range .Commits }}
480
+              <li class="shithub-pull-commit-row">
481
+                <div class="shithub-pull-commit-main">
482
+                  <a class="shithub-pull-commit-title" href="/{{ $.Owner }}/{{ $.Repo.Name }}/pulls/{{ $.PR.INumber }}/commits/{{ .C.Sha }}">{{ .C.Subject }}</a>
483
+                  <div class="shithub-pull-commit-meta">
484
+                    {{ if .Author.User }}
485
+                      <a href="/{{ .Author.Username }}"><img src="{{ .Author.AvatarURL }}" alt="" class="shithub-avatar-sm"></a>
486
+                      <a href="/{{ .Author.Username }}">{{ .AuthorLabel }}</a>
487
+                    {{ else }}
488
+                      <span class="shithub-avatar-sm shithub-identicon" data-seed="{{ .Author.IdenticonSeed }}" aria-hidden="true"></span>
489
+                      <span>{{ .AuthorLabel }}</span>
490
+                    {{ end }}
491
+                    <span>committed</span>
492
+                    {{ if .HasWhen }}<time datetime="{{ .When.Format "2006-01-02T15:04:05Z" }}">{{ relativeTime .When }}</time>{{ end }}
493
+                  </div>
494
+                </div>
495
+                <div class="shithub-pull-commit-actions">
496
+                  <a class="shithub-button shithub-button-compact shithub-pull-commit-sha" href="/{{ $.Owner }}/{{ $.Repo.Name }}/commit/{{ .C.Sha }}">{{ .ShortSHA }}</a>
497
+                  <button type="button" class="shithub-icon-button" aria-label="Copy full SHA for {{ .ShortSHA }}">{{ octicon "copy" }}</button>
498
+                  <a class="shithub-icon-button" aria-label="Browse repository at {{ .ShortSHA }}" href="/{{ $.Owner }}/{{ $.Repo.Name }}/tree/{{ .C.Sha }}">{{ octicon "code" }}</a>
499
+                </div>
500
+              </li>
501
+              {{ end }}
502
+            </ul>
503
+          </div>
504
+        </div>
478505
         {{ else }}
479
-        <li class="shithub-muted">No commits.</li>
506
+        <p class="shithub-muted">No commits.</p>
480507
         {{ end }}
481
-      </ul>
508
+      </section>
482509
     {{ else if eq .Tab "files" }}
483510
       <section class="shithub-pull-files">
484511
         <div class="shithub-pull-files-toolbar">