tangled
alpha
login
or
join now
tjh.dev
/
test
forked from
tangled.org/core
0
fork
atom
Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork
atom
overview
issues
pulls
pipelines
show stars in profile; styles for issue comments
oppi.li
1 year ago
2811e8c7
49651a73
+116
-26
7 changed files
expand all
collapse all
unified
split
appview
db
repos.go
star.go
pages
pages.go
templates
fragments
star.html
repo
issues
issue.html
issues.html
user
profile.html
+75
-4
appview/db/repos.go
reviewed
···
13
13
Created time.Time
14
14
AtUri string
15
15
Description string
16
16
+
17
17
+
// optionally, populate this when querying for reverse mappings
18
18
+
RepoStats *RepoStats
16
19
}
17
20
18
21
func GetAllRepos(e Execer, limit int) ([]Repo, error) {
···
55
52
func GetAllReposByDid(e Execer, did string) ([]Repo, error) {
56
53
var repos []Repo
57
54
58
58
-
rows, err := e.Query(`select did, name, knot, rkey, description, created from repos where did = ?`, did)
55
55
+
rows, err := e.Query(
56
56
+
`select
57
57
+
r.did,
58
58
+
r.name,
59
59
+
r.knot,
60
60
+
r.rkey,
61
61
+
r.description,
62
62
+
r.created,
63
63
+
count(s.id) as star_count
64
64
+
from
65
65
+
repos r
66
66
+
left join
67
67
+
stars s on r.at_uri = s.repo_at
68
68
+
where
69
69
+
r.did = ?
70
70
+
group by
71
71
+
r.at_uri`, did)
59
72
if err != nil {
60
73
return nil, err
61
74
}
···
79
60
80
61
for rows.Next() {
81
62
var repo Repo
82
82
-
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created)
63
63
+
var repoStats RepoStats
64
64
+
var createdAt string
65
65
+
var nullableDescription sql.NullString
66
66
+
67
67
+
err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount)
83
68
if err != nil {
84
69
return nil, err
85
70
}
71
71
+
72
72
+
if nullableDescription.Valid {
73
73
+
repo.Description = nullableDescription.String
74
74
+
} else {
75
75
+
repo.Description = ""
76
76
+
}
77
77
+
78
78
+
createdAtTime, err := time.Parse(time.RFC3339, createdAt)
79
79
+
if err != nil {
80
80
+
repo.Created = time.Now()
81
81
+
} else {
82
82
+
repo.Created = createdAtTime
83
83
+
}
84
84
+
85
85
+
repo.RepoStats = &repoStats
86
86
+
86
87
repos = append(repos, repo)
87
88
}
88
89
···
189
150
func CollaboratingIn(e Execer, collaborator string) ([]Repo, error) {
190
151
var repos []Repo
191
152
192
192
-
rows, err := e.Query(`select r.did, r.name, r.knot, r.rkey, r.description, r.created from repos r join collaborators c on r.id = c.repo where c.did = ?;`, collaborator)
153
153
+
rows, err := e.Query(
154
154
+
`select
155
155
+
r.did, r.name, r.knot, r.rkey, r.description, r.created, count(s.id) as star_count
156
156
+
from
157
157
+
repos r
158
158
+
join
159
159
+
collaborators c on r.id = c.repo
160
160
+
left join
161
161
+
stars s on r.at_uri = s.repo_at
162
162
+
where
163
163
+
c.did = ?
164
164
+
group by
165
165
+
r.id;`, collaborator)
193
166
if err != nil {
194
167
return nil, err
195
168
}
···
209
158
210
159
for rows.Next() {
211
160
var repo Repo
212
212
-
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created)
161
161
+
var repoStats RepoStats
162
162
+
var createdAt string
163
163
+
var nullableDescription sql.NullString
164
164
+
165
165
+
err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount)
213
166
if err != nil {
214
167
return nil, err
215
168
}
169
169
+
170
170
+
if nullableDescription.Valid {
171
171
+
repo.Description = nullableDescription.String
172
172
+
} else {
173
173
+
repo.Description = ""
174
174
+
}
175
175
+
176
176
+
createdAtTime, err := time.Parse(time.RFC3339, createdAt)
177
177
+
if err != nil {
178
178
+
repo.Created = time.Now()
179
179
+
} else {
180
180
+
repo.Created = createdAtTime
181
181
+
}
182
182
+
183
183
+
repo.RepoStats = &repoStats
184
184
+
216
185
repos = append(repos, repo)
217
186
}
218
187
+3
-1
appview/db/star.go
reviewed
···
10
10
type Star struct {
11
11
StarredByDid string
12
12
RepoAt syntax.ATURI
13
13
-
Repo *Repo
14
13
Created time.Time
15
14
Rkey string
15
15
+
16
16
+
// optionally, populate this when querying for reverse mappings
17
17
+
Repo *Repo
16
18
}
17
19
18
20
func (star *Star) ResolveRepo(e Execer) error {
+6
-1
appview/pages/pages.go
reviewed
···
523
523
524
524
func Cache(h http.Handler) http.Handler {
525
525
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
526
526
-
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
526
526
+
if strings.HasSuffix(r.URL.Path, ".css") {
527
527
+
// on day for css files
528
528
+
w.Header().Set("Cache-Control", "public, max-age=86400")
529
529
+
} else {
530
530
+
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
531
531
+
}
527
532
h.ServeHTTP(w, r)
528
533
})
529
534
}
-3
appview/pages/templates/fragments/star.html
reviewed
···
22
22
<span>
23
23
{{ .Stats.StarCount }}
24
24
</span>
25
25
-
<span id="starSpinner" class="hidden">
26
26
-
loading
27
27
-
</span>
28
25
</div>
29
26
</button>
30
27
<script>
+11
-8
appview/pages/templates/repo/issues/issue.html
reviewed
···
4
4
{{ end }}
5
5
6
6
{{ define "repoContent" }}
7
7
-
<h1>
7
7
+
<header>
8
8
+
<p class="text-2xl font-bold">
8
9
{{ .Issue.Title }}
9
9
-
<span class="text-gray-400">#{{ .Issue.IssueId }}</span>
10
10
-
</h1>
10
10
+
<span class="text-gray-500">#{{ .Issue.IssueId }}</span>
11
11
+
</p>
12
12
+
</header>
11
13
12
14
{{ $bgColor := "bg-gray-800" }}
13
15
{{ $icon := "ban" }}
···
25
23
<i data-lucide="{{ $icon }}" class="w-4 h-4 mr-1.5 text-white" ></i>
26
24
<span class="text-white">{{ .State }}</span>
27
25
</div>
28
28
-
<span class="text-gray-400 text-sm">
26
26
+
<span class="text-gray-500 text-sm">
29
27
opened by
30
28
{{ $owner := didOrHandle .Issue.OwnerDid .IssueOwnerHandle }}
31
29
<a href="/{{ $owner }}" class="no-underline hover:underline"
···
37
35
</div>
38
36
39
37
{{ if .Issue.Body }}
40
40
-
<article id="body" class="mt-8 prose">
38
38
+
<article id="body" class="mt-4 prose">
41
39
{{ .Issue.Body | markdown }}
42
40
</article>
43
41
{{ end }}
···
49
47
{{ range $index, $comment := .Comments }}
50
48
<div
51
49
id="comment-{{ .CommentId }}"
52
52
-
class="rounded bg-white p-4 relative"
50
50
+
class="rounded bg-white px-6 py-4 relative"
53
51
>
54
52
{{ if eq $index 0 }}
55
53
<div
···
60
58
class="absolute left-8 -top-4 w-px h-4 bg-gray-300"
61
59
></div>
62
60
{{ end }}
63
63
-
<div class="flex items-center gap-2 mb-2 text-gray-400">
61
61
+
<div class="flex items-center gap-2 mb-2 text-gray-500">
64
62
{{ $owner := index $.DidHandleMap .OwnerDid }}
65
63
<span class="text-sm">
66
64
<a
···
69
67
>{{ $owner }}</a
70
68
>
71
69
</span>
72
72
-
<span class="px-1 select-none before:content-['\00B7']"></span>
70
70
+
71
71
+
<span class="before:content-['·']"></span>
73
72
<a
74
73
href="#{{ .CommentId }}"
75
74
class="text-gray-500 text-sm hover:text-gray-500 hover:underline no-underline"
+4
-4
appview/pages/templates/repo/issues/issues.html
reviewed
···
4
4
<div class="flex justify-between items-center">
5
5
<p>
6
6
filtering
7
7
-
<select class="font-bold border border-gray-200 rounded" onchange="window.location.href = '/{{ .RepoInfo.FullName }}/issues?state=' + this.value">
7
7
+
<select class="border px-1 bg-white border-gray-200" onchange="window.location.href = '/{{ .RepoInfo.FullName }}/issues?state=' + this.value">
8
8
<option value="open" {{ if .FilteringByOpen }}selected{{ end }}>open</option>
9
9
<option value="closed" {{ if not .FilteringByOpen }}selected{{ end }}>closed</option>
10
10
</select>
···
30
30
class="no-underline hover:underline"
31
31
>
32
32
{{ .Title }}
33
33
-
<span class="text-gray-400">#{{ .IssueId }}</span>
33
33
+
<span class="text-gray-500">#{{ .IssueId }}</span>
34
34
</a>
35
35
</div>
36
36
-
<p class="text-sm text-gray-400">
36
36
+
<p class="text-sm text-gray-500">
37
37
{{ $bgColor := "bg-gray-800" }}
38
38
{{ $icon := "ban" }}
39
39
{{ $state := "closed" }}
···
64
64
{{ if eq .Metadata.CommentCount 1 }}
65
65
{{ $s = "" }}
66
66
{{ end }}
67
67
-
<a href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" class="text-gray-400">{{ .Metadata.CommentCount }} comment{{$s}}</a>
67
67
+
<a href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" class="text-gray-500">{{ .Metadata.CommentCount }} comment{{$s}}</a>
68
68
</span>
69
69
</p>
70
70
</div>
+17
-5
appview/pages/templates/user/profile.html
reviewed
···
44
44
class="py-4 px-6 drop-shadow-sm rounded bg-white"
45
45
>
46
46
<div id="repo-card-name" class="font-medium">
47
47
-
<a href="/@{{ or $.UserHandle $.UserDid }}/{{ .Name }}"
48
48
-
>{{ .Name }}</a
49
49
-
>
47
47
+
<a href="/@{{ or $.UserHandle $.UserDid }}/{{ .Name }}">{{ .Name }}</a>
50
48
</div>
51
49
{{ if .Description }}
52
50
<div class="text-gray-600 text-sm">
53
51
{{ .Description }}
54
52
</div>
55
53
{{ end }}
56
56
-
<div class="text-gray-600 text-sm font-mono">
54
54
+
<div class="text-gray-600 text-sm font-mono inline-flex gap-4">
57
55
{{ .Knot }}
56
56
+
57
57
+
{{ if .RepoStats.StarCount }}
58
58
+
<div class="flex gap-1 items-center text-sm">
59
59
+
<span class="w-2 h-2 fill-current" data-lucide="star"></span>
60
60
+
<span>{{ .RepoStats.StarCount }}</span>
61
61
+
</div>
62
62
+
{{ end }}
58
63
</div>
59
64
</div>
60
65
{{ else }}
···
86
81
{{ .Description }}
87
82
</div>
88
83
{{ end }}
89
89
-
<div class="text-gray-600 text-sm font-mono">
84
84
+
<div class="text-gray-600 text-sm font-mono inline-flex gap-4">
90
85
{{ .Knot }}
86
86
+
87
87
+
{{ if .RepoStats.StarCount }}
88
88
+
<div class="flex gap-1 items-center text-sm">
89
89
+
<span class="w-2 h-2 fill-current" data-lucide="star"></span>
90
90
+
<span>{{ .RepoStats.StarCount }}</span>
91
91
+
</div>
92
92
+
{{ end }}
91
93
</div>
92
94
</div>
93
95
{{ else }}