From 59d060622d375c4123ea88e2fa6c4f34d4fea4d3 Mon Sep 17 00:00:00 2001
From: wxiaoguang <wxiaoguang@gmail.com>
Date: Wed, 26 Apr 2023 10:53:44 +0800
Subject: [PATCH] Improve RSS (#24335)

Follow  #22719

### Major changes

1. `ServerError` doesn't do format, so remove the `%s`
2. Simplify `RenderBranchFeed` (slightly)
3. Remove unused `BranchFeedRSS`
4. Make `feed.RenderBranchFeed` respect `EnableFeed` config
5. Make `RepoBranchTagSelector.vue` respect `EnableFeed` setting,
otherwise there is always RSS icon
6. The `(branchURLPrefix + item.url).replace('src', 'rss')` doesn't seem
right for all cases, for example, the string `src` could appear in
`branchURLPrefix`, so we need a separate `rssURLPrefix`
7. The `<a>` in Vue menu needs `@click.stop`, otherwise the menu itself
would be triggered at the same time
8. Change `<a><button></button></a>` to `<a role=button>`
9. Use `{{PathEscapeSegments .TreePath}}` instead of `{{range $i, $v :=
.TreeNames}}/{{$v}}{{end}}`


Screenshot of changed parts:

<details>


![image](https://user-images.githubusercontent.com/2114189/234315538-66603694-9093-48a8-af33-83575fd7a018.png)


![image](https://user-images.githubusercontent.com/2114189/234315786-f1efa60b-012e-490b-8ce2-d448dc6fe5c9.png)


![image](https://user-images.githubusercontent.com/2114189/234334941-446941bc-1baa-4256-8850-ccc439476cda.png)

</details>


### Other thoughts

Should we remove the RSS icon from the branch dropdown list? It seems
too complex for a list UI, and users already have the chance to get the
RSS feed URL from "branches" page.

---------

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: silverwind <me@silverwind.io>
---
 routers/web/feed/branch.go                      |  2 +-
 routers/web/feed/file.go                        |  2 +-
 routers/web/feed/render.go                      | 12 ++++--------
 routers/web/repo/branch.go                      |  6 ------
 routers/web/web.go                              |  4 ++--
 templates/repo/branch_dropdown.tmpl             |  2 ++
 templates/repo/home.tmpl                        |  5 +++--
 templates/repo/view_file.tmpl                   |  4 +---
 tests/integration/pull_create_test.go           |  2 +-
 web_src/js/components/RepoBranchTagSelector.vue | 11 ++++++++++-
 10 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go
index fb9d2a7351..22b6e2f14b 100644
--- a/routers/web/feed/branch.go
+++ b/routers/web/feed/branch.go
@@ -18,7 +18,7 @@ import (
 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)
+		ctx.ServerError("ShowBranchFeed", err)
 		return
 	}
 
diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go
index 3dc9a4e27f..6a8d0c454d 100644
--- a/routers/web/feed/file.go
+++ b/routers/web/feed/file.go
@@ -23,7 +23,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string
 	}
 	commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ctx.Repo.RefName, fileName, 1)
 	if err != nil {
-		ctx.ServerError("ShowBranchFeed %s", err)
+		ctx.ServerError("ShowBranchFeed", err)
 		return
 	}
 
diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go
index 0f327f87f2..8931dae8cc 100644
--- a/routers/web/feed/render.go
+++ b/routers/web/feed/render.go
@@ -4,19 +4,15 @@
 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
+	if ctx.Repo.TreePath == "" {
+		ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType)
+	} else {
+		ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType)
 	}
-	renderer(ctx, ctx.Repo.Repository, showFeedType)
 }
diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go
index 1014449f78..9f26634311 100644
--- a/routers/web/repo/branch.go
+++ b/routers/web/repo/branch.go
@@ -25,7 +25,6 @@ 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"
@@ -341,11 +340,6 @@ 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/web.go b/routers/web/web.go
index af39059325..779499889f 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1454,8 +1454,8 @@ 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.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
+		m.Get("/atom/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
 
 		m.Group("/src", func() {
 			m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home)
diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl
index 1ec4b7ef16..0f79474d10 100644
--- a/templates/repo/branch_dropdown.tmpl
+++ b/templates/repo/branch_dropdown.tmpl
@@ -42,6 +42,8 @@
 		'branches': {{.root.Branches}},
 		'tags': {{.root.Tags}},
 		'defaultBranch': {{$defaultBranch}},
+		'enableFeed': {{.root.EnableFeed}},
+		'rssURLPrefix': '{{$.root.RepoLink}}/rss/branch/',
 		'branchURLPrefix': '{{if .branchURLPrefix}}{{.branchURLPrefix}}{{else}}{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/branch/{{end}}',
 		'branchURLSuffix': '{{if .branchURLSuffix}}{{.branchURLSuffix}}{{else}}{{if $.root.TreePath}}/{{PathEscapeSegments $.root.TreePath}}{{end}}{{end}}',
 		'tagURLPrefix': '{{if .tagURLPrefix}}{{.tagURLPrefix}}{{else if .release}}{{$.root.RepoLink}}/compare/{{else}}{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/tag/{{end}}',
diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl
index 3f6cffbc8e..69f7f03880 100644
--- a/templates/repo/home.tmpl
+++ b/templates/repo/home.tmpl
@@ -64,8 +64,9 @@
 				{{$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 id="new-pull-request" role="button" class="ui compact basic button" href="{{CompareLink .BaseRepo .Repository .BranchName}}"
+						data-tooltip-content="{{if .PullRequestCtx.Allowed}}{{.locale.Tr "repo.pulls.compare_changes"}}{{else}}{{.locale.Tr "action.compare_branch"}}{{end}}">
+						{{svg "octicon-git-pull-request"}}
 					</a>
 				{{end}}
 				{{if eq $n 0}}
diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl
index fe67de5392..03f90d71f2 100644
--- a/templates/repo/view_file.tmpl
+++ b/templates/repo/view_file.tmpl
@@ -43,9 +43,7 @@
 				<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>
+				<a class="btn-octicon" href="{{$.FeedURL}}/rss/{{$.BranchNameSubURL}}/{{PathEscapeSegments .TreePath}}">{{svg "octicon-rss" 14}}</a>
 				{{end}}
 				{{if .Repository.CanEnableEditor}}
 					{{if .CanEditFile}}
diff --git a/tests/integration/pull_create_test.go b/tests/integration/pull_create_test.go
index 3a13fb4fcb..6e2d65ca0a 100644
--- a/tests/integration/pull_create_test.go
+++ b/tests/integration/pull_create_test.go
@@ -22,7 +22,7 @@ func testPullCreate(t *testing.T, session *TestSession, user, repo, branch, titl
 
 	// Click the PR button to create a pull
 	htmlDoc := NewHTMLParser(t, resp.Body)
-	link, exists := htmlDoc.doc.Find("#new-pull-request").Parent().Attr("href")
+	link, exists := htmlDoc.doc.Find("#new-pull-request").Attr("href")
 	assert.True(t, exists, "The template has changed")
 	if branch != "master" {
 		link = strings.Replace(link, ":master", ":"+branch, 1)
diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue
index 863da6206f..d8451e8399 100644
--- a/web_src/js/components/RepoBranchTagSelector.vue
+++ b/web_src/js/components/RepoBranchTagSelector.vue
@@ -39,7 +39,7 @@
       <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')">
+          <a v-if="enableFeed && mode === 'branches'" role="button" class="ui compact muted right" :href="rssURLPrefix + item.url" target="_blank" @click.stop>
             <svg-icon name="octicon-rss" :size="14"/>
           </a>
         </div>
@@ -294,3 +294,12 @@ export function initRepoBranchTagSelector(selector) {
 
 export default sfc; // activate IDE's Vue plugin
 </script>
+
+<style scoped>
+.menu .item a {
+  display: none; /* only show RSS icon on hover */
+}
+.menu .item:hover a {
+  display: inline-block;
+}
+</style>