~gitpocket/gitpocket

1

feat(repos): show language, stars and forks

commit
8bc1fe990fa09de6eda26b429363b7db9d2d62e2 browse tree
parent
7988a6d0db6160c936507d9a6571a1f34feb4c47
author
obscurejames <354576047+obscurejames@users.noreply.github.com>
signature
Verified ~james signed with a key registered by ~james
date
2026-10-28 22:27 UTC

7 files changed, +18 −7

static/style.css modified

@@ -265,7 +265,10 @@ table.blame td.n{border-right:1px solid var(--bar)}
265265 .event h4{display:flex;align-items:baseline;flex-wrap:wrap}
266266 .event h4 .muted{margin-left:.4rem}
267267 .event h4 .tag{margin-left:.4rem}
268-.event h4 .starcount{margin-left:auto;color:var(--muted);font-size:.85rem;font-weight:400}
268+.event p.repometa{display:flex;gap:1.1rem;color:var(--muted);font-size:.85rem;margin:.3rem 0 0}
269+.repometa span{display:inline-flex;align-items:center}
270+.repometa .dot{width:10px;height:10px;border-radius:50%;margin-right:.35rem;border:1px solid rgba(0,0,0,.12)}
271+.repometa svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.3;margin-right:.25rem}
269272 .label{display:inline-block;color:#fff;font-size:.75rem;padding:0 .45rem;border-radius:.6rem;vertical-align:middle;line-height:1.4;font-weight:500;text-shadow:0 0 2px rgba(0,0,0,.3);margin-left:.35rem}
270273 .labelbar .label,.metaform .label,table .label{margin-left:0}
271274 a.label{opacity:.75}a.label.on,a.label:hover{opacity:1;text-decoration:none}

store.go modified

@@ -210,6 +210,7 @@ type Repo struct {
210210 Parent int64
211211 Archived bool
212212 Stars int
213+ Forks int
213214 Created time.Time
214215 Updated time.Time
215216 }
@@ -561,7 +562,7 @@ func scanRepos(rows *sql.Rows) ([]Repo, error) {
561562 var private, archived int
562563 var tags string
563564 var created, ucreated int64
564- if err := rows.Scan(&r.ID, &r.Name, &r.Description, &private, &tags, &r.Parent, &archived, &r.Stars, &created, &r.Owner.ID, &r.Owner.Name, &ucreated); err != nil {
565+ if err := rows.Scan(&r.ID, &r.Name, &r.Description, &private, &tags, &r.Parent, &archived, &r.Stars, &r.Forks, &created, &r.Owner.ID, &r.Owner.Name, &ucreated); err != nil {
565566 return nil, err
566567 }
567568 r.Archived = archived != 0
@@ -575,7 +576,7 @@ func scanRepos(rows *sql.Rows) ([]Repo, error) {
575576 return repos, rows.Err()
576577 }
577578
578-const repoColumns = `r.id, r.name, r.description, r.private, r.tags, r.parent, r.archived, (select count(*) from stars st where st.repo = r.id), r.created, u.id, u.name, u.created from repos r join users u on u.id = r.owner`
579+const repoColumns = `r.id, r.name, r.description, r.private, r.tags, r.parent, r.archived, (select count(*) from stars st where st.repo = r.id), (select count(*) from repos f where f.parent = r.id), r.created, u.id, u.name, u.created from repos r join users u on u.id = r.owner`
579580
580581 func (s *Store) Backup(path string) error {
581582 _, err := s.db.Exec(`vacuum into ?`, path)

templates/index.html modified

@@ -18,5 +18,5 @@
1818 </div>{{end}}
1919 {{end}}
2020 {{define "repolist"}}
21-{{if .}}<div class="events">{{range .}}<div class="event"><h4><a href="/{{.Path}}">{{.Path}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}{{if .Stars}}<span class="starcount" title="{{.Stars}} stars">☆ {{.Stars}}</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}</div>{{end}}</div>{{else}}<p class="muted">Nothing here yet.</p>{{end}}
21+{{if .}}<div class="events">{{range .}}<div class="event"><h4><a href="/{{.Path}}">{{.Path}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}{{template "repometa" .}}</div>{{end}}</div>{{else}}<p class="muted">Nothing here yet.</p>{{end}}
2222 {{end}}

templates/meta.html modified

@@ -9,4 +9,5 @@
99 </div>
1010 {{end}}
1111 {{define "who"}}{{with person .Email}}<a href="/~{{.}}">{{$.Author}}</a>{{else}}{{.Author}}{{end}}{{end}}
12-{{define "repoitem"}}<div class="event"><h4><a href="/{{.Path}}">{{.Name}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}{{if .Stars}}<span class="starcount" title="{{.Stars}} stars">☆ {{.Stars}}</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}</div>{{end}}
12+{{define "repoitem"}}<div class="event"><h4><a href="/{{.Path}}">{{.Name}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}{{template "repometa" .}}</div>{{end}}
13+{{define "repometa"}}{{$l := lang .}}<p class="repometa">{{with $l.Name}}<span><i class="dot" style="background:{{$l.Colour}}"></i>{{.}}</span>{{end}}<span title="{{.Stars}} star{{if ne .Stars 1}}s{{end}}"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="M8 1.6l1.9 4 4.4.5-3.3 3 .9 4.3L8 11.2 4.1 13.4l.9-4.3-3.3-3 4.4-.5z"/></svg>{{.Stars}}</span>{{if .Forks}}<span title="{{.Forks}} fork{{if ne .Forks 1}}s{{end}}"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="4" cy="3" r="1.6"/><circle cx="12" cy="3" r="1.6"/><circle cx="8" cy="13" r="1.6"/><path d="M4 4.6v1.4a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V4.6M8 8v3.4"/></svg>{{.Forks}}</span>{{end}}</p>{{end}}

templates/repos.html modified

@@ -5,5 +5,5 @@
55 <nav class="tabs small"><a href="/~{{$d.Owner.Name}}">about</a><a class="active" href="/~{{$d.Owner.Name}}/repos">repos{{if $d.Repos}} <span class="count">{{len $d.Repos}}</span>{{end}}</a>{{if not $d.Org}}<a href="/~{{$d.Owner.Name}}/stars">stars{{if $d.Count}} <span class="count">{{$d.Count}}</span>{{end}}</a>{{end}}<a href="/~{{$d.Owner.Name}}/feed">feed</a></nav>
66 {{if $d.Member}}<a class="btn primary newrepo" href="/create{{if $d.Org}}?owner={{$d.Owner.Name}}{{end}}">New repository</a>{{end}}
77 </div>
8-{{if $d.Repos}}<div class="events">{{range $d.Repos}}<div class="event"><h4><a href="/{{.Path}}">{{.Name}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}{{if .Stars}}<span class="starcount" title="{{.Stars}} stars">☆ {{.Stars}}</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}</div>{{end}}</div>{{else}}<p class="info">No repos yet.</p>{{end}}
8+{{if $d.Repos}}<div class="events">{{range $d.Repos}}<div class="event"><h4><a href="/{{.Path}}">{{.Name}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}{{template "repometa" .}}</div>{{end}}</div>{{else}}<p class="info">No repos yet.</p>{{end}}
99 {{end}}

templates/stars.html modified

@@ -3,5 +3,5 @@
33 <h2>~{{.Data.Owner.Name}}</h2>
44 <nav class="tabs small"><a href="/~{{.Data.Owner.Name}}">about</a><a href="/~{{.Data.Owner.Name}}/repos">repos</a><a class="active" href="/~{{.Data.Owner.Name}}/stars">stars{{if .Data.Count}} <span class="count">{{.Data.Count}}</span>{{end}}</a></nav>
55 </div>
6-{{if .Data.Starred}}<div class="events">{{range .Data.Starred}}<div class="event"><h4><a href="/~{{.Owner.Name}}">~{{.Owner.Name}}</a>/<a href="/{{.Path}}">{{.Name}}</a>{{if .Stars}}<span class="starcount" title="{{.Stars}} stars">☆ {{.Stars}}</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}</div>{{end}}</div>{{else}}<p class="info">~{{.Data.Owner.Name}} has not starred anything yet.</p>{{end}}
6+{{if .Data.Starred}}<div class="events">{{range .Data.Starred}}<div class="event"><h4><a href="/~{{.Owner.Name}}">~{{.Owner.Name}}</a>/<a href="/{{.Path}}">{{.Name}}</a></h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}{{template "repometa" .}}</div>{{end}}</div>{{else}}<p class="info">~{{.Data.Owner.Name}} has not starred anything yet.</p>{{end}}
77 {{end}}

web.go modified

@@ -92,6 +92,12 @@ func newServer(store *Store, root, host, name string, sshUser string) *Server {
9292 "inc": func(i int) int { return i + 1 },
9393 "perm": perm,
9494 "signer": s.signer,
95+ "lang": func(r Repo) language {
96+ if l := s.repoLanguages(r); len(l) > 0 {
97+ return l[0]
98+ }
99+ return language{}
100+ },
95101 "bare": func(u string) string {
96102 return strings.TrimSuffix(strings.TrimPrefix(strings.TrimPrefix(u, "https://"), "http://"), "/")
97103 },