feat(basin): git.sr.ht style summary and file views
5 files changed, +52 −35
- highlight.go modified +1 −1
- static/style.css modified +30 −13
- templates/layout.html modified +2 −3
- templates/repo.html modified +18 −17
- web.go modified +1 −1
highlight.go modified
| @@ -19,7 +19,7 @@ var formatter = html.New( | ||
| 19 | 19 | html.TabWidth(4), |
| 20 | 20 | ) |
| 21 | 21 | |
| 22 | -var highlightStyle = styles.Get("github") | |
| 22 | +var highlightStyle = styles.Get("pygments") | |
| 23 | 23 | |
| 24 | 24 | func highlight(name string, content []byte) (template.HTML, bool) { |
| 25 | 25 | if len(content) > 256<<10 { |
static/style.css modified
| @@ -35,21 +35,34 @@ nav.subtabs a,nav.tabs a{color:var(--muted);padding:.3rem .9rem} | ||
| 35 | 35 | nav.subtabs a.active{background:#e9ecef;color:var(--fg)} |
| 36 | 36 | nav.subtabs a:hover,nav.tabs a:hover{text-decoration:none;color:var(--fg)} |
| 37 | 37 | .repohead{margin-top:-1rem} |
| 38 | -.repohead h2{padding:.4rem 0 .3rem} | |
| 38 | +.repohead h2{padding:.4rem 0 .3rem;font-size:1.9rem} | |
| 39 | 39 | .tabbar{background:var(--bar)} |
| 40 | 40 | nav.tabs{display:flex} |
| 41 | 41 | nav.tabs a{padding:.25rem .9rem} |
| 42 | 42 | nav.tabs a.active{background:#fff;color:var(--fg)} |
| 43 | -.descbar{background:#e9ecef;margin-bottom:1rem} | |
| 44 | -.descbar+main,.repohead+main{margin-top:1rem} | |
| 43 | +.repohead .desc{margin:0 0 .4rem;color:var(--muted)} | |
| 44 | +.repohead+main{margin-top:1rem} | |
| 45 | +.repohead+main.file{margin-top:0;padding-top:1.3rem} | |
| 46 | +.summary{margin-top:.2rem;display:grid;grid-template-columns:4fr 1.5fr 2.6fr;gap:2rem;margin-bottom:1.5rem;align-items:start} | |
| 47 | +.summary .event{background:var(--soft);padding:.4rem .5rem .5rem;margin-bottom:.6rem} | |
| 48 | +.summary .event .row{display:flex;justify-content:space-between;gap:1rem} | |
| 49 | +.summary .event .when{font-size:.85rem;color:var(--link);text-decoration:underline} | |
| 50 | +.summary .event .hash{text-decoration:underline} | |
| 51 | +.summary .subject{margin:.3rem 0 0;background:none;border:0;padding:0;white-space:pre-wrap} | |
| 52 | +.summary h3{font-weight:400;font-size:1.25rem;margin:0 0 .5rem} | |
| 53 | +.summary .ref{margin-bottom:.6rem} | |
| 54 | +.summary .ref a,.summary .clone a{text-decoration:underline} | |
| 55 | +.summary .clone strong{display:block;margin-top:.4rem} | |
| 56 | +.summary .clone div{margin-bottom:.2rem;overflow-wrap:anywhere} | |
| 57 | +.readme{max-width:920px} | |
| 58 | +.readme>article>h1:first-child{margin-top:0} | |
| 59 | +@media(max-width:900px){.summary{grid-template-columns:1fr}} | |
| 45 | 60 | .descbar .inner{padding:.3rem 1rem} |
| 46 | 61 | .repohead+main{margin-top:0} |
| 47 | 62 | main{padding-bottom:3rem} |
| 48 | 63 | .welcome{max-width:50rem;margin:0 auto 1.5rem;padding:0 1rem} |
| 49 | 64 | .welcome p{margin:.3rem 0 0} |
| 50 | 65 | .cards{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem;margin-bottom:1.5rem} |
| 51 | -.cards.commits{grid-template-columns:repeat(3,1fr);gap:1rem} | |
| 52 | -.cards.commits .panel{margin:0} | |
| 53 | 66 | .panel{background:var(--soft);padding:.8rem 1rem;margin-bottom:1.5rem} |
| 54 | 67 | .panel.narrow{max-width:34rem;margin:1rem auto} |
| 55 | 68 | .panel .btn{margin-top:.6rem} |
| @@ -89,11 +102,12 @@ dl.meta dd{margin:0;overflow-wrap:anywhere} | ||
| 89 | 102 | .log .event{padding:.5rem 0;border-bottom:1px solid var(--line)} |
| 90 | 103 | .event .subject{color:var(--fg)} |
| 91 | 104 | .event pre.body{margin:.4rem 0 0} |
| 92 | -.filebar{display:flex;gap:1.2rem;align-items:baseline;border-bottom:1px solid var(--line);padding:0 0 .3rem;margin-bottom:.6rem;flex-wrap:wrap} | |
| 105 | +.filebar{display:flex;gap:1.2rem;align-items:baseline;border-bottom:1px solid var(--bar);padding:0 1rem .25rem;margin:-1rem -1rem .6rem;flex-wrap:wrap} | |
| 93 | 106 | .filebar .spacer{flex:1} |
| 94 | 107 | .filebar a.active{color:var(--fg);border-bottom:2px solid var(--fg);padding-bottom:.2rem} |
| 95 | 108 | .filebar a{color:var(--muted)} |
| 96 | -.filebar .crumbs a{color:var(--link)} | |
| 109 | +.filebar .crumbs a{color:var(--link);text-decoration:underline} | |
| 110 | +.filebar .mode{color:var(--muted);font-family:inherit;font-size:inherit} | |
| 97 | 111 | .filebar .lastcommit{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:40rem} |
| 98 | 112 | .readme img{max-width:100%} |
| 99 | 113 | .readme table{border-collapse:collapse} |
| @@ -112,17 +126,20 @@ table.tree .size{color:var(--muted);text-align:right} | ||
| 112 | 126 | table.tree .last{max-width:30rem;overflow:hidden;text-overflow:ellipsis;width:100%} |
| 113 | 127 | table.tree .when{text-align:right} |
| 114 | 128 | table.refs td,table.keys td{padding:.3rem 1rem .3rem 0;border-bottom:1px solid var(--line)} |
| 115 | -.code{border-left:1px solid var(--line)} | |
| 129 | +.code{margin:0 -1rem} | |
| 116 | 130 | table.blob,.code table{width:100%} |
| 117 | 131 | table.blob td,table.hunk td,.code td{padding:0 .5rem;white-space:pre;vertical-align:top} |
| 118 | 132 | td.n{text-align:right;color:var(--muted);user-select:none;width:1%} |
| 119 | -td.n a{color:var(--link)} | |
| 133 | +td.n a{color:var(--link);text-decoration:underline} | |
| 134 | +table.blob td.n{border-right:1px solid var(--bar);padding:0 .5rem 0 .6rem} | |
| 120 | 135 | td.l{white-space:pre-wrap;overflow-wrap:anywhere;width:100%} |
| 121 | 136 | tr:target td{background:#fff8c5} |
| 122 | -.code pre{background:none;border:0;padding:0;margin:0} | |
| 123 | -.code .lntd:first-child{width:1%;user-select:none;border-right:1px solid var(--line)} | |
| 124 | -.code .lnt,.code .ln{color:var(--link);margin-right:0;padding:0 .5rem 0 .3rem} | |
| 125 | -.code .lntd a{color:var(--link)} | |
| 137 | +.code pre,.code .chroma{background:#fff;border:0;padding:0;margin:0} | |
| 138 | +.code .lntable{margin-top:0} | |
| 139 | +.code .lntd:first-child{width:1%;user-select:none;border-right:1px solid var(--bar)} | |
| 140 | +.code .lnt,.code .ln{color:var(--link);margin-right:0;padding:0 .5rem 0 .6rem} | |
| 141 | +.code .lntd a{color:var(--link);text-decoration:underline} | |
| 142 | +.code .lntd:last-child{padding-left:.6rem} | |
| 126 | 143 | .code .line:target,.code .line:target .cl{background:#fff8c5} |
| 127 | 144 | table.hunk{width:100%;border:1px solid var(--line)} |
| 128 | 145 | .hunk .head td{color:var(--muted);background:var(--soft)} |
templates/layout.html modified
| @@ -29,16 +29,15 @@ | ||
| 29 | 29 | </header> |
| 30 | 30 | {{with .Data}}{{with index . "Page"}} |
| 31 | 31 | <div class="repohead"> |
| 32 | -<div class="inner"><h2><a href="/~{{.Repo.Owner.Name}}">~{{.Repo.Owner.Name}}</a>/{{.Repo.Name}}{{if .Repo.Private}} <span class="tag">private</span>{{end}}</h2></div> | |
| 32 | +<div class="inner"><h2><a href="/~{{.Repo.Owner.Name}}">~{{.Repo.Owner.Name}}</a>/{{.Repo.Name}}{{if .Repo.Private}} <span class="tag">private</span>{{end}}</h2>{{if and .Repo.Description (eq .Tab "summary")}}<p class="desc">{{.Repo.Description}}</p>{{end}}</div> | |
| 33 | 33 | <div class="tabbar"><nav class="tabs inner"> |
| 34 | 34 | <a href="/{{.Repo.Path}}"{{if eq .Tab "summary"}} class="active"{{end}}>summary</a> |
| 35 | 35 | {{if not .Empty}}<a href="/{{.Repo.Path}}/tree/{{.Ref}}/"{{if eq .Tab "tree"}} class="active"{{end}}>tree</a><a href="/{{.Repo.Path}}/log/{{.Ref}}"{{if eq .Tab "log"}} class="active"{{end}}>log</a><a href="/{{.Repo.Path}}/refs"{{if eq .Tab "refs"}} class="active"{{end}}>refs</a>{{end}} |
| 36 | 36 | {{if .Owner}}<a href="/{{.Repo.Path}}/settings"{{if eq .Tab "settings"}} class="active"{{end}}>settings</a>{{end}} |
| 37 | 37 | </nav></div> |
| 38 | 38 | </div> |
| 39 | -{{if .Repo.Description}}<div class="descbar"><div class="inner">{{.Repo.Description}}</div></div>{{end}} | |
| 40 | 39 | {{end}}{{end}} |
| 41 | -<main> | |
| 40 | +<main{{with .Data}}{{if index . "Entry"}} class="file"{{else if index . "Crumbs"}} class="file"{{end}}{{end}}> | |
| 42 | 41 | {{if .Error}}<p class="error">{{.Error}}</p>{{end}} |
| 43 | 42 | {{template "content" .}} |
| 44 | 43 | </main> |
templates/repo.html modified
| @@ -5,26 +5,27 @@ | ||
| 5 | 5 | <pre>git remote add origin git@{{.Host}}:{{$p.Repo.Path}} |
| 6 | 6 | git push -u origin {{$p.Ref}}</pre> |
| 7 | 7 | {{else}} |
| 8 | -<div class="cards commits"> | |
| 9 | -{{range .Data.Commits}}<div class="panel"><div><a class="hash" href="/{{$p.Repo.Path}}/commit/{{.Hash}}">{{short .Hash}}</a> <span class="subject">{{.Subject}}</span></div><div>{{.Author}} pushed to <a href="/{{$p.Repo.Path}}">{{$p.Repo.Path}}</a></div><div class="muted small">{{ago .Time}}</div></div>{{end}} | |
| 8 | +<div class="summary"> | |
| 9 | +<div class="commits"> | |
| 10 | +{{range .Data.Commits}}<div class="event"><div class="row"><span><a class="hash" href="/{{$p.Repo.Path}}/commit/{{.Hash}}">{{short .Hash}}</a> — {{.Author}}</span><a class="when" href="/{{$p.Repo.Path}}/commit/{{.Hash}}" title="{{date .Time}}">{{ago .Time}}</a></div><pre class="subject">{{.Subject}}</pre></div>{{end}} | |
| 10 | 11 | </div> |
| 11 | -<div class="columns"> | |
| 12 | -<div class="main"> | |
| 13 | -{{with .Data.Readme}}<article class="readme">{{.}}</article>{{end}} | |
| 12 | +<div class="refs"> | |
| 13 | +<h3>refs</h3> | |
| 14 | +{{range $i, $b := .Data.Branches}}{{if lt $i 4}}<div class="ref"><strong>{{$b.Name}}</strong><div><a href="/{{$p.Repo.Path}}/tree/{{$b.Name}}/">browse ▸</a> <a href="/{{$p.Repo.Path}}/log/{{$b.Name}}">log ▸</a></div></div>{{end}}{{end}} | |
| 15 | +{{range $i, $t := .Data.Tags}}{{if lt $i 3}}<div class="ref"><strong>{{$t.Name}}</strong><div><a href="/{{$p.Repo.Path}}/tree/{{$t.Name}}/">browse ▸</a> <a href="/{{$p.Repo.Path}}/log/{{$t.Name}}">log ▸</a></div></div>{{end}}{{end}} | |
| 16 | +</div> | |
| 17 | +<div class="clone"> | |
| 18 | +<h3>clone</h3> | |
| 19 | +<strong>read-only</strong> | |
| 20 | +<div><a href="https://{{.Host}}/{{$p.Repo.Path}}">https://{{.Host}}/{{$p.Repo.Path}}</a></div> | |
| 21 | +{{if $p.Owner}}<strong>read/write</strong> | |
| 22 | +<div>git@{{.Host}}:{{$p.Repo.Path}}</div>{{end}} | |
| 23 | +</div> | |
| 24 | +</div> | |
| 25 | +<div class="readme"> | |
| 26 | +{{with .Data.Readme}}<article>{{.}}</article>{{end}} | |
| 14 | 27 | {{with .Data.ReadmeText}}<pre class="plain">{{.}}</pre>{{end}} |
| 15 | 28 | {{if not .Data.ReadmeName}}<p class="muted">No README.</p>{{end}} |
| 16 | 29 | </div> |
| 17 | -<aside> | |
| 18 | -<h4>Clone</h4> | |
| 19 | -<dl class="clone"> | |
| 20 | -<dt>read-only</dt><dd><code>https://{{.Host}}/{{$p.Repo.Path}}</code></dd> | |
| 21 | -{{if $p.Owner}}<dt>read/write</dt><dd><code>git@{{.Host}}:{{$p.Repo.Path}}</code></dd>{{end}} | |
| 22 | -</dl> | |
| 23 | -<h4><a href="/{{$p.Repo.Path}}/refs">Branches</a></h4> | |
| 24 | -<ul class="side">{{range $i, $b := .Data.Branches}}{{if lt $i 5}}<li><a href="/{{$p.Repo.Path}}/tree/{{$b.Name}}/">{{$b.Name}}</a> <span class="muted small">{{ago $b.Time}}</span></li>{{end}}{{end}}</ul> | |
| 25 | -{{if .Data.Tags}}<h4><a href="/{{$p.Repo.Path}}/refs">Tags</a></h4> | |
| 26 | -<ul class="side">{{range $i, $t := .Data.Tags}}{{if lt $i 5}}<li><a href="/{{$p.Repo.Path}}/tree/{{$t.Name}}/">{{$t.Name}}</a> <span class="muted small">{{ago $t.Time}}</span></li>{{end}}{{end}}</ul>{{end}} | |
| 27 | -</aside> | |
| 28 | -</div> | |
| 29 | 30 | {{end}} |
| 30 | 31 | {{end}} |
web.go modified
| @@ -911,7 +911,7 @@ func perm(mode string) string { | ||
| 911 | 911 | func humanSize(n int64) string { |
| 912 | 912 | switch { |
| 913 | 913 | case n < 1024: |
| 914 | - return fmt.Sprintf("%d B", n) | |
| 914 | + return fmt.Sprintf("%d bytes", n) | |
| 915 | 915 | case n < 1<<20: |
| 916 | 916 | return fmt.Sprintf("%.1f KiB", float64(n)/1024) |
| 917 | 917 | default: |