diff --git a/appview/pages/templates/repo/tag.html b/appview/pages/templates/repo/tag.html
new file mode 100644
index 00000000..43033cea
--- /dev/null
+++ b/appview/pages/templates/repo/tag.html
@@ -0,0 +1,16 @@
+{{ define "title" }}
+ tags · {{ .RepoInfo.FullName }}
+{{ end }}
+
+{{ define "extrameta" }}
+ {{ $title := printf "tags · %s" .RepoInfo.FullName }}
+ {{ $url := printf "https://tangled.org/%s/tag/%s" .RepoInfo.FullName .Tag.Name }}
+
+ {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }}
+{{ end }}
+
+{{ define "repoContent" }}
+
+{{ end }}
diff --git a/appview/pages/templates/repo/tags.html b/appview/pages/templates/repo/tags.html
index 2ac85119..e14e777e 100644
--- a/appview/pages/templates/repo/tags.html
+++ b/appview/pages/templates/repo/tags.html
@@ -14,66 +14,7 @@
{{ range .Tags }}
-
-
-
-
-
-
- {{ if .Tag }}
- {{ $messageParts := splitN .Tag.Message "\n\n" 2 }}
-
{{ index $messageParts 0 }}
- {{ if gt (len $messageParts) 1 }}
-
{{ nl2br (index $messageParts 1) }}
- {{ end }}
- {{ block "artifacts" (list $ .) }} {{ end }}
- {{ else }}
-
no message
- {{ end }}
-
-
+ {{ template "repo/fragments/singleTag" (list $ . ) }}
{{ else }}
This repository does not contain any tags.
@@ -91,75 +32,6 @@
{{ end }}
{{ end }}
-{{ define "artifacts" }}
- {{ $root := index . 0 }}
- {{ $tag := index . 1 }}
- {{ $isPushAllowed := $root.RepoInfo.Roles.IsPushAllowed }}
- {{ $artifacts := index $root.ArtifactMap $tag.Tag.Hash }}
-
-
artifacts
-
- {{ range $artifact := $artifacts }}
- {{ $args := dict "LoggedInUser" $root.LoggedInUser "RepoInfo" $root.RepoInfo "Artifact" $artifact }}
- {{ template "repo/fragments/artifact" $args }}
- {{ end }}
-
- {{ if $isPushAllowed }}
- {{ block "uploadArtifact" (list $root $tag) }} {{ end }}
- {{ end }}
-
-{{ end }}
-
-{{ define "uploadArtifact" }}
-{{ $root := index . 0 }}
-{{ $tag := index . 1 }}
-{{ $unique := $tag.Tag.Target.String }}
-
-{{ end }}
-
{{ define "dangling" }}
{{ $root := . }}
{{ $isPushAllowed := $root.RepoInfo.Roles.IsPushAllowed }}
diff --git a/appview/repo/router.go b/appview/repo/router.go
index 1667ae58..35386e4e 100644
--- a/appview/repo/router.go
+++ b/appview/repo/router.go
@@ -23,6 +23,7 @@ func (rp *Repo) Router(mw *middleware.Middleware) http.Handler {
r.Route("/tags", func(r chi.Router) {
r.Get("/", rp.Tags)
r.Route("/{tag}", func(r chi.Router) {
+ r.Get("/", rp.Tag)
r.Get("/download/{file}", rp.DownloadArtifact)
// require repo:push to upload or delete artifacts
diff --git a/appview/repo/tags.go b/appview/repo/tags.go
index e81aed53..5b0f9efb 100644
--- a/appview/repo/tags.go
+++ b/appview/repo/tags.go
@@ -14,6 +14,7 @@ import (
"tangled.org/core/types"
indigoxrpc "github.com/bluesky-social/indigo/xrpc"
+ "github.com/go-chi/chi/v5"
"github.com/go-git/go-git/v5/plumbing"
)
@@ -70,6 +71,7 @@ func (rp *Repo) Tags(w http.ResponseWriter, r *http.Request) {
}
}
user := rp.oauth.GetMultiAccountUser(r)
+
rp.pages.RepoTags(w, pages.RepoTagsParams{
LoggedInUser: user,
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
@@ -78,3 +80,59 @@ func (rp *Repo) Tags(w http.ResponseWriter, r *http.Request) {
DanglingArtifacts: danglingArtifacts,
})
}
+
+func (rp *Repo) Tag(w http.ResponseWriter, r *http.Request) {
+ l := rp.logger.With("handler", "RepoTag")
+ f, err := rp.repoResolver.Resolve(r)
+ if err != nil {
+ l.Error("failed to get repo and knot", "err", err)
+ return
+ }
+ scheme := "http"
+ if !rp.config.Core.Dev {
+ scheme = "https"
+ }
+ host := fmt.Sprintf("%s://%s", scheme, f.Knot)
+ xrpcc := &indigoxrpc.Client{
+ Host: host,
+ }
+ repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
+ tag := chi.URLParam(r, "tag")
+
+ xrpcBytes, err := tangled.RepoTag(r.Context(), xrpcc, repo, tag)
+ if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
+ l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
+ rp.pages.Error503(w)
+ return
+ }
+ var result types.RepoTagResponse
+ if err := json.Unmarshal(xrpcBytes, &result); err != nil {
+ l.Error("failed to decode XRPC response", "err", err)
+ rp.pages.Error503(w)
+ return
+ }
+
+ filters := []orm.Filter{orm.FilterEq("repo_at", f.RepoAt())}
+ if result.Tag.Tag != nil {
+ filters = append(filters, orm.FilterEq("tag", result.Tag.Tag.Hash[:]))
+ }
+
+ artifacts, err := db.GetArtifact(rp.db, filters...)
+ if err != nil {
+ l.Error("failed grab artifacts", "err", err)
+ return
+ }
+ // convert artifacts to map for easy UI building
+ artifactMap := make(map[plumbing.Hash][]models.Artifact)
+ for _, a := range artifacts {
+ artifactMap[a.Tag] = append(artifactMap[a.Tag], a)
+ }
+
+ user := rp.oauth.GetMultiAccountUser(r)
+ rp.pages.RepoTag(w, pages.RepoTagParams{
+ LoggedInUser: user,
+ RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
+ RepoTagResponse: result,
+ ArtifactMap: artifactMap,
+ })
+}