diff options
-rw-r--r-- | routers/web/feed/branch.go | 50 | ||||
-rw-r--r-- | routers/web/feed/file.go | 56 | ||||
-rw-r--r-- | routers/web/feed/render.go | 22 | ||||
-rw-r--r-- | routers/web/repo/branch.go | 6 | ||||
-rw-r--r-- | routers/web/repo/view.go | 9 | ||||
-rw-r--r-- | routers/web/web.go | 3 | ||||
-rw-r--r-- | templates/repo/branch/list.tmpl | 10 | ||||
-rw-r--r-- | templates/repo/home.tmpl | 10 | ||||
-rw-r--r-- | templates/repo/view_file.tmpl | 5 | ||||
-rw-r--r-- | web_src/js/components/RepoBranchTagSelector.vue | 3 | ||||
-rw-r--r-- | web_src/js/svg.js | 2 |
11 files changed, 170 insertions, 6 deletions
diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go new file mode 100644 index 0000000000..fb9d2a7351 --- /dev/null +++ b/routers/web/feed/branch.go @@ -0,0 +1,50 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package feed + +import ( + "fmt" + "strings" + "time" + + "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/context" + + "github.com/gorilla/feeds" +) + +// ShowBranchFeed shows tags and/or releases on the repo as RSS / Atom feed +func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType string) { + commits, err := ctx.Repo.Commit.CommitsByRange(0, 10) + if err != nil { + ctx.ServerError("ShowBranchFeed %s", err) + return + } + + title := fmt.Sprintf("Latest commits for branch %s", ctx.Repo.BranchName) + link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.BranchNameSubURL()} + + feed := &feeds.Feed{ + Title: title, + Link: link, + Description: repo.Description, + Created: time.Now(), + } + + for _, commit := range commits { + feed.Items = append(feed.Items, &feeds.Item{ + Id: commit.ID.String(), + Title: strings.TrimSpace(strings.Split(commit.Message(), "\n")[0]), + Link: &feeds.Link{Href: repo.HTMLURL() + "/commit/" + commit.ID.String()}, + Author: &feeds.Author{ + Name: commit.Author.Name, + Email: commit.Author.Email, + }, + Description: commit.Message(), + Content: commit.Message(), + }) + } + + writeFeed(ctx, feed, formatType) +} diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go new file mode 100644 index 0000000000..3dc9a4e27f --- /dev/null +++ b/routers/web/feed/file.go @@ -0,0 +1,56 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package feed + +import ( + "fmt" + "strings" + "time" + + "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/util" + + "github.com/gorilla/feeds" +) + +// ShowFileFeed shows tags and/or releases on the repo as RSS / Atom feed +func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string) { + fileName := ctx.Repo.TreePath + if len(fileName) == 0 { + return + } + commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ctx.Repo.RefName, fileName, 1) + if err != nil { + ctx.ServerError("ShowBranchFeed %s", err) + return + } + + title := fmt.Sprintf("Latest commits for file %s", ctx.Repo.TreePath) + + link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)} + + feed := &feeds.Feed{ + Title: title, + Link: link, + Description: repo.Description, + Created: time.Now(), + } + + for _, commit := range commits { + feed.Items = append(feed.Items, &feeds.Item{ + Id: commit.ID.String(), + Title: strings.TrimSpace(strings.Split(commit.Message(), "\n")[0]), + Link: &feeds.Link{Href: repo.HTMLURL() + "/commit/" + commit.ID.String()}, + Author: &feeds.Author{ + Name: commit.Author.Name, + Email: commit.Author.Email, + }, + Description: commit.Message(), + Content: commit.Message(), + }) + } + + writeFeed(ctx, feed, formatType) +} diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go new file mode 100644 index 0000000000..0f327f87f2 --- /dev/null +++ b/routers/web/feed/render.go @@ -0,0 +1,22 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package feed + +import ( + model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/context" +) + +// RenderBranchFeed render format for branch or file +func RenderBranchFeed(ctx *context.Context) { + _, _, showFeedType := GetFeedType(ctx.Params(":reponame"), ctx.Req) + var renderer func(ctx *context.Context, repo *model.Repository, formatType string) + switch { + case ctx.Repo.TreePath == "": + renderer = ShowBranchFeed + case ctx.Repo.TreePath != "": + renderer = ShowFileFeed + } + renderer(ctx, ctx.Repo.Repository, showFeedType) +} diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 9f26634311..1014449f78 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" + "code.gitea.io/gitea/routers/web/feed" "code.gitea.io/gitea/services/forms" release_service "code.gitea.io/gitea/services/release" repo_service "code.gitea.io/gitea/services/repository" @@ -340,6 +341,11 @@ func getDeletedBranches(ctx *context.Context) ([]*Branch, error) { return branches, nil } +// BranchFeedRSS get feeds for tags in RSS format +func BranchFeedRSS(ctx *context.Context) { + feed.ShowBranchFeed(ctx, ctx.Repo.Repository, "rss") +} + // CreateBranch creates new branch in repository func CreateBranch(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewBranchForm) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index f9dca91844..9f2770a3ac 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -710,7 +710,14 @@ func Home(ctx *context.Context) { if setting.Other.EnableFeed { isFeed, _, showFeedType := feed.GetFeedType(ctx.Params(":reponame"), ctx.Req) if isFeed { - feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType) + switch { + case ctx.Link == fmt.Sprintf("%s.%s", ctx.Repo.RepoLink, showFeedType): + feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType) + case ctx.Repo.TreePath == "": + feed.ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType) + case ctx.Repo.TreePath != "": + feed.ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType) + } return } } diff --git a/routers/web/web.go b/routers/web/web.go index 88b6777d73..f7f32734d8 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1450,6 +1450,9 @@ func RegisterRoutes(m *web.Route) { m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) + m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feed.RenderBranchFeed) + m.Get("/atom/branch/*", context.RepoRefByType(context.RepoRefBranch), feed.RenderBranchFeed) + m.Group("/src", func() { m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home) m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.Home) diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index b027c175a4..596d9ae78b 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -26,6 +26,11 @@ {{svg "octicon-git-branch"}} </button> {{end}} + {{if .EnableFeed}} + <a role="button" class="ui basic button icon" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .DefaultBranch}}"> + {{svg "octicon-rss"}} + </a> + {{end}} {{if not $.DisableDownloadSourceArchives}} <button class="ui basic jump dropdown icon button" data-tooltip-content="{{$.locale.Tr "repo.branch.download" ($.DefaultBranch)}}"> {{svg "octicon-download"}} @@ -113,6 +118,11 @@ {{svg "octicon-git-branch"}} </button> {{end}} + {{if $.EnableFeed}} + <a role="button" class="ui basic button icon" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .Name}}"> + {{svg "octicon-rss"}} + </a> + {{end}} {{if and (not .IsDeleted) (not $.DisableDownloadSourceArchives)}} <button class="ui basic jump dropdown icon button" data-tooltip-content="{{$.locale.Tr "repo.branch.download" (.Name)}}"> {{svg "octicon-download"}} diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 4db12f2c95..3f6cffbc8e 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -63,12 +63,12 @@ {{$n := len .TreeNames}} {{$l := Eval $n "-" 1}} <!-- If home page, show new pr. If not, show breadcrumb --> + {{if and (eq $n 0) .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} + <a href="{{CompareLink .BaseRepo .Repository .BranchName}}"> + <button id="new-pull-request" class="ui compact basic button" data-tooltip-content="{{if .PullRequestCtx.Allowed}}{{.locale.Tr "repo.pulls.compare_changes"}}{{else}}{{.locale.Tr "action.compare_branch"}}{{end}}"><span class="text">{{svg "octicon-git-pull-request"}}</span></button> + </a> + {{end}} {{if eq $n 0}} - {{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} - <a href="{{CompareLink .BaseRepo .Repository .BranchName}}"> - <button id="new-pull-request" class="ui compact basic button" data-tooltip-content="{{if .PullRequestCtx.Allowed}}{{.locale.Tr "repo.pulls.compare_changes"}}{{else}}{{.locale.Tr "action.compare_branch"}}{{end}}"><span class="text">{{svg "octicon-git-pull-request"}}</span></button> - </a> - {{end}} <a href="{{.Repository.Link}}/find/{{.BranchNameSubURL}}" class="ui compact basic button">{{.locale.Tr "repo.find_file.go_to_file"}}</a> {{end}} diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 7ee08c9efc..fe67de5392 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -42,6 +42,11 @@ </div> <a download href="{{$.RawFileLink}}"><span class="btn-octicon" data-tooltip-content="{{.locale.Tr "repo.download_file"}}">{{svg "octicon-download"}}</span></a> <a id="copy-content" class="btn-octicon {{if not .CanCopyContent}} disabled{{end}}"{{if or .IsImageFile (and .HasSourceRenderedToggle (not .IsDisplayingSource))}} data-link="{{$.RawFileLink}}"{{end}} data-tooltip-content="{{if .CanCopyContent}}{{.locale.Tr "copy_content"}}{{else}}{{.locale.Tr "copy_type_unsupported"}}{{end}}">{{svg "octicon-copy" 14}}</a> + {{if .EnableFeed}} + <a class="btn-octicon" href="{{$.FeedURL}}/rss/{{$.BranchNameSubURL}}{{range $i, $v := .TreeNames}}/{{$v}}{{end}}"> + {{svg "octicon-rss" 14}} + </a> + {{end}} {{if .Repository.CanEnableEditor}} {{if .CanEditFile}} <a href="{{.RepoLink}}/_edit/{{PathEscapeSegments .BranchName}}/{{PathEscapeSegments .TreePath}}"><span class="btn-octicon" data-tooltip-content="{{.EditFileTooltip}}">{{svg "octicon-pencil"}}</span></a> diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue index 6a65eeec6f..863da6206f 100644 --- a/web_src/js/components/RepoBranchTagSelector.vue +++ b/web_src/js/components/RepoBranchTagSelector.vue @@ -39,6 +39,9 @@ <div class="scrolling menu" ref="scrollContainer"> <div v-for="(item, index) in filteredItems" :key="item.name" class="item" :class="{selected: item.selected, active: active === index}" @click="selectItem(item)" :ref="'listItem' + index"> {{ item.name }} + <a v-if="mode === 'branches'" role="button" class="ui compact muted right" :href="(branchURLPrefix + item.url).replace('src', 'rss')"> + <svg-icon name="octicon-rss" :size="14"/> + </a> </div> <div class="item" v-if="showCreateNewBranch" :class="{active: active === filteredItems.length}" :ref="'listItem' + filteredItems.length"> <a href="#" @click="createNewBranch()"> diff --git a/web_src/js/svg.js b/web_src/js/svg.js index 6fa79b8e9b..94f858d7d7 100644 --- a/web_src/js/svg.js +++ b/web_src/js/svg.js @@ -43,6 +43,7 @@ import octiconChevronLeft from '../../public/img/svg/octicon-chevron-left.svg'; import octiconOrganization from '../../public/img/svg/octicon-organization.svg'; import octiconTag from '../../public/img/svg/octicon-tag.svg'; import octiconGitBranch from '../../public/img/svg/octicon-git-branch.svg'; +import octiconRss from '../../public/img/svg/octicon-rss.svg'; const svgs = { 'octicon-blocked': octiconBlocked, @@ -89,6 +90,7 @@ const svgs = { 'octicon-organization': octiconOrganization, 'octicon-tag': octiconTag, 'octicon-git-branch': octiconGitBranch, + 'octicon-rss': octiconRss, }; // TODO: use a more general approach to access SVG icons. |