From 7ec39aa756c93654032dc91e60092a6410f0cb81 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 31 Mar 2024 02:07:27 +0000 Subject: [PATCH 001/488] Update bitnami/minio Docker tag to v2024.3.30 --- .forgejo/workflows/testing.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index f40cf1ed83..5a314c6850 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -41,7 +41,7 @@ jobs: image: 'docker.io/node:20-bookworm' services: minio: - image: bitnami/minio:2024.2.26 + image: bitnami/minio:2024.3.30 options: >- --hostname gitea.minio env: @@ -131,7 +131,7 @@ jobs: image: 'docker.io/node:20-bookworm' services: minio: - image: bitnami/minio:2024.2.26 + image: bitnami/minio:2024.3.30 env: MINIO_ROOT_USER: 123456 MINIO_ROOT_PASSWORD: 12345678 From e498069fd5ab8e532761aec2be1eb5e0fd2b4bd3 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Sun, 31 Mar 2024 10:52:24 +0500 Subject: [PATCH 002/488] Update checker setting updates - revert https://codeberg.org/forgejo/forgejo/commit/c53f802778c1951e0804507eec995bca37f1b09b - enable by default on install page - save checkbox state between form submissions Resolves https://codeberg.org/forgejo/forgejo/issues/2859 --- routers/install/install.go | 1 + services/cron/tasks_extended.go | 2 +- templates/install.tmpl | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/routers/install/install.go b/routers/install/install.go index 5030306d89..d5503db31f 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -159,6 +159,7 @@ func Install(ctx *context.Context) { form.DefaultAllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization form.DefaultEnableTimetracking = setting.Service.DefaultEnableTimetracking form.NoReplyAddress = setting.Service.NoReplyAddress + form.EnableUpdateChecker = true form.PasswordAlgorithm = hash.ConfigHashAlgorithm(setting.PasswordHashAlgo) middleware.AssignForm(form, ctx.Data) diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go index 569e8fbd24..e1ba5274e6 100644 --- a/services/cron/tasks_extended.go +++ b/services/cron/tasks_extended.go @@ -147,7 +147,7 @@ func registerUpdateGiteaChecker() { } RegisterTaskFatal("update_checker", &UpdateCheckerConfig{ BaseConfig: BaseConfig{ - Enabled: false, + Enabled: true, RunAtStart: false, Schedule: "@every 168h", }, diff --git a/templates/install.tmpl b/templates/install.tmpl index 6bb37d0a0c..d49de33a3f 100644 --- a/templates/install.tmpl +++ b/templates/install.tmpl @@ -150,7 +150,7 @@
- +
{{ctx.Locale.Tr "install.enable_update_checker_helper_forgejo"}}
From 4b09dd11ec77fd5758d307aac29202ae23cdc619 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Fri, 29 Mar 2024 23:07:01 +0500 Subject: [PATCH 003/488] [GITEA] Apply changes to archived labels This is a squashed result of conflict resolution for the following commits from Gitea: - https://github.com/go-gitea/gitea/commit/36de5b299bb3e6e6cf28062c832ab8165e83f91a - https://github.com/go-gitea/gitea/commit/9a93b1816e0bc65101e7ad7ca66786fb38a8e628 - https://github.com/go-gitea/gitea/commit/712e19fa6fbf2f1a5b0a471782d38a7d91e538ae - https://github.com/go-gitea/gitea/commit/83850cc4799285d766d0fb5751fff10a6e4d3353 It is lacking CSS rule for archived labels, though. Changes in this commit are authored by: - 6543 - delvh - silverwind --- models/issues/label.go | 12 ++++---- modules/templates/util_render.go | 28 +++++++++++++------ routers/web/repo/issue_label.go | 12 ++++---- templates/repo/issue/card.tmpl | 2 +- templates/repo/issue/filter_actions.tmpl | 2 +- templates/repo/issue/filter_list.tmpl | 2 +- templates/repo/issue/labels/label.tmpl | 2 +- templates/repo/issue/labels/label_list.tmpl | 4 +-- .../issue/labels/labels_selector_field.tmpl | 4 +-- .../repo/issue/view_content/comments.tmpl | 6 ++-- templates/shared/issuelist.tmpl | 2 +- 11 files changed, 42 insertions(+), 34 deletions(-) diff --git a/models/issues/label.go b/models/issues/label.go index f6ecc68cd1..2397a29e35 100644 --- a/models/issues/label.go +++ b/models/issues/label.go @@ -116,12 +116,17 @@ func (l *Label) CalOpenIssues() { func (l *Label) SetArchived(isArchived bool) { if !isArchived { l.ArchivedUnix = timeutil.TimeStamp(0) - } else if isArchived && l.ArchivedUnix.IsZero() { + } else if isArchived && !l.IsArchived() { // Only change the date when it is newly archived. l.ArchivedUnix = timeutil.TimeStampNow() } } +// IsArchived returns true if label is an archived +func (l *Label) IsArchived() bool { + return !l.ArchivedUnix.IsZero() +} + // CalOpenOrgIssues calculates the open issues of a label for a specific repo func (l *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) { counts, _ := CountIssuesByRepo(ctx, &IssuesOptions{ @@ -166,11 +171,6 @@ func (l *Label) BelongsToOrg() bool { return l.OrgID > 0 } -// IsArchived returns true if label is an archived -func (l *Label) IsArchived() bool { - return l.ArchivedUnix > 0 -} - // BelongsToRepo returns true if label is a repository label func (l *Label) BelongsToRepo() bool { return l.RepoID > 0 diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index 5deb051abe..d1c9b082fa 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/util" ) @@ -118,10 +119,14 @@ func RenderIssueTitle(ctx context.Context, text string, metas map[string]string) } // RenderLabel renders a label -func RenderLabel(ctx context.Context, label *issues_model.Label) template.HTML { - labelScope := label.ExclusiveScope() +// locale is needed due to an import cycle with our context providing the `Tr` function +func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_model.Label) template.HTML { + var ( + archivedCSSClass string + textColor = "#111" + labelScope = label.ExclusiveScope() + ) - textColor := "#111" r, g, b := util.HexToRBGColor(label.Color) // Determine if label text should be light or dark to be readable on background color if util.UseLightTextOnBackground(r, g, b) { @@ -130,10 +135,15 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) template.HTML { description := emoji.ReplaceAliases(template.HTMLEscapeString(label.Description)) + if label.IsArchived() { + archivedCSSClass = "archived-label" + description = fmt.Sprintf("(%s) %s", locale.TrString("archived"), description) + } + if labelScope == "" { // Regular label - s := fmt.Sprintf("
%s
", - textColor, label.Color, description, RenderEmoji(ctx, label.Name)) + s := fmt.Sprintf("
%s
", + archivedCSSClass, textColor, label.Color, description, RenderEmoji(ctx, label.Name)) return template.HTML(s) } @@ -166,11 +176,11 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) template.HTML { itemColor := "#" + hex.EncodeToString(itemBytes) scopeColor := "#" + hex.EncodeToString(scopeBytes) - s := fmt.Sprintf(""+ + s := fmt.Sprintf(""+ "
%s
"+ "
%s
"+ "
", - description, + archivedCSSClass, description, textColor, scopeColor, scopeText, textColor, itemColor, itemText) return template.HTML(s) @@ -211,7 +221,7 @@ func RenderMarkdownToHtml(ctx context.Context, input string) template.HTML { //n return output } -func RenderLabels(ctx context.Context, labels []*issues_model.Label, repoLink string) template.HTML { +func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issues_model.Label, repoLink string) template.HTML { htmlCode := `` for _, label := range labels { // Protect against nil value in labels - shouldn't happen but would cause a panic if so @@ -219,7 +229,7 @@ func RenderLabels(ctx context.Context, labels []*issues_model.Label, repoLink st continue } htmlCode += fmt.Sprintf("%s ", - repoLink, label.ID, RenderLabel(ctx, label)) + repoLink, label.ID, RenderLabel(ctx, locale, label)) } htmlCode += "" return template.HTML(htmlCode) diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index 9dedaefa4b..81bee4dbb5 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -13,7 +13,6 @@ import ( "code.gitea.io/gitea/modules/label" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" - "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" @@ -112,12 +111,11 @@ func NewLabel(ctx *context.Context) { } l := &issues_model.Label{ - RepoID: ctx.Repo.Repository.ID, - Name: form.Title, - Exclusive: form.Exclusive, - Description: form.Description, - Color: form.Color, - ArchivedUnix: timeutil.TimeStamp(0), + RepoID: ctx.Repo.Repository.ID, + Name: form.Title, + Exclusive: form.Exclusive, + Description: form.Description, + Color: form.Color, } if err := issues_model.NewLabel(ctx, l); err != nil { ctx.ServerError("NewLabel", err) diff --git a/templates/repo/issue/card.tmpl b/templates/repo/issue/card.tmpl index f3d533b862..bb9340bb2e 100644 --- a/templates/repo/issue/card.tmpl +++ b/templates/repo/issue/card.tmpl @@ -61,7 +61,7 @@ {{if or .Labels .Assignees}}
{{range .Labels}} - {{RenderLabel ctx .}} + {{RenderLabel ctx ctx.Locale .}} {{end}}
{{range .Assignees}} diff --git a/templates/repo/issue/filter_actions.tmpl b/templates/repo/issue/filter_actions.tmpl index e184a6b5e7..f23ca36d78 100644 --- a/templates/repo/issue/filter_actions.tmpl +++ b/templates/repo/issue/filter_actions.tmpl @@ -30,7 +30,7 @@ {{end}} {{$previousExclusiveScope = $exclusiveScope}}
- {{if SliceUtils.Contains $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context .}} + {{if SliceUtils.Contains $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context ctx.Locale .}} {{template "repo/issue/labels/label_archived" .}}
{{end}} diff --git a/templates/repo/issue/filter_list.tmpl b/templates/repo/issue/filter_list.tmpl index 6bf6d6b9d3..997557c45e 100644 --- a/templates/repo/issue/filter_list.tmpl +++ b/templates/repo/issue/filter_list.tmpl @@ -42,7 +42,7 @@ {{svg "octicon-check"}} {{end}} {{end}} - {{RenderLabel $.Context .}} + {{RenderLabel $.Context ctx.Locale .}}

{{template "repo/issue/labels/label_archived" .}}

{{end}} diff --git a/templates/repo/issue/labels/label.tmpl b/templates/repo/issue/labels/label.tmpl index 2480115129..3651ba118f 100644 --- a/templates/repo/issue/labels/label.tmpl +++ b/templates/repo/issue/labels/label.tmpl @@ -3,5 +3,5 @@ id="label_{{.label.ID}}" href="{{.root.RepoLink}}/{{if or .root.IsPull .root.Issue.IsPull}}pulls{{else}}issues{{end}}?labels={{.label.ID}}"{{/* FIXME: use .root.Issue.Link or create .root.Link */}} > - {{- RenderLabel $.Context .label -}} + {{- RenderLabel $.Context ctx.Locale .label -}} diff --git a/templates/repo/issue/labels/label_list.tmpl b/templates/repo/issue/labels/label_list.tmpl index ad4d8697e7..d84f14242a 100644 --- a/templates/repo/issue/labels/label_list.tmpl +++ b/templates/repo/issue/labels/label_list.tmpl @@ -32,7 +32,7 @@ {{range .Labels}}
  • - {{RenderLabel $.Context .}} + {{RenderLabel $.Context ctx.Locale .}} {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    @@ -72,7 +72,7 @@ {{range .OrgLabels}}
  • - {{RenderLabel $.Context .}} + {{RenderLabel $.Context ctx.Locale .}} {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    diff --git a/templates/repo/issue/labels/labels_selector_field.tmpl b/templates/repo/issue/labels/labels_selector_field.tmpl index 067361bf1e..e5f15caca5 100644 --- a/templates/repo/issue/labels/labels_selector_field.tmpl +++ b/templates/repo/issue/labels/labels_selector_field.tmpl @@ -21,7 +21,7 @@
    {{end}} {{$previousExclusiveScope = $exclusiveScope}} - {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context .}} + {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context ctx.Locale .}} {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}

    {{template "repo/issue/labels/label_archived" .}}

    @@ -34,7 +34,7 @@
    {{end}} {{$previousExclusiveScope = $exclusiveScope}} - {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context .}} + {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context ctx.Locale .}} {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}

    {{template "repo/issue/labels/label_archived" .}}

    diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 162762950d..a5fd02c190 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -177,11 +177,11 @@ {{template "shared/user/authorlink" .Poster}} {{if and .AddedLabels (not .RemovedLabels)}} - {{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels $.Context .AddedLabels $.RepoLink) $createdStr}} + {{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink) $createdStr}} {{else if and (not .AddedLabels) .RemovedLabels}} - {{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels $.Context .RemovedLabels $.RepoLink) $createdStr}} + {{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink) $createdStr}} {{else}} - {{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels $.Context .AddedLabels $.RepoLink) (RenderLabels $.Context .RemovedLabels $.RepoLink) $createdStr}} + {{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink) (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink) $createdStr}} {{end}}
    diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl index 06887c2914..1c0dfcc551 100644 --- a/templates/shared/issuelist.tmpl +++ b/templates/shared/issuelist.tmpl @@ -21,7 +21,7 @@ {{end}} {{range .Labels}} - {{RenderLabel $.Context .}} + {{RenderLabel $.Context ctx.Locale .}} {{end}}
  • From cab47bbb0e0b656117df339c32ef2cae90b90dc5 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Fri, 29 Mar 2024 23:17:00 +0500 Subject: [PATCH 004/488] [I18N] Improve translatability of archived labels Allow any position and writing style of `(Archived)`. --- modules/templates/util_render.go | 2 +- options/locale/locale_en-US.ini | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index d1c9b082fa..c167b32123 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -137,7 +137,7 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m if label.IsArchived() { archivedCSSClass = "archived-label" - description = fmt.Sprintf("(%s) %s", locale.TrString("archived"), description) + description = locale.TrString("repo.issues.archived_label_description", description) } if labelScope == "" { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b06e864869..d87916d8cc 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1627,6 +1627,7 @@ issues.label_modify = Edit label issues.label_deletion = Delete label issues.label_deletion_desc = Deleting a label removes it from all issues. Continue? issues.label_deletion_success = The label has been deleted. +issues.archived_label_description = (Archived) %s issues.label.filter_sort.alphabetically = Alphabetically issues.label.filter_sort.reverse_alphabetically = Reverse alphabetically issues.label.filter_sort.by_size = Smallest size From 1060b7cfa89158ad40f412981ba5441b4e332964 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Mon, 1 Apr 2024 17:17:12 +0500 Subject: [PATCH 005/488] Add opacity and grayscale to archived labels Co-authored-by: Gusted --- modules/templates/util_render.go | 24 +++++++++++++++++++++--- web_src/css/repo.css | 4 ++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index c167b32123..f593e1b897 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -105,6 +105,18 @@ func RenderCodeBlock(htmlEscapedTextToRender template.HTML) template.HTML { return template.HTML(htmlWithCodeTags) } +const ( + activeLabelOpacity = uint8(255) + archivedLabelOpacity = uint8(127) +) + +func GetLabelOpacityByte(isArchived bool) uint8 { + if isArchived { + return archivedLabelOpacity + } + return activeLabelOpacity +} + // RenderIssueTitle renders issue/pull title with defined post processors func RenderIssueTitle(ctx context.Context, text string, metas map[string]string) template.HTML { renderedText, err := markup.RenderIssueTitle(&markup.RenderContext{ @@ -126,9 +138,10 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m textColor = "#111" labelScope = label.ExclusiveScope() ) - r, g, b := util.HexToRBGColor(label.Color) + // Determine if label text should be light or dark to be readable on background color + // this doesn't account for saturation or transparency if util.UseLightTextOnBackground(r, g, b) { textColor = "#eee" } @@ -142,8 +155,10 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m if labelScope == "" { // Regular label + + labelColor := label.Color + hex.EncodeToString([]byte{GetLabelOpacityByte(label.IsArchived())}) s := fmt.Sprintf("
    %s
    ", - archivedCSSClass, textColor, label.Color, description, RenderEmoji(ctx, label.Name)) + archivedCSSClass, textColor, labelColor, description, RenderEmoji(ctx, label.Name)) return template.HTML(s) } @@ -162,19 +177,22 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m darkenFactor := math.Max(luminance-darken, 0.0) / math.Max(luminance, 1.0/255.0) lightenFactor := math.Min(luminance+lighten, 1.0) / math.Max(luminance, 1.0/255.0) + opacity := GetLabelOpacityByte(label.IsArchived()) scopeBytes := []byte{ uint8(math.Min(math.Round(r*darkenFactor), 255)), uint8(math.Min(math.Round(g*darkenFactor), 255)), uint8(math.Min(math.Round(b*darkenFactor), 255)), + opacity, } itemBytes := []byte{ uint8(math.Min(math.Round(r*lightenFactor), 255)), uint8(math.Min(math.Round(g*lightenFactor), 255)), uint8(math.Min(math.Round(b*lightenFactor), 255)), + opacity, } - itemColor := "#" + hex.EncodeToString(itemBytes) scopeColor := "#" + hex.EncodeToString(scopeBytes) + itemColor := "#" + hex.EncodeToString(itemBytes) s := fmt.Sprintf(""+ "
    %s
    "+ diff --git a/web_src/css/repo.css b/web_src/css/repo.css index 3d867fcf14..32620f6295 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -2399,6 +2399,10 @@ margin-left: 0; } +.archived-label { + filter: grayscale(0.25) saturate(0.75); +} + .repo-button-row { margin: 10px 0; display: flex; From 53dc9f3393d54f6fb675ecb2841f2f9f8cdb41b3 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Mon, 1 Apr 2024 21:38:34 +0500 Subject: [PATCH 006/488] Add integration test for (non-)archived label properties --- .../archived_labels_display_test.go | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tests/integration/archived_labels_display_test.go diff --git a/tests/integration/archived_labels_display_test.go b/tests/integration/archived_labels_display_test.go new file mode 100644 index 0000000000..c9748f81d6 --- /dev/null +++ b/tests/integration/archived_labels_display_test.go @@ -0,0 +1,71 @@ +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "net/http" + "net/url" + "strings" + "testing" + + "github.com/PuerkitoBio/goquery" + "github.com/stretchr/testify/assert" +) + +func TestArchivedLabelVisualProperties(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + session := loginUser(t, "user2") + + // Create labels + session.MakeRequest(t, NewRequestWithValues(t, "POST", "user2/repo1/labels/new", map[string]string{ + "_csrf": GetCSRF(t, session, "user2/repo1/labels"), + "title": "active_label", + "description": "", + "color": "#aa00aa", + }), http.StatusSeeOther) + session.MakeRequest(t, NewRequestWithValues(t, "POST", "user2/repo1/labels/new", map[string]string{ + "_csrf": GetCSRF(t, session, "user2/repo1/labels"), + "title": "archived_label", + "description": "", + "color": "#00aa00", + }), http.StatusSeeOther) + + // Get ID of label to archive it + var id string + doc := NewHTMLParser(t, session.MakeRequest(t, NewRequest(t, "GET", "user2/repo1/labels"), http.StatusOK).Body) + doc.Find(".issue-label-list .item").Each(func(i int, s *goquery.Selection) { + label := s.Find(".label-title .label") + if label.Text() == "archived_label" { + href, _ := s.Find(".label-issues a.open-issues").Attr("href") + hrefParts := strings.Split(href, "=") + id = hrefParts[len(hrefParts)-1] + } + }) + + // Make label archived + session.MakeRequest(t, NewRequestWithValues(t, "POST", "user2/repo1/labels/edit", map[string]string{ + "_csrf": GetCSRF(t, session, "user2/repo1/labels"), + "id": id, + "title": "archived_label", + "is_archived": "on", + "description": "", + "color": "#00aa00", + }), http.StatusSeeOther) + + // Test label properties + doc = NewHTMLParser(t, session.MakeRequest(t, NewRequest(t, "GET", "user2/repo1/labels"), http.StatusOK).Body) + doc.Find(".issue-label-list .item").Each(func(i int, s *goquery.Selection) { + label := s.Find(".label-title .label") + style, _ := label.Attr("style") + + if label.Text() == "active_label" { + assert.False(t, label.HasClass("archived-label")) + assert.Contains(t, style, "background-color: #aa00aaff") + } else if label.Text() == "archived_label" { + assert.True(t, label.HasClass("archived-label")) + assert.Contains(t, style, "background-color: #00aa007f") + } + }) + }) +} From 20a35972200fc7f2a5a105fe5e8aaaa118bc9b5d Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 30 Mar 2024 12:15:39 +0100 Subject: [PATCH 007/488] [FEAT] Visual separation between types of attachments - Add a visual (but still semantic way) separation between Forgejo's generated attachments and the user's uploaded ones. - The styling was first done by `ul` element, but is moved to the individual list items to have better control over them. - Add tooltip explaining the attachment was generated by Forgejo. - Remove the tooltip of the other attachments and 'simplify' them into a text. - Resolves #2893 Co-authored-by: 0ko <0ko@noreply.codeberg.org> --- options/locale/locale_en-US.ini | 3 ++- templates/repo/release/list.tmpl | 15 ++++++++++----- templates/repo/release/new.tmpl | 5 +---- web_src/css/repo/release-tag.css | 24 ++++++++++++++++++------ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 078c82c681..b40c80a794 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2632,11 +2632,12 @@ release.tag_name_invalid = The tag name is not valid. release.tag_name_protected = The tag name is protected. release.tag_already_exist = This tag name already exists. release.downloads = Downloads -release.download_count = Downloads: %s +release.download_count = %s downloads release.add_tag_msg = Use the title and content of release as tag message. release.add_tag = Create Tag Only release.releases_for = Releases for %s release.tags_for = Tags for %s +release.system_generated = This attachment is automatically generated. branch.name = Branch name branch.already_exists = A branch named "%s" already exists. diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl index 329dc932fb..96021b36d6 100644 --- a/templates/repo/release/list.tmpl +++ b/templates/repo/release/list.tmpl @@ -67,13 +67,21 @@ {{ctx.Locale.Tr "repo.release.downloads"}}
    diff --git a/templates/repo/settings/lfs.tmpl b/templates/repo/settings/lfs.tmpl index d63de3f53c..6d7aac229d 100644 --- a/templates/repo/settings/lfs.tmpl +++ b/templates/repo/settings/lfs.tmpl @@ -44,7 +44,7 @@

    {{$.CsrfTokenHtml}} - {{template "base/modal_actions_confirm" (dict "ModalButtonColors" "yellow")}} + {{template "base/modal_actions_confirm" (dict "ModalButtonColors" "primary")}}
    diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl index dc58df221e..54fdf9fbed 100644 --- a/templates/user/settings/applications.tmpl +++ b/templates/user/settings/applications.tmpl @@ -109,7 +109,7 @@

    {{ctx.Locale.Tr "settings.access_token_deletion_desc"}}

    - {{template "base/modal_actions_confirm" (dict "ModalButtonColors" "yellow")}} + {{template "base/modal_actions_confirm" (dict "ModalButtonColors" "primary")}} {{template "user/settings/layout_footer" .}} From f5ad6d4be58e7499c44f1ec93503920e2828d4e6 Mon Sep 17 00:00:00 2001 From: Gusted Date: Wed, 3 Apr 2024 02:41:57 +0200 Subject: [PATCH 015/488] [FEAT] Allow non-explicit push options - Currently the parsing of the push options require that `=` is present in the value, however we shouldn't be that strict and assume if that's not set the value is `true`. - This allow for more natural commands, so become `-o force-push=true` simply `-o force-push`. - Add unit test. --- cmd/hook.go | 14 ++++++++------ cmd/hook_test.go | 15 +++++++++++++++ tests/integration/git_test.go | 2 +- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/cmd/hook.go b/cmd/hook.go index 15ed1eb7f4..2e0b2ab3b7 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -488,10 +488,11 @@ func pushOptions() map[string]string { if pushCount, err := strconv.Atoi(os.Getenv(private.GitPushOptionCount)); err == nil { for idx := 0; idx < pushCount; idx++ { opt := os.Getenv(fmt.Sprintf("GIT_PUSH_OPTION_%d", idx)) - kv := strings.SplitN(opt, "=", 2) - if len(kv) == 2 { - opts[kv[0]] = kv[1] + key, value, found := strings.Cut(opt, "=") + if !found { + value = "true" } + opts[key] = value } } return opts @@ -631,10 +632,11 @@ Forgejo or set your environment appropriately.`, "") break } - kv := strings.SplitN(string(rs.Data), "=", 2) - if len(kv) == 2 { - hookOptions.GitPushOptions[kv[0]] = kv[1] + key, value, found := strings.Cut(string(rs.Data), "=") + if !found { + value = "true" } + hookOptions.GitPushOptions[key] = value } } diff --git a/cmd/hook_test.go b/cmd/hook_test.go index 0c1bee29f4..89dafeaa57 100644 --- a/cmd/hook_test.go +++ b/cmd/hook_test.go @@ -15,6 +15,7 @@ import ( "testing" "time" + "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" @@ -162,3 +163,17 @@ func TestDelayWriter(t *testing.T) { require.Empty(t, out) }) } + +func TestPushOptions(t *testing.T) { + require.NoError(t, os.Setenv(private.GitPushOptionCount, "3")) + require.NoError(t, os.Setenv("GIT_PUSH_OPTION_0", "force-push")) + require.NoError(t, os.Setenv("GIT_PUSH_OPTION_1", "option=value")) + require.NoError(t, os.Setenv("GIT_PUSH_OPTION_2", "option-double=another=value")) + require.NoError(t, os.Setenv("GIT_PUSH_OPTION_3", "not=valid")) + + assert.Equal(t, map[string]string{ + "force-push": "true", + "option": "value", + "option-double": "another=value", + }, pushOptions()) +} diff --git a/tests/integration/git_test.go b/tests/integration/git_test.go index 782390002c..708f9a820d 100644 --- a/tests/integration/git_test.go +++ b/tests/integration/git_test.go @@ -1025,7 +1025,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB t.Run("Succeeds", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - _, _, gitErr := git.NewCommand(git.DefaultContext, "push", "origin", "-o", "force-push=true").AddDynamicArguments("HEAD:refs/for/master/" + headBranch + "-force-push").RunStdString(&git.RunOpts{Dir: dstPath}) + _, _, gitErr := git.NewCommand(git.DefaultContext, "push", "origin", "-o", "force-push").AddDynamicArguments("HEAD:refs/for/master/" + headBranch + "-force-push").RunStdString(&git.RunOpts{Dir: dstPath}) assert.NoError(t, gitErr) currentHeadCommitID, err := upstreamGitRepo.GetRefCommitID(pr.GetGitRefName()) From f8e48e066af107225c7bdcae6ed16b067e175e2b Mon Sep 17 00:00:00 2001 From: hazycora Date: Mon, 25 Sep 2023 21:39:12 -0500 Subject: [PATCH 016/488] add pronoun field to user profiles --- models/user/user.go | 1 + modules/structs/admin_user.go | 1 + modules/structs/user.go | 1 + options/locale/locale_en-US.ini | 1 + routers/api/v1/admin/user.go | 1 + routers/api/v1/user/settings.go | 1 + routers/web/user/setting/profile.go | 1 + services/forms/user_form.go | 1 + services/user/update.go | 6 ++++++ templates/shared/user/profile_big_avatar.tmpl | 2 +- templates/user/settings/profile.tmpl | 4 ++++ 11 files changed, 19 insertions(+), 1 deletion(-) diff --git a/models/user/user.go b/models/user/user.go index 4aef30ca56..ff85c2cfa0 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -95,6 +95,7 @@ type User struct { Type UserType Location string Website string + Pronouns string Rands string `xorm:"VARCHAR(32)"` Salt string `xorm:"VARCHAR(32)"` Language string `xorm:"VARCHAR(5)"` diff --git a/modules/structs/admin_user.go b/modules/structs/admin_user.go index f7c6d10ba0..ad86f4ca03 100644 --- a/modules/structs/admin_user.go +++ b/modules/structs/admin_user.go @@ -41,6 +41,7 @@ type EditUserOption struct { MustChangePassword *bool `json:"must_change_password"` Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` Location *string `json:"location" binding:"MaxSize(50)"` + Pronouns *string `json:"pronouns" binding:"MaxSize(50)"` Description *string `json:"description" binding:"MaxSize(255)"` Active *bool `json:"active"` Admin *bool `json:"admin"` diff --git a/modules/structs/user.go b/modules/structs/user.go index 4e13669ad2..9e4858115c 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -87,6 +87,7 @@ type UserSettingsOptions struct { Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` Description *string `json:"description" binding:"MaxSize(255)"` Location *string `json:"location" binding:"MaxSize(50)"` + Pronouns *string `json:"pronouns" binding:"MaxSize(50)"` Language *string `json:"language"` Theme *string `json:"theme"` DiffViewStyle *string `json:"diff_view_style"` diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 3a871b2eb8..d099e78207 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -701,6 +701,7 @@ password_username_disabled = Non-local users are not allowed to change their use full_name = Full name website = Website location = Location +pronouns = Pronouns update_theme = Change theme update_profile = Update profile update_language = Change language diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 87a5b28fad..12da8a9597 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -236,6 +236,7 @@ func EditUser(ctx *context.APIContext) { Website: optional.FromPtr(form.Website), Location: optional.FromPtr(form.Location), Description: optional.FromPtr(form.Description), + Pronouns: optional.FromPtr(form.Pronouns), IsActive: optional.FromPtr(form.Active), IsAdmin: optional.FromPtr(form.Admin), Visibility: optional.FromNonDefault(api.VisibilityModes[form.Visibility]), diff --git a/routers/api/v1/user/settings.go b/routers/api/v1/user/settings.go index f594eb211c..bfd24013db 100644 --- a/routers/api/v1/user/settings.go +++ b/routers/api/v1/user/settings.go @@ -48,6 +48,7 @@ func UpdateUserSettings(ctx *context.APIContext) { opts := &user_service.UpdateOptions{ FullName: optional.FromPtr(form.FullName), Description: optional.FromPtr(form.Description), + Pronouns: optional.FromPtr(form.Pronouns), Website: optional.FromPtr(form.Website), Location: optional.FromPtr(form.Location), Language: optional.FromPtr(form.Language), diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 4e5c380ed9..b5d916b78f 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -90,6 +90,7 @@ func ProfilePost(ctx *context.Context) { FullName: optional.Some(form.FullName), KeepEmailPrivate: optional.Some(form.KeepEmailPrivate), Description: optional.Some(form.Description), + Pronouns: optional.Some(form.Pronouns), Website: optional.Some(form.Website), Location: optional.Some(form.Location), Visibility: optional.Some(form.Visibility), diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 3290179092..196b092990 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -218,6 +218,7 @@ type UpdateProfileForm struct { KeepEmailPrivate bool Website string `binding:"ValidSiteUrl;MaxSize(255)"` Location string `binding:"MaxSize(50)"` + Pronouns string `binding:"MaxSize(50)"` Description string `binding:"MaxSize(255)"` Visibility structs.VisibleType KeepActivityPrivate bool diff --git a/services/user/update.go b/services/user/update.go index e96ab4274a..1bdbf13f0d 100644 --- a/services/user/update.go +++ b/services/user/update.go @@ -22,6 +22,7 @@ type UpdateOptions struct { Website optional.Option[string] Location optional.Option[string] Description optional.Option[string] + Pronouns optional.Option[string] AllowGitHook optional.Option[bool] AllowImportLocal optional.Option[bool] MaxRepoCreation optional.Option[int] @@ -54,6 +55,11 @@ func UpdateUser(ctx context.Context, u *user_model.User, opts *UpdateOptions) er cols = append(cols, "full_name") } + if opts.Pronouns.Has() { + u.Pronouns = opts.Pronouns.Value() + + cols = append(cols, "pronouns") + } if opts.Website.Has() { u.Website = opts.Website.Value() diff --git a/templates/shared/user/profile_big_avatar.tmpl b/templates/shared/user/profile_big_avatar.tmpl index bc7785629e..329a06d84d 100644 --- a/templates/shared/user/profile_big_avatar.tmpl +++ b/templates/shared/user/profile_big_avatar.tmpl @@ -13,7 +13,7 @@
    {{if .ContextUser.FullName}}{{.ContextUser.FullName}}{{end}} - {{.ContextUser.Name}} {{if .IsAdmin}} + {{.ContextUser.Name}}{{if .ContextUser.Pronouns}} · {{.ContextUser.Pronouns}}{{end}} {{if .IsAdmin}} {{svg "octicon-gear" 18}} diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index aaaf8f30db..ac82606134 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -37,6 +37,10 @@
    +
    + + +
    From a6f068a93bda0ad501d793ad36448301941a1fa3 Mon Sep 17 00:00:00 2001 From: hazycora Date: Tue, 26 Sep 2023 00:34:09 -0500 Subject: [PATCH 017/488] use dropdown for pronoun input --- options/locale/locale_en-US.ini | 1 + routers/web/user/setting/profile.go | 2 ++ templates/user/settings/profile.tmpl | 52 ++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index d099e78207..b7237711de 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -702,6 +702,7 @@ full_name = Full name website = Website location = Location pronouns = Pronouns +pronouns_custom = Custom update_theme = Change theme update_profile = Update profile update_language = Change language diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index b5d916b78f..6843340fec 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -46,6 +46,7 @@ func Profile(ctx *context.Context) { ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) + ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" ctx.HTML(http.StatusOK, tplSettingsProfile) } @@ -56,6 +57,7 @@ func ProfilePost(ctx *context.Context) { ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) + ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" if ctx.HasError() { ctx.HTML(http.StatusOK, tplSettingsProfile) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index ac82606134..7638727e8c 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -37,9 +37,55 @@ -
    - - +
    + + + +
    From 994c6d3cde77278badc6dd74d9c1e54129e8c7e5 Mon Sep 17 00:00:00 2001 From: hazycora Date: Tue, 26 Sep 2023 00:56:20 -0500 Subject: [PATCH 018/488] move pronouns JS --- templates/user/settings/profile.tmpl | 24 --------------------- web_src/js/features/user-settings.js | 31 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 7638727e8c..822651a9db 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -62,30 +62,6 @@
    -
    diff --git a/web_src/js/features/user-settings.js b/web_src/js/features/user-settings.js index 2d8c53e457..d2617dda6a 100644 --- a/web_src/js/features/user-settings.js +++ b/web_src/js/features/user-settings.js @@ -1,5 +1,27 @@ import {hideElem, showElem} from '../utils/dom.js'; +function onPronounsDropdownUpdate() { + const pronounsCustom = document.getElementById('pronouns-custom'); + const pronounsInput = document.querySelector('#pronouns-dropdown input'); + const isCustom = !( + pronounsInput.value === 'he/him' || + pronounsInput.value === 'she/her' || + pronounsInput.value === 'they/them' || + pronounsInput.value === 'it/its' + ); + if (isCustom) { + pronounsCustom.value = pronounsInput.value; + pronounsCustom.style.display = ''; + } else { + pronounsCustom.style.display = 'none'; + } +} +function onPronounsCustomUpdate() { + const pronounsCustom = document.getElementById('pronouns-custom'); + const pronounsInput = document.querySelector('#pronouns-dropdown input'); + pronounsInput.value = pronounsCustom.value; +} + export function initUserSettings() { if (!document.querySelectorAll('.user.settings.profile').length) return; @@ -16,4 +38,13 @@ export function initUserSettings() { hideElem(promptRedirect); } }); + + const pronounsDropdown = document.getElementById('pronouns-dropdown'); + const pronounsCustom = document.getElementById('pronouns-custom'); + const pronounsInput = pronounsDropdown.querySelector('input'); + pronounsCustom.removeAttribute('name'); + pronounsDropdown.style.display = ''; + onPronounsDropdownUpdate(); + pronounsInput.addEventListener('change', onPronounsDropdownUpdate); + pronounsCustom.addEventListener('input', onPronounsCustomUpdate); } From 563e8b49e86785112ec440f2e82a3ed387089433 Mon Sep 17 00:00:00 2001 From: hazycora Date: Tue, 26 Sep 2023 01:21:52 -0500 Subject: [PATCH 019/488] Add "Unspecified" option to pronouns dropdown --- options/locale/locale_en-US.ini | 1 + routers/web/user/setting/profile.go | 4 ++-- templates/user/settings/profile.tmpl | 5 ++++- web_src/js/features/user-settings.js | 10 ++++++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b7237711de..6fa4e6d78f 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -703,6 +703,7 @@ website = Website location = Location pronouns = Pronouns pronouns_custom = Custom +pronouns_unspecified = Unspecified update_theme = Change theme update_profile = Update profile update_language = Change language diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 6843340fec..1b1cdb54d4 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -46,7 +46,7 @@ func Profile(ctx *context.Context) { ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) - ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" + ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" ctx.HTML(http.StatusOK, tplSettingsProfile) } @@ -57,7 +57,7 @@ func ProfilePost(ctx *context.Context) { ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) - ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" + ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" if ctx.HasError() { ctx.HTML(http.StatusOK, tplSettingsProfile) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 822651a9db..9d279f23a2 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -44,12 +44,15 @@
    {{if .PronounsAreCustom}} {{.locale.Tr "settings.pronouns_custom"}} + {{else if eq "" .SignedUser.Pronouns}} + {{.locale.Tr "settings.pronouns_unspecified"}} {{else}} {{.SignedUser.Pronouns}} {{end}}
    {{svg "octicon-triangle-down" 14 "dropdown icon"}} diff --git a/web_src/js/features/user-settings.js b/web_src/js/features/user-settings.js index d2617dda6a..ec99f168fe 100644 --- a/web_src/js/features/user-settings.js +++ b/web_src/js/features/user-settings.js @@ -2,15 +2,21 @@ import {hideElem, showElem} from '../utils/dom.js'; function onPronounsDropdownUpdate() { const pronounsCustom = document.getElementById('pronouns-custom'); - const pronounsInput = document.querySelector('#pronouns-dropdown input'); + const pronounsDropdown = document.getElementById('pronouns-dropdown'); + const pronounsInput = pronounsDropdown.querySelector('input'); const isCustom = !( + pronounsInput.value === '' || pronounsInput.value === 'he/him' || pronounsInput.value === 'she/her' || pronounsInput.value === 'they/them' || pronounsInput.value === 'it/its' ); if (isCustom) { - pronounsCustom.value = pronounsInput.value; + if (pronounsInput.value === '!') { + pronounsCustom.value = ''; + } else { + pronounsCustom.value = pronounsInput.value; + } pronounsCustom.style.display = ''; } else { pronounsCustom.style.display = 'none'; From 864a4332df4dafd3b1acd1fad1b5d912b9f86d3a Mon Sep 17 00:00:00 2001 From: hazycora Date: Tue, 26 Sep 2023 01:22:05 -0500 Subject: [PATCH 020/488] Make "Custom" pronoun option italic --- templates/user/settings/profile.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 9d279f23a2..0a576f9d3b 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -58,9 +58,9 @@
    they/them
    it/its
    {{if .PronounsAreCustom}} -
    {{.locale.Tr "settings.pronouns_custom"}}
    +
    {{.locale.Tr "settings.pronouns_custom"}}
    {{else}} -
    {{.locale.Tr "settings.pronouns_custom"}}
    +
    {{.locale.Tr "settings.pronouns_custom"}}
    {{end}} From 708327a548bce16a122c5f39999d14ba562330ab Mon Sep 17 00:00:00 2001 From: hazycora Date: Tue, 26 Sep 2023 12:51:30 -0500 Subject: [PATCH 021/488] set width on pronoun dropdown and custom input --- web_src/css/user.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web_src/css/user.css b/web_src/css/user.css index 33ffa1eabc..e96598768b 100644 --- a/web_src/css/user.css +++ b/web_src/css/user.css @@ -157,3 +157,7 @@ .notifications-item:hover .notifications-updated { display: none; } + +#pronouns-dropdown, #pronouns-custom { + width: 140px; +} \ No newline at end of file From 12e00abe29b7fbc091658897a711e659a67fbc7a Mon Sep 17 00:00:00 2001 From: hazycora Date: Tue, 26 Sep 2023 12:54:18 -0500 Subject: [PATCH 022/488] add any/all pronoun option to dropdown --- routers/web/user/setting/profile.go | 4 ++-- templates/user/settings/profile.tmpl | 1 + web_src/js/features/user-settings.js | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 1b1cdb54d4..7a2f6ba46d 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -46,7 +46,7 @@ func Profile(ctx *context.Context) { ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) - ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" + ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" && ctx.Doer.Pronouns != "any/all" ctx.HTML(http.StatusOK, tplSettingsProfile) } @@ -57,7 +57,7 @@ func ProfilePost(ctx *context.Context) { ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) - ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" + ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" && ctx.Doer.Pronouns != "any/all" if ctx.HasError() { ctx.HTML(http.StatusOK, tplSettingsProfile) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 0a576f9d3b..4a9074eb4d 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -57,6 +57,7 @@
    she/her
    they/them
    it/its
    +
    any/all
    {{if .PronounsAreCustom}}
    {{.locale.Tr "settings.pronouns_custom"}}
    {{else}} diff --git a/web_src/js/features/user-settings.js b/web_src/js/features/user-settings.js index ec99f168fe..5ad8bd94d4 100644 --- a/web_src/js/features/user-settings.js +++ b/web_src/js/features/user-settings.js @@ -9,7 +9,8 @@ function onPronounsDropdownUpdate() { pronounsInput.value === 'he/him' || pronounsInput.value === 'she/her' || pronounsInput.value === 'they/them' || - pronounsInput.value === 'it/its' + pronounsInput.value === 'it/its' || + pronounsInput.value === 'any/all' ); if (isCustom) { if (pronounsInput.value === '!') { From 74da95df67fc1579cb61fe1c2331a18f64903050 Mon Sep 17 00:00:00 2001 From: hazycora Date: Tue, 26 Sep 2023 12:57:01 -0500 Subject: [PATCH 023/488] move pronouns below full name in user profile settings --- templates/user/settings/profile.tmpl | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 4a9074eb4d..b8028a7007 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -21,22 +21,6 @@ -
    - -

    {{.SignedUser.Email}}

    -
    -
    - - -
    -
    - - -
    -
    - - -
    +
    + +

    {{.SignedUser.Email}}

    +
    +
    + + +
    +
    + + +
    +
    + + +
    From 21c8c0943028c02c234e346a8ad897bab125c83d Mon Sep 17 00:00:00 2001 From: hazycora Date: Wed, 27 Dec 2023 00:08:43 -0600 Subject: [PATCH 024/488] generate swagger --- templates/swagger/v1_json.tmpl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 181c564f4a..44aac59583 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -20331,6 +20331,10 @@ "type": "boolean", "x-go-name": "ProhibitLogin" }, + "pronouns": { + "type": "string", + "x-go-name": "Pronouns" + }, "restricted": { "type": "boolean", "x-go-name": "Restricted" @@ -23953,6 +23957,10 @@ "type": "string", "x-go-name": "Location" }, + "pronouns": { + "type": "string", + "x-go-name": "Pronouns" + }, "theme": { "type": "string", "x-go-name": "Theme" From bbf906eccc109c8bdc4656d4002a51e8a76b19c3 Mon Sep 17 00:00:00 2001 From: hazycora Date: Wed, 27 Dec 2023 01:18:19 -0600 Subject: [PATCH 025/488] fix locale function in profile settings --- templates/user/settings/profile.tmpl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index b8028a7007..a4b64da39b 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -22,30 +22,30 @@
    - + From 204dd9e30035cb8f975705cbc1c46862145dccbe Mon Sep 17 00:00:00 2001 From: hazycora Date: Fri, 23 Feb 2024 16:33:02 -0600 Subject: [PATCH 026/488] Add migration for pronouns --- models/forgejo_migrations/migrate.go | 2 ++ models/forgejo_migrations/v1_22/v10.go | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 models/forgejo_migrations/v1_22/v10.go diff --git a/models/forgejo_migrations/migrate.go b/models/forgejo_migrations/migrate.go index 965b748ac9..7c295247c0 100644 --- a/models/forgejo_migrations/migrate.go +++ b/models/forgejo_migrations/migrate.go @@ -56,6 +56,8 @@ var migrations = []*Migration{ NewMigration("Modify the `release`.`note` content to remove SSH signatures", forgejo_v1_22.RemoveSSHSignaturesFromReleaseNotes), // v8 -> v9 NewMigration("Add the `apply_to_admins` column to the `protected_branch` table", forgejo_v1_22.AddApplyToAdminsSetting), + // v9 -> v10 + NewMigration("Add pronouns to user", forgejo_v1_22.AddPronounsToUser), } // GetCurrentDBVersion returns the current Forgejo database version. diff --git a/models/forgejo_migrations/v1_22/v10.go b/models/forgejo_migrations/v1_22/v10.go new file mode 100644 index 0000000000..bf1639eeeb --- /dev/null +++ b/models/forgejo_migrations/v1_22/v10.go @@ -0,0 +1,16 @@ +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "xorm.io/xorm" +) + +func AddPronounsToUser(x *xorm.Engine) error { + type User struct { + Pronouns string + } + + return x.Sync(&User{}) +} From 20f96796d785603b01d173ef39a732d38790096a Mon Sep 17 00:00:00 2001 From: hazycora Date: Sat, 24 Feb 2024 12:13:49 -0600 Subject: [PATCH 027/488] use recognisedPronouns variable --- routers/web/user/setting/profile.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 7a2f6ba46d..e5750e724d 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -12,6 +12,7 @@ import ( "net/http" "os" "path/filepath" + "slices" "strings" "code.gitea.io/gitea/models/avatars" @@ -40,13 +41,17 @@ const ( tplSettingsRepositories base.TplName = "user/settings/repos" ) +var ( + recognisedPronouns = []string{"", "he/him", "she/her", "they/them", "it/its", "any/all"} +) + // Profile render user's profile page func Profile(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings.profile") ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) - ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" && ctx.Doer.Pronouns != "any/all" + ctx.Data["PronounsAreCustom"] = !slices.Contains(recognisedPronouns, ctx.Doer.Pronouns) ctx.HTML(http.StatusOK, tplSettingsProfile) } @@ -57,7 +62,7 @@ func ProfilePost(ctx *context.Context) { ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx) - ctx.Data["PronounsAreCustom"] = ctx.Doer.Pronouns != "" && ctx.Doer.Pronouns != "he/him" && ctx.Doer.Pronouns != "she/her" && ctx.Doer.Pronouns != "they/them" && ctx.Doer.Pronouns != "it/its" && ctx.Doer.Pronouns != "any/all" + ctx.Data["PronounsAreCustom"] = !slices.Contains(recognisedPronouns, ctx.Doer.Pronouns) if ctx.HasError() { ctx.HTML(http.StatusOK, tplSettingsProfile) From 8d086ad91c4ef5c0236bdb72cc3becd1356e8b78 Mon Sep 17 00:00:00 2001 From: hazycora Date: Sat, 24 Feb 2024 12:24:12 -0600 Subject: [PATCH 028/488] change "any/all" to "any pronouns" --- routers/web/user/setting/profile.go | 2 +- templates/user/settings/profile.tmpl | 2 +- web_src/js/features/user-settings.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index e5750e724d..5bbc497db8 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -42,7 +42,7 @@ const ( ) var ( - recognisedPronouns = []string{"", "he/him", "she/her", "they/them", "it/its", "any/all"} + recognisedPronouns = []string{"", "he/him", "she/her", "they/them", "it/its", "any pronouns"} ) // Profile render user's profile page diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index a4b64da39b..15eedc5056 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -41,7 +41,7 @@
    she/her
    they/them
    it/its
    -
    any/all
    +
    any pronouns
    {{if .PronounsAreCustom}}
    {{ctx.Locale.Tr "settings.pronouns_custom"}}
    {{else}} diff --git a/web_src/js/features/user-settings.js b/web_src/js/features/user-settings.js index 5ad8bd94d4..8f68b03b29 100644 --- a/web_src/js/features/user-settings.js +++ b/web_src/js/features/user-settings.js @@ -10,7 +10,7 @@ function onPronounsDropdownUpdate() { pronounsInput.value === 'she/her' || pronounsInput.value === 'they/them' || pronounsInput.value === 'it/its' || - pronounsInput.value === 'any/all' + pronounsInput.value === 'any pronouns' ); if (isCustom) { if (pronounsInput.value === '!') { From 75890e8f375da8e17c5b3c098ff0371a7f282a8b Mon Sep 17 00:00:00 2001 From: hazycora Date: Sat, 24 Feb 2024 12:24:20 -0600 Subject: [PATCH 029/488] gofumpt --- routers/web/user/setting/profile.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 5bbc497db8..24c2147a03 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -41,9 +41,7 @@ const ( tplSettingsRepositories base.TplName = "user/settings/repos" ) -var ( - recognisedPronouns = []string{"", "he/him", "she/her", "they/them", "it/its", "any pronouns"} -) +var recognisedPronouns = []string{"", "he/him", "she/her", "they/them", "it/its", "any pronouns"} // Profile render user's profile page func Profile(ctx *context.Context) { From 8cbacf850ad3e17ea3677bc39920fa832d68e695 Mon Sep 17 00:00:00 2001 From: hazycora Date: Sat, 24 Feb 2024 15:26:18 -0600 Subject: [PATCH 030/488] Add back ID field to pronouns migration looks unnecessary, but not doing this seems to cause failed tests. Other previous migrations follow this pattern as well. --- models/forgejo_migrations/v1_22/v10.go | 1 + 1 file changed, 1 insertion(+) diff --git a/models/forgejo_migrations/v1_22/v10.go b/models/forgejo_migrations/v1_22/v10.go index bf1639eeeb..819800ae71 100644 --- a/models/forgejo_migrations/v1_22/v10.go +++ b/models/forgejo_migrations/v1_22/v10.go @@ -9,6 +9,7 @@ import ( func AddPronounsToUser(x *xorm.Engine) error { type User struct { + ID int64 `xorm:"pk autoincr"` Pronouns string } From 454ceb2ada2678ecadd0bb6641e19cc6d05edcea Mon Sep 17 00:00:00 2001 From: hazycora Date: Mon, 26 Feb 2024 13:43:04 -0600 Subject: [PATCH 031/488] add some comments --- routers/web/user/setting/profile.go | 1 + web_src/js/features/user-settings.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 24c2147a03..a39c118ddd 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -41,6 +41,7 @@ const ( tplSettingsRepositories base.TplName = "user/settings/repos" ) +// must be kept in sync with `web_src/js/features/user-settings.js` var recognisedPronouns = []string{"", "he/him", "she/her", "they/them", "it/its", "any pronouns"} // Profile render user's profile page diff --git a/web_src/js/features/user-settings.js b/web_src/js/features/user-settings.js index 8f68b03b29..111bfc4465 100644 --- a/web_src/js/features/user-settings.js +++ b/web_src/js/features/user-settings.js @@ -4,6 +4,7 @@ function onPronounsDropdownUpdate() { const pronounsCustom = document.getElementById('pronouns-custom'); const pronounsDropdown = document.getElementById('pronouns-dropdown'); const pronounsInput = pronounsDropdown.querySelector('input'); + // must be kept in sync with `routers/web/user/setting/profile.go` const isCustom = !( pronounsInput.value === '' || pronounsInput.value === 'he/him' || @@ -49,8 +50,12 @@ export function initUserSettings() { const pronounsDropdown = document.getElementById('pronouns-dropdown'); const pronounsCustom = document.getElementById('pronouns-custom'); const pronounsInput = pronounsDropdown.querySelector('input'); + + // If JS is disabled, the page will show the custom input, as the dropdown requires JS to work. + // JS progressively enhances the input by adding a dropdown, but it works regardless. pronounsCustom.removeAttribute('name'); pronounsDropdown.style.display = ''; + onPronounsDropdownUpdate(); pronounsInput.addEventListener('change', onPronounsDropdownUpdate); pronounsCustom.addEventListener('input', onPronounsCustomUpdate); From 1c551f923b01292206f030bd0b533e671a238eeb Mon Sep 17 00:00:00 2001 From: hazycora Date: Mon, 26 Feb 2024 13:47:05 -0600 Subject: [PATCH 032/488] only add name attribute to pronouns input in JS, to ensure fallback works --- templates/user/settings/profile.tmpl | 2 +- web_src/js/features/user-settings.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 15eedc5056..e596fa3496 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -24,7 +24,7 @@