From df9a78cd04e364264c103cf3a92d94179cc1dd4f Mon Sep 17 00:00:00 2001
From: silverwind <me@silverwind.io>
Date: Sun, 15 Dec 2024 11:01:46 +0100
Subject: [PATCH] Tweak repo sidebar (#32847)

Before and after:

<img width="218" alt="Screenshot 2024-12-15 at 04 53 53"
src="https://github.com/user-attachments/assets/299b1f0a-ba72-47c6-b662-a9d540d4d741"
/>
<img width="222" alt="Screenshot 2024-12-15 at 04 53 41"
src="https://github.com/user-attachments/assets/5a2b5332-e324-4d20-82e9-21d1c850e826"
/>

Diff without whitespace:
https://github.com/go-gitea/gitea/pull/32847/files?diff=unified&w=1

The `tw-mt-2` is fine even if the element renders empty:

<img width="387" alt="image"
src="https://github.com/user-attachments/assets/76a976e4-ba2e-48a5-9248-c361552a937a"
/>

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
---
 options/locale/locale_en-US.ini         |   1 +
 templates/repo/home.tmpl                |   6 +-
 templates/repo/home_sidebar_bottom.tmpl |  94 +++++++++---------
 templates/repo/home_sidebar_top.tmpl    | 124 ++++++++++++------------
 templates/repo/release/label.tmpl       |  14 +++
 templates/repo/release/list.tmpl        |   8 +-
 web_src/css/repo.css                    |   5 -
 web_src/css/repo/home.css               |  14 +--
 web_src/js/features/repo-home.ts        |   6 +-
 9 files changed, 141 insertions(+), 131 deletions(-)
 create mode 100644 templates/repo/release/label.tmpl

diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 74ba70b8c8..92ce4f2db9 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -2632,6 +2632,7 @@ release.new_release = New Release
 release.draft = Draft
 release.prerelease = Pre-Release
 release.stable = Stable
+release.latest = Latest
 release.compare = Compare
 release.edit = edit
 release.ahead.commits = <strong>%d</strong> commits
diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl
index 4e6d375b51..d73b7470bc 100644
--- a/templates/repo/home.tmpl
+++ b/templates/repo/home.tmpl
@@ -18,7 +18,7 @@
 
 		{{$treeNamesLen := len .TreeNames}}
 		{{$isTreePathRoot := eq $treeNamesLen 0}}
-		{{$showSidebar := $isTreePathRoot}}
+		{{$showSidebar := and $isTreePathRoot (not .HideRepoInfo) (not .IsBlame)}}
 		<div class="{{Iif $showSidebar "repo-grid-filelist-sidebar" "repo-grid-filelist-only"}}">
 			<div class="repo-home-filelist">
 				{{template "repo/sub_menu" .}}
@@ -130,8 +130,8 @@
 			</div>
 
 			{{if $showSidebar}}
-				<div class="repo-home-sidebar-top">{{template "repo/home_sidebar_top" .}}</div>
-				<div class="repo-home-sidebar-bottom">{{template "repo/home_sidebar_bottom" .}}</div>
+				{{template "repo/home_sidebar_top" .}}
+				{{template "repo/home_sidebar_bottom" .}}
 			{{end}}
 		</div>
 	</div>
diff --git a/templates/repo/home_sidebar_bottom.tmpl b/templates/repo/home_sidebar_bottom.tmpl
index 57b4a95ddc..f780dc122d 100644
--- a/templates/repo/home_sidebar_bottom.tmpl
+++ b/templates/repo/home_sidebar_bottom.tmpl
@@ -1,59 +1,61 @@
-<div class="flex-list">
-	{{if .LatestRelease}}
-	<div class="flex-item">
-		<div class="flex-item-main">
-			<div class="flex-item-title">
-				<a class="item muted" href="{{.Link}}/releases">
-					{{ctx.Locale.Tr "repo.releases"}}
-					<span class="ui small label">{{.NumReleases}}</span>
-				</a>
-			</div>
-			<div class="flex-item">
-				<div class="flex-item-icon">
-					{{svg "octicon-tag" 16}}
+<div class="repo-home-sidebar-bottom">
+	<div class="flex-list">
+		{{if .LatestRelease}}
+		<div class="flex-item">
+			<div class="flex-item-main">
+				<div class="flex-item-title">
+					<a class="item muted" href="{{.Link}}/releases">
+						{{ctx.Locale.Tr "repo.releases"}}
+						<span class="ui small label">{{.NumReleases}}</span>
+					</a>
 				</div>
-				<div class="flex-item-main">
-					<div class="flex-item-header">
-						<div class="flex-item-title tw-gap-2">
-							<a class="gt-ellipsis muted" href="{{.LatestRelease.Link}}" title="{{.LatestRelease.Title}}">{{.LatestRelease.Title}}</a>
-							<span class="ui basic green label tw-h-100">{{ctx.Locale.Tr "latest"}}</span>
-						</div>
+				<div class="flex-item">
+					<div class="flex-item-icon">
+						{{svg "octicon-tag" 16}}
 					</div>
-					<div class="flex-item-body">
-						<span class="time">{{DateUtils.TimeSince .LatestRelease.CreatedUnix}}</span>
+					<div class="flex-item-main">
+						<div class="flex-item-header">
+							<div class="flex-item-title tw-gap-2">
+								<a class="gt-ellipsis muted" href="{{.LatestRelease.Link}}" title="{{.LatestRelease.Title}}">{{.LatestRelease.Title}}</a>
+								{{template "repo/release/label" (dict "Release" .LatestRelease "IsLatest" true)}}
+							</div>
+						</div>
+						<div class="flex-item-body">
+							<span class="time">{{DateUtils.TimeSince .LatestRelease.CreatedUnix}}</span>
+						</div>
 					</div>
 				</div>
 			</div>
 		</div>
-	</div>
-	{{end}}
+		{{end}}
 
-	{{if and (not .IsEmptyRepo) .LanguageStats}}
-	<div class="flex-item">
-		<div class="flex-item-main">
-			<div class="flex-item-title">
-				{{ctx.Locale.Tr "repo.repo_lang"}}
-			</div>
-
-			<div class="flex-item-body">
-				<div class="language-stats">
-					{{range .LanguageStats}}
-						<div class="bar" style="width: {{.Percentage}}%; background-color: {{.Color}}" data-tooltip-placement="top" data-tooltip-content={{.Language}} data-tooltip-follow-cursor="horizontal"></div>
-					{{end}}
+		{{if and (not .IsEmptyRepo) .LanguageStats}}
+		<div class="flex-item">
+			<div class="flex-item-main">
+				<div class="flex-item-title">
+					{{ctx.Locale.Tr "repo.repo_lang"}}
 				</div>
-				<div class="language-stats-details">
-					{{range .LanguageStats}}
-						<div class="item">
-							<i class="color-icon" style="background-color: {{.Color}}"></i>
-							<span class="tw-font-semibold">
-								{{Iif (eq .Language "other") (ctx.Locale.Tr "repo.language_other") .Language}}
-							</span>
-							{{.Percentage}}%
-						</div>
-					{{end}}
+
+				<div class="flex-item-body">
+					<div class="language-stats">
+						{{range .LanguageStats}}
+							<div class="bar" style="width: {{.Percentage}}%; background-color: {{.Color}}" data-tooltip-placement="top" data-tooltip-content={{.Language}} data-tooltip-follow-cursor="horizontal"></div>
+						{{end}}
+					</div>
+					<div class="language-stats-details">
+						{{range .LanguageStats}}
+							<div class="item">
+								<i class="color-icon" style="background-color: {{.Color}}"></i>
+								<span class="tw-font-semibold">
+									{{Iif (eq .Language "other") (ctx.Locale.Tr "repo.language_other") .Language}}
+								</span>
+								{{.Percentage}}%
+							</div>
+						{{end}}
+					</div>
 				</div>
 			</div>
 		</div>
+		{{end}}
 	</div>
-	{{end}}
 </div>
diff --git a/templates/repo/home_sidebar_top.tmpl b/templates/repo/home_sidebar_top.tmpl
index 4b0ebcd390..607dc62e2e 100644
--- a/templates/repo/home_sidebar_top.tmpl
+++ b/templates/repo/home_sidebar_top.tmpl
@@ -1,68 +1,70 @@
-<form class="ignore-dirty tw-flex tw-flex-1 tw-mt-1" action="{{.RepoLink}}/search" method="get">
-	<div class="ui small action input tw-flex-1">
-		<input name="q" size="10" placeholder="{{ctx.Locale.Tr "search.code_kind"}}">
-		{{template "shared/search/button"}}
-	</div>
-</form>
+<div class="repo-home-sidebar-top">
+	<form class="ignore-dirty tw-flex tw-flex-1 tw-mt-1" action="{{.RepoLink}}/search" method="get">
+		<div class="ui small action input tw-flex-1">
+			<input name="q" size="10" placeholder="{{ctx.Locale.Tr "search.code_kind"}}"> {{template "shared/search/button"}}
+		</div>
+	</form>
 
-<div class="flex-list">
-	<div class="flex-item">
-		<div class="flex-item-main">
-			<div class="flex-item-title">
-				{{ctx.Locale.Tr "repo.repo_desc"}}
-			</div>
-			{{if and (not .HideRepoInfo) (not .IsBlame)}}
-				<div class="flex-item-body repo-description tw-break-anywhere tw-gap-2 tw-mt-2">
-					{{- $description := .Repository.DescriptionHTML ctx -}}
-					{{if $description}}{{$description | RenderCodeBlock}}{{else}}{{ctx.Locale.Tr "repo.repo_no_desc"}}{{end}}
-					{{if .Repository.Website}}{{svg "octicon-link"}}<a href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}
-				</div>
-				<div class="tw-flex tw-items-center tw-flex-wrap tw-gap-2 tw-my-2" id="repo-topics">
-					{{/* !!!! it SHOULD and MUST match the code in issue-home.js */}}
-					{{range .Topics}}<a class="repo-topic ui large label gt-ellipsis" title={{.Name}} href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=1">{{.Name}}</a>{{end}}
-				</div>
-				{{if and .Permission.IsAdmin (not .Repository.IsArchived)}}
-					<button id="manage_topic" class="btn interact-fg tw-text-12">{{ctx.Locale.Tr "repo.topic.manage_topics"}}</button>
-				{{end}}
-			{{end}}
-			{{if and .Permission.IsAdmin (not .Repository.IsArchived)}}
-				<div class="ui form tw-hidden flex-item-body tw-gap-2 tw-my-2" id="topic_edit">
-					<div class="ui fluid multiple search selection dropdown tw-flex-wrap tw-flex-1">
-						<input type="hidden" name="topics" value="{{range $i, $v := .Topics}}{{.Name}}{{if Eval $i "+" 1 "<" (len $.Topics)}},{{end}}{{end}}">
-						{{range .Topics}}
-							{{/* keep the same layout as Fomantic UI generated labels */}}
-							<a class="ui label transition visible tw-cursor-default tw-inline-block repo-topic" data-value="{{.Name}}">{{.Name}}{{svg "octicon-x" 16 "delete icon"}}</a>
+	<div class="flex-list">
+		<div class="flex-item">
+			<div class="flex-item-main">
+				<div class="flex-item-title">{{ctx.Locale.Tr "repo.repo_desc"}}</div>
+				<div class="flex-item-body tw-text-16">
+					<div class="tw-flex tw-flex-col tw-gap-2 tw-mt-2">
+						<div class="repo-description tw-break-anywhere tw-gap-2">
+							{{- $description := .Repository.DescriptionHTML ctx -}}
+							{{if $description}}{{$description | RenderCodeBlock}}{{else}}{{ctx.Locale.Tr "repo.repo_no_desc"}}{{end}}
+						</div>
+
+						{{if .Repository.Website}}
+							<a class="flex-text-block" href="{{.Repository.Website}}">
+								{{svg "octicon-link" 16 "tw-text-text"}} <span class="tw-text-primary">{{.Repository.Website}}</span>
+							</a>
+						{{end}}
+
+						<div id="repo-topics" class="flex-text-block tw-flex-wrap tw-gap-1 tw-my-1 tw-text-text">
+							{{/* !!!! it SHOULD and MUST match the code in repo-home.ts */}}
+							{{range .Topics}}<a class="repo-topic ui large label gt-ellipsis" title={{.Name}} href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=1">{{.Name}}</a>{{end}}
+						</div>
+						{{if and .Permission.IsAdmin (not .Repository.IsArchived)}}
+							<button id="manage_topic" class="btn interact-fg tw-mb-2 tw-text-12">{{ctx.Locale.Tr "repo.topic.manage_topics"}}</button>
+							<div class="ui form tw-hidden tw-my-2" id="topic_edit">
+								<div class="ui fluid multiple search selection dropdown tw-flex-wrap tw-flex-1">
+									<input type="hidden" name="topics" value="{{range $i, $v := .Topics}}{{.Name}}{{if Eval $i "+" 1 "<" (len $.Topics)}},{{end}}{{end}}">
+									{{range .Topics}}
+										{{/* keep the same layout as Fomantic UI generated labels */}}
+										<a class="ui label transition visible tw-cursor-default tw-inline-block repo-topic" data-value="{{.Name}}">{{.Name}}{{svg "octicon-x" 16 "delete icon"}}</a>
+									{{end}}
+									<div class="text"></div>
+								</div>
+								<div class="tw-my-2">
+									<button class="ui primary button" id="save_topic" data-link="{{.RepoLink}}/topics">{{ctx.Locale.Tr "save"}}</button>
+									<button class="ui basic button" id="cancel_topic_edit">{{ctx.Locale.Tr "cancel"}}</button>
+								</div>
+							</div>
+						{{end}}
+
+						{{if .ReadmeExist}}
+							<a class="flex-text-block muted" href="{{.TreeLink}}/{{.FileName}}">
+								{{svg "octicon-book"}} {{ctx.Locale.Tr "readme"}}
+							</a>
+						{{end}}
+
+						{{if .DetectedRepoLicenses}}
+							<a class="flex-text-block muted" href="{{.RepoLink}}/src/{{.Repository.DefaultBranch}}/{{PathEscapeSegments .LicenseFileName}}" title="{{StringUtils.Join .DetectedRepoLicenses ", "}}">
+								{{svg "octicon-law"}} {{if eq (len .DetectedRepoLicenses) 1}}{{index .DetectedRepoLicenses 0}}{{else}}{{ctx.Locale.Tr "repo.multiple_licenses"}}{{end}}
+							</a>
+						{{end}}
+
+						{{if .CitiationExist}}
+							{{template "repo/cite/cite_modal" .}}
+							<a class="flex-text-block muted" id="cite-repo-button">
+								{{svg "octicon-cross-reference"}} {{ctx.Locale.Tr "repo.cite_this_repo"}}
+							</a>
 						{{end}}
-						<div class="text"></div>
-					</div>
-					<div>
-						<button class="ui primary button" id="save_topic" data-link="{{.RepoLink}}/topics">{{ctx.Locale.Tr "save"}}</button>
-						<button class="ui basic button" id="cancel_topic_edit">{{ctx.Locale.Tr "cancel"}}</button>
 					</div>
 				</div>
-			{{end}}
-			{{if .ReadmeExist}}
-				<div class="flex-item-body tw-mt-2">
-					<a class="flex-text-block muted" href="{{.TreeLink}}/{{.FileName}}">
-						{{svg "octicon-book"}} {{ctx.Locale.Tr "readme"}}
-					</a>
-				</div>
-			{{end}}
-			{{if .DetectedRepoLicenses}}
-				<div class="flex-item-body">
-					<a class="flex-text-block muted" href="{{.RepoLink}}/src/{{.Repository.DefaultBranch}}/{{PathEscapeSegments .LicenseFileName}}" title="{{StringUtils.Join .DetectedRepoLicenses ", "}}">
-						{{svg "octicon-law"}} {{if eq (len .DetectedRepoLicenses) 1}}{{index .DetectedRepoLicenses 0}}{{else}}{{ctx.Locale.Tr "repo.multiple_licenses"}}{{end}}
-					</a>
-				</div>
-			{{end}}
-			{{if .CitiationExist}}
-				<div class="flex-item-body">
-					{{template "repo/cite/cite_modal" .}}
-					<a class="flex-text-block muted" id="cite-repo-button">
-						{{svg "octicon-cross-reference"}} {{ctx.Locale.Tr "repo.cite_this_repo"}}
-					</a>
-				</div>
-			{{end}}
+			</div>
 		</div>
 	</div>
 </div>
diff --git a/templates/repo/release/label.tmpl b/templates/repo/release/label.tmpl
new file mode 100644
index 0000000000..eacb3e36f4
--- /dev/null
+++ b/templates/repo/release/label.tmpl
@@ -0,0 +1,14 @@
+{{/*
+Template Attributes:
+* Release: the release
+* IsLatest: boolean indicating whether this is the latest release, optional
+*/}}
+{{if .IsLatest}}
+	<span class="ui green label">{{ctx.Locale.Tr "repo.release.latest"}}</span>
+{{else if .Release.IsDraft}}
+	<span class="ui yellow label">{{ctx.Locale.Tr "repo.release.draft"}}</span>
+{{else if .Release.IsPrerelease}}
+	<span class="ui orange label">{{ctx.Locale.Tr "repo.release.prerelease"}}</span>
+{{else if (not .Release.IsTag)}}
+	<span class="ui green label">{{ctx.Locale.Tr "repo.release.stable"}}</span>
+{{end}}
diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl
index efaac4432a..99934d2118 100644
--- a/templates/repo/release/list.tmpl
+++ b/templates/repo/release/list.tmpl
@@ -33,13 +33,7 @@
 							<h4 class="release-list-title tw-break-anywhere">
 								{{if $.PageIsSingleTag}}{{$release.Title}}{{else}}<a class="muted" href="{{$.RepoLink}}/releases/tag/{{$release.TagName | PathEscapeSegments}}">{{$release.Title}}</a>{{end}}
 								{{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "tw-flex"}}
-								{{if $release.IsDraft}}
-									<span class="ui yellow label">{{ctx.Locale.Tr "repo.release.draft"}}</span>
-								{{else if $release.IsPrerelease}}
-									<span class="ui orange label">{{ctx.Locale.Tr "repo.release.prerelease"}}</span>
-								{{else if (not $release.IsTag)}}
-									<span class="ui green label">{{ctx.Locale.Tr "repo.release.stable"}}</span>
-								{{end}}
+								{{template "repo/release/label" (dict "Release" $release)}}
 							</h4>
 							<div>
 								{{if and $.CanCreateRelease (not $.PageIsSingleTag)}}
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
index 9a43e10e82..6fdc9ec2a8 100644
--- a/web_src/css/repo.css
+++ b/web_src/css/repo.css
@@ -101,11 +101,6 @@
   margin-bottom: 12px;
 }
 
-.repository .repo-description {
-  font-size: 16px;
-  margin-bottom: 5px;
-}
-
 .commit-summary {
   flex: 1;
   overflow-wrap: anywhere;
diff --git a/web_src/css/repo/home.css b/web_src/css/repo/home.css
index ca5b432804..65005e2263 100644
--- a/web_src/css/repo/home.css
+++ b/web_src/css/repo/home.css
@@ -4,22 +4,24 @@
   grid-template-rows: auto auto 1fr;
 }
 
-.repo-grid-filelist-sidebar .repo-home-filelist {
+.repo-home-filelist {
   min-width: 0;
   grid-column: 1;
   grid-row: 1 / 4;
 }
 
-.repo-grid-filelist-sidebar .repo-home-sidebar-top {
+.repo-home-sidebar-top {
   grid-column: 2;
   grid-row: 1;
   padding-left: 1em;
 }
-.repo-grid-filelist-sidebar .repo-home-sidebar-bottom {
+
+.repo-home-sidebar-bottom {
   grid-column: 2;
   grid-row: 2;
   padding-left: 1em;
 }
+
 .repo-home-sidebar-bottom .flex-list > :first-child {
   border-top: 1px solid var(--color-secondary); /* same to .flex-list > .flex-item + .flex-item */
 }
@@ -29,16 +31,16 @@
     grid-template-columns: 100%;
     grid-template-rows: auto auto auto;
   }
-  .repo-grid-filelist-sidebar .repo-home-filelist {
+  .repo-home-filelist {
     grid-column: 1;
     grid-row: 2;
   }
-  .repo-grid-filelist-sidebar .repo-home-sidebar-top {
+  .repo-home-sidebar-top {
     grid-column: 1;
     grid-row: 1;
     padding-left: 0;
   }
-  .repo-grid-filelist-sidebar .repo-home-sidebar-bottom {
+  .repo-home-sidebar-bottom {
     grid-column: 1;
     grid-row: 3;
     padding-left: 0;
diff --git a/web_src/js/features/repo-home.ts b/web_src/js/features/repo-home.ts
index 4c69a00434..abda29cc52 100644
--- a/web_src/js/features/repo-home.ts
+++ b/web_src/js/features/repo-home.ts
@@ -16,7 +16,7 @@ export function initRepoTopicBar() {
   let lastErrorToast: Toast;
 
   mgrBtn.addEventListener('click', () => {
-    hideElem(viewDiv);
+    hideElem([viewDiv, mgrBtn]);
     showElem(editDiv);
     topicDropdown.querySelector<HTMLInputElement>('input.search').focus();
   });
@@ -24,7 +24,7 @@ export function initRepoTopicBar() {
   document.querySelector('#cancel_topic_edit').addEventListener('click', () => {
     lastErrorToast?.hideToast();
     hideElem(editDiv);
-    showElem(viewDiv);
+    showElem([viewDiv, mgrBtn]);
     mgrBtn.focus();
   });
 
@@ -55,7 +55,7 @@ export function initRepoTopicBar() {
           }
         }
         hideElem(editDiv);
-        showElem(viewDiv);
+        showElem([viewDiv, mgrBtn]);
       }
     } else if (response.status === 422) {
       // how to test: input topic like " invalid topic " (with spaces), and select it from the list, then "Save"