+1
-1
appview/pages/funcmap.go
+1
-1
appview/pages/funcmap.go
+1
-2
appview/pages/pages.go
+1
-2
appview/pages/pages.go
+27
-47
appview/pages/templates/repo/index.html
+27
-47
appview/pages/templates/repo/index.html
···
127
127
{{ end }}
128
128
129
129
{{ define "fileTree" }}
130
-
<div
131
-
id="file-tree"
132
-
class="col-span-1 pr-2 md:border-r md:border-gray-200 dark:md:border-gray-700"
133
-
>
134
-
{{ $containerstyle := "py-1" }}
135
-
{{ $linkstyle := "no-underline hover:underline dark:text-white" }}
130
+
<div id="file-tree" class="col-span-1 pr-2 md:border-r md:border-gray-200 dark:md:border-gray-700" >
131
+
{{ $linkstyle := "no-underline hover:underline dark:text-white" }}
136
132
137
-
{{ range .Files }}
138
-
{{ if not .IsFile }}
139
-
<div class="{{ $containerstyle }}">
140
-
<div class="flex justify-between items-center">
141
-
<a
142
-
href="/{{ $.RepoInfo.FullName }}/tree/{{ $.Ref | urlquery }}/{{ .Name }}"
143
-
class="{{ $linkstyle }}"
144
-
>
145
-
<div class="flex items-center gap-2">
146
-
{{ i "folder" "size-4 fill-current" }}
147
-
{{ .Name }}
148
-
</div>
149
-
</a>
133
+
{{ range .Files }}
134
+
<div class="grid grid-cols-2 gap-4 items-center py-1">
135
+
<div class="col-span-1">
136
+
{{ $link := printf "/%s/%s/%s/%s" $.RepoInfo.FullName "tree" (urlquery $.Ref) .Name }}
137
+
{{ $icon := "folder" }}
138
+
{{ $iconStyle := "size-4 fill-current" }}
150
139
151
-
{{ if .LastCommit }}
152
-
<span class="text-xs text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .LastCommit.When }}</span>
153
-
{{ end }}
154
-
</div>
155
-
</div>
156
-
{{ end }}
157
-
{{ end }}
158
-
159
-
{{ range .Files }}
160
-
{{ if .IsFile }}
161
-
<div class="{{ $containerstyle }}">
162
-
<div class="flex justify-between items-center">
163
-
<a
164
-
href="/{{ $.RepoInfo.FullName }}/blob/{{ $.Ref | urlquery }}/{{ .Name }}"
165
-
class="{{ $linkstyle }}"
166
-
>
167
-
<div class="flex items-center gap-2">
168
-
{{ i "file" "size-4" }}{{ .Name }}
169
-
</div>
170
-
</a>
140
+
{{ if .IsFile }}
141
+
{{ $link = printf "/%s/%s/%s/%s" $.RepoInfo.FullName "blob" (urlquery $.Ref) .Name }}
142
+
{{ $icon = "file" }}
143
+
{{ $iconStyle = "size-4" }}
144
+
{{ end }}
145
+
<a href="{{ $link }}" class="{{ $linkstyle }}">
146
+
<div class="flex items-center gap-2">
147
+
{{ i $icon $iconStyle }}{{ .Name }}
148
+
</div>
149
+
</a>
150
+
</div>
171
151
172
-
{{ if .LastCommit }}
173
-
<span class="text-xs text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .LastCommit.When }}</span>
174
-
{{ end }}
175
-
</div>
176
-
</div>
177
-
{{ end }}
178
-
{{ end }}
179
-
</div>
152
+
<div class="text-xs col-span-1 text-right">
153
+
{{ with .LastCommit }}
154
+
<a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .When }}</a>
155
+
{{ end }}
156
+
</div>
157
+
</div>
158
+
{{ end }}
159
+
</div>
180
160
{{ end }}
181
161
182
162
{{ define "rightInfo" }}
+26
-34
appview/pages/templates/repo/tree.html
+26
-34
appview/pages/templates/repo/tree.html
···
19
19
{{define "repoContent"}}
20
20
<main>
21
21
<div class="tree">
22
-
{{ $containerstyle := "py-1" }}
23
22
{{ $linkstyle := "no-underline hover:underline" }}
24
23
25
24
<div class="pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700">
···
54
53
</div>
55
54
56
55
{{ range .Files }}
57
-
{{ if not .IsFile }}
58
-
<div class="{{ $containerstyle }}">
59
-
<div class="flex justify-between items-center">
60
-
<a href="/{{ $.BaseTreeLink }}/{{ .Name }}" class="{{ $linkstyle }}">
61
-
<div class="flex items-center gap-2">
62
-
{{ i "folder" "size-4 fill-current" }}{{ .Name }}
63
-
</div>
64
-
</a>
65
-
{{ if .LastCommit}}
66
-
<div class="flex items-end gap-2">
67
-
<span class="text text-gray-500 dark:text-gray-400 mr-6">{{ .LastCommit.Message }}</span>
68
-
<span class="text-xs text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .LastCommit.When }}</span>
56
+
<div class="grid grid-cols-12 gap-4 items-center py-1">
57
+
<div class="col-span-6 md:col-span-3">
58
+
{{ $link := printf "/%s/%s/%s/%s/%s" $.RepoInfo.FullName "tree" (urlquery $.Ref) $.TreePath .Name }}
59
+
{{ $icon := "folder" }}
60
+
{{ $iconStyle := "size-4 fill-current" }}
61
+
62
+
{{ if .IsFile }}
63
+
{{ $icon = "file" }}
64
+
{{ $iconStyle = "size-4" }}
65
+
{{ end }}
66
+
<a href="{{ $link }}" class="{{ $linkstyle }}">
67
+
<div class="flex items-center gap-2">
68
+
{{ i $icon $iconStyle }}{{ .Name }}
69
69
</div>
70
-
{{ end }}
70
+
</a>
71
71
</div>
72
-
</div>
73
-
{{ end }}
74
-
{{ end }}
75
72
76
-
{{ range .Files }}
77
-
{{ if .IsFile }}
78
-
<div class="{{ $containerstyle }}">
79
-
<div class="flex justify-between items-center">
80
-
<a href="/{{ $.BaseBlobLink }}/{{ .Name }}" class="{{ $linkstyle }}">
81
-
<div class="flex items-center gap-2">
82
-
{{ i "file" "size-4" }}{{ .Name }}
83
-
</div>
84
-
</a>
85
-
{{ if .LastCommit}}
86
-
<div class="flex items-end gap-2">
87
-
<span class="text text-gray-500 dark:text-gray-400 mr-6">{{ .LastCommit.Message }}</span>
88
-
<span class="text-xs text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .LastCommit.When }}</span>
89
-
</div>
90
-
{{ end }}
73
+
<div class="col-span-0 md:col-span-7 hidden md:block overflow-hidden">
74
+
{{ with .LastCommit }}
75
+
<a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400 block truncate">{{ .Message }}</a>
76
+
{{ end }}
77
+
</div>
78
+
79
+
<div class="col-span-6 md:col-span-2 text-right">
80
+
{{ with .LastCommit }}
81
+
<a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .When }}</a>
82
+
{{ end }}
91
83
</div>
92
-
</div>
84
+
</div>
93
85
{{ end }}
94
-
{{ end }}
86
+
95
87
</div>
96
88
</main>
97
89
{{end}}
+3
-3
appview/pages/templates/user/repos.html
+3
-3
appview/pages/templates/user/repos.html
···
8
8
{{ end }}
9
9
10
10
{{ define "content" }}
11
-
<div class="grid grid-cols-1 md:grid-cols-8 gap-4">
12
-
<div class="md:col-span-2 order-1 md:order-1">
11
+
<div class="grid grid-cols-1 md:grid-cols-11 gap-4">
12
+
<div class="md:col-span-3 order-1 md:order-1">
13
13
{{ template "user/fragments/profileCard" .Card }}
14
14
</div>
15
-
<div id="all-repos" class="md:col-span-6 order-2 md:order-2">
15
+
<div id="all-repos" class="md:col-span-8 order-2 md:order-2">
16
16
{{ block "ownRepos" . }}{{ end }}
17
17
</div>
18
18
</div>
+2
appview/repo/index.go
+2
appview/repo/index.go
+7
-28
appview/repo/repo.go
+7
-28
appview/repo/repo.go
···
10
10
"log"
11
11
"net/http"
12
12
"net/url"
13
-
"path"
14
13
"slices"
15
-
"sort"
16
14
"strconv"
17
15
"strings"
18
16
"time"
···
374
372
375
373
// redirects tree paths trying to access a blob; in this case the result.Files is unpopulated,
376
374
// so we can safely redirect to the "parent" (which is the same file).
377
-
if len(result.Files) == 0 && result.Parent == treePath {
375
+
unescapedTreePath, _ := url.PathUnescape(treePath)
376
+
if len(result.Files) == 0 && result.Parent == unescapedTreePath {
378
377
http.Redirect(w, r, fmt.Sprintf("/%s/blob/%s/%s", f.OwnerSlashRepo(), ref, result.Parent), http.StatusFound)
379
378
return
380
379
}
···
389
388
}
390
389
}
391
390
392
-
baseTreeLink := path.Join(f.OwnerSlashRepo(), "tree", ref, treePath)
393
-
baseBlobLink := path.Join(f.OwnerSlashRepo(), "blob", ref, treePath)
391
+
sortFiles(result.Files)
394
392
395
393
rp.pages.RepoTree(w, pages.RepoTreeParams{
396
394
LoggedInUser: user,
397
395
BreadCrumbs: breadcrumbs,
398
-
BaseTreeLink: baseTreeLink,
399
-
BaseBlobLink: baseBlobLink,
396
+
TreePath: treePath,
400
397
RepoInfo: f.RepoInfo(user),
401
398
RepoTreeResponse: result,
402
399
})
403
-
return
404
400
}
405
401
406
402
func (rp *Repo) RepoTags(w http.ResponseWriter, r *http.Request) {
···
480
476
return
481
477
}
482
478
483
-
slices.SortFunc(result.Branches, func(a, b types.Branch) int {
484
-
if a.IsDefault {
485
-
return -1
486
-
}
487
-
if b.IsDefault {
488
-
return 1
489
-
}
490
-
if a.Commit != nil && b.Commit != nil {
491
-
if a.Commit.Committer.When.Before(b.Commit.Committer.When) {
492
-
return 1
493
-
} else {
494
-
return -1
495
-
}
496
-
}
497
-
return strings.Compare(a.Name, b.Name) * -1
498
-
})
479
+
sortBranches(result.Branches)
499
480
500
481
user := rp.oauth.GetUser(r)
501
482
rp.pages.RepoBranches(w, pages.RepoBranchesParams{
···
503
484
RepoInfo: f.RepoInfo(user),
504
485
RepoBranchesResponse: *result,
505
486
})
506
-
return
507
487
}
508
488
509
489
func (rp *Repo) RepoBlob(w http.ResponseWriter, r *http.Request) {
···
1233
1213
return
1234
1214
}
1235
1215
branches := result.Branches
1236
-
sort.Slice(branches, func(i int, j int) bool {
1237
-
return branches[i].Commit.Committer.When.After(branches[j].Commit.Committer.When)
1238
-
})
1216
+
1217
+
sortBranches(branches)
1239
1218
1240
1219
var defaultBranch string
1241
1220
for _, b := range branches {
+34
appview/repo/repo_util.go
+34
appview/repo/repo_util.go
···
5
5
"crypto/rand"
6
6
"fmt"
7
7
"math/big"
8
+
"slices"
9
+
"sort"
10
+
"strings"
8
11
9
12
"tangled.sh/tangled.sh/core/appview/db"
10
13
"tangled.sh/tangled.sh/core/appview/pages/repoinfo"
14
+
"tangled.sh/tangled.sh/core/types"
11
15
12
16
"github.com/go-git/go-git/v5/plumbing/object"
13
17
)
18
+
19
+
func sortFiles(files []types.NiceTree) {
20
+
sort.Slice(files, func(i, j int) bool {
21
+
iIsFile := files[i].IsFile
22
+
jIsFile := files[j].IsFile
23
+
if iIsFile != jIsFile {
24
+
return !iIsFile
25
+
}
26
+
return files[i].Name < files[j].Name
27
+
})
28
+
}
29
+
30
+
func sortBranches(branches []types.Branch) {
31
+
slices.SortFunc(branches, func(a, b types.Branch) int {
32
+
if a.IsDefault {
33
+
return -1
34
+
}
35
+
if b.IsDefault {
36
+
return 1
37
+
}
38
+
if a.Commit != nil && b.Commit != nil {
39
+
if a.Commit.Committer.When.Before(b.Commit.Committer.When) {
40
+
return 1
41
+
} else {
42
+
return -1
43
+
}
44
+
}
45
+
return strings.Compare(a.Name, b.Name)
46
+
})
47
+
}
14
48
15
49
func uniqueEmails(commits []*object.Commit) []string {
16
50
emails := make(map[string]struct{})