forked from tangled.org/core
this repo has no description

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

Changed files
+83 -57
appview
types
+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 }} ··· 32 52 {{ else }} 33 53 <span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">MODIFIED</span> 34 54 {{ end }} 55 + 56 + {{ block "statPill" .Stats }} {{ end }} 35 57 36 58 {{ if .IsDelete }} 37 59 <a class="dark:text-white whitespace-nowrap overflow-x-auto" {{if $this }}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.Old }}"{{end}}> ··· 72 94 73 95 <div class="transition-all duration-700 ease-in-out"> 74 96 {{ if .IsDelete }} 75 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 76 - This file has been deleted in this commit. 77 - </p> 97 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 98 + This file has been deleted. 99 + </p> 100 + {{ else if .IsCopy }} 101 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 102 + This file has been copied. 103 + </p> 104 + {{ else if .IsRename }} 105 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 106 + This file has been renamed. 107 + </p> 108 + {{ else if .IsBinary }} 109 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 110 + This is a binary file and will not be displayed. 111 + </p> 78 112 {{ else }} 79 - {{ if .IsBinary }} 80 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 81 - This is a binary file and will not be displayed. 82 - </p> 83 - {{ else }} 113 + {{ $name := .Name.New }} 84 114 <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> 85 115 {{- $oldStart := .OldPosition -}} 86 116 {{- $newStart := .NewPosition -}} 87 - {{- $lineNrStyle := "min-w-[3rem] flex-shrink-0 select-none text-right" -}} 88 - {{- $lineNrSepStyle1 := "text-gray-400 dark:text-gray-500 bg-white dark:bg-gray-800" -}} 89 - {{- $lineNrSepStyle2 := "text-gray-400 dark:text-gray-500 bg-white dark:bg-gray-800 pr-2" -}} 117 + {{- $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 " -}} 118 + {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} 119 + {{- $lineNrSepStyle1 := "" -}} 120 + {{- $lineNrSepStyle2 := "pr-2" -}} 90 121 {{- range .Lines -}} 91 122 {{- if eq .Op.String "+" -}} 92 123 <div class="bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400 flex min-w-full items-center"> 93 124 <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}"><span aria-hidden="true" class="invisible">{{$newStart}}</span></div> 94 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}">{{ $newStart }}</div> 125 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}" id="{{$name}}-N{{$newStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{$newStart}}">{{ $newStart }}</a></div> 95 126 <div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div> 96 127 <div class="px-2">{{ .Line }}</div> 97 128 </div> ··· 99 130 {{- end -}} 100 131 {{- if eq .Op.String "-" -}} 101 132 <div class="bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 flex min-w-full items-center"> 102 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}">{{ $oldStart }}</div> 133 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}" id="{{$name}}-O{{$oldStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}">{{ $oldStart }}</a></div> 103 134 <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}"><span aria-hidden="true" class="invisible">{{$oldStart}}</span></div> 104 135 <div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div> 105 136 <div class="px-2">{{ .Line }}</div> ··· 108 139 {{- end -}} 109 140 {{- if eq .Op.String " " -}} 110 141 <div class="bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 flex min-w-full items-center"> 111 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}">{{ $oldStart }}</div> 112 - <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}">{{ $newStart }}</div> 142 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}" id="{{$name}}-O{{$oldStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}">{{ $oldStart }}</a></div> 143 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}" id="{{$name}}-N{{$newStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{$newStart}}">{{ $newStart }}</a></div> 113 144 <div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div> 114 145 <div class="px-2">{{ .Line }}</div> 115 146 </div> ··· 119 150 {{- end -}} 120 151 {{- end -}}</div></div></pre> 121 152 {{- end -}} 122 - {{ end }} 123 153 </div> 124 154 125 155 </details> ··· 130 160 {{ end }} 131 161 {{ end }} 132 162 {{ end }} 163 + 164 + {{ define "statPill" }} 165 + <div class="flex items-center font-mono text-sm"> 166 + {{ if and .Insertions .Deletions }} 167 + <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> 168 + <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> 169 + {{ else if .Insertions }} 170 + <span class="rounded p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400">+{{ .Insertions }}</span> 171 + {{ else if .Deletions }} 172 + <span class="rounded p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400">-{{ .Deletions }}</span> 173 + {{ end }} 174 + </div> 175 + {{ 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"> ··· 13 11 <div> 14 12 <p class="pb-2">{{ index $messageParts 0 }}</p> 15 13 {{ if gt (len $messageParts) 1 }} 16 - <p class="mt-1 cursor-text pb-2 text-sm">{{ nl2br (unwrapText (index $messageParts 1)) }}</p> 14 + <p class="mt-1 cursor-text pb-2 text-sm">{{ nl2br (index $messageParts 1) }}</p> 17 15 {{ end }} 18 16 </div> 19 17 </div> ··· 29 27 {{ end }} 30 28 <span class="px-1 select-none before:content-['\00B7']"></span> 31 29 {{ timeFmt $commit.Author.When }} 32 - <span class="px-1 select-none before:content-['\00B7']"></span> 33 - <span>{{ $stat.FilesChanged }}</span> files <span class="font-mono">(+{{ $stat.Insertions }}, -{{ $stat.Deletions }})</span> 34 30 <span class="px-1 select-none before:content-['\00B7']"></span> 35 31 </p> 36 32 ··· 43 39 </p> 44 40 </div> 45 41 46 - <div class="diff-stat"> 47 - <br> 48 - <strong class="text-sm uppercase mb-4 dark:text-gray-200">Changed files</strong> 49 - <div class="overflow-x-auto"> 50 - {{ range $diff }} 51 - <ul class="dark:text-gray-200"> 52 - {{ if .IsDelete }} 53 - <li><a href="#file-{{ .Name.Old }}" class="dark:hover:text-gray-300">{{ .Name.Old }}</a></li> 54 - {{ else }} 55 - <li><a href="#file-{{ .Name.New }}" class="dark:hover:text-gray-300">{{ .Name.New }}</a></li> 56 - {{ end }} 57 - </ul> 58 - {{ end }} 59 - </div> 60 - </div> 61 42 </section> 62 43 63 44 {{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 }} 33 - <span>{{ $stats.NumFolders }} folder</span> 34 32 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 33 + <span>{{ $stats.NumFolders }} folder</span> 35 34 {{ else if gt $stats.NumFolders 1 }} 35 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 36 36 <span>{{ $stats.NumFolders }} folders</span> 37 - <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></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 {