+6
-5
appview/db/profile.go
+6
-5
appview/db/profile.go
···
1
1
package db
2
2
3
3
import (
4
+
"fmt"
4
5
"sort"
5
6
"time"
6
7
)
···
19
20
20
21
pulls, err := GetPullsByOwnerDid(e, forDid)
21
22
if err != nil {
22
-
return timeline, err
23
+
return timeline, fmt.Errorf("error getting pulls by owner did: %w", err)
23
24
}
24
25
25
26
for _, pull := range pulls {
26
27
repo, err := GetRepoByAtUri(e, string(pull.RepoAt))
27
28
if err != nil {
28
-
return timeline, err
29
+
return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
29
30
}
30
31
31
32
timeline = append(timeline, ProfileTimelineEvent{
···
38
39
39
40
issues, err := GetIssuesByOwnerDid(e, forDid)
40
41
if err != nil {
41
-
return timeline, err
42
+
return timeline, fmt.Errorf("error getting issues by owner did: %w", err)
42
43
}
43
44
44
45
for _, issue := range issues {
45
46
repo, err := GetRepoByAtUri(e, string(issue.RepoAt))
46
47
if err != nil {
47
-
return timeline, err
48
+
return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
48
49
}
49
50
50
51
timeline = append(timeline, ProfileTimelineEvent{
···
57
58
58
59
repos, err := GetAllReposByDid(e, forDid)
59
60
if err != nil {
60
-
return timeline, err
61
+
return timeline, fmt.Errorf("error getting all repos by did: %w", err)
61
62
}
62
63
63
64
for _, repo := range repos {
+5
-4
appview/db/repos.go
+5
-4
appview/db/repos.go
···
88
88
var repoStats RepoStats
89
89
var createdAt string
90
90
var nullableDescription sql.NullString
91
+
var nullableSource sql.NullString
91
92
92
-
err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount)
93
+
err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount, &nullableSource)
93
94
if err != nil {
94
95
return nil, err
95
96
}
···
179
180
}
180
181
181
182
func GetRepoSource(e Execer, repoAt syntax.ATURI) (string, error) {
182
-
var source string
183
-
err := e.QueryRow(`select source from repos where at_uri = ?`, repoAt).Scan(&source)
183
+
var nullableSource sql.NullString
184
+
err := e.QueryRow(`select source from repos where at_uri = ?`, repoAt).Scan(&nullableSource)
184
185
if err != nil {
185
186
return "", err
186
187
}
187
-
return source, nil
188
+
return nullableSource.String, nil
188
189
}
189
190
190
191
func AddCollaborator(e Execer, collaborator, repoOwnerDid, repoName, repoKnot string) error {
+3
-3
appview/pages/pages.go
+3
-3
appview/pages/pages.go
···
199
199
return p.executePlain("fragments/follow", w, params)
200
200
}
201
201
202
-
type StarFragmentParams struct {
202
+
type RepoActionsFragmentParams struct {
203
203
IsStarred bool
204
204
RepoAt syntax.ATURI
205
205
Stats db.RepoStats
206
206
}
207
207
208
-
func (p *Pages) StarFragment(w io.Writer, params StarFragmentParams) error {
209
-
return p.executePlain("fragments/star", w, params)
208
+
func (p *Pages) RepoActionsFragment(w io.Writer, params RepoActionsFragmentParams) error {
209
+
return p.executePlain("fragments/repoActions", w, params)
210
210
}
211
211
212
212
type RepoDescriptionParams struct {
+8
-2
appview/pages/templates/fragments/star.html
appview/pages/templates/fragments/repoActions.html
+8
-2
appview/pages/templates/fragments/star.html
appview/pages/templates/fragments/repoActions.html
···
1
-
{{ define "fragments/star" }}
1
+
{{ define "fragments/repoActions" }}
2
+
<div class="flex items-center">
2
3
<button id="starBtn"
3
-
class="text-sm disabled:opacity-50 disabled:cursor-not-allowed"
4
+
class="btn disabled:opacity-50 disabled:cursor-not-allowed"
4
5
5
6
{{ if .IsStarred }}
6
7
hx-delete="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}"
···
24
25
</span>
25
26
</div>
26
27
</button>
28
+
<a class="btn no-underline hover:no-underline flex items-center" href="/{{ .FullName }}/fork">
29
+
{{ i "git-fork" "w-3 h-3 mr-1"}}
30
+
fork
31
+
</a>
32
+
</div>
27
33
{{ end }}
28
34
+26
-22
appview/pages/templates/layouts/repobase.html
+26
-22
appview/pages/templates/layouts/repobase.html
···
1
1
{{ define "title" }}{{ .RepoInfo.FullName }}{{ end }}
2
2
3
3
{{ define "content" }}
4
-
<section id="repo-header" class="mb-4 py-2 px-6 dark:text-white">
5
-
{{ if .RepoInfo.Source }}
6
-
<p class="text-sm">
7
-
<div class="flex items-center">
8
-
{{ i "git-fork" "w-3 h-3 mr-1"}}
9
-
forked from
10
-
{{ $sourceOwner := didOrHandle .RepoInfo.Source.Did .RepoInfo.SourceHandle }}
11
-
<a class="ml-1 underline" href="/{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}">{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}</a>
12
-
</div>
13
-
</p>
14
-
{{ end }}
15
-
<p class="text-lg">
16
-
<a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a>
17
-
<span class="select-none">/</span>
18
-
<a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a>
19
-
<span class="ml-3">
20
-
{{ template "fragments/star" .RepoInfo }}
21
-
</span>
22
-
</p>
23
-
{{ template "fragments/repoDescription" . }}
24
-
</section>
4
+
<section id="repo-header" class="mb-4 py-2 px-6 dark:text-white">
5
+
{{ if .RepoInfo.Source }}
6
+
<p class="text-sm">
7
+
<div class="flex items-center">
8
+
{{ i "git-fork" "w-3 h-3 mr-1"}}
9
+
forked from
10
+
{{ $sourceOwner := didOrHandle .RepoInfo.Source.Did .RepoInfo.SourceHandle }}
11
+
<a class="ml-1 underline" href="/{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}">{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}</a>
12
+
</div>
13
+
</p>
14
+
{{ end }}
15
+
<div class="text-lg flex items-center justify-between">
16
+
<div>
17
+
<a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a>
18
+
<span class="select-none">/</span>
19
+
<a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a>
20
+
</div>
21
+
<div class="flex items-center">
22
+
<span class="mr-3">
23
+
{{ template "fragments/repoActions" .RepoInfo }}
24
+
</span>
25
+
</div>
26
+
</div>
27
+
{{ template "fragments/repoDescription" . }}
28
+
</section>
25
29
<section class="min-h-screen flex flex-col drop-shadow-sm">
26
30
<nav class="w-full pl-4 overflow-auto">
27
31
<div class="flex z-60">
···
46
50
{{ end }}
47
51
"
48
52
>
49
-
{{ $key }}
53
+
{{ $key }}
50
54
{{ if not (isNil $meta) }}
51
55
<span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-sm">{{ $meta }}</span>
52
56
{{ end }}
+14
-9
appview/state/repo.go
+14
-9
appview/state/repo.go
···
807
807
if errors.Is(err, sql.ErrNoRows) {
808
808
source = ""
809
809
} else if err != nil {
810
-
log.Println("failed to get repo source for ", f.RepoAt)
810
+
log.Println("failed to get repo source for ", f.RepoAt, err)
811
811
}
812
812
813
813
var sourceRepo *db.Repo
···
818
818
}
819
819
}
820
820
821
-
knot := f.Knot
822
-
if knot == "knot1.tangled.sh" {
823
-
knot = "tangled.sh"
824
-
}
825
-
826
821
var sourceHandle *identity.Identity
827
822
if sourceRepo != nil {
828
823
sourceHandle, err = s.resolver.ResolveIdent(context.Background(), sourceRepo.Did)
···
831
826
}
832
827
}
833
828
834
-
return pages.RepoInfo{
829
+
knot := f.Knot
830
+
if knot == "knot1.tangled.sh" {
831
+
knot = "tangled.sh"
832
+
}
833
+
834
+
repoInfo := pages.RepoInfo{
835
835
OwnerDid: f.OwnerDid(),
836
836
OwnerHandle: f.OwnerHandle(),
837
837
Name: f.RepoName,
···
845
845
IssueCount: issueCount,
846
846
PullCount: pullCount,
847
847
},
848
-
Source: sourceRepo,
849
-
SourceHandle: sourceHandle.Handle.String(),
848
+
}
849
+
850
+
if sourceRepo != nil {
851
+
repoInfo.Source = sourceRepo
852
+
repoInfo.SourceHandle = sourceHandle.Handle.String()
850
853
}
854
+
855
+
return repoInfo
851
856
}
852
857
853
858
func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) {
+2
-2
appview/state/star.go
+2
-2
appview/state/star.go
···
62
62
63
63
log.Println("created atproto record: ", resp.Uri)
64
64
65
-
s.pages.StarFragment(w, pages.StarFragmentParams{
65
+
s.pages.RepoActionsFragment(w, pages.RepoActionsFragmentParams{
66
66
IsStarred: true,
67
67
RepoAt: subjectUri,
68
68
Stats: db.RepoStats{
···
101
101
log.Println("failed to get star count for ", subjectUri)
102
102
}
103
103
104
-
s.pages.StarFragment(w, pages.StarFragmentParams{
104
+
s.pages.RepoActionsFragment(w, pages.RepoActionsFragmentParams{
105
105
IsStarred: false,
106
106
RepoAt: subjectUri,
107
107
Stats: db.RepoStats{