tangled
alpha
login
or
join now
bad-example.com
/
core
forked from
tangled.org/core
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
show stars in profile; styles for issue comments
oppi.li
10 months 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
···
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) {
···
52
55
func GetAllReposByDid(e Execer, did string) ([]Repo, error) {
53
56
var repos []Repo
54
57
55
55
-
rows, err := e.Query(`select did, name, knot, rkey, description, created from repos where did = ?`, did)
58
58
+
rows, err := e.Query(
59
59
+
`select
60
60
+
r.did,
61
61
+
r.name,
62
62
+
r.knot,
63
63
+
r.rkey,
64
64
+
r.description,
65
65
+
r.created,
66
66
+
count(s.id) as star_count
67
67
+
from
68
68
+
repos r
69
69
+
left join
70
70
+
stars s on r.at_uri = s.repo_at
71
71
+
where
72
72
+
r.did = ?
73
73
+
group by
74
74
+
r.at_uri`, did)
56
75
if err != nil {
57
76
return nil, err
58
77
}
···
60
79
61
80
for rows.Next() {
62
81
var repo Repo
63
63
-
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created)
82
82
+
var repoStats RepoStats
83
83
+
var createdAt string
84
84
+
var nullableDescription sql.NullString
85
85
+
86
86
+
err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount)
64
87
if err != nil {
65
88
return nil, err
66
89
}
90
90
+
91
91
+
if nullableDescription.Valid {
92
92
+
repo.Description = nullableDescription.String
93
93
+
} else {
94
94
+
repo.Description = ""
95
95
+
}
96
96
+
97
97
+
createdAtTime, err := time.Parse(time.RFC3339, createdAt)
98
98
+
if err != nil {
99
99
+
repo.Created = time.Now()
100
100
+
} else {
101
101
+
repo.Created = createdAtTime
102
102
+
}
103
103
+
104
104
+
repo.RepoStats = &repoStats
105
105
+
67
106
repos = append(repos, repo)
68
107
}
69
108
···
150
189
func CollaboratingIn(e Execer, collaborator string) ([]Repo, error) {
151
190
var repos []Repo
152
191
153
153
-
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)
192
192
+
rows, err := e.Query(
193
193
+
`select
194
194
+
r.did, r.name, r.knot, r.rkey, r.description, r.created, count(s.id) as star_count
195
195
+
from
196
196
+
repos r
197
197
+
join
198
198
+
collaborators c on r.id = c.repo
199
199
+
left join
200
200
+
stars s on r.at_uri = s.repo_at
201
201
+
where
202
202
+
c.did = ?
203
203
+
group by
204
204
+
r.id;`, collaborator)
154
205
if err != nil {
155
206
return nil, err
156
207
}
···
158
209
159
210
for rows.Next() {
160
211
var repo Repo
161
161
-
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created)
212
212
+
var repoStats RepoStats
213
213
+
var createdAt string
214
214
+
var nullableDescription sql.NullString
215
215
+
216
216
+
err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount)
162
217
if err != nil {
163
218
return nil, err
164
219
}
220
220
+
221
221
+
if nullableDescription.Valid {
222
222
+
repo.Description = nullableDescription.String
223
223
+
} else {
224
224
+
repo.Description = ""
225
225
+
}
226
226
+
227
227
+
createdAtTime, err := time.Parse(time.RFC3339, createdAt)
228
228
+
if err != nil {
229
229
+
repo.Created = time.Now()
230
230
+
} else {
231
231
+
repo.Created = createdAtTime
232
232
+
}
233
233
+
234
234
+
repo.RepoStats = &repoStats
235
235
+
165
236
repos = append(repos, repo)
166
237
}
167
238
+3
-1
appview/db/star.go
···
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
···
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
···
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
···
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" }}
···
23
25
<i data-lucide="{{ $icon }}" class="w-4 h-4 mr-1.5 text-white" ></i>
24
26
<span class="text-white">{{ .State }}</span>
25
27
</div>
26
26
-
<span class="text-gray-400 text-sm">
28
28
+
<span class="text-gray-500 text-sm">
27
29
opened by
28
30
{{ $owner := didOrHandle .Issue.OwnerDid .IssueOwnerHandle }}
29
31
<a href="/{{ $owner }}" class="no-underline hover:underline"
···
35
37
</div>
36
38
37
39
{{ if .Issue.Body }}
38
38
-
<article id="body" class="mt-8 prose">
40
40
+
<article id="body" class="mt-4 prose">
39
41
{{ .Issue.Body | markdown }}
40
42
</article>
41
43
{{ end }}
···
47
49
{{ range $index, $comment := .Comments }}
48
50
<div
49
51
id="comment-{{ .CommentId }}"
50
50
-
class="rounded bg-white p-4 relative"
52
52
+
class="rounded bg-white px-6 py-4 relative"
51
53
>
52
54
{{ if eq $index 0 }}
53
55
<div
···
58
60
class="absolute left-8 -top-4 w-px h-4 bg-gray-300"
59
61
></div>
60
62
{{ end }}
61
61
-
<div class="flex items-center gap-2 mb-2 text-gray-400">
63
63
+
<div class="flex items-center gap-2 mb-2 text-gray-500">
62
64
{{ $owner := index $.DidHandleMap .OwnerDid }}
63
65
<span class="text-sm">
64
66
<a
···
67
69
>{{ $owner }}</a
68
70
>
69
71
</span>
70
70
-
<span class="px-1 select-none before:content-['\00B7']"></span>
72
72
+
73
73
+
<span class="before:content-['·']"></span>
71
74
<a
72
75
href="#{{ .CommentId }}"
73
76
class="text-gray-500 text-sm hover:text-gray-500 hover:underline no-underline"
+4
-4
appview/pages/templates/repo/issues/issues.html
···
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
···
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 }}
···
81
86
{{ .Description }}
82
87
</div>
83
88
{{ end }}
84
84
-
<div class="text-gray-600 text-sm font-mono">
89
89
+
<div class="text-gray-600 text-sm font-mono inline-flex gap-4">
85
90
{{ .Knot }}
91
91
+
92
92
+
{{ if .RepoStats.StarCount }}
93
93
+
<div class="flex gap-1 items-center text-sm">
94
94
+
<span class="w-2 h-2 fill-current" data-lucide="star"></span>
95
95
+
<span>{{ .RepoStats.StarCount }}</span>
96
96
+
</div>
97
97
+
{{ end }}
86
98
</div>
87
99
</div>
88
100
{{ else }}