+13
appview/pages/pages.go
+13
appview/pages/pages.go
···
11
11
12
12
"github.com/sotangled/tangled/appview/auth"
13
13
"github.com/sotangled/tangled/appview/db"
14
+
"github.com/sotangled/tangled/types"
14
15
)
15
16
16
17
//go:embed templates/*
···
125
126
func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error {
126
127
return p.execute("user/profile", w, params)
127
128
}
129
+
130
+
type RepoIndexParams struct {
131
+
LoggedInUser *auth.User
132
+
Name string
133
+
UserDid string
134
+
UserHandle string
135
+
types.RepoIndexResponse
136
+
}
137
+
138
+
func (p *Pages) RepoIndexPage(w io.Writer, params RepoIndexParams) error {
139
+
return p.execute("repo/index", w, params)
140
+
}
+41
appview/pages/templates/repo/index.html
+41
appview/pages/templates/repo/index.html
···
1
+
{{define "title"}} {{ or .UserHandle .UserDid }} / {{ .Name }} {{end}}
2
+
3
+
{{define "content"}}
4
+
{{- $id := "" -}}
5
+
{{- if .UserHandle -}}
6
+
{{- $id = printf "@%s" .UserHandle -}}
7
+
{{- else -}}
8
+
{{- $id = .UserDid -}}
9
+
{{- end -}}
10
+
11
+
<h1>
12
+
{{ $id }} / {{ .Name }}
13
+
</h1>
14
+
<main>
15
+
<div class="log">
16
+
{{ range .Commits }}
17
+
<div>
18
+
<div><a href="/{{ $id }}/{{ $.Name }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
19
+
<pre>{{ .Message }}</pre>
20
+
</div>
21
+
<div class="commit-info">
22
+
{{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a>
23
+
<div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
24
+
</div>
25
+
{{ end }}
26
+
</div>
27
+
{{- if .Readme }}
28
+
<article class="readme">
29
+
{{- .Readme -}}
30
+
</article>
31
+
{{- end -}}
32
+
33
+
<div class="clone-url">
34
+
<strong>clone</strong>
35
+
<pre>
36
+
git clone https://tangled.sh/{{ $id }}/{{ .Name }}
37
+
</pre>
38
+
</div>
39
+
</main>
40
+
{{end}}
41
+
-36
appview/pages/templates/repo/repo.html
-36
appview/pages/templates/repo/repo.html
···
1
-
<html>
2
-
{{ template "layouts/head" . }}
3
-
4
-
{{ template "layouts/repo-header" . }}
5
-
6
-
<body>
7
-
{{ template "layouts/nav" . }}
8
-
<main>
9
-
{{ $repo := .name }}
10
-
<div class="log">
11
-
{{ range .commits }}
12
-
<div>
13
-
<div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
14
-
<pre>{{ .Message }}</pre>
15
-
</div>
16
-
<div class="commit-info">
17
-
{{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a>
18
-
<div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
19
-
</div>
20
-
{{ end }}
21
-
</div>
22
-
{{- if .readme }}
23
-
<article class="readme">
24
-
{{- .readme -}}
25
-
</article>
26
-
{{- end -}}
27
-
28
-
<div class="clone-url">
29
-
<strong>clone</strong>
30
-
<pre>
31
-
git clone https://{{ .servername }}/{{ .name }}
32
-
</pre>
33
-
</div>
34
-
</main>
35
-
</body>
36
-
</html>
+1
-1
appview/pages/templates/user/profile.html
+1
-1
appview/pages/templates/user/profile.html
+28
-2
appview/state/repo.go
+28
-2
appview/state/repo.go
···
1
1
package state
2
2
3
3
import (
4
+
"encoding/json"
4
5
"fmt"
5
6
"io"
6
7
"log"
···
8
9
9
10
"github.com/bluesky-social/indigo/atproto/identity"
10
11
"github.com/go-chi/chi/v5"
12
+
"github.com/sotangled/tangled/appview/pages"
13
+
"github.com/sotangled/tangled/types"
11
14
)
12
15
13
16
func (s *State) RepoIndex(w http.ResponseWriter, r *http.Request) {
···
33
36
log.Println("failed to reach knotserver", err)
34
37
return
35
38
}
39
+
defer resp.Body.Close()
36
40
37
-
txt, err := io.ReadAll(resp.Body)
38
-
log.Println(resp.Status, string(txt))
41
+
// Read the response body
42
+
body, err := io.ReadAll(resp.Body)
43
+
if err != nil {
44
+
log.Fatalf("Error reading response body: %v", err)
45
+
return
46
+
}
47
+
48
+
var result types.RepoIndexResponse
49
+
err = json.Unmarshal(body, &result)
50
+
if err != nil {
51
+
log.Fatalf("Error unmarshalling response body: %v", err)
52
+
return
53
+
}
54
+
55
+
log.Println(resp.Status, result)
56
+
57
+
user := s.auth.GetUser(r)
58
+
s.pages.RepoIndexPage(w, pages.RepoIndexParams{
59
+
LoggedInUser: user,
60
+
UserDid: id.DID.String(),
61
+
UserHandle: id.Handle.String(),
62
+
Name: repoName,
63
+
RepoIndexResponse: result,
64
+
})
39
65
40
66
return
41
67
}
+14
-8
knotserver/routes.go
+14
-8
knotserver/routes.go
···
21
21
"github.com/russross/blackfriday/v2"
22
22
"github.com/sotangled/tangled/knotserver/db"
23
23
"github.com/sotangled/tangled/knotserver/git"
24
+
"github.com/sotangled/tangled/types"
24
25
)
25
26
26
27
func (h *Handle) Index(w http.ResponseWriter, r *http.Request) {
27
-
w.Write([]byte("This is a knot, part of the wider Tangle network: https://knots.sh"))
28
+
w.Write([]byte("This is a knot, part of the wider Tangle network: https://tangled.sh"))
28
29
}
29
30
30
31
func (h *Handle) RepoIndex(w http.ResponseWriter, r *http.Request) {
···
34
35
gr, err := git.Open(path, "")
35
36
if err != nil {
36
37
if errors.Is(err, plumbing.ErrReferenceNotFound) {
37
-
writeMsg(w, "repo empty")
38
+
resp := types.RepoIndexResponse{
39
+
IsEmpty: true,
40
+
}
41
+
writeJSON(w, resp)
38
42
return
39
43
} else {
40
44
l.Error("opening repo", "error", err.Error())
···
86
90
if len(commits) >= 3 {
87
91
commits = commits[:3]
88
92
}
89
-
data := make(map[string]any)
90
-
data["ref"] = mainBranch
91
-
data["readme"] = readmeContent
92
-
data["commits"] = commits
93
-
data["desc"] = getDescription(path)
93
+
resp := types.RepoIndexResponse{
94
+
IsEmpty: false,
95
+
Ref: mainBranch,
96
+
Commits: commits,
97
+
Description: getDescription(path),
98
+
Readme: readmeContent,
99
+
}
94
100
95
-
writeJSON(w, data)
101
+
writeJSON(w, resp)
96
102
return
97
103
}
98
104
+15
types/repo.go
+15
types/repo.go
···
1
+
package types
2
+
3
+
import (
4
+
"html/template"
5
+
6
+
"github.com/go-git/go-git/v5/plumbing/object"
7
+
)
8
+
9
+
type RepoIndexResponse struct {
10
+
IsEmpty bool `json:"is_empty"`
11
+
Ref string `json:"ref,omitempty"`
12
+
Readme template.HTML `json:"readme,omitempty"`
13
+
Commits []*object.Commit `json:"commits,omitempty"`
14
+
Description string `json:"description,omitempty"`
15
+
}