Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).

appview: add stats and line-nr links to diffs

drive-by fix: style the separator between pull submissions

authored by oppi.li and committed by

Tangled 48cbc686 438f94f1

+83 -57
+59 -16
appview/pages/templates/fragments/diff.html
··· 8 8 {{ $this := $commit.This }} 9 9 {{ $parent := $commit.Parent }} 10 10 11 + <section class="mt-6 p-6 border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 12 + <div class="diff-stat"> 13 + <div class="flex gap-2 items-center"> 14 + <strong class="text-sm uppercase dark:text-gray-200">Changed files</strong> 15 + {{ block "statPill" $stat }} {{ end }} 16 + </div> 17 + <div class="overflow-x-auto"> 18 + {{ range $diff }} 19 + <ul class="dark:text-gray-200"> 20 + {{ if .IsDelete }} 21 + <li><a href="#file-{{ .Name.Old }}" class="dark:hover:text-gray-300">{{ .Name.Old }}</a></li> 22 + {{ else }} 23 + <li><a href="#file-{{ .Name.New }}" class="dark:hover:text-gray-300">{{ .Name.New }}</a></li> 24 + {{ end }} 25 + </ul> 26 + {{ end }} 27 + </div> 28 + </div> 29 + </section> 30 + 11 31 {{ $last := sub (len $diff) 1 }} 12 32 {{ range $idx, $hunk := $diff }} 13 33 {{ with $hunk }} ··· 52 32 {{ else }} 53 33 <span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">MODIFIED</span> 54 34 {{ end }} 35 + 36 + {{ block "statPill" .Stats }} {{ end }} 55 37 56 38 {{ if .IsDelete }} 57 39 <a class="dark:text-white whitespace-nowrap overflow-x-auto" {{if $this }}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.Old }}"{{end}}> ··· 94 72 95 73 <div class="transition-all duration-700 ease-in-out"> 96 74 {{ if .IsDelete }} 97 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 98 - This file has been deleted in this commit. 99 - </p> 75 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 76 + This file has been deleted. 77 + </p> 78 + {{ else if .IsCopy }} 79 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 80 + This file has been copied. 81 + </p> 82 + {{ else if .IsRename }} 83 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 84 + This file has been renamed. 85 + </p> 86 + {{ else if .IsBinary }} 87 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 88 + This is a binary file and will not be displayed. 89 + </p> 100 90 {{ else }} 101 - {{ if .IsBinary }} 102 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 103 - This is a binary file and will not be displayed. 104 - </p> 105 - {{ else }} 91 + {{ $name := .Name.New }} 106 92 <pre class="overflow-x-auto"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}}<div class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center">&middot;&middot;&middot;</div> 107 93 {{- $oldStart := .OldPosition -}} 108 94 {{- $newStart := .NewPosition -}} 109 - {{- $lineNrStyle := "min-w-[3rem] flex-shrink-0 select-none text-right" -}} 110 - {{- $lineNrSepStyle1 := "text-gray-400 dark:text-gray-500 bg-white dark:bg-gray-800" -}} 111 - {{- $lineNrSepStyle2 := "text-gray-400 dark:text-gray-500 bg-white dark:bg-gray-800 pr-2" -}} 95 + {{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800 scroll-mt-10 target:border target:border-amber-500 target:rounded " -}} 96 + {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} 97 + {{- $lineNrSepStyle1 := "" -}} 98 + {{- $lineNrSepStyle2 := "pr-2" -}} 112 99 {{- range .Lines -}} 113 100 {{- if eq .Op.String "+" -}} 114 101 <div class="bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400 flex min-w-full items-center"> 115 102 <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}"><span aria-hidden="true" class="invisible">{{$newStart}}</span></div> 116 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}">{{ $newStart }}</div> 103 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}" id="{{$name}}-N{{$newStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{$newStart}}">{{ $newStart }}</a></div> 117 104 <div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div> 118 105 <div class="px-2">{{ .Line }}</div> 119 106 </div> ··· 130 99 {{- end -}} 131 100 {{- if eq .Op.String "-" -}} 132 101 <div class="bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 flex min-w-full items-center"> 133 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}">{{ $oldStart }}</div> 102 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}" id="{{$name}}-O{{$oldStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}">{{ $oldStart }}</a></div> 134 103 <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}"><span aria-hidden="true" class="invisible">{{$oldStart}}</span></div> 135 104 <div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div> 136 105 <div class="px-2">{{ .Line }}</div> ··· 139 108 {{- end -}} 140 109 {{- if eq .Op.String " " -}} 141 110 <div class="bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 flex min-w-full items-center"> 142 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}">{{ $oldStart }}</div> 143 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}">{{ $newStart }}</div> 111 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}" id="{{$name}}-O{{$oldStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}">{{ $oldStart }}</a></div> 112 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}" id="{{$name}}-N{{$newStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{$newStart}}">{{ $newStart }}</a></div> 144 113 <div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div> 145 114 <div class="px-2">{{ .Line }}</div> 146 115 </div> ··· 150 119 {{- end -}} 151 120 {{- end -}}</div></div></pre> 152 121 {{- end -}} 153 - {{ end }} 154 122 </div> 155 123 156 124 </details> ··· 159 129 </section> 160 130 {{ end }} 161 131 {{ end }} 132 + {{ end }} 133 + 134 + {{ define "statPill" }} 135 + <div class="flex items-center font-mono text-sm"> 136 + {{ if and .Insertions .Deletions }} 137 + <span class="rounded-l p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400">+{{ .Insertions }}</span> 138 + <span class="rounded-r p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400">-{{ .Deletions }}</span> 139 + {{ else if .Insertions }} 140 + <span class="rounded p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400">+{{ .Insertions }}</span> 141 + {{ else if .Deletions }} 142 + <span class="rounded p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400">-{{ .Deletions }}</span> 143 + {{ end }} 144 + </div> 162 145 {{ end }}
+1 -20
appview/pages/templates/repo/commit.html
··· 4 4 5 5 {{ $repo := .RepoInfo.FullName }} 6 6 {{ $commit := .Diff.Commit }} 7 - {{ $stat := .Diff.Stat }} 8 - {{ $diff := .Diff.Diff }} 9 7 10 8 <section class="commit dark:text-white"> 11 9 <div id="commit-message"> ··· 11 13 <div> 12 14 <p class="pb-2">{{ index $messageParts 0 }}</p> 13 15 {{ if gt (len $messageParts) 1 }} 14 - <p class="mt-1 cursor-text pb-2 text-sm">{{ nl2br (unwrapText (index $messageParts 1)) }}</p> 16 + <p class="mt-1 cursor-text pb-2 text-sm">{{ nl2br (index $messageParts 1) }}</p> 15 17 {{ end }} 16 18 </div> 17 19 </div> ··· 28 30 <span class="px-1 select-none before:content-['\00B7']"></span> 29 31 {{ timeFmt $commit.Author.When }} 30 32 <span class="px-1 select-none before:content-['\00B7']"></span> 31 - <span>{{ $stat.FilesChanged }}</span> files <span class="font-mono">(+{{ $stat.Insertions }}, -{{ $stat.Deletions }})</span> 32 - <span class="px-1 select-none before:content-['\00B7']"></span> 33 33 </p> 34 34 35 35 <p class="flex items-center text-sm text-gray-500 dark:text-gray-300"> ··· 39 43 </p> 40 44 </div> 41 45 42 - <div class="diff-stat"> 43 - <br> 44 - <strong class="text-sm uppercase mb-4 dark:text-gray-200">Changed files</strong> 45 - <div class="overflow-x-auto"> 46 - {{ range $diff }} 47 - <ul class="dark:text-gray-200"> 48 - {{ if .IsDelete }} 49 - <li><a href="#file-{{ .Name.Old }}" class="dark:hover:text-gray-300">{{ .Name.Old }}</a></li> 50 - {{ else }} 51 - <li><a href="#file-{{ .Name.New }}" class="dark:hover:text-gray-300">{{ .Name.New }}</a></li> 52 - {{ end }} 53 - </ul> 54 - {{ end }} 55 - </div> 56 - </div> 57 46 </section> 58 47 59 48 {{end}}
+1 -1
appview/pages/templates/repo/index.html
··· 146 146 <p 147 147 class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300" 148 148 > 149 - {{ nl2br (unwrapText (index $messageParts 1)) }} 149 + {{ nl2br (index $messageParts 1) }} 150 150 </p> 151 151 {{ end }} 152 152 </div>
+1 -1
appview/pages/templates/repo/issues/issues.html
··· 4 4 <div class="flex justify-between items-center"> 5 5 <p> 6 6 filtering 7 - <select class="border px-1 bg-white border-gray-200 dark:bg-gray-800 dark:border-gray-700" onchange="window.location.href = '/{{ .RepoInfo.FullName }}/issues?state=' + this.value"> 7 + <select class="border p-1 bg-white border-gray-200 dark:bg-gray-800 dark:border-gray-700" onchange="window.location.href = '/{{ .RepoInfo.FullName }}/issues?state=' + this.value"> 8 8 <option value="open" {{ if .FilteringByOpen }}selected{{ end }}>open ({{ .RepoInfo.Stats.IssueCount.Open }})</option> 9 9 <option value="closed" {{ if not .FilteringByOpen }}selected{{ end }}>closed ({{ .RepoInfo.Stats.IssueCount.Closed }})</option> 10 10 </select>
+1 -1
appview/pages/templates/repo/log.html
··· 83 83 <p 84 84 class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300" 85 85 > 86 - {{ nl2br (unwrapText (index $messageParts 1)) }} 86 + {{ nl2br (index $messageParts 1) }} 87 87 </p> 88 88 {{ end }} 89 89 </div>
-13
appview/pages/templates/repo/pulls/patch.html
··· 69 69 {{ end }} 70 70 </section> 71 71 72 - <div id="diff-stat"> 73 - <br> 74 - <strong class="text-sm uppercase mb-4">Changed files</strong> 75 - {{ range .Diff.Diff }} 76 - <ul> 77 - {{ if .IsDelete }} 78 - <li><a href="#file-{{ .Name.Old }}">{{ .Name.Old }}</a></li> 79 - {{ else }} 80 - <li><a href="#file-{{ .Name.New }}">{{ .Name.New }}</a></li> 81 - {{ end }} 82 - </ul> 83 - {{ end }} 84 - </div> 85 72 </div> 86 73 87 74 <section>
+1 -1
appview/pages/templates/repo/pulls/pull.html
··· 156 156 {{ end }} 157 157 </div> 158 158 </details> 159 - <hr class="md:hidden"/> 159 + <hr class="md:hidden border-t border-gray-300 dark:border-gray-600"/> 160 160 {{ end }} 161 161 {{ end }} 162 162 {{ end }}
+1 -1
appview/pages/templates/repo/pulls/pulls.html
··· 5 5 <p class="dark:text-white"> 6 6 filtering 7 7 <select 8 - class="border px-1 bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-600 dark:text-white" 8 + class="border p-1 bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-600 dark:text-white" 9 9 onchange="window.location.href = '/{{ .RepoInfo.FullName }}/pulls?state=' + this.value" 10 10 > 11 11 <option value="open" {{ if .FilteringBy.IsOpen }}selected{{ end }}>
+4 -3
appview/pages/templates/repo/tree.html
··· 28 28 {{ $stats := .TreeStats }} 29 29 30 30 <span>at <a href="/{{ $.RepoInfo.FullName }}/tree/{{ $.Ref }}">{{ $.Ref }}</a></span> 31 - <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 32 31 {{ if eq $stats.NumFolders 1 }} 32 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 33 33 <span>{{ $stats.NumFolders }} folder</span> 34 - <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 35 34 {{ else if gt $stats.NumFolders 1 }} 36 - <span>{{ $stats.NumFolders }} folders</span> 37 35 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 36 + <span>{{ $stats.NumFolders }} folders</span> 38 37 {{ end }} 39 38 40 39 {{ if eq $stats.NumFiles 1 }} 40 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 41 41 <span>{{ $stats.NumFiles }} file</span> 42 42 {{ else if gt $stats.NumFiles 1 }} 43 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 43 44 <span>{{ $stats.NumFiles }} files</span> 44 45 {{ end }} 45 46
+14
types/diff.go
··· 23 23 IsRename bool `json:"is_rename"` 24 24 } 25 25 26 + type DiffStat struct { 27 + Insertions int64 28 + Deletions int64 29 + } 30 + 31 + func (d *Diff) Stats() DiffStat { 32 + var stats DiffStat 33 + for _, f := range d.TextFragments { 34 + stats.Insertions += f.LinesAdded 35 + stats.Deletions += f.LinesDeleted 36 + } 37 + return stats 38 + } 39 + 26 40 // A nicer git diff representation. 27 41 type NiceDiff struct { 28 42 Commit struct {