+22
appview/pages/pages.go
+22
appview/pages/pages.go
···
71
71
return s
72
72
},
73
73
"timeFmt": humanize.Time,
74
+
"byteFmt": humanize.Bytes,
74
75
"length": func(v []string) int {
75
76
return len(v)
76
77
},
···
293
294
BaseTreeLink string
294
295
BaseBlobLink string
295
296
types.RepoTreeResponse
297
+
}
298
+
299
+
type RepoTreeStats struct {
300
+
NumFolders uint64
301
+
NumFiles uint64
302
+
}
303
+
304
+
func (r RepoTreeParams) TreeStats() RepoTreeStats {
305
+
numFolders, numFiles := 0, 0
306
+
for _, f := range r.Files {
307
+
if !f.IsFile {
308
+
numFolders += 1
309
+
} else if f.IsFile {
310
+
numFiles += 1
311
+
}
312
+
}
313
+
314
+
return RepoTreeStats{
315
+
NumFolders: uint64(numFolders),
316
+
NumFiles: uint64(numFiles),
317
+
}
296
318
}
297
319
298
320
func (p *Pages) RepoTree(w io.Writer, params RepoTreeParams) error {
+1
-1
appview/pages/templates/layouts/base.html
+1
-1
appview/pages/templates/layouts/base.html
+16
-5
appview/pages/templates/repo/blob.html
+16
-5
appview/pages/templates/repo/blob.html
···
5
5
{{ $code_number_style := "text-gray-400 left-0 bg-white text-right mr-2 select-none" }}
6
6
{{ $linkstyle := "no-underline hover:underline" }}
7
7
<div class="pb-2 text-base">
8
-
{{ range $idx, $value := .BreadCrumbs }}
9
-
{{ if ne $idx (sub (len $.BreadCrumbs) 1) }}
8
+
<div class="flex justify-between">
9
+
<div id="breadcrumbs">
10
+
{{ range $idx, $value := .BreadCrumbs }}
11
+
{{ if ne $idx (sub (len $.BreadCrumbs) 1) }}
10
12
<a href="{{ index . 1}}" class="text-bold text-gray-500 {{ $linkstyle }}">{{ index . 0 }}</a> /
11
-
{{ else }}
13
+
{{ else }}
12
14
<span class="text-bold text-gray-500">{{ index . 0 }}</span>
13
-
{{ end }}
14
-
{{ end }}
15
+
{{ end }}
16
+
{{ end }}
17
+
</div>
18
+
<div id="file-info">
19
+
<span class="text-gray-500 text-xs">
20
+
{{ .Lines }} lines
21
+
·
22
+
{{ byteFmt .SizeHint }}
23
+
</span>
24
+
</div>
25
+
</div>
15
26
</div>
16
27
17
28
+1
-1
appview/pages/templates/repo/index.html
+1
-1
appview/pages/templates/repo/index.html
+27
-6
appview/pages/templates/repo/tree.html
+27
-6
appview/pages/templates/repo/tree.html
···
5
5
{{ $linkstyle := "no-underline hover:underline" }}
6
6
7
7
<div class="pb-2 text-base">
8
-
{{ range .BreadCrumbs }}
9
-
<a href="{{ index . 1}}" class="text-bold text-gray-500 {{ $linkstyle }}">{{ index . 0 }}</a> /
10
-
{{ end }}
8
+
<div class="flex justify-between">
9
+
<div id="breadcrumbs">
10
+
{{ range .BreadCrumbs }}
11
+
<a href="{{ index . 1}}" class="text-bold text-gray-500 {{ $linkstyle }}">{{ index . 0 }}</a> /
12
+
{{ end }}
13
+
</div>
14
+
<div id="dir-info">
15
+
<span class="text-gray-500 text-xs">
16
+
{{ $stats := .TreeStats }}
17
+
18
+
{{ if eq $stats.NumFolders 1 }}
19
+
{{ $stats.NumFolders }} folder
20
+
·
21
+
{{ else if gt $stats.NumFolders 1 }}
22
+
{{ $stats.NumFolders }} folders
23
+
·
24
+
{{ end }}
25
+
26
+
{{ if eq $stats.NumFiles 1 }}
27
+
{{ $stats.NumFiles }} file
28
+
{{ else if gt $stats.NumFiles 1 }}
29
+
{{ $stats.NumFiles }} files
30
+
{{ end }}
31
+
</span>
32
+
</div>
33
+
</div>
11
34
</div>
12
35
13
36
{{ range .Files }}
···
19
42
<i class="w-3 h-3 fill-current" data-lucide="folder"></i>{{ .Name }}
20
43
</div>
21
44
</a>
45
+
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.Author.When }}</time>
22
46
</div>
23
-
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.Author.When }}</time>
24
47
</div>
25
48
{{ end }}
26
49
{{ end }}
···
28
51
{{ range .Files }}
29
52
{{ if .IsFile }}
30
53
<div class="{{ $containerstyle }}">
31
-
32
54
<div class="flex justify-between items-center">
33
55
<a href="/{{ $.BaseBlobLink }}/{{ .Name }}" class="{{ $linkstyle }}">
34
56
<div class="flex items-center gap-2">
35
57
<i class="w-3 h-3" data-lucide="file"></i>{{ .Name }}
36
58
</div>
37
59
</a>
38
-
39
60
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.Author.When }}</time>
40
61
</div>
41
62
</div>
+4
-1
knotserver/routes.go
+4
-1
knotserver/routes.go
···
215
215
return
216
216
}
217
217
218
-
safe := string(sanitize([]byte(contents)))
218
+
bytes := []byte(contents)
219
+
safe := string(sanitize(bytes))
220
+
sizeHint := len(bytes)
219
221
220
222
resp := types.RepoBlobResponse{
221
223
Ref: ref,
222
224
Contents: string(safe),
223
225
Path: treePath,
224
226
IsBinary: isBinaryFile,
227
+
SizeHint: uint64(sizeHint),
225
228
}
226
229
227
230
h.showFile(resp, w, l)