diff --git a/appview/pages/pages.go b/appview/pages/pages.go --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -846,6 +846,20 @@ return p.executeRepo("repo/tags", w, params) } +type RepoTagParams struct { + LoggedInUser *oauth.MultiAccountUser + RepoInfo repoinfo.RepoInfo + Active string + types.RepoTagResponse + ArtifactMap map[plumbing.Hash][]models.Artifact + DanglingArtifacts []models.Artifact +} + +func (p *Pages) RepoTag(w io.Writer, params RepoTagParams) error { + params.Active = "overview" + return p.executeRepo("repo/tag", w, params) +} + type RepoArtifactParams struct { LoggedInUser *oauth.MultiAccountUser RepoInfo repoinfo.RepoInfo diff --git a/appview/repo/router.go b/appview/repo/router.go --- a/appview/repo/router.go +++ b/appview/repo/router.go @@ -23,6 +23,7 @@ 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 --- a/appview/repo/tags.go +++ b/appview/repo/tags.go @@ -14,6 +14,7 @@ "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,11 +71,68 @@ } } user := rp.oauth.GetMultiAccountUser(r) + rp.pages.RepoTags(w, pages.RepoTagsParams{ LoggedInUser: user, RepoInfo: rp.repoResolver.GetRepoInfo(r, user), RepoTagsResponse: result, ArtifactMap: artifactMap, 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, }) } diff --git a/appview/pages/templates/repo/index.html b/appview/pages/templates/repo/index.html --- a/appview/pages/templates/repo/index.html +++ b/appview/pages/templates/repo/index.html @@ -334,7 +334,7 @@ {{ with $tag }}
- {{ .Reference.Name }} diff --git a/appview/pages/templates/repo/tag.html b/appview/pages/templates/repo/tag.html new file mode 100644 --- /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" }} +
+ {{ template "repo/fragments/singleTag" (list $ .Tag ) }} +
+{{ end }} diff --git a/appview/pages/templates/repo/tags.html b/appview/pages/templates/repo/tags.html --- a/appview/pages/templates/repo/tags.html +++ b/appview/pages/templates/repo/tags.html @@ -14,66 +14,7 @@

tags

{{ range .Tags }} -
- -
- -
- - {{ i "tag" "w-4 h-4" }} - {{ .Name }} - - -
- {{ if .Tag }} - - {{ slice .Tag.Target.String 0 8 }} - - - - {{ .Tag.Tagger.Name }} - - - {{ template "repo/fragments/shortTime" .Tag.Tagger.When }} - {{ end }} -
-
- - - -
- - -
- {{ 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. @@ -89,75 +30,6 @@ {{ block "dangling" . }} {{ end }} {{ 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 }} -
-
- {{ i "archive" "w-4 h-4" }} - - Source code (.tar.gz) - -
-
- {{ 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" }} diff --git a/appview/pages/templates/repo/fragments/artifact.html b/appview/pages/templates/repo/fragments/artifact.html --- a/appview/pages/templates/repo/fragments/artifact.html +++ b/appview/pages/templates/repo/fragments/artifact.html @@ -19,14 +19,15 @@ {{ if and .LoggedInUser (eq .LoggedInUser.Did .Artifact.Did) }} {{ end }}
diff --git a/appview/pages/templates/repo/fragments/artifactList.html b/appview/pages/templates/repo/fragments/artifactList.html new file mode 100644 --- /dev/null +++ b/appview/pages/templates/repo/fragments/artifactList.html @@ -0,0 +1,70 @@ +{{ define "repo/fragments/artifactList" }} + {{ $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 }} +
+
+ {{ i "archive" "w-4 h-4" }} + + Source code (.tar.gz) + +
+
+ {{ if $isPushAllowed }} + {{ template "uploadArtifact" (list $root $tag) }} + {{ end }} +
+{{ end }} + +{{ define "uploadArtifact" }} +{{ $root := index . 0 }} +{{ $tag := index . 1 }} +{{ $unique := $tag.Tag.Target.String }} +
+
+ + +
+
+ +
+
+{{ end }} + diff --git a/appview/pages/templates/repo/fragments/singleTag.html b/appview/pages/templates/repo/fragments/singleTag.html new file mode 100644 --- /dev/null +++ b/appview/pages/templates/repo/fragments/singleTag.html @@ -0,0 +1,67 @@ +{{ define "repo/fragments/singleTag" }} + {{ $root := index . 0 }} + {{ $item := index . 1 }} + {{ with $item }} +
+ +
+ +
+ + {{ i "tag" "w-4 h-4" }} + {{ .Name }} + + +
+ {{ if .Tag }} + + {{ slice .Tag.Target.String 0 8 }} + + + + {{ .Tag.Tagger.Name }} + + + {{ template "repo/fragments/shortTime" .Tag.Tagger.When }} + {{ end }} +
+
+ + + +
+ + +
+ {{ if .Tag }} + {{ $messageParts := splitN .Tag.Message "\n\n" 2 }} +

{{ index $messageParts 0 }}

+ {{ if gt (len $messageParts) 1 }} +

{{ nl2br (index $messageParts 1) }}

+ {{ end }} + {{ template "repo/fragments/artifactList" (list $root .) }} + {{ else }} +

no message

+ {{ end }} +
+
+ {{ end }} +{{ end }} +